ワンクリックで
abstract-machine
Implement abstract machines for defining and executing operational semantics of programming languages.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Implement abstract machines for defining and executing operational semantics of programming languages.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Implements alias and points-to analysis for pointer programs. Use for: (1) Optimizing compilers, (2) Verifying memory safety, (3) Program understanding, (4) Parallelization.
Define program meaning through logical assertions and proof rules (Hoare logic).
Transforms closures to explicit environments. Use when: (1) Implementing functional languages, (2) Building compilers, (3) Understanding closures.
Implements common subexpression elimination (CSE). Use when: (1) Building compilers, (2) Optimizing code, (3) Program analysis.
Implements general dataflow analysis framework. Use when: (1) Building compilers, (2) Static analysis tools, (3) Program verification.
Builds denotational semantic models. Use when: (1) Formalizing language semantics, (2) Proving program properties, (3) Semantic analysis.
| name | abstract-machine |
| description | Implement abstract machines for defining and executing operational semantics of programming languages. |
| version | 1.0.0 |
| tags | ["semantics","interpreters","popl","theory"] |
| difficulty | intermediate |
| languages | ["haskell","ocaml","python"] |
| dependencies | ["lambda-calculus-interpreter","operational-semantics-definer"] |
Abstract machines define operational semantics by specifying computation as transitions between configurations. They bridge formal semantics and practical interpreters, enabling both reasoning about programs and efficient implementation.
| Concept | Description |
|---|---|
| Configuration | Complete machine state at a point |
| Control | Expression or value being processed |
| Environment | Variable bindings |
| Continuation | What to do next (stack) |
| Transition | Rule for moving between configurations |
lambda-calculus-interpreter - Direct style interpretationoperational-semantics-definer - Small-step/big-step semanticsdenotational-semantics-builder - Mathematical semanticscps-transformer - Continuation-passing style| Reference | Why It Matters |
|---|---|
| Felleisen & Friedman, "Control Operators, the SECD-Machine, and the λ-Calculus" (1986) | CEK machine |
| Landin, "The Mechanical Evaluation of Expressions" (1964) | SECD machine |
| Krivine, "A Call-by-Name Lambda-Calculus Machine" (published 2007, developed earlier) | Krivine machine |
| Approach | Pros | Cons |
|---|---|---|
| CEK | Simple, CBN/CBV variants | Explicit environments |
| SECD | Stack-based, familiar | More complex state |
| Krivine | Elegant for CBN | Not for CBV |
A high-quality implementation should have:
| Criterion | What to Look For |
|---|---|
| Completeness | Handles all language constructs |
| Determinism | Each configuration has unique successor |
| Termination | Reaches final state for terminating programs |
| Correctness | Matches expected semantics |
✅ Good: Complete transition rules, handles all cases, matches expected semantics ⚠️ Warning: Missing some constructs, stuck states ❌ Bad: Non-deterministic, doesn't terminate correctly
Real-world abstract machine implementations to study:
| Artifact | Why It Matters |
|---|---|
| GHC's STG machine | Production call-by-need machine with sparks, blackholes, info tables |
| Lua 5.3 VM | Simple, efficient register-based VM with upvalues and coroutines |
| JavaScript V8 Ignition | Register-based bytecode interpreter with turbofan integration |
| OCaml bytecode interpreter | Direct-style VM with closures and effect handlers |
| JVM HotSpot interpreter | Stack-based with JIT compilation hints |
| WebAssembly reference interpreter | Formal specification machine |
Current active research in abstract machines:
| Direction | Key Papers | Challenge |
|---|---|---|
| Effect handlers | "Handlers of Algebraic Effects" (Plotkin & Pretnar, 2009) | Encoding algebraic effects in CEK/Krivine |
| Delimited continuations | "Control Delimiters and their Hierarchies" (Felleisen, 1988) | Multiple prompts, composable snapshots |
| Multi-stage | "MetaOCaml" (2003) | Staging the machine itself |
| WebAssembly | "A Formal Specification" (2020) | Verification of the reference interpreter |
| Zero-cost exceptions | "Zero-cost Exception Handling" (2018) | Efficient error paths without overhead |
Common bugs in production abstract machine implementations:
| Pitfall | Real Example | Prevention |
|---|---|---|
| Stack overflow | Early OCaml bytecode had limited stack | Grow stacks dynamically, detect overflow |
| Space leaks | GHC's CAF retention issues | Analyze closure usage, prune unused |
| Wrong tail recursion | Early JavaScript engines | Verify tail call optimization (TCO) |
| Closure escape | Lua's upvalue capture bugs | Track closure lifetimes precisely |
| Wrong environment capture | Python's late binding closures | Capture by value vs reference |
| Improper frame pointers | Debug builds vs optimized | Preserve stack frame invariants |
GHC once had a famous space leak where CAFs (Constant Applicative Forms) retained heap:
-- This creates a CAF that retains xs
result = map expensiveFunction veryLargeList
-- Forces entire list despite laziness
Solution: Selective CAF elimination, scrutinize, and blackholes for synchronization.
Wrong TCO can cause crashes: