Programming Language Concepts - Comprehensive Guide
Table of Contents
- Core Programming Concepts
- Compile Time vs Runtime
- Interpreters
- V8 Engine
- JIT Compilation
- Python vs JavaScript Engines
- Universal Engine Pipeline
Shared from "Study" on Inkdown
Think of programming languages as recipes for a computer:
Interpreted Languages (Python, JavaScript):
Compiled to Native Binaries (C, Rust, Go):
What is it? Automatic memory cleanup. When you create variables, they use RAM. GC automatically frees that memory when no longer needed.
Languages WITH GC: Python, JavaScript, Java, Go Languages WITHOUT GC: C, C++, Rust
Why no GC?
Think of it like building a house vs living in it:
This happens before the program runs. The compiler checks your code, finds errors, and converts it into executable form.
This is when you execute the compiled binary. The program is doing its actual job.
| Compile Time | Runtime |
|---|---|
| Check syntax | Execute instructions |
| Type checking | User input |
| Memory analysis | Network requests |
| Error code generation | File reading/writing |
| Optimize code | Database queries |
| Produce binary | Crash if bug exists |
| Stage | Cooking Analogy | Programming |
|---|---|---|
| Compile Time | Reading recipe, checking ingredients, prepping kitchen | Compiler reads code, checks for errors, builds executable |
| Runtime | Actually cooking and eating | Program runs, interacts with user, does real work |
Modern IDEs blur the line:
| What You See | What's Actually Happening |
|---|---|
| Red squiggly lines while typing | IDE secretly runs compiler in background |
| "Problems" panel auto-updating | Language server doing mini-compile checks |
| Auto-complete suggestions | IDE parsing your code continuously |
This feels like "real-time compilation," but it's just your IDE being helpful. The actual compile time is still the explicit build step.
Ask yourself: Does the compiler produce a runnable program?
| Scenario | Phase |
|---|---|
| Typing code, seeing red underlines | Editing (+ IDE background checks) |
Running cargo build, getting errors | Compile time |
Double-clicking .exe, program crashes | Runtime |
| Phase | Essay Writing Analogy |
|---|---|
| Editing | Writing the essay in Word |
| Compile time | Grammar/spell check + printing to PDF |
| Runtime | Someone actually reads the printed essay |
So: writing โ compiling. Compile time is the deliberate step where your code gets turned into an executable.
An interpreter is a program that executes your code line-by-line without compiling it first.
When you run:
The Python interpreter:
print("Hello") โ executes it โ prints "Hello"x = 10 โ executes it โ stores 10 in memoryprint(x) โ executes it โ prints "10"All happens at runtime, no compilation step.
| Aspect | Interpreter (Python, JS) | Compiler (C, Rust) |
|---|---|---|
| Process | Read & execute line-by-line | Compile once, then run binary |
| Speed | Slower (translation every run) | Faster (no translation at runtime) |
| Output | No binary file | Produces .exe / binary |
| Error detection | Runtime only | Compile time (mostly) |
| Distribution | Need interpreter installed | Just need the binary |
Interpreters run on your machine as a program itself:
Before running interpreted code, you must install the interpreter:
JavaScript in Browser:
Interpreter = A program that runs your other programs
V8 is Google's JavaScript engine. It's the interpreter + JIT compiler that runs JavaScript in Chrome and Node.js.
V8 is a hybrid โ it's both interpreter AND compiler:
Phase 1: Interpreter (Ignition)
Phase 2: JIT Compiler (TurboFan)
JIT = Just-In-Time compilation. It compiles code while running based on usage patterns.
| Feature | Simple Interpreter | V8 Engine |
|---|---|---|
| Executes JS | Yes | Yes |
| Compiles to machine code | No | Yes (JIT) |
| Fast execution | No | Yes (after JIT) |
| Garbage collection | Yes | Yes |
| Optimizations | No | Yes (inline, etc.) |
Old days (2008): JavaScript was slow (pure interpretation)
Today (V8): JavaScript is almost as fast as compiled languages because:
V8 = JavaScript engine that:
Without V8, JavaScript would be slow like old Python. With V8, it's fast enough to run Gmail, Facebook, and VS Code.
JIT (Just-In-Time) compilation turns the most repeated code into binary machine code while the program is running.
JIT (Just-In-Time) = Compiles frequently-used code to machine code while the program is running
Example:
The key word is "repeated" โ V8 watches which functions run often and optimizes those specifically. Code that runs once stays interpreted.
| Type | When Compilation Happens | Example |
|---|---|---|
| AOT | Before running | C, Rust, Go |
| JIT | While running | V8 (JavaScript) |
| Bytecode | Before running, to intermediate | Python, Java |
Key difference from V8: Python compiles to bytecode (not machine code), then interprets that bytecode.
When you run python script.py:
__pycache__/script.cpython-311.pycThe bytecode looks like this:
| Component | V8 (JavaScript) | Python (CPython) |
|---|---|---|
| Parser | Yes | Yes |
| Compiler | Yes (to machine code) | Yes (to bytecode) |
| Interpreter | Yes | Yes |
| JIT Compiler | Yes (TurboFan) | No |
| Garbage Collector | Yes | Yes |
| Virtual Machine | No (direct CPU) | Yes (Python VM) |
Input: Raw text
Output: Tokens
Input: Tokens Output: Abstract Syntax Tree (AST)
What it checks:
This is where engines diverge:
| Engine | Generates | Then Executes Via |
|---|---|---|
| CPython | Bytecode | Python VM |
| V8 | Machine code (for hot code) | Direct CPU |
| Rust | Machine code | Direct CPU |
| Java | Bytecode | JVM |
| Go | Machine code | Direct CPU |
Bytecode engines (Python, Java):
Native engines (C, Rust, V8-compiled):
Two approaches:
Automatic (GC):
Manual:
All engines follow the same flow. The only difference is:
Step 4 (Code Generation) + Step 5 (Execution) + Step 6 (Memory Management)
That's where each engine makes its design choice:
Everything else (lexing, parsing, semantic analysis) is essentially the same across all languages.
| Language | Engine Name | What We Call It |
|---|---|---|
| Python | CPython | Python interpreter / Python engine |
| JavaScript (Chrome/Node) | V8 | JavaScript engine |
| JavaScript (Safari) | JavaScriptCore | JavaScript engine |
| JavaScript (Firefox) | SpiderMonkey | JavaScript engine |
| Java | HotSpot JVM | Java Virtual Machine |
| Ruby | CRuby | Ruby interpreter |
| Go | gc | Go compiler |
Note: The terms "engine," "interpreter," "runtime," and "VM" are sometimes used interchangeably, but they all mean the same thing: the software that makes your code run.
Every language needs one piece of software that:
That software is the engine/interpreter/runtime.
For Python โ CPython For JavaScript (Chrome) โ V8 For JavaScript (Safari) โ JavaScriptCore For Java โ JVM
| Phase | What Happens | When |
|---|---|---|
| Compile Time | Code is checked, converted to executable | When you run build command |
| Runtime | Program actually executes | When you run the binary |
| Type | Process | Example |
|---|---|---|
| Compiled | Source โ Compiler โ Binary โ CPU | C, Rust, Go |
| Interpreted | Source โ Interpreter โ CPU | Python, JavaScript |
| Approach | Language | Pros/Cons |
|---|---|---|
| GC | Python, JS, Java | Automatic but pauses performance |
| Manual | C, C++ | Fast but error-prone |
| Ownership | Rust | Safe and fast, compile-time checked |
| Component | Purpose | Present In |
|---|---|---|
| Lexer | Breaks code into tokens | All engines |
| Parser | Builds AST | All engines |
| Semantic Analysis | Type/scope checking | All engines |
| Code Generator | Converts to executable form | All engines |
| JIT Compiler | Optimizes hot code | V8, some others |
| GC | Automatic memory cleanup | Python, V8, Java |
| VM | Executes bytecode | Python, Java |
This guide covers the fundamental concepts of how programming languages work under the hood. Understanding these concepts will help you:
The key takeaway: All languages follow the same basic pipeline, but differ in their specific design choices at the code generation and execution stages. These choices determine the language's performance, safety, and ease of use.