🧬 Languages & Compilers
How code becomes behavior. 50 topics, from beginner to advanced.
Programming languages and compilers explain how source code becomes instructions a machine can run. This area covers lexing, parsing, type systems, interpreters, compilers and optimization, along with language features such as closures, generics and memory management. Understanding them helps you write clearer code and read error messages more effectively.
Who this area is for
Developers who want to understand the tools they use, students of compilers, and language designers.
Real-world use cases
- Building a small domain-specific language for a configuration format.
- Understanding why a compiler rejects code with a type error before it runs.
- Choosing between an interpreted and a compiled language for a project.
- Writing a linter that finds unused variables before code is run.
- Choosing between compiled and interpreted languages for a project that needs fast startup.
Topics in Languages & Compilers
Beginner (17)
- Compiled vs Interpreted Languages — Translating ahead of time versus executing line by line.
- Syntax and Semantics — Form of programs versus their meaning.
- Programming Paradigms — Styles such as imperative, declarative and functional.
- Static vs Dynamic Typing — Types checked before running versus during execution.
- Strong vs Weak Typing — How strictly a language prevents mixing types.
- Garbage Collection — Automatic reclamation of unused memory.
- Manual Memory Management — Explicit allocation and freeing by the programmer.
- Pointers — Variables holding memory addresses.
- Stack vs Heap — Automatic call-frame memory versus dynamically allocated memory.
- Undefined Behavior — Program actions the language standard leaves unspecified.
- Preprocessors and Macros — Text or syntax substitution before compilation.
- Linking and Loading — Combining object files and placing programs in memory.
- Bytecode — Portable low-level instructions run by a virtual machine.
- Virtual Machines — Software emulating a machine to run bytecode.
- Lexical Analysis — Splitting source text into tokens.
- Parsing — Building structure from tokens according to a grammar.
- Abstract Syntax Trees — Tree representations of program structure.
Intermediate (17)
- Symbol Tables — Compiler maps tracking identifiers and their attributes.
- Semantic Analysis — Checking types and scope rules in a parsed program.
- Type Inference — Automatically deducing types without annotations.
- Generics and Templates — Writing code parameterized over types.
- Compiler Phases — Frontend, optimization and backend stages.
- Recursive Descent Parsing — Hand-written top-down parsing with mutually recursive functions.
- LL and LR Parsing — Families of deterministic parsing algorithms.
- Parser Generators — Tools producing parsers from grammar specifications.
- Intermediate Representations — Language-neutral forms used between compiler stages.
- Three-Address Code — Simple IR with at most three operands per instruction.
- Static Single Assignment — IR where each variable is assigned exactly once.
- Control Flow Graphs — Graphs of basic blocks and jumps.
- Code Generation — Emitting machine code from an IR.
- Register Allocation — Mapping many variables onto few CPU registers.
- Compiler Optimizations — Transformations making code faster or smaller.
- Constant Folding and Propagation — Evaluating known values at compile time.
- Dead Code Elimination — Removing code that never affects results.
Advanced (16)
- Loop Optimizations — Unrolling, hoisting and fusion to speed loops.
- Inlining — Replacing a call with the function's body.
- Data-Flow Analysis — Computing facts about values across a program.
- Just-In-Time Compilation — Compiling hot code at runtime.
- LLVM — Modular compiler infrastructure with a common IR.
- Type Systems — Rules assigning and checking types.
- Algebraic Data Types — Types built from sums and products.
- Pattern Matching — Destructuring values by shape in branching.
- Ownership and Borrowing — Compile-time rules ensuring memory safety without GC.
- Hindley-Milner Inference — Classic algorithm for polymorphic type inference.
- Dependent Types — Types that depend on values.
- Linear and Affine Types — Types restricting how many times a value is used.
- Garbage Collection Algorithms — Mark-sweep, copying and generational collectors.
- Domain-Specific Languages — Languages tailored to a narrow problem area.
- Operational and Denotational Semantics — Formal ways of defining program meaning.
- Language Interoperability — Calling code across languages via FFI.
How to study Languages & Compilers
Take a tiny language, such as arithmetic expressions, and build a tokenizer, a parser and an evaluator for it. Then add a variable and a loop. Each step makes the later topics, such as bytecode and data-flow analysis, concrete.
Frequently asked questions
What is the difference between a compiler and an interpreter?
What does a parser do?
What is static typing?
Do I need to build a compiler to understand languages?
Why do languages have different semantics for the same syntax?
Open the interactive Languages & Compilers area Take the Languages & Compilers quiz
Other areas
- 💻 Programming Fundamentals
- 🧱 Data Structures
- ⚙️ Algorithms
- 🔌 Computer Architecture & Logic
- 🖥️ Operating Systems
- 🌐 Computer Networks
- 🗄️ Databases
- 🏗️ Software Engineering
- 🕸️ Web Development
- 🔐 Security & Cryptography
- ∑ Theory & Discrete Math
- 🤖 AI & Machine Learning
- ☁️ Distributed Systems & Cloud
- 🎨 Graphics, Vision & Media
- 📐 Math for Computing
- 🔀 Concurrency & Parallelism
- 📱 Mobile, Embedded & IoT
- 🛠️ DevOps & Tooling
- 🚀 Emerging & Frontier Topics