optional · CSS study notes
II.5 Types of Programming Languages (2017)
⬆️ P-I.II. Programming Fundamentals · Question Bank · Chapter II (2016–2026)
🧠
Remember: Ask three separate questions: level, execution method, paradigm.
Start here — what you should be able to do
- Compare machine, assembly and high-level code.
- Explain compiler, interpreter and bytecode/JIT workflows.
- Classify a language without confusing paradigm with implementation.
Reading order: foundation checks → full notes and examples → exam traps → self-test without notes → past-paper answers. All sections below remain part of the topic; code examples are kept in full.
Foundation checks
Keep the classifications separate
| Question | Categories | Example |
|---|---|---|
| How close to hardware? | Machine, assembly, high-level | Assembly names registers/instructions. |
| How is it executed? | Ahead-of-time compilation, interpretation, JIT, combinations | CPython compiles source to bytecode for its interpreter. |
| How is code organised? | Procedural, object-oriented, functional, logic | C++ supports several paradigms. |
- A language is not permanently tied to one execution method.
- Portability depends on libraries, platform features and implementation as well as language level.
- Execution speed depends on the algorithm and generated code; assembly is not automatically fastest.
- 1GL–5GL is a textbook classification; later generations are not universally better.
Source: Python glossary: bytecode.
1. Classification by Level
- Low-level languages
- Machine language: binary (0s and 1s), directly executed by hardware, no translation needed
- Assembly language: mnemonic codes (e.g.
MOV,ADD), translated by an assembler
- High-level languages
- Human-readable syntax (e.g. C, C++, Java, Python), translated by a compiler or interpreter
- Portable across machine architectures (unlike low-level languages)
2. Classification by Translation Method
- Compiled languages: entire source translated to machine code before execution (C, C++)
- Interpretation: a runtime executes source or an intermediate representation; literal line-by-line execution is only a simplified model.
- Hybrid (bytecode-based): compiled to intermediate bytecode, then interpreted/JIT-compiled by a virtual machine (Java, C#)
3. Classification by Paradigm
- Procedural: sequence of instructions/procedures (C, Pascal)
- Object-Oriented: organizes code around objects/classes (C++, Java)
- Functional: computation as evaluation of functions (Haskell, parts of Python)
- Logic-based: facts and rules, inference-driven (Prolog)
- Scripting: lightweight, often interpreted, used for automation/glue code (Bash, Python, JavaScript)
4. Classification by Generation
| Generation | Description | Example |
|---|---|---|
| 1GL | Machine language — raw binary | Direct 0/1 instructions |
| 2GL | Assembly language — mnemonics | MASM, NASM |
| 3GL | High-level, procedural | C, Pascal, FORTRAN |
| 4GL | Closer to human language, often domain-specific (e.g. database queries) | SQL |
| 5GL | Constraint/goal-based, AI-oriented — program describes the problem, not the steps | Prolog |
5. 💻 Code Examples: C & C++
The same problem (represent a point and print it) written procedurally in C vs object-oriented in C++ — both are compiled, 3GL, high-level languages, but the paradigm differs:
C (procedural — data and functions are separate):
#include <stdio.h>
struct Point { int x, y; };
void printPoint(struct Point p) {
printf("(%d, %d)\n", p.x, p.y);
}
int main(void) {
struct Point p1 = {3, 4};
printPoint(p1); // procedural: pass the data to a free-standing function
return 0;
}
// compiled with: gcc file.c -o file
C++ (object-oriented — data and behavior bundled together):
#include <iostream>
using namespace std;
class Point {
int x, y;
public:
Point(int a, int b) : x(a), y(b) {}
void print() { cout << "(" << x << ", " << y << ")" << endl; }
};
int main() {
Point p1(3, 4);
p1.print(); // OOP: the method is called ON the object
return 0;
}
// compiled with: g++ file.cpp -o file
- Both are compiled (not interpreted) high-level, 3GL languages — the difference tested here is paradigm (procedural vs OOP), not translation method or generation
6. MCQ Traps
- Machine language needs no translator; assembly needs an assembler; high-level needs a compiler/interpreter
- Java is not purely interpreted — it's compiled to bytecode, then run on the JVM (hybrid model)
- Low-level languages are hardware-specific; high-level languages are portable
- Generation number does not equal quality — 4GL/5GL are suited to specific domains (queries, AI), not general-purpose replacements for 3GLs
- Assembly language is 2GL and still needs an assembler, not a compiler, to become machine code
7. ✅ Self-Test Questions (with Answers)
Q1. Differentiate low-level and high-level programming languages with one example each.
Answer
- Machine language: CPU instruction encodings; architecture-specific.
- Assembly: symbolic instructions and registers, normally translated by an assembler.
- High-level language: abstractions such as expressions, functions and data structures; translated or executed by an implementation.
- Control: low-level code exposes hardware details; higher-level code usually reduces manual detail.
- Portability: high-level source is often easier to port, but platform-specific libraries and assumptions still matter.
- Performance: depends on algorithms, compiler output and hardware; language level alone does not determine speed.
| Aspect | Low-Level Language | High-Level Language |
|---|---|---|
| Example | Assembly (also machine code) | C++ (also C, Java, Python) |
| Generation | 1GL and 2GL | 3GL and above |
| Translator needed | Assembler (machine code needs none) | Compiler or interpreter |
| Portability | Machine-dependent | Portable across machines |
| Ease of writing | Difficult, error-prone | Easy, English-like |
| Performance | Depends on code and implementation | Depends on code and implementation |
| Typical use | Device drivers, embedded, OS kernels | Applications, general-purpose software |
; ASSEMBLY (low-level) -- add 5 and 3
MOV AX, 5
ADD AX, 3
// C++ (high-level) -- the same task, one readable line
int sum = 5 + 3;
cout << sum; // prints 8
- MCQ trap: machine language needs no translator at all; only assembly needs an assembler (not a compiler).
- Examiners also test that assembly is low-level but still not machine code — it must be assembled first — and that low-level does not mean "less capable", merely closer to the hardware.
Q2. Where does Java fit in the compiled vs interpreted classification, and why?
Answer
javactranslates Java source into class-file bytecode.- A compatible JVM executes that bytecode.
- A JVM may interpret code and JIT-compile selected paths; the exact strategy varies.
- The bytecode is portable across compatible JVM environments, subject to dependencies.
- Memory hook: source → bytecode → JVM → execution.
- Comparison: CPython also uses bytecode; native C++ workflows usually compile and link ahead of time.
- Avoid: saying Python has no intermediate form, or ranking all languages as fastest/slowest.
| Aspect | C / C++ (compiled) | Python (interpreted) | Java (hybrid) |
|---|---|---|---|
| Execution tools | Compiler, linker and runtime | Interpreter/runtime, often bytecode | Compiler and JVM |
| Intermediate output | Object/native code in a typical build | Often bytecode in CPython | Bytecode (.class) |
| Portability | Recompile per platform | Source is portable | Bytecode runs anywhere a JVM exists |
| Performance | Workload dependent | Workload dependent | Workload dependent |
javac Hello.java // COMPILE -> Hello.class (bytecode, machine-independent)
java Hello // JVM LOADS + INTERPRETS/JIT-compiles the bytecode
// Contrast with C++, which goes straight to native code:
// g++ hello.cpp -o hello -> ./hello
- This design is the source of Java's slogan "Write Once, Run Anywhere": the same
.classfile runs on Windows, Linux or macOS provided a JVM is installed, whereas a C++ executable must be recompiled for each platform. - C# uses the same approach, compiling to CIL/MSIL for the CLR.
MCQ trap: Java is not purely interpreted — saying so is the classic wrong option. Note also that portability belongs to the bytecode, not the JVM: the JVM itself is platform-specific, and a different JVM build is needed for each operating system.
Q3. Name one language each for the procedural, OOP, and functional paradigms.
Answer — key points
- A paradigm is the style in which a program is organised — it is independent of a language's level, generation or translation method.
- Procedural — C (also Pascal, FORTRAN, COBOL): the program is a sequence of procedures/functions operating on data that is kept separate from them
- Object-Oriented — C++ (also Java, C#, Smalltalk): data and the operations on it are bundled into objects/classes, supporting encapsulation, inheritance and polymorphism
- Functional — Haskell (also Lisp, Scheme, ML, and functional features in Python): computation is the evaluation of mathematical functions, avoiding mutable state and side effects
// PROCEDURAL style: data and function are separate
struct Point { int x, y; };
void printPoint(Point p) { cout << "(" << p.x << "," << p.y << ")"; }
// OBJECT-ORIENTED style: data and behaviour bundled together
class Point2 {
int x, y;
public:
Point2(int a, int b) : x(a), y(b) {}
void print() { cout << "(" << x << "," << y << ")"; }
};
// FUNCTIONAL style: pure function, no state mutated, no side effects
int square(int n) { return n * n; } // same input always gives same output
- Two further paradigms worth naming: logic-based — Prolog (facts, rules and inference) and scripting — Python/Bash/JavaScript (lightweight automation and glue code)
MCQ trap: C++ is multi-paradigm. C and C++ overlap but are distinct languages; valid C is not automatically valid C++. Paradigm, language level and execution method are separate classifications.
Q4. Where does SQL fit in the generational classification of languages, and why is it described as "closer to human language"?
Answer — key points
- SQL is the standard example of a fourth-generation language (4GL).
- A 4GL is non-procedural and domain-specific: the programmer specifies the result wanted, and the system's engine (here, the DBMS query optimiser) works out the access path, the loops and the ordering.
- SQL is called "closer to human language" because its statements read almost as English sentences —
SELECT name FROM students WHERE marks > 80 ORDER BY nameis intelligible to a non-programmer — and because a single line of it replaces dozens of lines of 3GL code. - This conciseness and readability, not any increase in raw power, is what separates 4GL from 3GL.
-- SQL (4GL): declare WHAT is wanted; the DBMS decides how to get it
SELECT name, marks FROM students WHERE marks > 80 ORDER BY marks DESC;
// C++ (3GL): the same task, with the HOW written out in full
for (int i = 0; i < n; i++) // scan
if (students[i].marks > 80) // filter
selected[k++] = students[i];
for (int i = 0; i < k - 1; i++) // sort, by hand
for (int j = 0; j < k - 1 - i; j++)
if (selected[j].marks < selected[j+1].marks)
swap(selected[j], selected[j+1]);
for (int i = 0; i < k; i++) // output
cout << selected[i].name << " " << selected[i].marks << endl;
- Other 4GLs: report generators, spreadsheet formulas, MATLAB, SAS, Oracle Forms
- 3GL → 4GL shift: procedural → declarative; general-purpose → domain-specific; many statements → one statement
- MCQ trap: SQL is a 4GL and a declarative, domain-specific language, not a general-purpose one — it cannot by itself build an operating system or a game.
- Examiners also test that SQL is not 5GL: 5GL (Prolog) is inference/constraint-based, whereas 4GL merely describes a desired data result.
Q5. Why is Prolog (a 5GL) described as goal/constraint-based rather than procedural?
Answer — key points
- Because in Prolog the programmer states what is true and what is to be proved, not how to compute it.
- A Prolog program is a knowledge base of facts and rules
- the programmer then poses a goal (query), and the language's built-in inference engine searches for a solution automatically using unification, resolution and backtracking.
- Control flow — the loops, counters and conditionals a procedural programmer must write by hand — is supplied by the engine, not by the code.
- This makes Prolog declarative, the defining trait of a fifth-generation language (5GL) and the reason it is associated with AI, expert systems and natural-language processing.
% FACTS
parent(ali, bilal).
parent(bilal, zara).
% RULE: X is a grandparent of Z if X is a parent of Y and Y of Z
grandparent(X, Z) :- parent(X, Y), parent(Y, Z).
?- grandparent(ali, zara). % GOAL -> true
?- grandparent(ali, Who). % Who = zara (engine finds it by backtracking)
// The PROCEDURAL equivalent: the programmer must code the search himself
bool grandparent(string x, string z) {
for (auto &p1 : facts) // explicit loop
if (p1.parent == x)
for (auto &p2 : facts) // explicit nested loop
if (p2.parent == p1.child && p2.child == z)
return true;
return false;
}
| Aspect | Procedural (3GL, e.g. C) | Logic / Goal-based (5GL, Prolog) |
|---|---|---|
| Programmer specifies | HOW: the exact steps | WHAT: facts, rules and the goal |
| Control flow | Written by hand (loops, ifs) | Supplied by the inference engine |
| Searching | Explicitly coded | Automatic backtracking |
| Typical use | General-purpose software | AI, expert systems, NLP |
MCQ trap: a higher generation number does not mean a better language — 5GLs are specialised for inference-driven problems and are poor choices for systems programming, where a 3GL such as C remains the right tool.
8. 📜 Past-Paper Questions & MCQs (CSS 2016–2026)
2017 · Paper-I · Q3(a) · 8 marks
Recall cue: Compare abstraction, portability and translation; distinguish assembler, compiler and interpreter.
Q. Elucidate the three types of programming languages (machine, low-level, high-level), giving details of how low-level and high-level language are converted into machine language.
Answer — key points
- Machine language: CPU instructions specific to an architecture; the CPU executes them directly. Speed depends on the actual instructions and algorithm.
- Low-level (assembly) language: symbolic mnemonics such as
ADD,MOV. It is close to hardware, easier than binary, and machine-dependent. - High-level language: English-like, portable and machine-independent (C++, Java, Python). It is easy to write but needs translation.
- Conversion of assembly: an assembler converts each mnemonic into machine code (one-to-one).
- Conversion of high-level code:
- a compiler translates the whole program into object code through lexical, syntax and semantic analysis, intermediate code, optimisation and code generation, and the linker then produces the executable
- Interpretation: a runtime executes source or an intermediate representation; literal line-by-line execution is only a simplified model.
- Comparison: abstraction and hardware control differ; neither language level nor generation guarantees execution speed.
Recall check and coverage
- Explain the three learning outcomes at the top without looking.
- Reproduce one example or trace and test a boundary case.
- Answer each self-test, then compare with the key.
- Attempt each recorded past-paper task on this page.
Recorded written references: 2017 · Paper-I · Q3(a) · 8 marks
Evidence limit: this page preserves the question records found in your Notion notes. Disputed labels and questions not checked against original PDFs remain flagged in the Question Bank; this is not a claim of exhaustive original-paper verification.