git » homepage.git » commit ebaaff1

Destination driven article

author Alan Dipert
2026-01-02 03:20:04 UTC
committer Alan Dipert
2026-01-02 03:20:04 UTC
parent 0827200d067ec26ab7442808c58039f34a5bcc4e

Destination driven article

md/Home.md +1 -0
md/Lisp.md +1 -1
md/Lisp/DestinationDrivenCompilation.md +45 -0

diff --git a/md/Home.md b/md/Home.md
index 3768529..93e78d3 100644
--- a/md/Home.md
+++ b/md/Home.md
@@ -24,6 +24,7 @@ Updates
 
 | Date       | Note                                                                                                                                       |
 |:-----------|:-------------------------------------------------------------------------------------------------------------------------------------------|
+| 2026-01-01 | Added [Lisp:DestinationDrivenCompilation](./Lisp/DestinationDrivenCompilation.md), comparing statement-context emitters with destination-driven code generation for bracketed hosts. |
 | 2025-12-27 | Added [AIAndRisk](./AIAndRisk.md), reflecting on why AI upside favors owners who can offload risk while salaried engineers must retain understanding. |
 | 2025-12-27 | Added [Coherence](./Coherence.md) on treating an AI coding agent like an employee by keeping intent, artifacts, and execution aligned.    |
 | 2025-11-19 | Added [WhoIsGod](./WhoIsGod.md) as the hub linking to the names and covenants reference tables.                                         |
diff --git a/md/Lisp.md b/md/Lisp.md
index 5fbde47..d007d62 100644
--- a/md/Lisp.md
+++ b/md/Lisp.md
@@ -5,5 +5,5 @@ I have been interested in all things Lisp since around 2009, when I learned Cloj
 
 
 * [Lisp:GherkinHistory](./Lisp/GherkinHistory.md) provides context around an interpreter I wrote in 2013 that was extremely gratifying. 
-
+* [Lisp:DestinationDrivenCompilation](./Lisp/DestinationDrivenCompilation.md) compares statement-context emission to destination-driven code generation for bracketed host languages.
 
diff --git a/md/Lisp/DestinationDrivenCompilation.md b/md/Lisp/DestinationDrivenCompilation.md
new file mode 100644
index 0000000..15ba7d3
--- /dev/null
+++ b/md/Lisp/DestinationDrivenCompilation.md
@@ -0,0 +1,45 @@
+# DestinationDrivenCompilation
+
+Compilers that target hosts with a hard statement/expression split (JavaScript, C, and similar "bracket" languages) have to respect where values are allowed and where only effects make sense. ClojureScript's emitter handled this with context-sensitive emission: every node got an expression-or-statement flag and picked a matching output form. I patterned [JACL](https://tailrecursion.com/git-arr/r/jacl.git/) after that mode because it kept the emitter easy to read while the backend was taking shape. (See the [ClojureScript emitter](https://github.com/clojure/clojurescript/blob/515900f9762102987bda7d53b919dafc0b6c0580/src/clj/clojure/cljs.clj) `:context` handling.)
+
+Context-sensitive emission (expression/statement mode)
+
+- Feels natural: each emitter mirrors the host syntax it is asked to produce.
+- Adds scaffolding: expression-only paths fabricate values even when only effects are needed.
+- Adds wrappers: expression nodes in statement position often become immediately invoked function expressions (IIFEs) to "unwrap" a value back into a statement.
+- Propagates mode: the flag is carried to every child, so subexpressions default to producing values even when the parent needs only effects.
+
+Destination-driven compilation (value/effect/tail)
+
+- Each node is compiled toward a destination: produce a value, perform an effect, or return from tail position.
+- Eliminates wrappers: an effect destination emits straight-line statements; a tail destination emits direct `return`s.
+- Reduces temps: only value destinations introduce locals, so fewer temps appear and less dead code needs removal.
+- Propagates destinations: children inherit the current destination and can short-circuit—effect destinations can drop unused values, and tail destinations emit the final `return`.
+
+Example: compiling a value-binding `if`
+Source (Lisp-ish):
+```
+(let [x (if test (f) (g))]
+  (h x))
+```
+Context-sensitive emission (expression mode needing a value):
+```
+var x = (function(){
+  if (test) { return f(); }
+  else { return g(); }
+})();
+h(x);
+```
+Destination-driven emission (value destination):
+```
+var x;
+if (test) { x = f(); }
+else { x = g(); }
+h(x);
+```
+
+Destination-driven output already looks like the optimized version. If I rewrote JACL to target destinations instead of expression-versus-statement mode, I expect fewer IIFEs, fewer temps, and fewer cleanup passes to bridge the abstraction mismatch with bracketed hosts.
+
+Background reading
+- Destination-driven code generation was popularized by Kent Dybvig (see "[Destination-Driven Code Generation](http://www.cs.indiana.edu/~dyb/pubs/dest.pdf)").
+- Context-sensitive emission in ClojureScript is visible in its compiler emitter path that threads a `:context` flag per node.