Previous | Tutorial index | Next
To be able to discuss computer programming languages.
In Tutorial 3, we discussed the levels of abstraction in computing. At the bottom is digital logic, and at the top is human-readable high-level code. But that abstraction is only useful because we have programming languages—formal systems of syntax and semantics designed to translate human intent into machine-executable instructions.
There is no single "best" programming language. Each language is a tool designed for a specific purpose, era, and philosophy. A language that excels at system programming (like C) might be cumbersome for data science (where Python shines). This tutorial maps the landscape of programming languages, from the raw binary of machine code to the declarative queries of SQL, explaining why we have so many and how they are translated into the 0s and 1s the CPU understands.
Machine language is the native tongue of the computer. It consists entirely of binary digits (0s and 1s) that the CPU can interpret and execute directly. No translation is needed—it is the only language the hardware truly understands.
Structure of a Machine Instruction: A typical machine instruction has two parts:
Example (x86 Architecture - simplified):
The instruction to move the value 5 into the CPU's EAX register might look like:
10111000 00000101 00000000 00000000 00000000
Why we don't use it:
0 or 1 breaks the program.Historical Context: The very first programmers (like the "ENIAC women") literally plugged wires into patch panels to represent machine code. Later, programs were entered via punch cards, where a hole represented a 1 and no hole represented a 0.
Assembly language was developed in the early 1950s as a human-readable mnemonic representation of machine code. Instead of writing 10111000, you write MOV EAX, 5.
Key Features:
ADD, SUB, JMP, CMP).LOOP:, COUNTER:) instead of using raw numeric addresses.The Assembler: An assembler is a program that translates assembly code into machine code. The translation is relatively straightforward because it's nearly a direct substitution.
Why assembly still matters:
Example (x86 Assembly):
section .data
msg db 'Hello', 0 ; Define a string "Hello"
section .text
mov eax, 4 ; System call for 'write' (Linux)
mov ebx, 1 ; File descriptor 1 (stdout)
mov ecx, msg ; Pointer to the string
mov edx, 5 ; Length of the string
int 0x80 ; Invoke the kernel (system call)
High-level languages were created to free programmers from the tedious details of the hardware. They use syntax that is closer to human language or mathematics, making programming faster, safer, and more productive.
Key Characteristics:
begin...end) and structured programming. It was the academic standard but never achieved widespread commercial adoption.ADD X TO Y GIVING Z) and excelled at handling large files and records. It is still used in banking and government legacy systems (e.g., 70% of global financial transactions touch COBOL).While the hardware generations (vacuum tubes, transistors, etc.) are distinct, software generations are broader and often overlap.
| Generation | Name | Description | Examples |
|---|---|---|---|
| 1GL | Machine Language | Binary code directly executed by the CPU. No translation needed. | 11001010 00001111 |
| 2GL | Assembly Language | Mnemonic representation using an assembler. | MOV, ADD, JMP (x86, ARM) |
| 3GL | High-Level Language | Procedural and structured languages. Portable across architectures via compilers/interpreters. | Python, C, Java, FORTRAN, COBOL |
| 4GL | Domain-Specific Language (DSL) | Languages designed for a specific application domain. Often used for database queries or report generation. Focus on what to do, not how. | SQL (databases), MATLAB (math), R (statistics), HTML/CSS (markup) |
| 5GL | Constraint / Logic / AI | Languages that use constraints and logical rules to specify problems, where the system "figures out" the solution. Focus on constraints, not steps. | Prolog, Lisp, Mercury, some modern declarative DSLs. |
How does your high-level code turn into machine code? The translation strategy has a massive impact on performance, portability, and development speed.
How does Python fit?
Python source code is first compiled by the Python interpreter into Python bytecode (saved in .pyc files). This bytecode is then executed by the Python Virtual Machine (PVM). Traditionally, the PVM interprets the bytecode line-by-line, making Python slower. However, modern Python implementations (like PyPy) include a JIT compiler, and CPython (the standard version) is gaining a JIT to boost performance significantly.
A programming paradigm is a fundamental style of programming. Languages often support multiple paradigms.
Definition: The program is structured as a sequence of instructions (procedures/functions) that operate on data. It uses loops, conditionals, and variables.
Focus: How to do it—the step-by-step process.
Languages: C, Pascal, Python (can be written procedurally).
Example:
total = 0
for i in range(1, 11):
total += i
print(total)
Definition: Organizes code around "objects" that contain data (attributes) and code (methods). Concepts include Encapsulation (bundling data/methods), Inheritance (child classes acquire parent traits), and Polymorphism (one interface, many implementations).
Focus: Modeling real-world entities and their interactions.
Languages: Java, C++, Python, C#, Ruby.
Example (Python):
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
print(f"{self.name} says woof!")
my_dog = Dog("Rex")
my_dog.bark()
Definition: Emphasizes pure functions (no side-effects, output depends only on input) and immutability (data is never changed, only transformed). Uses constructs like map, filter, reduce and recursion instead of loops.
Focus: What to compute, relying on function evaluation.
Languages: Haskell, Clojure, Erlang. Python (supports functional features like lambda, map, filter).
Example (Python):
numbers = [1, 2, 3, 4, 5]
# Doubling the list using a pure function pattern
doubled = list(map(lambda x: x * 2, numbers))
# numbers is still [1,2,3,4,5] - immutability preserved
Definition: You specify what the problem is and the conditions (constraints), but you do not specify how to find the solution. The language engine figures out the steps.
Focus: Declaring relationships and rules.
Languages: SQL, Prolog, HTML (markup).
Example (SQL):
SELECT name FROM customers WHERE age > 18 AND city = 'New York';
You are declaring which data you want, not how the database should traverse its indices to find it.
When learning Python, it's crucial to understand how it handles types compared to others.
Static Typing: Variable types are checked at compile-time. You must declare the type (or the compiler infers it strictly).
Dynamic Typing: Variable types are checked at runtime. You don't have to declare types; a variable can hold an integer, then a string.
Strong Typing: Type conversions are strict. You cannot easily add a string and an integer without explicitly converting them.
"2" + 2 throws a TypeError).Weak Typing: Types are loosely enforced; the language will implicitly convert types.
"2" + 2 results in "22").Python is: Dynamically and Strongly typed.
| Aspect | Key Concept | Real-World Example |
|---|---|---|
| Lowest Level | Machine Code (1GL) | 10111000 00000101 |
| Human-friendly Low | Assembly (2GL) | MOV EAX, 5 |
| Efficiency & Control | Compiled Languages | C, C++, Rust |
| Rapid Dev & Portability | Interpreted Languages | Python, Ruby |
| Performance + Portability | JIT Compiled | Java, C# |
| Step-by-step logic | Procedural Paradigm | C, Pascal |
| Modeling Entities | OOP Paradigm | Java, Python, C++ |
| Pure functions | Functional Paradigm | Haskell, Lisp |
| What-to-do, not how | Declarative Paradigm | SQL, Prolog |
| Type safety | Static/Dynamic Typing | Static: C; Dynamic: Python |
1. What is the lowest-level programming language that a CPU can directly execute without translation?
2. Which generation of programming language primarily uses mnemonics like ADD, SUB, and JMP?
3. FORTRAN and COBOL are examples of which generation of languages?
4. SQL (Structured Query Language) is typically categorized as a:
5. Which of the following languages typically compiles directly to a standalone machine-code executable?
6. Java compiles source code into an intermediate format called:
7. A JIT (Just-In-Time) compiler is unique because it:
8. The Python standard interpreter (CPython) primarily:
9. Which programming paradigm focuses on pure functions and avoids mutable state?
10. Which paradigm encapsulates data and behavior using classes and objects?
11. Which paradigm describes the process as a sequence of steps, using loops and conditions?
12. What happens when you try to run "Hello" + 5 in Python (which is strongly and dynamically typed)?
"Hello5"TypeError)5Hello13. Which of the following languages is statically typed?
14. Which language was specifically designed for business data processing with a verbose, English-like syntax?
15. ALGOL was historically significant because it introduced:
begin...end) and structured programming16. Which of the following is a 5th Generation (constraint/logic) programming language?
Instructions: Classify the following languages based on: (a) Generation, (b) Typical Translation Method (Compiled/Interpreted/JIT), (c) Primary Paradigm, and (d) Typing System (Static/Dynamic, Strong/Weak).
| Language | Generation | Translation | Paradigm(s) | Typing |
|---|---|---|---|---|
| Python | ||||
| C | ||||
| Java | ||||
| SQL | ||||
| x86 Assembly | ||||
| Prolog |
Instructions: Given the following simplified x86 machine code bytes (in hex), answer the questions.
B8 0A 00 00 00 (This means: Move the value 10 into the EAX register).
BB 05 00 00 00 (Move the value 5 into the EBX register).
01 D8 (Add EBX to EAX).
int variables).Instructions: Read the following short code snippets and identify which programming paradigm(s) they represent (Procedural, OOP, Functional, Declarative). Justify your choice.
Snippet A (Python):
def factorial(n):
if n <= 1:
return 1
else:
return n * factorial(n-1)
Identify & Justify: ________________________________
Snippet B (Python):
class Car:
def __init__(self, make, model):
self.make = make
self.model = model
def start(self):
print(f"{self.make} {self.model} is starting.")
my_car = Car("Toyota", "Camry")
my_car.start()
Identify & Justify: ________________________________
Snippet C (SQL):
SELECT product_name, price
FROM inventory
WHERE quantity > 10
ORDER BY price DESC;
Identify & Justify: ________________________________
Snippet D (Python):
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
Identify & Justify: ________________________________
Instructions: Create a timeline of the major programming languages mentioned in this tutorial (Machine/Assembly, FORTRAN, ALGOL, COBOL, C, C++, Java, Python). For each, list:
Answer the following questions in complete sentences. Each response should be 3–5 sentences unless otherwise specified.
1. Explain the difference between a compiler and an interpreter. Which approach is used by the standard version of Python (CPython), and what is the consequence for execution speed?
2. Why is Assembly language (2GL) still used today when high-level languages are much easier to write?
3. Describe one key difference between the procedural paradigm and the object-oriented paradigm. Give a real-world scenario where OOP would be a better choice than procedural programming.
4. What is the difference between a 4GL (Domain-Specific Language) and a 3GL (General-Purpose Language)? Provide an example of each and explain why a 4GL might be preferred for its specific domain.
5. Why is Python considered a "multi-paradigm" language? Give an example of how you could write code in Python using two different paradigms discussed in this tutorial.
Answer the following questions in 300–500 words each.
6. Trace the evolution of programming languages from the 1940s to the present day. How did the shift from 1GL to 3GL (and beyond) change the nature of software development and who could become a programmer?
Suggested outline:
7. Compare and contrast compiled languages (like C), JIT-compiled languages (like Java), and interpreted languages (like Python) in terms of performance, development speed, portability, and use cases. Which type of language is best for a system-level operating system kernel, and which is best for a rapid data science script, and why?
Suggested outline:
These questions require additional research beyond the tutorial content.
8. Research the history of the ALGOL programming language. Why is it considered one of the most influential languages, even though it was not commercially successful? How did ALGOL-60 influence the design of C, Pascal, and even modern Python?
9. Research the concept of "Turing Completeness" (briefly introduced in Tutorial 4). Are all programming languages Turing Complete? What does this imply about the theoretical capabilities of languages like C, Python, and even SQL? Provide specific evidence for your answer.
10. Research the development of Rust or Go. Why were these modern compiled languages created? What specific problems with C and C++ (e.g., memory safety, concurrency) were they trying to solve, and how do they fit into the landscape of programming languages today?