agentleFS
rainoftimerainoftime/pl-skills/abstract-machine/SKILL.md

abstract-machine

Skill17 starsChanged 9 months agoApache-2.0View on GitHub

Implement abstract machines for defining and executing operational semantics of programming languages.

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 6 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈6

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use de Bruijn indices to avoid variable capture

    line 43
  2. Distinctive:

    When denotational semantics is more appropriate

    line 84
  3. Distinctive:

    When efficiency is the only concern

    line 86
  4. Distinctive:

    Must check accumulator patterns correctly

    line 175
  5. Distinctive:

    Must handle mutual recursion

    line 176
  6. Distinctive:

    Must preserve tail position across branches

    line 177

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Abstract Machine

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.

When to Use This Skill

  • Defining operational semantics for languages
  • Building efficient interpreters
  • Reasoning about program evaluation
  • Implementing virtual machines
  • Teaching programming language theory

What This Skill Does

  1. Configuration Definition: Define machine state (code, environment, continuation)
  2. Transition Rules: Specify how configurations evolve
  3. Stack Management: Handle control flow with continuations
  4. Environment Handling: Manage variable bindings
  5. Termination Detection: Identify final states

Key Concepts

ConceptDescription
ConfigurationComplete machine state at a point
ControlExpression or value being processed
EnvironmentVariable bindings
ContinuationWhat to do next (stack)
TransitionRule for moving between configurations

Tips

  • Use de Bruijn indices to avoid variable capture
  • CEK is good for call-by-value
  • Krivine is elegant for call-by-name
  • SECD was designed for functional languages
  • Defunctionalize continuations for compilers

Common Use Cases

  • Formalizing language semantics
  • Building interpreters
  • Proving type safety
  • Implementing virtual machines
  • Teaching PL concepts

Related Skills

  • lambda-calculus-interpreter - Direct style interpretation
  • operational-semantics-definer - Small-step/big-step semantics
  • denotational-semantics-builder - Mathematical semantics
  • cps-transformer - Continuation-passing style

Canonical References

ReferenceWhy 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

Tradeoffs and Limitations

Approach Tradeoffs

ApproachProsCons
CEKSimple, CBN/CBV variantsExplicit environments
SECDStack-based, familiarMore complex state
KrivineElegant for CBNNot for CBV

When NOT to Use This Skill

  • When denotational semantics is more appropriate
  • For simple expression evaluation
  • When efficiency is the only concern

Limitations

  • May be less intuitive than big-step
  • Need to handle errors explicitly
  • Control flow can be spread across rules

Assessment Criteria

A high-quality implementation should have:

CriterionWhat to Look For
CompletenessHandles all language constructs
DeterminismEach configuration has unique successor
TerminationReaches final state for terminating programs
CorrectnessMatches expected semantics

Quality Indicators

✅ Good: Complete transition rules, handles all cases, matches expected semantics ⚠️ Warning: Missing some constructs, stuck states ❌ Bad: Non-deterministic, doesn't terminate correctly

Research Tools & Artifacts

Real-world abstract machine implementations to study:

ArtifactWhy It Matters
GHC's STG machineProduction call-by-need machine with sparks, blackholes, info tables
Lua 5.3 VMSimple, efficient register-based VM with upvalues and coroutines
JavaScript V8 IgnitionRegister-based bytecode interpreter with turbofan integration
OCaml bytecode interpreterDirect-style VM with closures and effect handlers
JVM HotSpot interpreterStack-based with JIT compilation hints
WebAssembly reference interpreterFormal specification machine

Key Implementations to Study

  • PyPy interpreter (RPython): How meta-tracing works with the VM
  • LuaJIT: Efficient closure representation and JIT compilation
  • GHCi interpreter: Bytecode-based REPL for Haskell

Research Frontiers

Current active research in abstract machines:

DirectionKey PapersChallenge
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

Hot Topics

  1. Compacting collectors for VM heaps: GCs designed for short-lived bytecode
  2. Speculative optimization: Profile-guided specialization at runtime
  3. Hardware-enforced isolation: CHERI capabilities in VM design

Implementation Pitfalls

Common bugs in production abstract machine implementations:

PitfallReal ExamplePrevention
Stack overflowEarly OCaml bytecode had limited stackGrow stacks dynamically, detect overflow
Space leaksGHC's CAF retention issuesAnalyze closure usage, prune unused
Wrong tail recursionEarly JavaScript enginesVerify tail call optimization (TCO)
Closure escapeLua's upvalue capture bugsTrack closure lifetimes precisely
Wrong environment capturePython's late binding closuresCapture by value vs reference
Improper frame pointersDebug builds vs optimizedPreserve stack frame invariants

The "Space Leak" Story

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.

Tail Call Optimization Pitfalls

Wrong TCO can cause crashes:

  • Must check accumulator patterns correctly
  • Must handle mutual recursion
  • Must preserve tail position across branches
  • Debugging: stack traces differ in tail-recursive code

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.