Motivation & Vision¶
Two perspectives¶
From Haskell's perspective, Grasp is the part of the RTS you can script. GHC's runtime -- the STG machine -- is one of the most sophisticated pieces of runtime engineering ever built: parallel generational GC, green threads, STM, an efficient closure representation, and a calling convention optimized for higher-order functional programming. But it serves exactly one language. Grasp opens it up.
From Grasp's perspective, it is a dynamic language with the full power of the GHC runtime beneath it. Not a Lisp "implemented in Haskell" (like Husk Scheme), not a syntax skin over Haskell (like Liskell), and not a Haskell REPL with extra steps (like GHCi). Grasp values ARE GHC heap objects. Its closures are indistinguishable from those produced by compiled Haskell.
The shared foundation¶
The GHC compilation pipeline erases types:
Haskell source → Core (System FC) → STG → Cmm → machine code
full types types erased, RuntimeRep survives
Grasp enters at the STG level -- the point where types have been erased but runtime representations remain. Haskell and Grasp share:
- Primops: The same primitive operations (
+#,newMutVar#,catch#, etc.) - RuntimeRep: The same representation kinds (
IntRep,DoubleRep,BoxedRep Lifted) - The heap: GHC's generational GC manages both Haskell and Grasp objects
- The mutator: Closure allocation, thunk entry, update-in-place, blackholing
Nothing more. Grasp does not inherit Haskell's type classes, GADTs, higher-rank polymorphism, or type families. Those are Haskell's discipline, built above the same foundation. Grasp builds its own.
Formal foundations¶
v2 is grounded in established theory:
-
Call-by-Push-Value (Levy, 2001): The semantic spine. Distinguishes values (data that exists) from computations (work to be done), extended to three modes with STM transactions as a first-class intermediate layer.
-
Gradual typing (Siek & Taha, 2006): The type discipline. All REPL values start as
?(dynamic,Any). Concrete types can be introduced incrementally. The gradient runs from fully dynamic (tree-walking, info-pointer dispatch) to fully typed (primops, no dispatch). -
Henglein coercions (Henglein, 1994): The cost model. Boundary crossings between dynamic and typed code use
tag_T : T -> Any(box) andcheck_T : Any -> T(unbox). Coercion reduction eliminates redundant pairs.
Compilation has a precise meaning: resolving ? to concrete types, eliminating interpreter dispatch, emitting direct primop calls. This is not an optimization -- it is the formal definition of what it means to compile Grasp code.
Use cases¶
Live-coding and interactive development¶
Redefine functions in a running system. Inspect state. Build programs incrementally at a REPL. Like Common Lisp's SLIME or Erlang's shell, but on GHC's runtime -- with its GC, threads, and STM available.
Scripting Haskell libraries¶
GHC's ecosystem has thousands of libraries. Today, using them requires writing Haskell and compiling it. Grasp enables calling into these libraries dynamically, from a REPL, without a compilation step.
Runtime research¶
GHC's STG machine is well-documented in papers but opaque in practice. Grasp provides a hands-on way to explore it: construct closures, trigger evaluation, observe GC behavior, experiment with thunks and update frames.
Embeddable extension language¶
Haskell applications could embed Grasp as a scripting layer -- like how C applications embed Lua. The embedding is natural because Grasp lives on the same runtime. The future QuasiQuoter interface ([grasp| ... |]) makes this a compile-time embedding with zero runtime overhead for typed code.
The thesis¶
A dynamic language can be a native tenant of the STG machine, not a foreign guest:
- Grasp values ARE STG closures (not wrappers around them)
- GHC's GC traces Grasp values (no separate GC)
- GHC's scheduler runs Grasp computations (no separate scheduler)
- Grasp closures can be passed to Haskell functions and vice versa (no marshaling)
If this works fully, it establishes a new design point: symbiotic runtimes, where multiple languages share a single runtime substrate at the closure level. The formal foundations (CBPV + gradual typing + coercions) provide the theory to reason about this sharing precisely.