Last updated: 2026-09-26

U
Undergraduate level
FDN
Foundational โ€” Knowledge that endures for decades โ€” core principles

Polyglot Programming & Paradigm Shifting

Languages are ephemeral; paradigms are foundational. Learn only syntax and every new language is a fresh start; learn how memory, execution flow and state change are managed across paradigms and you can pick up a new language in a weekend โ€” because you will recognise it as a new accent, not a new tongue.

The Meta-Skill of Language Translation

When you meet an unfamiliar language, interrogate it with the same six questions and map the answers onto what you already know. This approach โ€” organising paradigms by the underlying dimensions they vary along (state, control flow, binding, and so on) rather than treating each language's syntax as sui generis โ€” is the same one Van Roy and Haridi take at book length, building up every major paradigm from a shared kernel language by adding one concept at a time1: paradigms turn out to be points in a shared space, not an unrelated list to memorise separately.syntax differs, the six questions dont

QuestionWhat you're mappingExample spread
Where do values live, and who frees them?Memory modelGC heap (Java/Ruby) โ†” ownership (Rust) โ†” manual (C)
When is a name visible, and when does its value die?Scope & lifetimeLexical closures โ†” block scope โ†” dynamic scope
When are types checked, and how strong is the promise?Type disciplineStatic/nominal (Java) โ†” static/structural (Go, TS) โ†” dynamic/duck (Ruby, Python)
How does one piece of behaviour substitute for another?PolymorphismSubtyping โ†” interfaces/protocols โ†” higher-order functions โ†” generics
What changes, and who is allowed to change it?State modelMutable objects โ†” immutable values โ†” monadic effects
Who decides what runs next?Control flowCall stack โ†” event loop โ†” solver/backtracking

The Paradigm Landscape

  • Imperative & procedural. Step-by-step state manipulation through explicit instructions grouped into routines. The focus is how: sequence, selection, iteration. Every mainstream language contains this core, which is why it is taught first โ€” and why its habits (shared mutable state everywhere) are what the other paradigms exist to discipline.
  • Object-oriented. Encapsulating state and behaviour into cohesive objects that communicate โ€” as the rest of this track explores โ€” by message passing, with polymorphism and interface contracts enforcing structural invariants. The deep idea is less "classes" than protected state behind a behavioural boundary (see Event-Driven Programming for messaging taken to its logical conclusion). Classes are simply the dominant mechanism for building that boundary, not the only one; see Prototype-Based Programming for the delegation-based alternative used by Self and JavaScript.
  • Functional. Computation as evaluation of pure functions; mutable state and side effects pushed to the edges. Higher-order functions are first-class citizens: functions consume and return functions. You already use this paradigm every time you write a map/filter chain, a Ruby block, or a Java stream โ€” the paradigm arrived inside the OO languages while nobody was watching.
  • Event-driven. Control flow inverted: the system idles until a message arrives โ€” a click, a packet, a domain event โ€” and routes it to a handler. Covered in depth on Event-Driven Programming, including what the inversion costs in traceability.
  • Logic programming. Declare facts and rules about what's true, and let a resolution engine derive new facts by backward-chaining through them โ€” Prolog's approach, formalised by Kowalski's insight that a restricted fragment of first-order logic (Horn clauses) could double as an executable programming language2. You're not writing a search; you're writing the space of facts the engine searches.
  • Goal-oriented programming. A close cousin, easy to conflate with logic programming but answering a genuinely different question: not "is this true?" but "what sequence of actions gets me from here to a declared goal state?" Each action declares its own preconditions and effects, and a planner searches for an ordered, often cost-minimising, path from the current state to the goal. That is the STRIPS formalism from 1970s AI planning research3, repackaged for real-time NPC behaviour as GOAP and demonstrated as a runnable planner (alongside Prolog-style backward chaining) in PatLang's goal-oriented programming demo. A build tool like Make is the same idea wearing yet another disguise โ€” declare a goal (a target file), declare what it depends on, and let the tool work backward from the goal to find which rules actually need to run; see below. See GOAP vs Rule-Based Reasoning for the same small domain solved both ways side by side, and for real problems each approach actually suits.

One Problem, Six Accents

Total the prices of in-stock items" โ€” watch the state and control flow move between paradigms:

# Imperative: explicit accumulation, mutable loop state
total = 0
for item in items:
    if item.in_stock:
        total += item.price
# Object-oriented: the collection owns the behaviour
total = basket.total_in_stock()   # state hidden behind the message
# Functional: expression over immutable data, no assignment
total = sum(i.price for i in items if i.in_stock)
# Event-driven: totals maintained by reacting to facts
bus.subscribe("item.stocked",   lambda e: ledger.add(e.price))
bus.subscribe("item.sold_out",  lambda e: ledger.remove(e.price))
% Logic: declare the relation; the engine finds the total
in_stock_price(P) :- item(I), in_stock(I), price(I, P).
total(T) :- findall(P, in_stock_price(P), Ps), sum_list(Ps, T).
# Goal-oriented (Make): declare the goal (an up-to-date total.txt) and
# what it depends on; make works backward from the goal to find which
# rules must fire, and in what order โ€” you never write "run step 1, then
# step 2", only what each step needs and produces.
total.txt: in_stock_items.txt
	awk '{s+=$$2} END {print s}' in_stock_items.txt > total.txt

in_stock_items.txt: items.txt
	awk '$$3=="instock" {print $$1, $$2}' items.txt > in_stock_items.txt

Run make total.txt and Make doesn't execute a script from top to bottom โ€” it starts from the goal, notices total.txt depends on in_stock_items.txt, notices that depends on items.txt, and only then decides which rules actually need to run and in what order. That's the same backward-from-the-goal shape as a GOAP planner searching from a desired world-state back to the current one, just applied to files and timestamps instead of a game character's preconditions and effects.

Choosing (and Composing) the Tool

Real architectures rarely stay inside one paradigm; they compose them. A typical modern service is an object-oriented shell (modules, dependency boundaries, SOLID discipline) around functional stream processing (pure transformations over immutable events), driven by an event loop, with a declarative configuration layer on top. The skill is not picking a winner โ€” it is noticing which paradigm's guarantees each layer of the problem needs: auditability wants immutable events; complex domain invariants want encapsulating objects; concurrency wants purity; interaction wants events.

The practical advice: learn one language from an unfamiliar paradigm properly โ€” far enough to feel its idioms stop being weird. Each paradigm permanently adds a lens, and code in your home language improves because you now see which of its features are borrowed lenses too.fluency needs discomfort first

References


  1. Van Roy, P., & Haridi, S. (2004). Concepts, Techniques, and Models of Computer Programming. MIT Press. โ†ฉ

  2. Kowalski, R. (1974). Predicate logic as a programming language. Proceedings of IFIP Congress 1974, Stockholm. North-Holland, 569โ€“574. โ†ฉ

  3. Fikes, R. E., & Nilsson, N. J. (1971). STRIPS: A new approach to the application of theorem proving to problem solving. Artificial Intelligence, 2(3โ€“4), 189โ€“208. https://doi.org/10.1016/0004-3702(71)90010-5 โ†ฉ

Graduate Attributes

Directly developed

  • Self-Directed Learner: Readers plan their study by learning one language from an unfamiliar paradigm properly to gain new perspectives.
  • Critical Thinker: Readers interrogate unfamiliar languages with six questions to map answers onto existing knowledge.

Modelled on this page

  • Subject Specialist: Systematic knowledge of paradigms is applied to real problems by composing different paradigms for specific architectural needs.
  • Reflective: Assumptions about language learning are examined by contrasting syntax memorisation with understanding foundational paradigms.
  • Confident Communicator: Complex technical concepts are communicated clearly through metaphors such as accents and lenses.

University of Reading Graduate Attributes framework.