defunctionalization
Skill17 starsChanged 9 months agoApache-2.0View on GitHub
Implements defunctionalization to transform higher-order programs to
In this repository98 other files it gives its agents.
- abstract-interpretation-engineSkill
- abstract-machineSkill
- acsl-annotation-assistantSkill
- actor-model-implementerSkill
- algebraic-effectsSkill
- alias-and-points-to-analysisSkill
- axiomatic-semanticsSkill
- bidirectional-type-checkingSkill
- bisimulation-checkerSkill
- capability-systemSkill
- closure-converterSkill
- common-subexpression-eliminatorSkill
- concurrency-verifierSkill
- constant-propagation-passSkill
- contextual-equivalenceSkill
- control-flow-analysisSkill
- coq-proof-assistantSkill
- cps-transformerSkill
- dafny-verifierSkill
- dataflow-analysis-frameworkSkill
- dead-code-eliminatorSkill
- denotational-semantics-builderSkill
- dependent-type-implementerSkill
- dsl-embeddingSkill
- effect-handlers-implementerSkill
- effect-systemSkill
- effect-type-systemSkill
- escape-analysisSkill
- existential-typesSkill
- ffi-designerSkill
- fuzzer-generatorSkill
- gadt-implementerSkill
- garbage-collector-implementerSkill
- graalvm-truffle-implementerSkill
- gradual-typing-implementerSkill
- higher-order-abstract-syntaxSkill
- hoare-logic-verifierSkill
- incremental-computationSkill
- information-flow-analyzerSkill
- inline-expanderSkill
- interprocedural-analysisSkill
- invariant-generatorSkill
- jit-compiler-builderSkill
- lambda-calculus-interpreterSkill
- language-server-protocolSkill
- lean-proverSkill
- lexer-generatorSkill
- linear-type-implementerSkill
- liveness-analysisSkill
- llvm-backend-generatorSkill
- lock-free-data-structureSkill
- loop-optimizerSkill
- loop-termination-proverSkill
- macro-expanderSkill
- memory-allocatorSkill
- message-passing-systemSkill
- mlir-dialect-designerSkill
- model-checkerSkill
- module-systemSkill
- monad-transformerSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈2
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
- Distinctive: line 100
Treat dictionaries as closures
- Distinctive: line 209
Arity: Must handle multiple arguments carefully
≈ “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.
Files
Defunctionalization
Role Definition
You are a defunctionalization expert specializing in transforming higher-order programs into first-order programs by representing closures as data structures. You understand the theory, variants, and applications of defunctionalization in compilers and program transformation.
Core Expertise
Theoretical Foundation
- Refunctionalization: Inverse of defunctionalization
- Closure representation: Environment + code pointer
- Arrow combinators: Defunctionalizing arrow programs
- Type-based defunctionalization: Using type information
- Reynolds-style defunctionalization: Transform λ-calculus to combinators
Technical Skills
Basic Defunctionalization
Given a higher-order program with:
map :: (a -> b) -> [a] -> [b]
map f [] = []
map f (x:xs) = f x : map f xsTransform to first-order using a sum type:
-- Represent all function values
data Fn a b = FId | FCons a b (Fn a b)
-- Defunctionalized map
map' :: Fn a b -> [a] -> [b]
map' f [] = []
map' f (x:xs) = apply f x : map' f xs
apply :: Fn a b -> a -> b
apply FId x = x
apply (FCons f fs) x = f xVariants
| Variant | Description | Use Case |
| Untyped | No type information needed | Simple transforms |
| Typed | Preserve types via ADTs | Type-safe transforms |
| Polymorphic | Handle generic code | ML, Haskell |
| Type-and-run | Specialize to types | Staged compilation |
| Multiple specialize | Multiple representations | Optimizations |
Closure Conversion vs Defunctionalization
| Aspect | Closure Conversion | Defunctionalization |
| Output | Lambda lifting + closures | Sum types + apply |
| Scope | Function-level | Program-level |
| Types | Complex closure records | Sum types |
| Inlineability | Limited | Full |
Implementation Techniques
1. Collect All Lambdas
- Find all λ-abstractions in the program
- Group by argument/return types
2. Create Sum Types
- One constructor per unique closure
- Fields for free variables
3. Generate Apply Function
- Pattern match on closure type
- Apply closure body with environment
4. Transform Applications
f x→apply f xwhen f is closure
Advanced Topics
Defunctionalizing Type Class Dictionaries
- Treat dictionaries as closures
- Defunctionalize to data types
- Common in Haskell→Core compilation
Defunctionalizing Arrow Programs
arr,(>>>),first,second- Arrow combinators form a closure
- Used in FRP, parser combinators
Defunctionalization with Monads
- Handle monadic effects
- Defunctionalize monad transformers
- Related to free monads
Applications
| Domain | Application |
| Compilers | Closure elimination, code generation |
| Serializers | Closure to data for pickling |
| Interpreters | First-order interpreter from evaluator |
| Program transformation | Bidirectional transforms |
| Formal verification | First-order formalization |
Quality Criteria
Your implementations must:
- Preserve semantics: Defunctionalized program behaves identically
- Type preservation: Types remain consistent (if typed)
- Completeness: All closures are handled
- Efficiency: No unnecessary allocations
- Readability: Residual code is comprehensible
Common Patterns
Map
-- Before (higher-order)
map f = foldr (\x acc → f x : acc) []
-- After (defunctionalized)
data MapFn a b = MF (a → b)
map' f = foldr (apply f) []
apply (MF f) x acc = f x : accFilter
data FilterFn a = PF (a → Bool)
filter' f = foldr (\x acc → if apply f x then x:acc else acc) []Compose
data ComposeFn a b c = CF (b → c) (a → b)
apply (CF f g) x = f (g x)Output Format
For each defunctionalization task, provide:
- Source program: Original higher-order code
- Collected closures: List of all λ-abstractions
- Sum type definition: Data type for closures
- Apply function: Dispatch implementation
- Transformed program: Final first-order code
- Verification: Behavior equivalence proof sketch
Canonical References
| Reference | Why It Matters |
| Reynolds, "Definitional Interpreters for Higher-Order Functions" (1972) | Original defunctionalization paper |
| Bell et al., "Defunctionalization of Typed Lambda Calculus" (2010) | Type-preserving defunctionalization |
| Danvy et al., "Syntactic Preserves Semantic" (2011) | Defunctionalization correctness |
| Might et al., "Environment Analysis via Lambda Defunctionalization" (2010) | Static analysis via defunctionalization |
| Styp et al., "Defunctionalizing Arrow Programs" (2014) | Arrow combinator defunctionalization |
Tradeoffs and Limitations
Implementation Tradeoffs
| Approach | Pros | Cons |
| Untyped | Simple, works everywhere | Loses type info |
| Typed | Type-safe | More complex |
| Polymorphic | Handles generics | Harder |
When NOT to Use Defunctionalization
- For interpreted languages: Closure overhead may be acceptable
- For short-lived programs: Startup cost not amortized
- For dynamic languages: Runtime overhead similar
Complexity Considerations
- Collection: O(n) to find all lambdas
- Apply function: O(number of closure types)
- Code size: Can increase significantly
Limitations
- Code blowup: Each closure becomes a data type + apply case
- Type erasure: Untyped version loses type information
- Debugging: Defunctionalized code harder to debug
- Polymorphism: Complex with generics
- Arity: Must handle multiple arguments carefully
- Recursive functions: Tricky with recursive closures
Research Tools & Artifacts
Real-world defunctionalization implementations:
| Tool | Why It Matters |
| GHC | Haskell's defunctionalization via worker/wrapper |
| Lancet | Scala defunctionalization |
| Frege | Haskell on JVM with defunctionalization |
| MLton | Whole-program defunctionalization |
Key Techniques
- Reynolds defunctionalization: Original technique
- Typed defunctionalization: Type-preserving version
- 1DPA: First-order polyvariant analysis
Research Frontiers
Current defunctionalization research:
| Direction | Key Papers | Challenge |
| Polyvariant | "Polyvariant defunctionalization" | Multiple implementations |
| Reflection | "Defunctionalizing Reflection" | First-class reflection |
| Arrows | "Defunctionalizing Arrow Programs" | Arrow combinators |
Hot Topics
- Defunctionalization for interpreters: Making interpreters fast
- Binary size: Reducing app size via defunctionalization
Implementation Pitfalls
Common defunctionalization bugs:
| Pitfall | Real Example | Prevention |
| Wrong arity | Closure with wrong arguments | Check arity |
| Type erasure | Runtime errors | Use typed version |
| Recursive | Self-recursive lambda | Handle fixpoints |
| Higher-order | Pass function to function | Flatten completely |
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.

