Basics Story

Chapter #8 – Programming Languages

compiled, interpreted, typing, paradigms, memory management, choosing

8.0  Prologue

A programming language is a formal notation for expressing computation. Languages differ in how they translate to machine code, what guarantees they make about types, which programming styles they support, and how they manage memory. Understanding these dimensions makes it easier to choose the right language for a job and to read code written by others.

8.1  Compiled vs. Interpreted vs. JIT

  • Compiled (ahead-of-time): a compiler translates source code directly to native machine code before execution. Examples: C, C++, Rust, Go, Zig. Advantage: maximum runtime speed, no interpreter overhead. Disadvantage: platform-specific binary; longer build times.
  • Interpreted: an interpreter reads source (or bytecode) and executes it instruction by instruction at runtime. Examples: Python, Ruby, shell scripts. Advantage: fast to run a first version; easy to interact via a REPL. Disadvantage: 10–100× slower than native for CPU-bound work.
  • JIT (Just-In-Time) compiled: code starts as bytecode and is profiled at runtime; hot paths are compiled to native machine code on the fly. Examples: Java, C#, JavaScript (V8, SpiderMonkey), PyPy. Advantage: near-native performance after warmup; still platform-portable. Disadvantage: warmup latency; higher memory use; less predictable pauses.
In practice the boundaries blur: Python uses a bytecode compiler step; LLVM-based languages like Swift and Rust are compiled but rely on a sophisticated middle layer.

8.2  Static vs. Dynamic Typing

  • Static typing: types are checked at compile time; a variable’s type is fixed. Examples: C++, Rust, Java, C#, Go, TypeScript. Catches many errors before the program runs; enables richer tooling (auto-complete, safe refactoring).
  • Dynamic typing: types are checked at runtime; a variable can hold any type at any time. Examples: Python, JavaScript, Ruby. Faster to write initially; type errors surface at runtime, often in rarely executed paths.
  • Gradual typing: type annotations are optional; a type checker enforces them where present. Examples: Python + mypy/pyright, TypeScript. Lets teams add types incrementally to dynamic codebases.
Static typing does not guarantee correctness (a C program can type-check and still crash), but it eliminates an entire class of bugs and enables better editor tooling.

8.3  Programming Paradigms

A paradigm is a style of programming. Most modern languages blend several:
  • Imperative: sequences of statements that mutate state. Closest to how hardware works. C, Pascal.
  • Object-oriented (OOP): data and behaviour bundled into objects; classes, inheritance, polymorphism. Java, C#, Python, C++.
  • Functional: computation as evaluation of pure functions; avoids mutable state; higher-order functions, closures. Haskell, Erlang, F#; functional features now standard in Python, JavaScript, Rust, C++.
  • Declarative: describe what you want, not how to compute it. SQL, HTML/CSS, Prolog, configuration languages (YAML, HCL).
  • Generic / parametric: algorithms and data structures written once and used with any type that satisfies constraints. C++ templates, Rust generics, Java/C# generics.

8.4  Language Families and Use Cases

Language Typing Execution Primary Use
C static compiled OS kernels, embedded, firmware
C++ static compiled Games, HPC, systems, embedded
Rust static compiled Safe systems, WebAssembly, network services
Go static compiled Cloud tools, network servers, CLIs
Java static JIT (JVM) Enterprise, Android
C# static JIT (.NET) Enterprise, games (Unity), Windows
Python dynamic interpreted + bytecode Data science, ML, scripting, web back-end
JavaScript / TypeScript dynamic / gradual JIT (V8) Web front-end, Node.js back-end
SQL declarative interpreted Relational databases

8.5  Memory Management Strategies

One of the most significant differences between languages is how they manage heap-allocated memory:
  • Manual (C, C++): the programmer explicitly allocates (malloc / new) and frees (free / delete) memory. Maximum performance and control; prone to leaks, use-after-free, and double-free bugs.
  • Garbage collection (Java, Python, C#, Go, JavaScript): the runtime periodically traces reachable objects and reclaims the rest. Convenient; eliminates use-after-free; GC pauses can cause latency spikes.
  • Ownership and borrowing (Rust): compile-time rules ensure that every allocation has exactly one owner, no reference outlives the owned data, and aliased mutable access is impossible. No GC overhead; no use-after-free at runtime; initially steep learning curve.
  • Reference counting (Python, Swift, PHP): each object tracks how many references point at it; freed when the count reaches zero. Convenient; fails to collect cycles without a supplemental cycle collector.

8.6  Choosing a Language

No language wins on every dimension. Useful questions to ask:
  • Performance requirements? Hard real-time or high-throughput → C, C++, or Rust. Data analysis scripts → Python is fine.
  • Platform constraints? iOS → Swift; Android → Kotlin; browser → JavaScript or WebAssembly; embedded bare-metal → C or Rust.
  • Ecosystem? Python dominates ML libraries; Go dominates cloud tooling; JavaScript dominates web; Java dominates enterprise.
  • Safety requirements? Networked system handling untrusted data → prefer memory-safe language (Rust, Go, Java, C#) over C.
  • Team expertise and hiring pool? The best language is often the one your team already knows well.
  • Interoperability? Existing C/C++ codebase → C-compatible FFI matters (Rust, Go, and most managed languages have one).

8.7  Epilogue

Programming languages encode a set of trade-offs. Knowing those trade-offs helps you read unfamiliar code more quickly and make better architectural decisions. The next chapter surveys the tooling that surrounds these languages: editors, build systems, version control, and testing.

8.8  References

TIOBE Language Popularity Index
Stack Overflow Developer Survey — Languages section
Programming Paradigm — Wikipedia
The Rust Programming Language (free online book)