,

Contents · Language paradigms (OO, functional, logic, dataflow)


Object-oriented (OO)

  • Key ideas: objects, classes, inheritance, polymorphism, dynamic dispatch.
  • Design patterns and composition vs inheritance; interfaces/traits.
  • Runtime: vtables, interface tables, subtype checks, GC-friendly layouts.
dispatch(obj, m): slot = vtable[obj.klass][m]; jump slot

Functional programming (FP)

  • First-class functions, immutability, higher-order combinators, recursion.
  • Evaluation: strict vs lazy; thunks; tail calls; algebraic data types and pattern matching.
  • Runtime: closures, garbage collection, optimizing with fusion and deforestation.
map f (x:xs) = f x : map f xs

Logic programming

  • Programs as relations; resolution and unification; Prolog, Datalog.
  • Backtracking search, cut, and tabling (memoization) to avoid recomputation.
  • Runtime: WAM (Warren Abstract Machine) for efficient unification.
ancestor(X,Y) :- parent(X,Y).
ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y).

Dataflow and reactive

  • Computation driven by data availability; nodes fire when inputs ready.
  • Reactive systems use push-based events and signal propagation.
  • Runtime: schedulers, backpressure, and fusion for throughput.
z := map2 (+) x y; z updates whenever x or y updates

Multi-paradigm languages

  • Many modern languages mix OO + FP + imperative (Scala, Kotlin, Swift, Rust).
  • Paradigms influence library design, error handling, and concurrency models.
  • Interoperability and FFI shape the practical paradigm choices.

Implementation notes: runtime + compiler implications

  • OO: vtable layout, inline caches, devirtualization, escape analysis.
  • FP: closure conversion, GC pressure, defunctionalization, CPS.
  • Logic/Dataflow: backtracking stacks, schedulers, and determinism control.

Exercises

  1. Implement dynamic dispatch with a simple vtable and measure call overhead.
  2. Build a tiny interpreter for a lambda-calculus subset with closures and beta-reduction.
  3. Write a mini Prolog and solve family-tree queries using unification and backtracking.
Paradigms shape how we think and how runtimes execute—understanding them helps you pick the right tools and build better compilers.