about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-11-29 14:18:52 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-11-29 14:18:52 -0800
commitdb1f56c8449d2ea3d158753fe37bac5a750a2566 (patch)
tree508a24c522c040498dbe7d60036035f3c4ae440a
parent3670fb87f6d38c9ba4fcbb1eaa6439b4007a194e (diff)
downloadmu-db1f56c8449d2ea3d158753fe37bac5a750a2566.tar.gz
2611
-rw-r--r--html/000organization.cc.html1
-rw-r--r--html/001help.cc.html10
-rw-r--r--html/003trace.cc.html6
-rw-r--r--html/010vm.cc.html45
-rw-r--r--html/011load.cc.html26
-rw-r--r--html/012transform.cc.html9
-rw-r--r--html/013update_operation.cc.html2
-rw-r--r--html/014literal_string.cc.html22
-rw-r--r--html/020run.cc.html12
-rw-r--r--html/021check_instruction.cc.html95
-rw-r--r--html/029tools.cc.html5
-rw-r--r--html/030container.cc.html52
-rw-r--r--html/031address.cc.html10
-rw-r--r--html/032array.cc.html40
-rw-r--r--html/035call_ingredient.cc.html15
-rw-r--r--html/036call_reply.cc.html3
-rw-r--r--html/038scheduler.cc.html5
-rw-r--r--html/040brace.cc.html2
-rw-r--r--html/041jump_target.cc.html2
-rw-r--r--html/042name.cc.html35
-rw-r--r--html/043new.cc.html10
-rw-r--r--html/044space.cc.html16
-rw-r--r--html/045space_surround.cc.html4
-rw-r--r--html/047global.cc.html4
-rw-r--r--html/048check_type_by_name.cc.html12
-rw-r--r--html/050scenario.cc.html28
-rw-r--r--html/051scenario_test.mu.html4
-rw-r--r--html/052tangle.cc.html2
-rw-r--r--html/053rewrite_stash.cc.html85
-rw-r--r--html/054dilated_reagent.cc.html26
-rw-r--r--html/055parse_tree.cc.html4
-rw-r--r--html/056recipe_header.cc.html18
-rw-r--r--html/057static_dispatch.cc.html241
-rw-r--r--html/058shape_shifting_container.cc.html11
-rw-r--r--html/059shape_shifting_recipe.cc.html227
-rw-r--r--html/070text.mu.html (renamed from html/070string.mu.html)464
-rw-r--r--html/071channel.mu.html58
-rw-r--r--html/073list.mu.html87
-rw-r--r--html/076stream.mu.html30
-rw-r--r--html/081print.mu.html301
-rw-r--r--html/082scenario_screen.cc.html17
-rw-r--r--html/083scenario_screen_test.mu.html4
-rw-r--r--html/084console.mu.html49
-rw-r--r--html/090trace_browser.cc.html30
-rw-r--r--html/091run_interactive.cc.html36
-rw-r--r--html/092persist.cc.html2
-rw-r--r--html/998check_type_pointers.cc.html75
-rw-r--r--html/999spaces.cc.html51
-rw-r--r--html/channel.mu.html8
-rw-r--r--html/chessboard.mu.html120
-rw-r--r--html/edit/001-editor.mu.html14
-rw-r--r--html/edit/002-typing.mu.html6
-rw-r--r--html/edit/003-shortcuts.mu.html8
-rw-r--r--html/edit/004-programming-environment.mu.html162
-rw-r--r--html/edit/005-sandbox.mu.html34
-rw-r--r--html/edit/008-sandbox-test.mu.html8
-rw-r--r--html/edit/009-sandbox-trace.mu.html6
-rw-r--r--html/edit/010-warnings.mu.html91
-rw-r--r--html/edit/011-editor-undo.mu.html4
-rw-r--r--html/screen.mu.html4
-rw-r--r--index.html5
61 files changed, 1662 insertions, 1101 deletions
diff --git a/html/000organization.cc.html b/html/000organization.cc.html
index bbc09e8d..a3822fb5 100644
--- a/html/000organization.cc.html
+++ b/html/000organization.cc.html
@@ -136,6 +136,7 @@ int main<span class="Delimiter">(</span>int argc<span class="Delimiter">,</span>
 
   <span class="Comment">// End One-time Setup</span>
 
+  <span class="Comment">// Commandline Parsing</span>
   <span class="Comment">// End Commandline Parsing</span>
 
   <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>  <span class="Comment">// End Main</span>
diff --git a/html/001help.cc.html b/html/001help.cc.html
index a6a34cdd..eaa49b8b 100644
--- a/html/001help.cc.html
+++ b/html/001help.cc.html
@@ -49,6 +49,9 @@ if <span class="Delimiter">(</span>argc &lt;= <span class="Constant">1</span> ||
        &lt;&lt; <span class="Constant">&quot;You can test directories just like files.</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
        &lt;&lt; <span class="Constant">&quot;To pass ingredients to a mu program, provide them after '--':</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
        &lt;&lt; <span class="Constant">&quot;  mu file_or_dir1 file_or_dir2 ... -- ingredient1 ingredient2 ...</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;To browse a trace generated by a previous run:</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       &lt;&lt; <span class="Constant">&quot;  mu browse-trace file</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
        <span class="Delimiter">;</span>
   <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
@@ -146,6 +149,13 @@ template&lt;typename T&gt; typename T::mapped_type&amp; get_or_insert<span class
 <span class="Delimiter">}</span>
 <span class="Comment">//: The contract: any container that relies on get_or_insert should never call</span>
 <span class="Comment">//: contains_key.</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: 7. istreams are a royal pain in the arse. You have to be careful about</span>
+<span class="Comment">//: what subclass you try to putback into. You have to watch out for the pesky</span>
+<span class="Comment">//: failbit and badbit. Just avoid eof() and use this helper instead.</span>
+bool has_data<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Identifier">return</span> in &amp;&amp; !in<span class="Delimiter">.</span>eof<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
 
 <span class="Delimiter">:(before &quot;End Includes&quot;)</span>
 <span class="PreProc">#include</span><span class="Constant">&lt;assert.h&gt;</span>
diff --git a/html/003trace.cc.html b/html/003trace.cc.html
index 022ad5f1..a1c0be03 100644
--- a/html/003trace.cc.html
+++ b/html/003trace.cc.html
@@ -192,10 +192,8 @@ trace_stream* Trace_stream = <span class="Constant">NULL</span><span class="Deli
 
 <span class="Comment">// Top-level helper. IMPORTANT: can't nest.</span>
 <span class="PreProc">#define trace(</span><span class="Delimiter">...</span><span class="PreProc">)  !Trace_stream ? cerr </span><span class="Comment">/*</span><span class="Comment">print nothing</span><span class="Comment">*/</span><span class="PreProc"> : Trace_stream</span><span class="Delimiter">-&gt;</span><span class="PreProc">stream(__VA_ARGS__)</span>
-<span class="Comment">// Errors and warnings should go straight to cerr by default since calls to trace() have</span>
-<span class="Comment">// some unfriendly constraints (they delay printing, they can't nest)</span>
-<span class="PreProc">#define raise  ((!Trace_stream || !Hide_warnings) ? (tb_shutdown()</span><span class="Delimiter">,</span><span class="PreProc">cerr) </span><span class="Comment">/*</span><span class="Comment">do print</span><span class="Comment">*/</span><span class="PreProc"> : Trace_stream</span><span class="Delimiter">-&gt;</span><span class="PreProc">stream(Warning_depth</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">&quot;warn&quot;</span><span class="PreProc">))</span>
-<span class="PreProc">#define raise_error  ((!Trace_stream || !Hide_errors) ? (tb_shutdown()</span><span class="Delimiter">,</span><span class="PreProc">cerr) </span><span class="Comment">/*</span><span class="Comment">do print</span><span class="Comment">*/</span><span class="PreProc"> : Trace_stream</span><span class="Delimiter">-&gt;</span><span class="PreProc">stream(Error_depth</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">&quot;error&quot;</span><span class="PreProc">))</span>
+<span class="PreProc">#define raise  (!Trace_stream ? (tb_shutdown()</span><span class="Delimiter">,</span><span class="PreProc">cerr) </span><span class="Comment">/*</span><span class="Comment">do print</span><span class="Comment">*/</span><span class="PreProc"> : Trace_stream</span><span class="Delimiter">-&gt;</span><span class="PreProc">stream(Warning_depth</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">&quot;warn&quot;</span><span class="PreProc">))</span>
+<span class="PreProc">#define raise_error  (!Trace_stream ? (tb_shutdown()</span><span class="Delimiter">,</span><span class="PreProc">cerr) </span><span class="Comment">/*</span><span class="Comment">do print</span><span class="Comment">*/</span><span class="PreProc"> : Trace_stream</span><span class="Delimiter">-&gt;</span><span class="PreProc">stream(Error_depth</span><span class="Delimiter">,</span><span class="PreProc"> </span><span class="Constant">&quot;error&quot;</span><span class="PreProc">))</span>
 
 <span class="Delimiter">:(before &quot;End Types&quot;)</span>
 struct end <span class="Delimiter">{};</span>
diff --git a/html/010vm.cc.html b/html/010vm.cc.html
index f476aa61..976edf51 100644
--- a/html/010vm.cc.html
+++ b/html/010vm.cc.html
@@ -94,6 +94,7 @@ struct reagent <span class="Delimiter">{</span>
   reagent<span class="Delimiter">(</span>string s<span class="Delimiter">);</span>
   reagent<span class="Delimiter">();</span>
   ~reagent<span class="Delimiter">();</span>
+  void clear<span class="Delimiter">();</span>
   reagent<span class="Delimiter">(</span>const reagent&amp; old<span class="Delimiter">);</span>
   reagent&amp; operator=<span class="Delimiter">(</span>const reagent&amp; old<span class="Delimiter">);</span>
   void set_value<span class="Delimiter">(</span>double v<span class="Delimiter">)</span> <span class="Delimiter">{</span> value = v<span class="Delimiter">;</span> initialized = <span class="Constant">true</span><span class="Delimiter">;</span> <span class="Delimiter">}</span>
@@ -270,7 +271,7 @@ reagent::reagent<span class="Delimiter">(</span>string s<span class="Delimiter">
   istringstream in<span class="Delimiter">(</span>s<span class="Delimiter">);</span>
   in &gt;&gt; std::noskipws<span class="Delimiter">;</span>
   <span class="Comment">// properties</span>
-  while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     istringstream row<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">'/'</span><span class="Delimiter">));</span>
     row &gt;&gt; std::noskipws<span class="Delimiter">;</span>
     string key = slurp_until<span class="Delimiter">(</span>row<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span>
@@ -295,7 +296,7 @@ reagent::reagent<span class="Delimiter">(</span>string s<span class="Delimiter">
 
 string_tree* parse_property_list<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
   string_tree* result = new string_tree<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">));</span>
   result<span class="Delimiter">-&gt;</span>right = parse_property_list<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   <span class="Identifier">return</span> result<span class="Delimiter">;</span>
@@ -353,9 +354,18 @@ reagent&amp; reagent::operator=<span class="Delimiter">(</span>const reagent&amp
 <span class="Delimiter">}</span>
 
 reagent::~reagent<span class="Delimiter">()</span> <span class="Delimiter">{</span>
-  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
-    if <span class="Delimiter">(</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">)</span> delete properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">;</span>
+  clear<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
+void reagent::clear<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>properties<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      delete properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second<span class="Delimiter">;</span>
+      properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>second = <span class="Constant">NULL</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
+  <span class="Delimiter">}</span>
   delete type<span class="Delimiter">;</span>
+  type = <span class="Constant">NULL</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 type_tree::~type_tree<span class="Delimiter">()</span> <span class="Delimiter">{</span>
   delete left<span class="Delimiter">;</span>
@@ -510,31 +520,6 @@ string_tree* property<span class="Delimiter">(</span>const reagent&amp; r<span c
   <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-bool deeply_equal<span class="Delimiter">(</span>const string_tree* a<span class="Delimiter">,</span> const string_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>!a<span class="Delimiter">)</span> <span class="Identifier">return</span> !b<span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>!b<span class="Delimiter">)</span> <span class="Identifier">return</span> !a<span class="Delimiter">;</span>
-  <span class="Identifier">return</span> a<span class="Delimiter">-&gt;</span>value == b<span class="Delimiter">-&gt;</span>value
-      &amp;&amp; deeply_equal<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span>
-      &amp;&amp; deeply_equal<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
-<span class="Delimiter">}</span>
-
-<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
-set&lt;string&gt; Literal_type_names<span class="Delimiter">;</span>
-<span class="Delimiter">:(before &quot;End One-time Setup&quot;)</span>
-Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;literal&quot;</span><span class="Delimiter">);</span>
-Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;number&quot;</span><span class="Delimiter">);</span>
-Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;character&quot;</span><span class="Delimiter">);</span>
-<span class="Delimiter">:(code)</span>
-bool deeply_equal_types<span class="Delimiter">(</span>const string_tree* a<span class="Delimiter">,</span> const string_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>!a<span class="Delimiter">)</span> <span class="Identifier">return</span> !b<span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>!b<span class="Delimiter">)</span> <span class="Identifier">return</span> !a<span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
-    <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>b<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
-  <span class="Identifier">return</span> a<span class="Delimiter">-&gt;</span>value == b<span class="Delimiter">-&gt;</span>value
-      &amp;&amp; deeply_equal_types<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span>
-      &amp;&amp; deeply_equal_types<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
-<span class="Delimiter">}</span>
-
 void dump_memory<span class="Delimiter">()</span> <span class="Delimiter">{</span>
   for <span class="Delimiter">(</span>map&lt;long long int<span class="Delimiter">,</span> double&gt;::iterator p = Memory<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Memory<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     cout &lt;&lt; p<span class="Delimiter">-&gt;</span>first &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
@@ -573,7 +558,7 @@ void dump<span class="Delimiter">(</span>const string_tree* x<span class="Delimi
 <span class="Delimiter">}</span>
 
 void skip_whitespace<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> &amp;&amp; isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> &amp;&amp; in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>in &amp;&amp; isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> &amp;&amp; in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
diff --git a/html/011load.cc.html b/html/011load.cc.html
index 3e74bc02..7296d1bb 100644
--- a/html/011load.cc.html
+++ b/html/011load.cc.html
@@ -53,9 +53,9 @@ vector&lt;recipe_ordinal&gt; load<span class="Delimiter">(</span>string form<spa
 vector&lt;recipe_ordinal&gt; load<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   in &gt;&gt; std::noskipws<span class="Delimiter">;</span>
   vector&lt;recipe_ordinal&gt; result<span class="Delimiter">;</span>
-  while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-    if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
     string command = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     <span class="Comment">// Command Handlers</span>
     if <span class="Delimiter">(</span>command == <span class="Constant">&quot;recipe&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -116,25 +116,25 @@ void slurp_body<span class="Delimiter">(</span>istream&amp; in<span class="Delim
 
 bool next_instruction<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> instruction* curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   curr<span class="Delimiter">-&gt;</span>clear<span class="Delimiter">();</span>
-  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     raise_error &lt;&lt; <span class="Constant">&quot;0: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     raise_error &lt;&lt; <span class="Constant">&quot;1: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     raise_error &lt;&lt; <span class="Constant">&quot;2: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
 
   vector&lt;string&gt; words<span class="Delimiter">;</span>
-  while <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span> &amp;&amp; !in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> &amp;&amp; in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-    if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
       raise_error &lt;&lt; <span class="Constant">&quot;3: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
       <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
@@ -151,7 +151,7 @@ bool next_instruction<span class="Delimiter">(</span>istream&amp; in<span class=
     curr<span class="Delimiter">-&gt;</span>is_label = <span class="Constant">true</span><span class="Delimiter">;</span>
     curr<span class="Delimiter">-&gt;</span>label = words<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;parse&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;label: &quot;</span> &lt;&lt; curr<span class="Delimiter">-&gt;</span>label &lt;&lt; end<span class="Delimiter">();</span>
-    if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
       raise_error &lt;&lt; <span class="Constant">&quot;7: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
       <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
@@ -185,7 +185,7 @@ bool next_instruction<span class="Delimiter">(</span>istream&amp; in<span class=
   for <span class="Delimiter">(</span>vector&lt;reagent&gt;::iterator p = curr<span class="Delimiter">-&gt;</span>products<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != curr<span class="Delimiter">-&gt;</span>products<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;parse&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;  product: &quot;</span> &lt;&lt; p<span class="Delimiter">-&gt;</span>to_string<span class="Delimiter">()</span> &lt;&lt; end<span class="Delimiter">();</span>
   <span class="Delimiter">}</span>
-  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     raise_error &lt;&lt; <span class="Constant">&quot;9: unbalanced '[' for recipe</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
@@ -210,7 +210,7 @@ string Ignore<span class="Delimiter">(</span><span class="Constant">&quot;,&quot
 <span class="Delimiter">:(code)</span>
 void slurp_word<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> ostream&amp; out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   char c<span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> &amp;&amp; Terminators<span class="Delimiter">.</span>find<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> &amp;&amp; Terminators<span class="Delimiter">.</span>find<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     in &gt;&gt; c<span class="Delimiter">;</span>
     out &lt;&lt; c<span class="Delimiter">;</span>
     <span class="Identifier">return</span><span class="Delimiter">;</span>
@@ -232,7 +232,7 @@ void skip_ignored_characters<span class="Delimiter">(</span>istream&amp; in<span
 
 void skip_whitespace_and_comments<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   while <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
     if <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()))</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
     else if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">','</span><span class="Delimiter">)</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
     else if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'#'</span><span class="Delimiter">)</span> skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
@@ -241,9 +241,9 @@ void skip_whitespace_and_comments<span class="Delimiter">(</span>istream&amp; in
 <span class="Delimiter">}</span>
 
 void skip_comment<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> &amp;&amp; in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> &amp;&amp; in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
-    while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> &amp;&amp; in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
+    while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> &amp;&amp; in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/012transform.cc.html b/html/012transform.cc.html
index 6770e137..7ddd15af 100644
--- a/html/012transform.cc.html
+++ b/html/012transform.cc.html
@@ -57,8 +57,16 @@ vector&lt;transform_fn&gt; Transform<span class="Delimiter">;</span>
 
 <span class="Delimiter">:(after &quot;int main&quot;)</span>
   <span class="Comment">// Begin Transforms</span>
+    <span class="Comment">// Begin Instruction Inserting/Deleting Transforms</span>
+    <span class="Comment">// End Instruction Inserting/Deleting Transforms</span>
+
+    <span class="Comment">// Begin Instruction Modifying Transforms</span>
+    <span class="Comment">// End Instruction Modifying Transforms</span>
   <span class="Comment">// End Transforms</span>
 
+  <span class="Comment">// Begin Checks</span>
+  <span class="Comment">// End Checks</span>
+
 <span class="Delimiter">:(code)</span>
 void transform_all<span class="Delimiter">()</span> <span class="Delimiter">{</span>
   trace<span class="Delimiter">(</span><span class="Constant">9990</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;=== transform_all()&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
@@ -73,6 +81,7 @@ void transform_all<span class="Delimiter">()</span> <span class="Delimiter">{</s
       r<span class="Delimiter">.</span>transformed_until = t<span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;wrapping up transform\n&quot;;</span>
   parse_int_reagents<span class="Delimiter">();</span>  <span class="Comment">// do this after all other transforms have run</span>
   <span class="Comment">// End Transform All</span>
 <span class="Delimiter">}</span>
diff --git a/html/013update_operation.cc.html b/html/013update_operation.cc.html
index c2377b97..7a6c5f78 100644
--- a/html/013update_operation.cc.html
+++ b/html/013update_operation.cc.html
@@ -33,7 +33,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="Comment">//: Once all code is loaded, save operation ids of instructions and check that</span>
 <span class="Comment">//: nothing's undefined.</span>
 
-<span class="Delimiter">:(before &quot;End Transforms&quot;)</span>
+<span class="Delimiter">:(before &quot;End Instruction Modifying Transforms&quot;)</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>update_instruction_operations<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(code)</span>
diff --git a/html/014literal_string.cc.html b/html/014literal_string.cc.html
index b137323a..024a0efc 100644
--- a/html/014literal_string.cc.html
+++ b/html/014literal_string.cc.html
@@ -55,17 +55,17 @@ recipe main [
 put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;literal-string&quot;</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
 
 <span class="Delimiter">:(before &quot;End next_word Special-cases&quot;)</span>
-  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    string result = slurp_quoted<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-    skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-    skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-    <span class="Identifier">return</span> result<span class="Delimiter">;</span>
-  <span class="Delimiter">}</span>
+if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  string result = slurp_quoted<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  skip_comment<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
 
 <span class="Delimiter">:(code)</span>
 string slurp_quoted<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   ostringstream out<span class="Delimiter">;</span>
-  assert<span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">());</span>  assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span>  out &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span>  <span class="Comment">// slurp the '['</span>
+  assert<span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">));</span>  assert<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'['</span><span class="Delimiter">);</span>  out &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span>  <span class="Comment">// slurp the '['</span>
   if <span class="Delimiter">(</span>is_code_string<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">))</span>
     slurp_quoted_comment_aware<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<span class="Delimiter">);</span>
   else
@@ -76,7 +76,7 @@ string slurp_quoted<span class="Delimiter">(</span>istream&amp; in<span class="D
 <span class="Comment">// A string is a code string if it contains a newline before any non-whitespace</span>
 <span class="Comment">// todo: support comments before the newline. But that gets messy.</span>
 bool is_code_string<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> ostream&amp; out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     char c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
     if <span class="Delimiter">(</span>!isspace<span class="Delimiter">(</span>c<span class="Delimiter">))</span> <span class="Delimiter">{</span>
       in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span>c<span class="Delimiter">);</span>
@@ -94,7 +94,7 @@ bool is_code_string<span class="Delimiter">(</span>istream&amp; in<span class="D
 <span class="Comment">// strings.</span>
 void slurp_quoted_comment_oblivious<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> ostream&amp; out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   int brace_depth = <span class="Constant">1</span><span class="Delimiter">;</span>
-  while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     char c = in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
     if <span class="Delimiter">(</span>c == <span class="cSpecial">'\\'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
       out &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span>
@@ -105,7 +105,7 @@ void slurp_quoted_comment_oblivious<span class="Delimiter">(</span>istream&amp;
     if <span class="Delimiter">(</span>c == <span class="Constant">']'</span><span class="Delimiter">)</span> --brace_depth<span class="Delimiter">;</span>
     if <span class="Delimiter">(</span>brace_depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> &amp;&amp; brace_depth &gt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> &amp;&amp; brace_depth &gt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     raise_error &lt;&lt; <span class="Constant">&quot;unbalanced '['</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     out<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
   <span class="Delimiter">}</span>
@@ -121,7 +121,7 @@ void slurp_quoted_comment_aware<span class="Delimiter">(</span>istream&amp; in<s
     <span class="Delimiter">}</span>
     if <span class="Delimiter">(</span>c == <span class="Constant">'#'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
       out &lt;&lt; c<span class="Delimiter">;</span>
-      while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">()</span> &amp;&amp; in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> out &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span>
+      while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">)</span> &amp;&amp; in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> out &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">());</span>
       <span class="Identifier">continue</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
     if <span class="Delimiter">(</span>c == <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
diff --git a/html/020run.cc.html b/html/020run.cc.html
index 38ffeb73..e5ee3061 100644
--- a/html/020run.cc.html
+++ b/html/020run.cc.html
@@ -104,9 +104,7 @@ void run_current_routine<span class="Delimiter">()</span>
       raise_error &lt;&lt; <span class="Constant">&quot;something wrote to location 0; this should never happen</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
       put<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
     <span class="Delimiter">}</span>
-    <span class="Comment">// Read all ingredients from memory.</span>
-    <span class="Comment">// Each ingredient loads a vector of values rather than a single value; mu</span>
-    <span class="Comment">// permits operating on reagents spanning multiple locations.</span>
+    <span class="Comment">// read all ingredients from memory, each potentially spanning multiple locations</span>
     vector&lt;vector&lt;double&gt; &gt; ingredients<span class="Delimiter">;</span>
     if <span class="Delimiter">(</span>should_copy_ingredients<span class="Delimiter">())</span> <span class="Delimiter">{</span>
       for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -115,7 +113,7 @@ void run_current_routine<span class="Delimiter">()</span>
 <span class="CommentedCode">//?         Locations_read_by_instruction[current_instruction().name] += SIZE(ingredients.back());</span>
       <span class="Delimiter">}</span>
     <span class="Delimiter">}</span>
-    <span class="Comment">// Instructions below will write to 'products'.</span>
+    <span class="Comment">// instructions below will write to 'products'</span>
     vector&lt;vector&lt;double&gt; &gt; products<span class="Delimiter">;</span>
     switch <span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       <span class="Comment">// Primitive Recipe Implementations</span>
@@ -191,14 +189,14 @@ if <span class="Delimiter">(</span>argc &gt; <span class="Constant">1</span><spa
   <span class="Delimiter">}</span>
   transform_all<span class="Delimiter">();</span>
 <span class="CommentedCode">//?   dump_recipe(&quot;handle-keyboard-event&quot;),  exit(0);</span>
-  if <span class="Delimiter">(</span>Run_tests<span class="Delimiter">)</span> Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">&quot;main&quot;</span><span class="Delimiter">)));</span>
+  if <span class="Delimiter">(</span>Run_tests<span class="Delimiter">)</span> Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;main&quot;</span><span class="Delimiter">));</span>
   <span class="Comment">// End Loading .mu Files</span>
 <span class="Delimiter">}</span>
 
 <span class="Comment">//: Step 3: if we aren't running tests, locate a recipe called 'main' and</span>
 <span class="Comment">//: start running it.</span>
 <span class="Delimiter">:(before &quot;End Main&quot;)</span>
-if <span class="Delimiter">(</span>!Run_tests &amp;&amp; contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">&quot;main&quot;</span><span class="Delimiter">))</span> &amp;&amp; contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">&quot;main&quot;</span><span class="Delimiter">))))</span> <span class="Delimiter">{</span>
+if <span class="Delimiter">(</span>!Run_tests &amp;&amp; contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;main&quot;</span><span class="Delimiter">)</span> &amp;&amp; contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;main&quot;</span><span class="Delimiter">)))</span> <span class="Delimiter">{</span>
   setup<span class="Delimiter">();</span>
 <span class="CommentedCode">//?   Trace_file = &quot;interactive&quot;;</span>
 <span class="CommentedCode">//?   START_TRACING_UNTIL_END_OF_SCOPE;</span>
@@ -209,7 +207,7 @@ if <span class="Delimiter">(</span>!Run_tests &amp;&amp; contains_key<span class
 
 <span class="Delimiter">:(code)</span>
 void run_main<span class="Delimiter">(</span>int argc<span class="Delimiter">,</span> char* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">&quot;main&quot;</span><span class="Delimiter">));</span>
+  recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;main&quot;</span><span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>r<span class="Delimiter">)</span> run<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/021check_instruction.cc.html b/html/021check_instruction.cc.html
index e203a386..585c2c3a 100644
--- a/html/021check_instruction.cc.html
+++ b/html/021check_instruction.cc.html
@@ -42,7 +42,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="Comment">//: sophisticated layer system I'd introduce the simpler version first and</span>
 <span class="Comment">//: transform it in a separate layer or set of layers.</span>
 
-<span class="Delimiter">:(after &quot;Transform.push_back(update_instruction_operations)&quot;)</span>
+<span class="Delimiter">:(before &quot;End Checks&quot;)</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_instruction<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(code)</span>
@@ -61,7 +61,7 @@ void check_instruction<span class="Delimiter">(</span>const recipe_ordinal r<spa
           <span class="Identifier">break</span><span class="Delimiter">;</span>
         <span class="Delimiter">}</span>
         for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-          if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+          if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
             raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;can't copy &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot; to &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot;; types don't match</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
             <span class="Identifier">goto</span> finish_checking_instruction<span class="Delimiter">;</span>
           <span class="Delimiter">}</span>
@@ -106,57 +106,78 @@ recipe main [
 ]
 <span class="traceContains">+error: main: can't copy 34 to 1:address:number; types don't match</span>
 
+<span class="Delimiter">:(scenario write_address_to_number_allowed)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>/unsafe
+  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:address:number
+]
+<span class="traceContains">+mem: storing 12 in location 2</span>
+$error: <span class="Constant">0</span>
+
 <span class="Delimiter">:(code)</span>
-bool types_match<span class="Delimiter">(</span>reagent lhs<span class="Delimiter">,</span> reagent rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="Comment">// types_match with some leniency</span>
+bool types_coercible<span class="Delimiter">(</span>const reagent&amp; lhs<span class="Delimiter">,</span> const reagent&amp; rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> &amp;&amp; is_mu_number<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  <span class="Comment">// End types_coercible Special-cases</span>
+  <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+bool types_match<span class="Delimiter">(</span>const reagent&amp; lhs<span class="Delimiter">,</span> const reagent&amp; rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Comment">// to sidestep type-checking, use /unsafe in the source.</span>
+  <span class="Comment">// this will be highlighted in red inside vim. just for setting up some tests.</span>
+  if <span class="Delimiter">(</span>is_unsafe<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+    <span class="Comment">// End Matching Types For Literal(lhs)</span>
+    <span class="Comment">// allow writing 0 to any address</span>
+    if <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> rhs<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span><span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>!lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;boolean&quot;</span><span class="Delimiter">))</span>
+      <span class="Identifier">return</span> boolean_matches_literal<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<span class="Delimiter">);</span>
+    <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">;</span>  <span class="Comment">// literals are always scalars</span>
+  <span class="Delimiter">}</span>
+  <span class="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+bool boolean_matches_literal<span class="Delimiter">(</span>const reagent&amp; lhs<span class="Delimiter">,</span> const reagent&amp; rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!is_literal<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>!lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value != get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;boolean&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+  <span class="Identifier">return</span> rhs<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span> || rhs<span class="Delimiter">.</span>name == <span class="Constant">&quot;1&quot;</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">// copy arguments because later layers will want to make changes to them</span>
+<span class="Comment">// without perturbing the caller</span>
+bool types_strictly_match<span class="Delimiter">(</span>reagent lhs<span class="Delimiter">,</span> reagent rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> &amp;&amp; lhs<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;number&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  <span class="Comment">// to sidestep type-checking, use /unsafe in the source.</span>
+  <span class="Comment">// this will be highlighted in red inside vim. just for setting up some tests.</span>
+  if <span class="Delimiter">(</span>is_unsafe<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
   <span class="Comment">// '_' never raises type error</span>
   if <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-  <span class="Comment">// to sidestep type-checking, use /raw in the source.</span>
-  <span class="Comment">// this is unsafe, and will be highlighted in red inside vim. just for some tests.</span>
-  if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> valid_type_for_literal<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<span class="Delimiter">)</span> &amp;&amp; size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>!lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> !rhs<span class="Delimiter">.</span>type<span class="Delimiter">;</span>
-  <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">,</span> rhs<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
-<span class="Delimiter">}</span>
-
-bool valid_type_for_literal<span class="Delimiter">(</span>const reagent&amp; lhs<span class="Delimiter">,</span> const reagent&amp; literal_rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
-  <span class="Comment">// End valid_type_for_literal Special-cases</span>
-  <span class="Comment">// allow writing 0 to any address</span>
-  if <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> literal_rhs<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span><span class="Delimiter">;</span>
-  <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  <span class="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">,</span> rhs<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
 <span class="Comment">// two types match if the second begins like the first</span>
 <span class="Comment">// (trees perform the same check recursively on each subtree)</span>
-bool types_match<span class="Delimiter">(</span>type_tree* lhs<span class="Delimiter">,</span> type_tree* rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+bool types_strictly_match<span class="Delimiter">(</span>type_tree* lhs<span class="Delimiter">,</span> type_tree* rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>!lhs<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>!rhs || rhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;array&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
-    if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;address&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
-    <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
-  <span class="Delimiter">}</span>
-  if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;character&quot;</span><span class="Delimiter">)</span> &amp;&amp; rhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;number&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;number&quot;</span><span class="Delimiter">)</span> &amp;&amp; rhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;character&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>!rhs<span class="Delimiter">)</span> <span class="Identifier">return</span> lhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">0</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value != rhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
-  <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span> &amp;&amp; types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
-<span class="Delimiter">}</span>
-
-<span class="Comment">// hacky version that allows 0 addresses</span>
-bool types_match<span class="Delimiter">(</span>const reagent lhs<span class="Delimiter">,</span> const type_tree* rhs<span class="Delimiter">,</span> const vector&lt;double&gt;&amp; data<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>is_dummy<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>rhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;array&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
-    if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;address&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> scalar<span class="Delimiter">(</span>data<span class="Delimiter">)</span> &amp;&amp; data<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">;</span>
-    <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
-  <span class="Delimiter">}</span>
-  if <span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value != rhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
-  <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span> &amp;&amp; types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> types_strictly_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span> &amp;&amp; types_strictly_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
 bool is_raw<span class="Delimiter">(</span>const reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   <span class="Identifier">return</span> has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">&quot;raw&quot;</span><span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
+bool is_unsafe<span class="Delimiter">(</span>const reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Identifier">return</span> has_property<span class="Delimiter">(</span>r<span class="Delimiter">,</span> <span class="Constant">&quot;unsafe&quot;</span><span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
 bool is_mu_array<span class="Delimiter">(</span>reagent r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>!r<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>r<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
diff --git a/html/029tools.cc.html b/html/029tools.cc.html
index 4f5242fe..4b78fe12 100644
--- a/html/029tools.cc.html
+++ b/html/029tools.cc.html
@@ -72,7 +72,7 @@ case TRACE: <span class="Delimiter">{</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-<span class="Comment">//: a smarter but more limited version of 'trace'</span>
+<span class="Comment">//: simpler limited version of 'trace'</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
 STASH<span class="Delimiter">,</span>
@@ -117,9 +117,8 @@ string print_mu<span class="Delimiter">(</span>const reagent&amp; r<span class="
     <span class="Identifier">return</span> r<span class="Delimiter">.</span>name+<span class="Constant">' '</span><span class="Delimiter">;</span>
   <span class="Comment">// End print Special-cases(reagent r, data)</span>
   ostringstream out<span class="Delimiter">;</span>
-  for <span class="Delimiter">(</span>long long i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  for <span class="Delimiter">(</span>long long i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>data<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
     out &lt;&lt; no_scientific<span class="Delimiter">(</span>data<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">' '</span><span class="Delimiter">;</span>
-  <span class="Delimiter">}</span>
   <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/030container.cc.html b/html/030container.cc.html
index 403c6a60..8ef0dda6 100644
--- a/html/030container.cc.html
+++ b/html/030container.cc.html
@@ -16,7 +16,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .traceContains { color: #008000; }
 .SalientComment { color: #00ffff; }
 .cSpecial { color: #008000; }
-.traceAbsent { color: #c00000; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
@@ -191,11 +190,12 @@ case GET: <span class="Delimiter">{</span>
     raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;invalid offset &quot;</span> &lt;&lt; offset_value &lt;&lt; <span class="Constant">&quot; for &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
+  if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
   reagent product = inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
   <span class="Comment">// Update GET product in Check</span>
   const reagent element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">,</span> offset_value<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-    raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'get' &quot;</span> &lt;&lt; offset<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot; (&quot;</span> &lt;&lt; offset_value &lt;&lt; <span class="Constant">&quot;) on &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; can't be saved in &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;; type should be &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; but is &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>product<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+  if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+    raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'get &quot;</span> &lt;&lt; base<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;, &quot;</span> &lt;&lt; offset<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;' should write to &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; but &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; has type &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>product<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -275,7 +275,17 @@ recipe main [
   <span class="Constant">14</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">36</span>
   <span class="Constant">15</span>:address:number<span class="Special"> &lt;- </span>get <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset
 ]
-<span class="traceContains">+error: main: 'get' 1:offset (1) on point-number can't be saved in 15:address:number; type should be number but is &lt;address : &lt;number : &lt;&gt;&gt;&gt;</span>
+<span class="traceContains">+error: main: 'get 12:point-number/raw, 1:offset' should write to number but 15 has type &lt;address : &lt;number : &lt;&gt;&gt;&gt;</span>
+
+<span class="Comment">//: we might want to call 'get' without saving the results, say in a sandbox</span>
+
+<span class="Delimiter">:(scenario get_without_product)</span>
+recipe main [
+  <span class="Constant">12</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+  <span class="Constant">13</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">35</span>
+  get <span class="Constant">12</span>:point/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset  <span class="Comment"># unsafe</span>
+]
+<span class="Comment"># just don't die</span>
 
 <span class="SalientComment">//:: To write to elements of containers, you need their address.</span>
 
@@ -326,8 +336,8 @@ case GET_ADDRESS: <span class="Delimiter">{</span>
   reagent element = element_type<span class="Delimiter">(</span>base<span class="Delimiter">,</span> offset_value<span class="Delimiter">);</span>
   <span class="Comment">// ..except for an address at the start</span>
   element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;address&quot;</span><span class="Delimiter">),</span> element<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-    raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'get-address' &quot;</span> &lt;&lt; offset<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot; (&quot;</span> &lt;&lt; offset_value &lt;&lt; <span class="Constant">&quot;) on &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; can't be saved in &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;; type should be &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+  if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+    raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'get-address &quot;</span> &lt;&lt; base<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;, &quot;</span> &lt;&lt; offset<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;' should write to &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; but &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; has type &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>product<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -377,13 +387,16 @@ recipe main [
 
 <span class="Delimiter">:(scenario get_address_product_type_mismatch)</span>
 <span class="Special">% Hide_errors = true;</span>
+container boolbool [
+  x:boolean
+  y:boolean
+]
 recipe main [
-  <span class="Constant">12</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
-  <span class="Constant">13</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">35</span>
-  <span class="Constant">14</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">36</span>
-  <span class="Constant">15</span>:number<span class="Special"> &lt;- </span>get-address <span class="Constant">12</span>:point-number/<span class="Special">raw</span><span class="Delimiter">,</span> <span class="Constant">1</span>:offset
+  <span class="Constant">12</span>:boolean<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
+  <span class="Constant">13</span>:boolean<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
+  <span class="Constant">15</span>:boolean<span class="Special"> &lt;- </span>get-address <span class="Constant">12</span>:boolbool<span class="Delimiter">,</span> <span class="Constant">1</span>:offset
 ]
-<span class="traceContains">+error: main: 'get-address' 1:offset (1) on point-number can't be saved in 15:number; type should be &lt;address : &lt;number : &lt;&gt;&gt;&gt;</span>
+<span class="traceContains">+error: main: 'get-address 12:boolbool, 1:offset' should write to &lt;address : &lt;boolean : &lt;&gt;&gt;&gt; but 15 has type boolean</span>
 
 <span class="SalientComment">//:: Allow containers to be defined in mu code.</span>
 
@@ -439,7 +452,7 @@ void insert_container<span class="Delimiter">(</span>const string&amp; command<s
   recently_added_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">));</span>
   info<span class="Delimiter">.</span>name = name<span class="Delimiter">;</span>
   info<span class="Delimiter">.</span>kind = kind<span class="Delimiter">;</span>
-  while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     string element = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     if <span class="Delimiter">(</span>element == <span class="Constant">&quot;]&quot;</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
@@ -448,7 +461,7 @@ void insert_container<span class="Delimiter">(</span>const string&amp; command<s
     info<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>slurp_until<span class="Delimiter">(</span>inner<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">));</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;parse&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;  element name: &quot;</span> &lt;&lt; info<span class="Delimiter">.</span>element_names<span class="Delimiter">.</span>back<span class="Delimiter">()</span> &lt;&lt; end<span class="Delimiter">();</span>
     type_tree* new_type = <span class="Constant">NULL</span><span class="Delimiter">;</span>
-    for <span class="Delimiter">(</span>type_tree** curr_type = &amp;new_type<span class="Delimiter">;</span> !inner<span class="Delimiter">.</span>eof<span class="Delimiter">();</span> curr_type = &amp;<span class="Delimiter">(</span>*curr_type<span class="Delimiter">)-&gt;</span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    for <span class="Delimiter">(</span>type_tree** curr_type = &amp;new_type<span class="Delimiter">;</span> has_data<span class="Delimiter">(</span>inner<span class="Delimiter">);</span> curr_type = &amp;<span class="Delimiter">(</span>*curr_type<span class="Delimiter">)-&gt;</span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       string type_name = slurp_until<span class="Delimiter">(</span>inner<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span>
       <span class="Comment">// End insert_container Special Uses(type_name)</span>
       if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">)</span>
@@ -535,22 +548,23 @@ recipe main [
   <span class="Comment"># integer is not a type</span>
   <span class="Constant">1</span>:integer<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
 ]
-<span class="traceContains">+error: main: unknown type in '1:integer &lt;- copy 0'</span>
+<span class="traceContains">+error: main: unknown type integer in '1:integer &lt;- copy 0'</span>
 
 <span class="Delimiter">:(scenario run_allows_type_definition_after_use)</span>
 <span class="Special">% Hide_errors = true;</span>
 recipe main [
-  <span class="Constant">1</span>:bar<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span>
+  <span class="Constant">1</span>:bar<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/unsafe
 ]
 
 container bar [
   x:number
 ]
-<span class="traceAbsent">-error: unknown type: bar</span>
 $error: <span class="Constant">0</span>
 
-<span class="Delimiter">:(after &quot;Begin Transforms&quot;)</span>
+<span class="Delimiter">:(after &quot;Begin Instruction Modifying Transforms&quot;)</span>
+<span class="Comment">// Begin Type Modifying Transforms</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_or_set_invalid_types<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
+<span class="Comment">// End Type Modifying Transforms</span>
 
 <span class="Delimiter">:(code)</span>
 void check_or_set_invalid_types<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -578,8 +592,10 @@ void check_or_set_invalid_types<span class="Delimiter">(</span>type_tree* type<s
   if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>type_name &amp;&amp; contains_key<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span>
       type<span class="Delimiter">-&gt;</span>value = get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> type_name<span class="Delimiter">-&gt;</span>value<span class="Delimiter">);</span>
+    else if <span class="Delimiter">(</span>type_name<span class="Delimiter">)</span>
+      raise_error &lt;&lt; block &lt;&lt; <span class="Constant">&quot;unknown type &quot;</span> &lt;&lt; type_name<span class="Delimiter">-&gt;</span>value &lt;&lt; <span class="Constant">&quot; in &quot;</span> &lt;&lt; name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     else
-      raise_error &lt;&lt; block &lt;&lt; <span class="Constant">&quot;unknown type in &quot;</span> &lt;&lt; name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+      raise_error &lt;&lt; block &lt;&lt; <span class="Constant">&quot;missing type in &quot;</span> &lt;&lt; name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
   <span class="Delimiter">}</span>
   check_or_set_invalid_types<span class="Delimiter">(</span>type<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> type_name ? type_name<span class="Delimiter">-&gt;</span>left : <span class="Constant">NULL</span><span class="Delimiter">,</span> block<span class="Delimiter">,</span> name<span class="Delimiter">);</span>
   check_or_set_invalid_types<span class="Delimiter">(</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> type_name ? type_name<span class="Delimiter">-&gt;</span>right : <span class="Constant">NULL</span><span class="Delimiter">,</span> block<span class="Delimiter">,</span> name<span class="Delimiter">);</span>
diff --git a/html/031address.cc.html b/html/031address.cc.html
index f2b0e28f..5a58fc2f 100644
--- a/html/031address.cc.html
+++ b/html/031address.cc.html
@@ -38,7 +38,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="Delimiter">:(scenario copy_indirect)</span>
 recipe main [
-  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>/<span class="Special">raw</span>
+  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>/unsafe
   <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
   <span class="Comment"># This loads location 1 as an address and looks up *that* location.</span>
   <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:address:number/lookup
@@ -52,7 +52,7 @@ canonize<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
 <span class="Comment">//: 'lookup' property</span>
 <span class="Delimiter">:(scenario store_indirect)</span>
 recipe main [
-  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>/<span class="Special">raw</span>
+  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>/unsafe
   <span class="Constant">1</span>:address:number/lookup<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
 ]
 <span class="traceContains">+mem: storing 34 in location 2</span>
@@ -96,7 +96,7 @@ void lookup_memory<span class="Delimiter">(</span>reagent&amp; x<span class="Del
   drop_one_lookup<span class="Delimiter">(</span>x<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
-<span class="Delimiter">:(after &quot;bool types_match(reagent lhs, reagent rhs)&quot;)</span>
+<span class="Delimiter">:(after &quot;bool types_strictly_match(reagent lhs, reagent rhs)&quot;)</span>
   if <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>!canonize_type<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
 
@@ -161,7 +161,7 @@ recipe main [
   <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>
   <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
   <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">35</span>
-  <span class="Constant">4</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">5</span>/<span class="Special">raw</span>
+  <span class="Constant">4</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">5</span>/unsafe
   *<span class="Constant">4</span>:address:number<span class="Special"> &lt;- </span>get <span class="Constant">1</span>:address:point/lookup<span class="Delimiter">,</span> <span class="Constant">0</span>:offset
 ]
 <span class="traceContains">+mem: storing 34 in location 5</span>
@@ -203,7 +203,7 @@ canonize<span class="Delimiter">(</span>base<span class="Delimiter">);</span>
 
 <span class="Delimiter">:(scenario lookup_abbreviation)</span>
 recipe main [
-  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>/<span class="Special">raw</span>
+  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>/unsafe
   <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
   <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy *<span class="Constant">1</span>:address:number
 ]
diff --git a/html/032array.cc.html b/html/032array.cc.html
index 8c0ce105..d2689076 100644
--- a/html/032array.cc.html
+++ b/html/032array.cc.html
@@ -119,7 +119,7 @@ recipe main [
   <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span>
   <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span>
   <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span>
-  <span class="Constant">5</span>:address:array:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
+  <span class="Constant">5</span>:address:array:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/unsafe
   <span class="Constant">6</span>:array:number<span class="Special"> &lt;- </span>copy *<span class="Constant">5</span>:address:array:number
 ]
 <span class="traceContains">+mem: storing 3 in location 6</span>
@@ -194,7 +194,7 @@ case INDEX: <span class="Delimiter">{</span>
   canonize_type<span class="Delimiter">(</span>product<span class="Delimiter">);</span>
   reagent element<span class="Delimiter">;</span>
   element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>*array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">));</span>
-  if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'index' on &quot;</span> &lt;&lt; base<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot; can't be saved in &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;; type should be &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
@@ -238,7 +238,7 @@ recipe main [
   <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span>
   <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span>
   <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span>
-  <span class="Constant">5</span>:address:array:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
+  <span class="Constant">5</span>:address:array:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/unsafe
   <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>index *<span class="Constant">5</span>:address:array:number<span class="Delimiter">,</span> <span class="Constant">1</span>
 ]
 <span class="traceContains">+mem: storing 15 in location 6</span>
@@ -268,7 +268,7 @@ recipe main [
   <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span>
   <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span>
   <span class="Constant">7</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span>
-  <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
+  <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/unsafe
   index *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> -<span class="Constant">1</span>
 ]
 <span class="traceContains">+error: main: invalid index -1</span>
@@ -283,11 +283,23 @@ recipe main [
   <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span>
   <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span>
   <span class="Constant">7</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span>
-  <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
+  <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/unsafe
   <span class="Constant">9</span>:number<span class="Special"> &lt;- </span>index *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">0</span>
 ]
 <span class="traceContains">+error: main: 'index' on *8:address:array:point can't be saved in 9:number; type should be point</span>
 
+<span class="Comment">//: we might want to call 'index' without saving the results, say in a sandbox</span>
+
+<span class="Delimiter">:(scenario index_without_product)</span>
+recipe main [
+  <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Special"> &lt;- </span>create-array
+  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span>
+  <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span>
+  <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span>
+  index <span class="Constant">1</span>:array:number:<span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">0</span>
+]
+<span class="Comment"># just don't die</span>
+
 <span class="SalientComment">//:: To write to elements of containers, you need their address.</span>
 
 <span class="Delimiter">:(scenario index_address)</span>
@@ -322,7 +334,7 @@ case INDEX_ADDRESS: <span class="Delimiter">{</span>
   reagent element<span class="Delimiter">;</span>
   element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>*array_element<span class="Delimiter">(</span>base<span class="Delimiter">.</span>type<span class="Delimiter">));</span>
   element<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;address&quot;</span><span class="Delimiter">),</span> element<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span> element<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;'index' on &quot;</span> &lt;&lt; base<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot; can't be saved in &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot;; type should be &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>element<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
@@ -376,7 +388,7 @@ recipe main [
   <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span>
   <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span>
   <span class="Constant">7</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span>
-  <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
+  <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/unsafe
   index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> -<span class="Constant">1</span>
 ]
 <span class="traceContains">+error: main: invalid index -1</span>
@@ -391,7 +403,7 @@ recipe main [
   <span class="Constant">5</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">14</span>
   <span class="Constant">6</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">15</span>
   <span class="Constant">7</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">16</span>
-  <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/<span class="Special">raw</span>
+  <span class="Constant">8</span>:address:array:point<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>/unsafe
   <span class="Constant">9</span>:address:number<span class="Special"> &lt;- </span>index-address *<span class="Constant">8</span>:address:array:point<span class="Delimiter">,</span> <span class="Constant">0</span>
 ]
 <span class="traceContains">+error: main: 'index' on *8:address:array:point can't be saved in 9:address:number; type should be &lt;address : &lt;point : &lt;&gt;&gt;&gt;</span>
@@ -445,6 +457,18 @@ case LENGTH: <span class="Delimiter">{</span>
 recipe_ordinal r = current_instruction<span class="Delimiter">().</span>operation<span class="Delimiter">;</span>
 if <span class="Delimiter">(</span>r == CREATE_ARRAY || r == INDEX || r == INDEX_ADDRESS || r == LENGTH<span class="Delimiter">)</span>
   <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+
+<span class="Comment">//: a particularly common array type is the string, or address:array:character</span>
+<span class="Delimiter">:(code)</span>
+bool is_mu_string<span class="Delimiter">(</span>const reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Identifier">return</span> x<span class="Delimiter">.</span>type
+    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;address&quot;</span><span class="Delimiter">)</span>
+    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right
+    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;array&quot;</span><span class="Delimiter">)</span>
+    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right
+    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;character&quot;</span><span class="Delimiter">)</span>
+    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right == <span class="Constant">NULL</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
 </pre>
 </body>
 </html>
diff --git a/html/035call_ingredient.cc.html b/html/035call_ingredient.cc.html
index ff46da6f..34c4c270 100644
--- a/html/035call_ingredient.cc.html
+++ b/html/035call_ingredient.cc.html
@@ -55,7 +55,7 @@ recipe f [
 
 <span class="Delimiter">:(before &quot;End call Fields&quot;)</span>
 vector&lt;vector&lt;double&gt; &gt; ingredient_atoms<span class="Delimiter">;</span>
-vector&lt;type_tree*&gt; ingredient_types<span class="Delimiter">;</span>
+vector&lt;reagent&gt; ingredients<span class="Delimiter">;</span>
 long long int next_ingredient_to_process<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End call Constructor&quot;)</span>
 next_ingredient_to_process = <span class="Constant">0</span><span class="Delimiter">;</span>
@@ -65,12 +65,7 @@ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</
   current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
   reagent ingredient = call_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
   canonize_type<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span>
-  current_call<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredient<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
-  ingredient<span class="Delimiter">.</span>type = <span class="Constant">NULL</span><span class="Delimiter">;</span>  <span class="Comment">// release long-lived pointer</span>
-<span class="Delimiter">}</span>
-<span class="Delimiter">:(before &quot;End call Destructor&quot;)</span>
-for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>ingredient_types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  delete ingredient_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+  current_call<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
@@ -97,10 +92,10 @@ case NEXT_INGREDIENT: <span class="Delimiter">{</span>
       if <span class="Delimiter">(</span>!is_mu_string<span class="Delimiter">(</span>product<span class="Delimiter">))</span>
         raise_error &lt;&lt; <span class="Constant">&quot;main: wrong type for ingredient &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Delimiter">}</span>
-    else if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span>
-                          current_call<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">),</span>
-                          current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+    else if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>product<span class="Delimiter">,</span>
+                              current_call<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
       raise_error &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;wrong type for ingredient &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+      <span class="Comment">// End next-ingredient Type Mismatch Error</span>
     <span class="Delimiter">}</span>
     products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>
         current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">));</span>
diff --git a/html/036call_reply.cc.html b/html/036call_reply.cc.html
index 45622e07..1784c8f9 100644
--- a/html/036call_reply.cc.html
+++ b/html/036call_reply.cc.html
@@ -73,13 +73,14 @@ case REPLY: <span class="Delimiter">{</span>
     <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>!types_coercible<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
       raise_error &lt;&lt; maybe<span class="Delimiter">(</span>callee<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;reply ingredient &quot;</span> &lt;&lt; reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot; can't be saved in &quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
       reagent lhs = reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
       canonize_type<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
       reagent rhs = caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
       canonize_type<span class="Delimiter">(</span>rhs<span class="Delimiter">);</span>
       raise_error &lt;&lt; debug_string<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; vs &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>rhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+      <span class="Comment">// End reply Type Mismatch Error</span>
       <span class="Identifier">goto</span> finish_reply<span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
diff --git a/html/038scheduler.cc.html b/html/038scheduler.cc.html
index 16b3efbb..56396b68 100644
--- a/html/038scheduler.cc.html
+++ b/html/038scheduler.cc.html
@@ -146,7 +146,7 @@ Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</s
 <span class="Comment">//: special case for the very first routine</span>
 <span class="Delimiter">:(replace{} &quot;void run_main(int argc, char* argv[])&quot;)</span>
 void run_main<span class="Delimiter">(</span>int argc<span class="Delimiter">,</span> char* argv[]<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> string<span class="Delimiter">(</span><span class="Constant">&quot;main&quot;</span><span class="Delimiter">));</span>
+  recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;main&quot;</span><span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     routine* main_routine = new routine<span class="Delimiter">(</span>r<span class="Delimiter">);</span>
     <span class="Comment">// Update main_routine</span>
@@ -200,8 +200,7 @@ case START_RUNNING: <span class="Delimiter">{</span>
     new_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
     reagent ingredient = current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     canonize_type<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span>
-    new_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredient<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
-    ingredient<span class="Delimiter">.</span>type = <span class="Constant">NULL</span><span class="Delimiter">;</span>  <span class="Comment">// release long-lived pointer</span>
+    new_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
   Routines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_routine<span class="Delimiter">);</span>
   products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
diff --git a/html/040brace.cc.html b/html/040brace.cc.html
index 6f994e22..a65f6e0f 100644
--- a/html/040brace.cc.html
+++ b/html/040brace.cc.html
@@ -65,7 +65,7 @@ recipe main [
 <span class="traceContains">+transform: jump 1:offset</span>
 <span class="traceContains">+transform: copy ...</span>
 
-<span class="Delimiter">:(after &quot;Begin Transforms&quot;)</span>
+<span class="Delimiter">:(before &quot;End Instruction Modifying Transforms&quot;)</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_braces<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(code)</span>
diff --git a/html/041jump_target.cc.html b/html/041jump_target.cc.html
index e85829db..341cf3c2 100644
--- a/html/041jump_target.cc.html
+++ b/html/041jump_target.cc.html
@@ -52,7 +52,7 @@ recipe main [
 <span class="Delimiter">:(before &quot;End Mu Types Initialization&quot;)</span>
 put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;label&quot;</span><span class="Delimiter">,</span> <span class="Constant">0</span><span class="Delimiter">);</span>
 
-<span class="Delimiter">:(before &quot;Transform.push_back(transform_braces)&quot;)</span>
+<span class="Delimiter">:(before &quot;End Instruction Modifying Transforms&quot;)</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_labels<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(code)</span>
diff --git a/html/042name.cc.html b/html/042name.cc.html
index da006079..aa0a1fe9 100644
--- a/html/042name.cc.html
+++ b/html/042name.cc.html
@@ -54,7 +54,7 @@ recipe main [
 <span class="traceContains">+error: main: use before set: y</span>
 <span class="Comment"># todo: detect conditional defines</span>
 
-<span class="Delimiter">:(after &quot;Transform.push_back(check_or_set_invalid_types&quot;)</span>  <span class="Comment">// there'll be other transforms relating to types; they all need to happen first</span>
+<span class="Delimiter">:(before &quot;End Instruction Modifying Transforms&quot;)</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>transform_names<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
@@ -66,31 +66,32 @@ for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</
 
 <span class="Delimiter">:(code)</span>
 void transform_names<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;--- transform names for recipe &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name &lt;&lt; end<span class="Delimiter">();</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;--- transform names for recipe &quot; &lt;&lt; get(Recipe, r).name &lt;&lt; '\n';</span>
+  recipe&amp; caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+  trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;--- transform names for recipe &quot;</span> &lt;&lt; caller<span class="Delimiter">.</span>name &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;--- transform names for recipe &quot; &lt;&lt; caller.name &lt;&lt; '\n';</span>
   bool names_used = <span class="Constant">false</span><span class="Delimiter">;</span>
   bool numeric_locations_used = <span class="Constant">false</span><span class="Delimiter">;</span>
   map&lt;string<span class="Delimiter">,</span> long long int&gt;&amp; names = Name[r]<span class="Delimiter">;</span>
   <span class="Comment">// store the indices 'used' so far in the map</span>
   long long int&amp; curr_idx = names[<span class="Constant">&quot;&quot;</span>]<span class="Delimiter">;</span>
   ++curr_idx<span class="Delimiter">;</span>  <span class="Comment">// avoid using index 0, benign skip in some other cases</span>
-  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    instruction&amp; inst = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    instruction&amp; inst = caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     <span class="Comment">// End transform_names(inst) Special-cases</span>
     <span class="Comment">// map names to addresses</span>
     for <span class="Delimiter">(</span>long long int in = <span class="Constant">0</span><span class="Delimiter">;</span> in &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       if <span class="Delimiter">(</span>is_numeric_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">)))</span> numeric_locations_used = <span class="Constant">true</span><span class="Delimiter">;</span>
       if <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">)))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span>
-      if <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+      if <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> inst<span class="Delimiter">,</span> caller<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
       if <span class="Delimiter">(</span>!already_transformed<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> names<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-        raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;use before set: &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">).</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+        raise_error &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;use before set: &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">).</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
       <span class="Delimiter">}</span>
       inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>lookup_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> r<span class="Delimiter">));</span>
     <span class="Delimiter">}</span>
     for <span class="Delimiter">(</span>long long int out = <span class="Constant">0</span><span class="Delimiter">;</span> out &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       if <span class="Delimiter">(</span>is_numeric_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">)))</span> numeric_locations_used = <span class="Constant">true</span><span class="Delimiter">;</span>
       if <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">)))</span> names_used = <span class="Constant">true</span><span class="Delimiter">;</span>
-      if <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+      if <span class="Delimiter">(</span>disqualified<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> inst<span class="Delimiter">,</span> caller<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
       if <span class="Delimiter">(</span>names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name<span class="Delimiter">)</span> == names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
         trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;name&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;assign &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; &quot;</span> &lt;&lt; curr_idx &lt;&lt; end<span class="Delimiter">();</span>
         names[inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">).</span>name] = curr_idx<span class="Delimiter">;</span>
@@ -100,7 +101,7 @@ void transform_names<span class="Delimiter">(</span>const recipe_ordinal r<span
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
   if <span class="Delimiter">(</span>names_used &amp;&amp; numeric_locations_used<span class="Delimiter">)</span>
-    raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;mixing variable names and numeric addresses</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+    raise_error &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;mixing variable names and numeric addresses</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
 
 bool disqualified<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">mutable</span><span class="Comment">*/</span> reagent&amp; x<span class="Delimiter">,</span> const instruction&amp; inst<span class="Delimiter">,</span> const string&amp; recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -240,8 +241,10 @@ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <
   if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">&quot;0123456789&quot;</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     <span class="Comment">// since first non-address in base type must be a container, we don't have to canonize</span>
     type_ordinal base_type = skip_addresses<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>type<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">);</span>
-    inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span>
-    trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;name&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;element &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; of type &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; is at offset &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>value<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
+    if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">))</span> <span class="Delimiter">{</span>  <span class="Comment">// otherwise we'll raise an error elsewhere</span>
+      inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;name&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;element &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; of type &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; is at offset &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>value<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
+    <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
@@ -249,8 +252,8 @@ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <
 <span class="Delimiter">:(scenarios transform)</span>
 <span class="Delimiter">:(scenario transform_names_handles_containers)</span>
 recipe main [
-  a:point<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span>
-  b:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span>
+  a:point<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/unsafe
+  b:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/unsafe
 ]
 <span class="traceContains">+name: assign a 1</span>
 <span class="traceContains">+name: assign b 3</span>
@@ -279,8 +282,10 @@ if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <
   if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>find_first_not_of<span class="Delimiter">(</span><span class="Constant">&quot;0123456789&quot;</span><span class="Delimiter">)</span> != string::npos<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     <span class="Comment">// since first non-address in base type must be an exclusive container, we don't have to canonize</span>
     type_ordinal base_type = skip_addresses<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>type<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">);</span>
-    inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span>
-    trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;name&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;variant &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; of type &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; has tag &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>value<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
+    if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">))</span> <span class="Delimiter">{</span>  <span class="Comment">// otherwise we'll raise an error elsewhere</span>
+      inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>set_value<span class="Delimiter">(</span>find_element_name<span class="Delimiter">(</span>base_type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">));</span>
+      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;name&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;variant &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; of type &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base_type<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; has tag &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">).</span>value<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
+    <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 </pre>
diff --git a/html/043new.cc.html b/html/043new.cc.html
index 35398d9f..81a1c1c7 100644
--- a/html/043new.cc.html
+++ b/html/043new.cc.html
@@ -459,16 +459,6 @@ long long int unicode_length<span class="Delimiter">(</span>const string&amp; s<
   <span class="Identifier">return</span> result<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-bool is_mu_string<span class="Delimiter">(</span>const reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  <span class="Identifier">return</span> x<span class="Delimiter">.</span>type
-    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;address&quot;</span><span class="Delimiter">)</span>
-    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right
-    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;array&quot;</span><span class="Delimiter">)</span>
-    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right
-    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;character&quot;</span><span class="Delimiter">)</span>
-    &amp;&amp; x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right == <span class="Constant">NULL</span><span class="Delimiter">;</span>
-<span class="Delimiter">}</span>
-
 string read_mu_string<span class="Delimiter">(</span>long long int address<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   long long int size = get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>size == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span>
diff --git a/html/044space.cc.html b/html/044space.cc.html
index 0bd414cb..10e456cb 100644
--- a/html/044space.cc.html
+++ b/html/044space.cc.html
@@ -42,7 +42,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="Comment"># then location 0 is really location 11, location 1 is really location 12, and so on.</span>
 recipe main [
   <span class="Constant">10</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">5</span>  <span class="Comment"># pretend array; in practice we'll use new</span>
-  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span>
+  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>/unsafe
   <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">23</span>
 ]
 <span class="traceContains">+mem: storing 23 in location 12</span>
@@ -54,8 +54,8 @@ recipe main [
   <span class="Comment"># pretend array</span>
   <span class="Constant">1000</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">5</span>
   <span class="Comment"># actual start of this recipe</span>
-  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">1000</span>/<span class="Special">raw</span>
-  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>/<span class="Special">raw</span>
+  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">1000</span>/unsafe
+  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>/unsafe
   <span class="Constant">8</span>:number/<span class="Special">raw &lt;- </span>copy *<span class="Constant">1</span>:address:number
 ]
 <span class="traceContains">+mem: storing 34 in location 8</span>
@@ -105,8 +105,8 @@ recipe main [
   <span class="Comment"># pretend array</span>
   <span class="Constant">1000</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">5</span>
   <span class="Comment"># actual start of this recipe</span>
-  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">1000</span>/<span class="Special">raw</span>
-  <span class="Constant">1</span>:address:point<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>/<span class="Special">raw</span>
+  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">1000</span>/unsafe
+  <span class="Constant">1</span>:address:point<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>/unsafe
   <span class="Constant">9</span>:number/<span class="Special">raw &lt;- </span>get *<span class="Constant">1</span>:address:point<span class="Delimiter">,</span> <span class="Constant">1</span>:offset
 ]
 <span class="traceContains">+mem: storing 35 in location 9</span>
@@ -125,8 +125,8 @@ recipe main [
   <span class="Comment"># pretend array</span>
   <span class="Constant">1000</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">5</span>
   <span class="Comment"># actual start of this recipe</span>
-  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">1000</span>/<span class="Special">raw</span>
-  <span class="Constant">1</span>:address:array:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>/<span class="Special">raw</span>
+  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">1000</span>/unsafe
+  <span class="Constant">1</span>:address:array:number<span class="Special"> &lt;- </span>copy <span class="Constant">12</span>/unsafe
   <span class="Constant">9</span>:number/<span class="Special">raw &lt;- </span>index *<span class="Constant">1</span>:address:array:number<span class="Delimiter">,</span> <span class="Constant">1</span>
 ]
 <span class="traceContains">+mem: storing 35 in location 9</span>
@@ -259,7 +259,7 @@ long long int address<span class="Delimiter">(</span>long long int offset<span c
 
 <span class="Delimiter">:(scenario get_default_space)</span>
 recipe main [
-  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span>
+  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>/unsafe
   <span class="Constant">1</span>:address:array:location/<span class="Special">raw &lt;- </span>copy default-space:address:array:location
 ]
 <span class="traceContains">+mem: storing 10 in location 1</span>
diff --git a/html/045space_surround.cc.html b/html/045space_surround.cc.html
index da74d215..29d58818 100644
--- a/html/045space_surround.cc.html
+++ b/html/045space_surround.cc.html
@@ -42,8 +42,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 recipe main [
   <span class="Constant">10</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">5</span>  <span class="Comment"># pretend array</span>
   <span class="Constant">20</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">5</span>  <span class="Comment"># pretend array</span>
-  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span>
-  <span class="Constant">0</span>:address:array:location/names:dummy<span class="Special"> &lt;- </span>copy <span class="Constant">20</span>/<span class="Special">raw</span>  <span class="Comment"># later layers will explain the /names: property</span>
+  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>/unsafe
+  <span class="Constant">0</span>:address:array:location/names:dummy<span class="Special"> &lt;- </span>copy <span class="Constant">20</span>/unsafe  <span class="Comment"># later layers will explain the /names: property</span>
   <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">32</span>
   <span class="Constant">1</span>:number/space:<span class="Constant">1</span><span class="Special"> &lt;- </span>copy <span class="Constant">33</span>
 ]
diff --git a/html/047global.cc.html b/html/047global.cc.html
index da8d790f..b2017a82 100644
--- a/html/047global.cc.html
+++ b/html/047global.cc.html
@@ -42,8 +42,8 @@ recipe main [
   <span class="Constant">10</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">5</span>
   <span class="Constant">20</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">5</span>
   <span class="Comment"># actual start of this recipe</span>
-  global-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">20</span>/<span class="Special">raw</span>
-  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>/<span class="Special">raw</span>
+  global-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">20</span>/unsafe
+  default-space:address:array:location<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>/unsafe
   <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">23</span>
   <span class="Constant">1</span>:number/space:global<span class="Special"> &lt;- </span>copy <span class="Constant">24</span>
 ]
diff --git a/html/048check_type_by_name.cc.html b/html/048check_type_by_name.cc.html
index d091ba31..13703a0e 100644
--- a/html/048check_type_by_name.cc.html
+++ b/html/048check_type_by_name.cc.html
@@ -21,7 +21,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .CommentedCode { color: #6c6c6c; }
-.Todo { color: #000000; background-color: #ffff00; padding-bottom: 1px; }
 -->
 </style>
 
@@ -49,11 +48,11 @@ recipe main [
 ]
 <span class="traceContains">+error: main: x used with multiple types</span>
 
-<span class="Delimiter">:(before &quot;Transform.push_back(check_or_set_invalid_types)&quot;)</span>
-Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_types_by_name<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
+<span class="Delimiter">:(after &quot;Begin Instruction Modifying Transforms&quot;)</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_or_set_types_by_name<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(code)</span>
-void check_types_by_name<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+void check_or_set_types_by_name<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;--- deduce types for recipe &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name &lt;&lt; end<span class="Delimiter">();</span>
 <span class="CommentedCode">//?   cerr &lt;&lt; &quot;--- deduce types for recipe &quot; &lt;&lt; get(Recipe, r).name &lt;&lt; '\n';</span>
   map&lt;string<span class="Delimiter">,</span> type_tree*&gt; type<span class="Delimiter">;</span>
@@ -82,7 +81,6 @@ void deduce_missing_type<span class="Delimiter">(</span>map&lt;string<span class
 
 void check_type<span class="Delimiter">(</span>map&lt;string<span class="Delimiter">,</span> type_tree*&gt;&amp; type<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> string_tree*&gt;&amp; type_name<span class="Delimiter">,</span> const reagent&amp; x<span class="Delimiter">,</span> const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>x<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>  <span class="Comment">// </span><span class="Todo">TODO</span><span class="Comment">: delete this</span>
   <span class="Comment">// if you use raw locations you're probably doing something unsafe</span>
   if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>  <span class="Comment">// will throw a more precise error elsewhere</span>
@@ -93,7 +91,7 @@ void check_type<span class="Delimiter">(</span>map&lt;string<span class="Delimit
   if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     type_name[x<span class="Delimiter">.</span>name] = x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>type[x<span class="Delimiter">.</span>name]<span class="Delimiter">,</span> x<span class="Delimiter">.</span>type<span class="Delimiter">))</span>
+  if <span class="Delimiter">(</span>!types_strictly_match<span class="Delimiter">(</span>type[x<span class="Delimiter">.</span>name]<span class="Delimiter">,</span> x<span class="Delimiter">.</span>type<span class="Delimiter">))</span>
     raise_error &lt;&lt; maybe<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>name<span class="Delimiter">)</span> &lt;&lt; x<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; used with multiple types</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
 
@@ -130,7 +128,7 @@ recipe main [
   y:address:charcter<span class="Special"> &lt;- </span>new character:type
   *y<span class="Special"> &lt;- </span>copy <span class="Constant">67</span>
 ]
-<span class="traceContains">+error: main: unknown type in 'y:address:charcter &lt;- new character:type'</span>
+<span class="traceContains">+error: main: unknown type charcter in 'y:address:charcter &lt;- new character:type'</span>
 </pre>
 </body>
 </html>
diff --git a/html/050scenario.cc.html b/html/050scenario.cc.html
index c586b575..523ea59f 100644
--- a/html/050scenario.cc.html
+++ b/html/050scenario.cc.html
@@ -233,9 +233,13 @@ case RUN: <span class="Delimiter">{</span>
 case RUN: <span class="Delimiter">{</span>
   ostringstream tmp<span class="Delimiter">;</span>
   tmp &lt;&lt; <span class="Constant">&quot;recipe run&quot;</span> &lt;&lt; Next_recipe_ordinal &lt;&lt; <span class="Constant">&quot; [ &quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot; ]&quot;</span><span class="Delimiter">;</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;before load\n&quot;;</span>
   vector&lt;recipe_ordinal&gt; tmp_recipe = load<span class="Delimiter">(</span>tmp<span class="Delimiter">.</span>str<span class="Delimiter">());</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;before bind\n&quot;;</span>
   bind_special_scenario_names<span class="Delimiter">(</span>tmp_recipe<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;before transform\n&quot;;</span>
   transform_all<span class="Delimiter">();</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;end\n&quot;;</span>
   if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     ++Trace_stream<span class="Delimiter">-&gt;</span>callstack_depth<span class="Delimiter">;</span>
     trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">&quot;trace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;run: incrementing callstack depth to &quot;</span> &lt;&lt; Trace_stream<span class="Delimiter">-&gt;</span>callstack_depth &lt;&lt; end<span class="Delimiter">();</span>
@@ -306,7 +310,7 @@ void check_memory<span class="Delimiter">(</span>const string&amp; s<span class=
   set&lt;long long int&gt; locations_checked<span class="Delimiter">;</span>
   while <span class="Delimiter">(</span><span class="Constant">true</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-    if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
     string lhs = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     if <span class="Delimiter">(</span>!is_integer<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Delimiter">{</span>
       check_type<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> in<span class="Delimiter">);</span>
@@ -341,7 +345,10 @@ void check_memory<span class="Delimiter">(</span>const string&amp; s<span class=
 
 void check_type<span class="Delimiter">(</span>const string&amp; lhs<span class="Delimiter">,</span> istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   reagent x<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;string&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  const string_tree* type_name = x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>type_name<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;array&quot;</span>
+      &amp;&amp; type_name<span class="Delimiter">-&gt;</span>right &amp;&amp; type_name<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;character&quot;</span>
+      &amp;&amp; !type_name<span class="Delimiter">-&gt;</span>right<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span>to_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
     skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     string _assign = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
@@ -362,7 +369,7 @@ void check_string<span class="Delimiter">(</span>long long int address<span clas
   trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;checking string length at &quot;</span> &lt;&lt; address &lt;&lt; end<span class="Delimiter">();</span>
   if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>Current_scenario &amp;&amp; !Scenario_testing_scenario<span class="Delimiter">)</span>
-      raise_error &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: expected location &quot;</span> &lt;&lt; address &lt;&lt; <span class="Constant">&quot; to contain length &quot;</span> &lt;&lt; SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; of string [&quot;</span> &lt;&lt; literal &lt;&lt; <span class="Constant">&quot;] but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+      raise_error &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: expected location &quot;</span> &lt;&lt; address &lt;&lt; <span class="Constant">&quot; to contain length &quot;</span> &lt;&lt; SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; of string [&quot;</span> &lt;&lt; literal &lt;&lt; <span class="Constant">&quot;] but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot; (&quot;</span> &lt;&lt; read_mu_string<span class="Delimiter">(</span>address<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;)</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     else
       raise_error &lt;&lt; <span class="Constant">&quot;expected location &quot;</span> &lt;&lt; address &lt;&lt; <span class="Constant">&quot; to contain length &quot;</span> &lt;&lt; SIZE<span class="Delimiter">(</span>literal<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; of string [&quot;</span> &lt;&lt; literal &lt;&lt; <span class="Constant">&quot;] but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address<span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     if <span class="Delimiter">(</span>!Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -377,7 +384,7 @@ void check_string<span class="Delimiter">(</span>long long int address<span clas
     if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">)</span> != literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> <span class="Delimiter">{</span>
       if <span class="Delimiter">(</span>Current_scenario &amp;&amp; !Scenario_testing_scenario<span class="Delimiter">)</span> <span class="Delimiter">{</span>
         <span class="Comment">// genuine test in a mu file</span>
-        raise_error &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: expected location &quot;</span> &lt;&lt; <span class="Delimiter">(</span>address+i<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; to contain &quot;</span> &lt;&lt; literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+        raise_error &lt;&lt; <span class="Constant">&quot;</span><span class="cSpecial">\n</span><span class="Constant">F - &quot;</span> &lt;&lt; Current_scenario<span class="Delimiter">-&gt;</span>name &lt;&lt; <span class="Constant">&quot;: expected location &quot;</span> &lt;&lt; <span class="Delimiter">(</span>address+i<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; to contain &quot;</span> &lt;&lt; literal<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; but saw &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot; ('&quot;</span> &lt;&lt; static_cast&lt;char&gt;<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> address+i<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;')</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
       <span class="Delimiter">}</span>
       else <span class="Delimiter">{</span>
         <span class="Comment">// just testing scenario support</span>
@@ -412,7 +419,7 @@ recipe main [
   <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">98</span>  <span class="Comment"># 'b'</span>
   <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">99</span>  <span class="Comment"># 'c'</span>
   memory-should-contain [
-    <span class="Constant">1</span>:string<span class="Special"> &lt;- </span>[ab]
+    <span class="Constant">1</span>:array:character<span class="Special"> &lt;- </span>[ab]
   ]
 ]
 <span class="traceContains">+error: expected location 1 to contain length 2 of string [ab] but saw 3</span>
@@ -424,7 +431,7 @@ recipe main [
   <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">98</span>  <span class="Comment"># 'b'</span>
   <span class="Constant">4</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">99</span>  <span class="Comment"># 'c'</span>
   memory-should-contain [
-    <span class="Constant">1</span>:string<span class="Special"> &lt;- </span>[abc]
+    <span class="Constant">1</span>:array:character<span class="Special"> &lt;- </span>[abc]
   ]
 ]
 <span class="traceContains">+run: checking string length at 1</span>
@@ -467,25 +474,22 @@ case TRACE_SHOULD_CONTAIN: <span class="Delimiter">{</span>
 <span class="Delimiter">:(code)</span>
 <span class="Comment">// simplified version of check_trace_contents() that emits errors rather</span>
 <span class="Comment">// than just printing to stderr</span>
-bool check_trace<span class="Delimiter">(</span>const string&amp; expected<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+void check_trace<span class="Delimiter">(</span>const string&amp; expected<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   Trace_stream<span class="Delimiter">-&gt;</span>newline<span class="Delimiter">();</span>
   vector&lt;trace_line&gt; expected_lines = parse_trace<span class="Delimiter">(</span>expected<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   long long int curr_expected_line = <span class="Constant">0</span><span class="Delimiter">;</span>
   for <span class="Delimiter">(</span>vector&lt;trace_line&gt;::iterator p = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label != p<span class="Delimiter">-&gt;</span>label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
     if <span class="Delimiter">(</span>expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents != trim<span class="Delimiter">(</span>p<span class="Delimiter">-&gt;</span>contents<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
     <span class="Comment">// match</span>
     ++curr_expected_line<span class="Delimiter">;</span>
-    if <span class="Delimiter">(</span>curr_expected_line == SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-      <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-    <span class="Delimiter">}</span>
+    if <span class="Delimiter">(</span>curr_expected_line == SIZE<span class="Delimiter">(</span>expected_lines<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
 
   raise_error &lt;&lt; <span class="Constant">&quot;missing [&quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>contents &lt;&lt; <span class="Constant">&quot;] &quot;</span>
               &lt;&lt; <span class="Constant">&quot;in trace with label &quot;</span> &lt;&lt; expected_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>curr_expected_line<span class="Delimiter">).</span>label &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
   Passed = <span class="Constant">false</span><span class="Delimiter">;</span>
-  <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
 vector&lt;trace_line&gt; parse_trace<span class="Delimiter">(</span>const string&amp; expected<span class="Delimiter">)</span> <span class="Delimiter">{</span>
diff --git a/html/051scenario_test.mu.html b/html/051scenario_test.mu.html
index d38539dd..074da198 100644
--- a/html/051scenario_test.mu.html
+++ b/html/051scenario_test.mu.html
@@ -60,7 +60,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> check_string_in_memory [
+<span class="muScenario">scenario</span> check_text_in_memory [
   run [
     <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>
     <span class="Constant">2</span>:character<span class="Special"> &lt;- </span>copy <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
@@ -68,7 +68,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>copy <span class="Constant">99</span>  <span class="Comment"># 'c'</span>
   ]
   memory-should-contain [
-    <span class="Constant">1</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
+    <span class="Constant">1</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
   ]
 ]
 
diff --git a/html/052tangle.cc.html b/html/052tangle.cc.html
index 4fc37210..131de37a 100644
--- a/html/052tangle.cc.html
+++ b/html/052tangle.cc.html
@@ -88,7 +88,7 @@ else if <span class="Delimiter">(</span>command == <span class="Constant">&quot;
 
 <span class="Comment">//: after all recipes are loaded, insert fragments at appropriate labels.</span>
 
-<span class="Delimiter">:(after &quot;Begin Transforms&quot;)</span>
+<span class="Delimiter">:(after &quot;Begin Instruction Inserting/Deleting Transforms&quot;)</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>insert_fragments<span class="Delimiter">);</span>  <span class="Comment">// NOT idempotent</span>
 
 <span class="Comment">//: We might need to perform multiple passes, in case inserted fragments</span>
diff --git a/html/053rewrite_stash.cc.html b/html/053rewrite_stash.cc.html
new file mode 100644
index 00000000..ba867faf
--- /dev/null
+++ b/html/053rewrite_stash.cc.html
@@ -0,0 +1,85 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+<title>Mu - 053rewrite_stash.cc</title>
+<meta name="Generator" content="Vim/7.4">
+<meta name="plugin-version" content="vim7.4_v1">
+<meta name="syntax" content="cpp">
+<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
+<meta name="colorscheme" content="minimal">
+<style type="text/css">
+<!--
+pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
+body { font-family: monospace; color: #eeeeee; background-color: #080808; }
+* { font-size: 1.05em; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Identifier { color: #804000; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">//: when encountering other types, try to convert them to strings using</span>
+<span class="Comment">//: 'to-text'</span>
+
+<span class="Delimiter">:(before &quot;End Instruction Inserting/Deleting Transforms&quot;)</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>rewrite_stashes_to_text<span class="Delimiter">);</span>
+
+<span class="Delimiter">:(code)</span>
+void rewrite_stashes_to_text<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  recipe&amp; caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>contains_named_locations<span class="Delimiter">(</span>caller<span class="Delimiter">))</span>
+    rewrite_stashes_to_text_named<span class="Delimiter">(</span>caller<span class="Delimiter">);</span>
+  <span class="Comment">// in recipes without named locations, 'stash' is still not configurable</span>
+<span class="Delimiter">}</span>
+
+bool contains_named_locations<span class="Delimiter">(</span>const recipe&amp; caller<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    const instruction&amp; inst = caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+    for <span class="Delimiter">(</span>long long int in = <span class="Constant">0</span><span class="Delimiter">;</span> in &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span>
+      if <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">)))</span>
+        <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+    for <span class="Delimiter">(</span>long long int out = <span class="Constant">0</span><span class="Delimiter">;</span> out &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span>
+      if <span class="Delimiter">(</span>is_named_location<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">)))</span>
+        <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+void rewrite_stashes_to_text_named<span class="Delimiter">(</span>recipe&amp; caller<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  static long long int stash_instruction_idx = <span class="Constant">0</span><span class="Delimiter">;</span>
+  vector&lt;instruction&gt; new_instructions<span class="Delimiter">;</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    instruction&amp; inst = caller<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+    if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;stash&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+        if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+        if <span class="Delimiter">(</span>is_mu_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+        instruction def<span class="Delimiter">;</span>
+        def<span class="Delimiter">.</span>name = <span class="Constant">&quot;to-text-line&quot;</span><span class="Delimiter">;</span>
+        def<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">));</span>
+        ostringstream ingredient_name<span class="Delimiter">;</span>
+        ingredient_name &lt;&lt; <span class="Constant">&quot;stash_&quot;</span> &lt;&lt; stash_instruction_idx &lt;&lt; <span class="Constant">'_'</span> &lt;&lt; j &lt;&lt; <span class="Constant">&quot;:address:array:character&quot;</span><span class="Delimiter">;</span>
+        def<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span>ingredient_name<span class="Delimiter">.</span>str<span class="Delimiter">()));</span>
+        new_instructions<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>def<span class="Delimiter">);</span>
+        inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>clear<span class="Delimiter">();</span>  <span class="Comment">// reclaim old memory</span>
+        inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">)</span> = reagent<span class="Delimiter">(</span>ingredient_name<span class="Delimiter">.</span>str<span class="Delimiter">());</span>
+      <span class="Delimiter">}</span>
+    <span class="Delimiter">}</span>
+    new_instructions<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>inst<span class="Delimiter">);</span>
+  <span class="Delimiter">}</span>
+  new_instructions<span class="Delimiter">.</span>swap<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>steps<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/054dilated_reagent.cc.html b/html/054dilated_reagent.cc.html
index 4f107a15..02f714e4 100644
--- a/html/054dilated_reagent.cc.html
+++ b/html/054dilated_reagent.cc.html
@@ -15,11 +15,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
+.PreProc { color: #c000c0; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
 .Constant { color: #00a0a0; }
+.Error { color: #ffffff; background-color: #ff6060; padding-bottom: 1px; }
 -->
 </style>
 
@@ -42,26 +44,32 @@ recipe main [
 ]
 <span class="traceContains">+parse:   product: {&quot;1&quot;: &quot;number&quot;, &quot;foo&quot;: &quot;bar&quot;}</span>
 
+<span class="Delimiter">:(scenario load_trailing_space_after_curly_bracket)</span>
+recipe main [
+<span class="PreProc">  </span><span class="Comment"># line below has a space at the end</span>
+  <span class="Delimiter">{</span><span class="Error"> </span>
+]
+<span class="Comment"># successfully parsed</span>
+
 <span class="Comment">//: First augment next_word to group balanced brackets together.</span>
 
 <span class="Delimiter">:(before &quot;End next_word Special-cases&quot;)</span>
-  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'('</span><span class="Delimiter">)</span>
-    <span class="Identifier">return</span> slurp_balanced_bracket<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-  <span class="Comment">// treat curlies mostly like parens, but don't mess up labels</span>
-  if <span class="Delimiter">(</span>start_of_dilated_reagent<span class="Delimiter">(</span>in<span class="Delimiter">))</span>
-    <span class="Identifier">return</span> slurp_balanced_bracket<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">'('</span><span class="Delimiter">)</span>
+  <span class="Identifier">return</span> slurp_balanced_bracket<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+<span class="Comment">// treat curlies mostly like parens, but don't mess up labels</span>
+if <span class="Delimiter">(</span>start_of_dilated_reagent<span class="Delimiter">(</span>in<span class="Delimiter">))</span>
+  <span class="Identifier">return</span> slurp_balanced_bracket<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
 
 <span class="Delimiter">:(code)</span>
 <span class="Comment">// A curly is considered a label if it's the last thing on a line. Dilated</span>
 <span class="Comment">// reagents should remain all on one line.</span>
-<span class="Comment">//</span>
-<span class="Comment">// Side-effect: This might delete some whitespace after an initial '{'.</span>
 bool start_of_dilated_reagent<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">'{'</span><span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+  long long int pos = in<span class="Delimiter">.</span>tellg<span class="Delimiter">();</span>
   in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>  <span class="Comment">// slurp '{'</span>
   skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   char next = in<span class="Delimiter">.</span>peek<span class="Delimiter">();</span>
-  in<span class="Delimiter">.</span>putback<span class="Delimiter">(</span><span class="Constant">'{'</span><span class="Delimiter">);</span>
+  in<span class="Delimiter">.</span>seekg<span class="Delimiter">(</span>pos<span class="Delimiter">);</span>
   <span class="Identifier">return</span> next != <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
@@ -107,7 +115,7 @@ if <span class="Delimiter">(</span>s<span class="Delimiter">.</span>at<span clas
   istringstream in<span class="Delimiter">(</span>s<span class="Delimiter">);</span>
   in &gt;&gt; std::noskipws<span class="Delimiter">;</span>
   in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>  <span class="Comment">// skip '{'</span>
-  while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     string key = slurp_key<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     if <span class="Delimiter">(</span>key<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
     if <span class="Delimiter">(</span>key == <span class="Constant">&quot;}&quot;</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
diff --git a/html/055parse_tree.cc.html b/html/055parse_tree.cc.html
index 7d9e158f..14142686 100644
--- a/html/055parse_tree.cc.html
+++ b/html/055parse_tree.cc.html
@@ -61,7 +61,7 @@ string_tree* parse_string_tree<span class="Delimiter">(</span>const string&amp;
 
 string_tree* parse_string_tree<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="Constant">')'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
     in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
     <span class="Identifier">return</span> <span class="Constant">NULL</span><span class="Delimiter">;</span>
@@ -74,7 +74,7 @@ string_tree* parse_string_tree<span class="Delimiter">(</span>istream&amp; in<sp
   string_tree* result = <span class="Constant">NULL</span><span class="Delimiter">;</span>
   string_tree** curr = &amp;result<span class="Delimiter">;</span>
   while <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> != <span class="Constant">')'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    assert<span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">());</span>
+    assert<span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">));</span>
     *curr = new string_tree<span class="Delimiter">(</span><span class="Constant">&quot;&quot;</span><span class="Delimiter">);</span>
     skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     skip_ignored_characters<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
diff --git a/html/056recipe_header.cc.html b/html/056recipe_header.cc.html
index 5000a703..a1c6dd82 100644
--- a/html/056recipe_header.cc.html
+++ b/html/056recipe_header.cc.html
@@ -164,12 +164,12 @@ if <span class="Delimiter">(</span>curr<span class="Delimiter">.</span>name == <
 recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-&gt;</span> z:number [
   local-scope
   load-ingredients
-  z:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span>
+  z:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/unsafe
   reply z
 ]
 <span class="traceContains">+error: add2: replied with the wrong type at 'reply z'</span>
 
-<span class="Delimiter">:(after &quot;Transform.push_back(check_types_by_name)&quot;)</span>
+<span class="Delimiter">:(before &quot;End Checks&quot;)</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_reply_instructions_against_header<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(code)</span>
@@ -181,9 +181,7 @@ void check_reply_instructions_against_header<span class="Delimiter">(</span>cons
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     const instruction&amp; inst = caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name != <span class="Constant">&quot;reply&quot;</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
-    if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span>
-      raise_error &lt;&lt; maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;tried to reply the wrong number of products in '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
-    for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>
         raise_error &lt;&lt; maybe<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;replied with the wrong type at '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;'</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Delimiter">}</span>
@@ -202,11 +200,11 @@ recipe add2 x:number<span class="Delimiter">,</span> x:number <span class="Delim
 <span class="Delimiter">:(before &quot;End recipe Fields&quot;)</span>
 map&lt;string<span class="Delimiter">,</span> int&gt; ingredient_index<span class="Delimiter">;</span>
 
-<span class="Delimiter">:(after &quot;Transform.push_back(insert_fragments)&quot;)</span>
-Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_and_update_header_reagents<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
+<span class="Delimiter">:(after &quot;Begin Instruction Modifying Transforms&quot;)</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_header_ingredients<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(code)</span>
-void check_and_update_header_reagents<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+void check_header_ingredients<span class="Delimiter">(</span>const recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   recipe&amp; caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;--- checking reply instructions against header for &quot;</span> &lt;&lt; caller_recipe<span class="Delimiter">.</span>name &lt;&lt; end<span class="Delimiter">();</span>
@@ -232,7 +230,7 @@ recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delim
 ]
 <span class="traceContains">+mem: storing 8 in location 1</span>
 
-<span class="Delimiter">:(before &quot;Transform.push_back(check_reply_instructions_against_header)&quot;)</span>
+<span class="Delimiter">:(after &quot;Begin Type Modifying Transforms&quot;)</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>deduce_types_from_header<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(code)</span>
@@ -299,7 +297,7 @@ recipe add2 x:number<span class="Delimiter">,</span> y:number <span class="Delim
 ]
 <span class="traceContains">+mem: storing 8 in location 1</span>
 
-<span class="Delimiter">:(after &quot;Transform.push_back(check_and_update_header_reagents)&quot;)</span>
+<span class="Delimiter">:(after &quot;Transform.push_back(check_header_ingredients)&quot;)</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>fill_in_reply_ingredients<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(code)</span>
diff --git a/html/057static_dispatch.cc.html b/html/057static_dispatch.cc.html
index 243b9c28..1c7b28b7 100644
--- a/html/057static_dispatch.cc.html
+++ b/html/057static_dispatch.cc.html
@@ -14,11 +14,13 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 1.05em; }
 .traceContains { color: #008000; }
-.Identifier { color: #804000; }
+.traceAbsent { color: #c00000; }
+.cSpecial { color: #008000; }
+.CommentedCode { color: #6c6c6c; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.CommentedCode { color: #6c6c6c; }
+.Identifier { color: #804000; }
 .Constant { color: #00a0a0; }
 -->
 </style>
@@ -65,12 +67,11 @@ for <span class="Delimiter">(</span>map&lt;string<span class="Delimiter">,</span
 <span class="Delimiter">:(before &quot;End Load Recipe Header(result)&quot;)</span>
 if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
   const recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
-<span class="CommentedCode">//?   if (variant_already_exists(result)) cerr &lt;&lt; &quot;AAAAAAAAAAAAAAAAAA variant already exists &quot; &lt;&lt; result.name &lt;&lt; '\n';</span>
   if <span class="Delimiter">((</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>has_header<span class="Delimiter">)</span>
       &amp;&amp; !variant_already_exists<span class="Delimiter">(</span>result<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     string new_name = next_unused_recipe_name<span class="Delimiter">(</span>result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
     put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">,</span> Next_recipe_ordinal++<span class="Delimiter">);</span>
-    get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">));</span>
+    get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">));</span>
     result<span class="Delimiter">.</span>name = new_name<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
@@ -82,7 +83,7 @@ else <span class="Delimiter">{</span>
 
 <span class="Delimiter">:(code)</span>
 bool variant_already_exists<span class="Delimiter">(</span>const recipe&amp; rr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  const vector&lt;recipe_ordinal&gt;&amp; variants = get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> rr<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+  const vector&lt;recipe_ordinal&gt;&amp; variants = get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> rr<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span>
         &amp;&amp; all_reagents_match<span class="Delimiter">(</span>rr<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))))</span> <span class="Delimiter">{</span>
@@ -110,11 +111,24 @@ bool all_reagents_match<span class="Delimiter">(</span>const recipe&amp; r1<span
   <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-bool exact_match<span class="Delimiter">(</span>type_tree* a<span class="Delimiter">,</span> type_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>a == b<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+set&lt;string&gt; Literal_type_names<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End One-time Setup&quot;)</span>
+Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;number&quot;</span><span class="Delimiter">);</span>
+Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;character&quot;</span><span class="Delimiter">);</span>
+<span class="Delimiter">:(code)</span>
+bool deeply_equal_types<span class="Delimiter">(</span>const string_tree* a<span class="Delimiter">,</span> const string_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!a<span class="Delimiter">)</span> <span class="Identifier">return</span> !b<span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>!b<span class="Delimiter">)</span> <span class="Identifier">return</span> !a<span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span> &amp;&amp; b<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span>
+    <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span>
+    <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>b<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
+  if <span class="Delimiter">(</span>b<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span>
+    <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
   <span class="Identifier">return</span> a<span class="Delimiter">-&gt;</span>value == b<span class="Delimiter">-&gt;</span>value
-      &amp;&amp; exact_match<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span>
-      &amp;&amp; exact_match<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
+      &amp;&amp; deeply_equal_types<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span>
+      &amp;&amp; deeply_equal_types<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
 string next_unused_recipe_name<span class="Delimiter">(</span>const string&amp; recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -141,32 +155,33 @@ recipe test a:number<span class="Delimiter">,</span> b:number <span class="Delim
 ]
 <span class="traceContains">+mem: storing 2 in location 7</span>
 
-<span class="Comment">//: after insert_fragments (tangle) and before computing operation ids</span>
 <span class="Comment">//: after filling in all missing types (because we'll be introducing 'blank' types in this transform in a later layer, for shape-shifting recipes)</span>
-<span class="Delimiter">:(after &quot;Transform.push_back(deduce_types_from_header)&quot;)</span>
+<span class="Delimiter">:(after &quot;End Type Modifying Transforms&quot;)</span>
 Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>resolve_ambiguous_calls<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
 
 <span class="Delimiter">:(code)</span>
 void resolve_ambiguous_calls<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   recipe&amp; caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
   trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;--- resolve ambiguous calls for recipe &quot;</span> &lt;&lt; caller_recipe<span class="Delimiter">.</span>name &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;--- resolve ambiguous calls for recipe &quot; &lt;&lt; caller_recipe.name &lt;&lt; '\n';</span>
   for <span class="Delimiter">(</span>long long int index = <span class="Constant">0</span><span class="Delimiter">;</span> index &lt; SIZE<span class="Delimiter">(</span>caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     instruction&amp; inst = caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
     if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
-    if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
-    assert<span class="Delimiter">(</span>!get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">).</span>empty<span class="Delimiter">());</span>
+    if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">).</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
     replace_best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
-<span class="CommentedCode">//?   if (caller_recipe.name == &quot;main&quot;) cerr &lt;&lt; &quot;=============== &quot; &lt;&lt; debug_string(caller_recipe) &lt;&lt; '\n';</span>
 <span class="Delimiter">}</span>
 
 void replace_best_variant<span class="Delimiter">(</span>instruction&amp; inst<span class="Delimiter">,</span> const recipe&amp; caller_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;instruction &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>name &lt;&lt; end<span class="Delimiter">();</span>
   vector&lt;recipe_ordinal&gt;&amp; variants = get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+<span class="CommentedCode">//?   trace(9992, &quot;transform&quot;) &lt;&lt; &quot;checking base: &quot; &lt;&lt; get(Recipe_ordinal, inst.name) &lt;&lt; end();</span>
   long long int best_score = variant_score<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
+  trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;score for base: &quot;</span> &lt;&lt; best_score &lt;&lt; end<span class="Delimiter">();</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?     trace(9992, &quot;transform&quot;) &lt;&lt; &quot;checking variant &quot; &lt;&lt; i &lt;&lt; &quot;: &quot; &lt;&lt; variants.at(i) &lt;&lt; end();</span>
     long long int current_score = variant_score<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
-    trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;checking variant &quot;</span> &lt;&lt; i &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; current_score &lt;&lt; end<span class="Delimiter">();</span>
+    trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;score for variant &quot;</span> &lt;&lt; i &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; current_score &lt;&lt; end<span class="Delimiter">();</span>
     if <span class="Delimiter">(</span>current_score &gt; best_score<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       inst<span class="Delimiter">.</span>name = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>name<span class="Delimiter">;</span>
       best_score = current_score<span class="Delimiter">;</span>
@@ -176,32 +191,74 @@ void replace_best_variant<span class="Delimiter">(</span>instruction&amp; inst<s
 <span class="Delimiter">}</span>
 
 long long int variant_score<span class="Delimiter">(</span>const instruction&amp; inst<span class="Delimiter">,</span> recipe_ordinal variant<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  long long int result = <span class="Constant">1000</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>variant == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>  <span class="Comment">// ghost from a previous test</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;variant score: &quot; &lt;&lt; inst.to_string() &lt;&lt; '\n';</span>
+  if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+    assert<span class="Delimiter">(</span>variant &lt; MAX_PRIMITIVE_RECIPES<span class="Delimiter">);</span>
+    <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
   const vector&lt;reagent&gt;&amp; header_ingredients = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &lt; SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;too few ingredients&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;too few ingredients\n&quot;;</span>
     <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;=== checking ingredients\n&quot;;</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
       trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;mismatch: ingredient &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;mismatch: ingredient &quot; &lt;&lt; i &lt;&lt; '\n';</span>
       <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
+    if <span class="Delimiter">(</span>types_strictly_match<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;strict match: ingredient &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;strict match: ingredient &quot; &lt;&lt; i &lt;&lt; '\n';</span>
+    <span class="Delimiter">}</span>
+    else if <span class="Delimiter">(</span>boolean_matches_literal<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      <span class="Comment">// slight penalty for coercing literal to boolean (prefer direct conversion to number if possible)</span>
+      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;boolean matches literal: ingredient &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
+      result--<span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
+    else <span class="Delimiter">{</span>
+      <span class="Comment">// slightly larger penalty for modifying type in other ways</span>
+      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;non-strict match: ingredient &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;non-strict match: ingredient &quot; &lt;&lt; i &lt;&lt; '\n';</span>
+      result-=<span class="Constant">10</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;=== done checking ingredients\n&quot;;</span>
   if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> &gt; SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;too few products&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;too few products\n&quot;;</span>
     <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   const vector&lt;reagent&gt;&amp; header_products = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">;</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>header_products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
       trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;mismatch: product &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;mismatch: product &quot; &lt;&lt; i &lt;&lt; '\n';</span>
       <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
+    if <span class="Delimiter">(</span>types_strictly_match<span class="Delimiter">(</span>header_products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;strict match: product &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;strict match: product &quot; &lt;&lt; i &lt;&lt; '\n';</span>
+    <span class="Delimiter">}</span>
+    else if <span class="Delimiter">(</span>boolean_matches_literal<span class="Delimiter">(</span>header_products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      <span class="Comment">// slight penalty for coercing literal to boolean (prefer direct conversion to number if possible)</span>
+      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;boolean matches literal: product &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
+      result--<span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
+    else <span class="Delimiter">{</span>
+      <span class="Comment">// slightly larger penalty for modifying type in other ways</span>
+      trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;non-strict match: product &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;non-strict match: product &quot; &lt;&lt; i &lt;&lt; '\n';</span>
+      result-=<span class="Constant">10</span><span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
-  <span class="Comment">// the greater the number of unused ingredients, the lower the score</span>
-  <span class="Identifier">return</span> <span class="Constant">100</span> - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">))</span>
-             - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">));</span>  <span class="Comment">// ok to go negative</span>
+  <span class="Comment">// the greater the number of unused ingredients/products, the lower the score</span>
+  <span class="Identifier">return</span> result - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">))</span>
+                - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">));</span>  <span class="Comment">// ok to go negative</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(scenario static_dispatch_disabled_on_headerless_definition)</span>
@@ -223,6 +280,154 @@ recipe test a:number <span class="Delimiter">-&gt;</span> z:number [
   z<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>
 ]
 <span class="traceContains">+warn: redefining recipe test</span>
+
+<span class="Delimiter">:(scenario static_dispatch_on_primitive_names)</span>
+recipe main [
+  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+  <span class="Constant">3</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">1</span>:number<span class="Delimiter">,</span> <span class="Constant">2</span>:number
+  <span class="Constant">4</span>:boolean<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Constant">false</span>
+  <span class="Constant">5</span>:boolean<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Constant">false</span>
+  <span class="Constant">6</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">4</span>:boolean<span class="Delimiter">,</span> <span class="Constant">5</span>:boolean
+]
+
+<span class="Comment"># temporarily hardcode number equality to always fail</span>
+recipe equal x:number<span class="Delimiter">,</span> y:number <span class="Delimiter">-&gt;</span> z:boolean [
+  local-scope
+  load-ingredients
+  z<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Constant">false</span>
+]
+<span class="Comment"># comparing numbers used overload</span>
+<span class="traceContains">+mem: storing 0 in location 3</span>
+<span class="Comment"># comparing booleans continues to use primitive</span>
+<span class="traceContains">+mem: storing 1 in location 6</span>
+
+<span class="Delimiter">:(scenario static_dispatch_prefers_literals_to_be_numbers_rather_than_addresses)</span>
+recipe main [
+  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>foo <span class="Constant">0</span>
+]
+recipe foo x:address:number <span class="Delimiter">-&gt;</span> y:number [
+  reply <span class="Constant">34</span>
+]
+recipe foo x:number <span class="Delimiter">-&gt;</span> y:number [
+  reply <span class="Constant">35</span>
+]
+<span class="traceContains">+mem: storing 35 in location 1</span>
+
+<span class="Delimiter">:(scenario static_dispatch_on_non_literal_character_ignores_variant_with_numbers)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  local-scope
+  x:character<span class="Special"> &lt;- </span>copy <span class="Constant">10</span>/newline
+  <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>foo x
+]
+recipe foo x:number <span class="Delimiter">-&gt;</span> y:number [
+  load-ingredients
+  reply <span class="Constant">34</span>
+]
+<span class="traceContains">+error: foo: wrong type for ingredient x:number</span>
+<span class="traceAbsent">-mem: storing 34 in location 1</span>
+
+<span class="Delimiter">:(scenario static_dispatch_dispatches_literal_to_boolean_before_character)</span>
+recipe main [
+  <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>foo <span class="Constant">0</span>  <span class="Comment"># valid literal for boolean</span>
+]
+recipe foo x:character <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">34</span>
+]
+recipe foo x:boolean <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">35</span>
+]
+<span class="Comment"># boolean variant is preferred</span>
+<span class="traceContains">+mem: storing 35 in location 1</span>
+
+<span class="Delimiter">:(scenario static_dispatch_dispatches_literal_to_character_when_out_of_boolean_range)</span>
+recipe main [
+  <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>foo <span class="Constant">97</span>  <span class="Comment"># not a valid literal for boolean</span>
+]
+recipe foo x:character <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">34</span>
+]
+recipe foo x:boolean <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">35</span>
+]
+<span class="Comment"># character variant is preferred</span>
+<span class="traceContains">+mem: storing 34 in location 1</span>
+
+<span class="Delimiter">:(scenario static_dispatch_dispatches_literal_to_number_if_at_all_possible)</span>
+recipe main [
+  <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>foo <span class="Constant">97</span>
+]
+recipe foo x:character <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">34</span>
+]
+recipe foo x:number <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">35</span>
+]
+<span class="Comment"># number variant is preferred</span>
+<span class="traceContains">+mem: storing 35 in location 1</span>
+
+<span class="Comment">//: after we make all attempts to dispatch, any unhandled cases will end up at</span>
+<span class="Comment">//: some wrong variant and trigger an error while trying to load-ingredients</span>
+
+<span class="Delimiter">:(scenario static_dispatch_shows_clear_error_on_missing_variant)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>foo <span class="Constant">34</span>
+]
+recipe foo x:boolean <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">35</span>
+]
+<span class="traceContains">+error: foo: wrong type for ingredient x:boolean</span>
+<span class="traceContains">+error:   (we're inside recipe foo x:boolean -&gt; y:number)</span>
+<span class="traceContains">+error:   (we're trying to call '1:number &lt;- foo 34' inside recipe main)</span>
+
+<span class="Delimiter">:(before &quot;End next-ingredient Type Mismatch Error&quot;)</span>
+raise_error &lt;&lt; <span class="Constant">&quot;   (we're inside &quot;</span> &lt;&lt; header_label<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>running_recipe<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;)</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+raise_error &lt;&lt; <span class="Constant">&quot;   (we're trying to call '&quot;</span> &lt;&lt; to_instruction<span class="Delimiter">(</span>*++Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>begin<span class="Delimiter">()).</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' inside &quot;</span> &lt;&lt; header_label<span class="Delimiter">((</span>++Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>begin<span class="Delimiter">())-&gt;</span>running_recipe<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;)</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+
+<span class="Delimiter">:(scenario static_dispatch_shows_clear_error_on_missing_variant_2)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  <span class="Constant">1</span>:boolean<span class="Special"> &lt;- </span>foo <span class="Constant">34</span>
+]
+recipe foo x:number <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply x
+]
+<span class="traceContains">+error: foo: reply ingredient x can't be saved in 1:boolean</span>
+<span class="traceContains">+error:   (we just returned from recipe foo x:number -&gt; y:number)</span>
+
+<span class="Delimiter">:(before &quot;End reply Type Mismatch Error&quot;)</span>
+raise_error &lt;&lt; <span class="Constant">&quot;   (we just returned from &quot;</span> &lt;&lt; header_label<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>operation<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;)</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+
+<span class="Delimiter">:(code)</span>
+string header_label<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  const recipe&amp; caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+  ostringstream out<span class="Delimiter">;</span>
+  out &lt;&lt; <span class="Constant">&quot;recipe &quot;</span> &lt;&lt; caller<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+    out &lt;&lt; <span class="Constant">' '</span> &lt;&lt; caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string<span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>!caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> out &lt;&lt; <span class="Constant">&quot; -&gt;&quot;</span><span class="Delimiter">;</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+    out &lt;&lt; <span class="Constant">' '</span> &lt;&lt; caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>original_string<span class="Delimiter">;</span>
+  <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
 </pre>
 </body>
 </html>
diff --git a/html/058shape_shifting_container.cc.html b/html/058shape_shifting_container.cc.html
index 0402d54b..6229c527 100644
--- a/html/058shape_shifting_container.cc.html
+++ b/html/058shape_shifting_container.cc.html
@@ -21,7 +21,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
 .Identifier { color: #804000; }
-.CommentedCode { color: #6c6c6c; }
 -->
 </style>
 
@@ -84,7 +83,7 @@ void read_type_ingredients<span class="Delimiter">(</span>string&amp; name<span
     put<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">,</span> Next_type_ordinal++<span class="Delimiter">);</span>
   type_info&amp; info = get_or_insert<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">));</span>
   long long int next_type_ordinal = START_TYPE_INGREDIENTS<span class="Delimiter">;</span>
-  while <span class="Delimiter">(</span>!in<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     string curr = slurp_until<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">':'</span><span class="Delimiter">);</span>
     if <span class="Delimiter">(</span>info<span class="Delimiter">.</span>type_ingredient_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>curr<span class="Delimiter">)</span> != info<span class="Delimiter">.</span>type_ingredient_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
       raise_error &lt;&lt; <span class="Constant">&quot;can't repeat type ingredient names in a single container definition</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
@@ -130,13 +129,7 @@ long long int size_of_type_ingredient<span class="Delimiter">(</span>const type_
   <span class="Delimiter">}</span>
   assert<span class="Delimiter">(</span>curr<span class="Delimiter">);</span>
   assert<span class="Delimiter">(</span>!curr<span class="Delimiter">-&gt;</span>left<span class="Delimiter">);</span>  <span class="Comment">// unimplemented</span>
-  if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-    <span class="Comment">// temporarily while we're still ironing out kinks; eventually replace with a raise_error</span>
-<span class="CommentedCode">//?     DUMP(&quot;&quot;);</span>
-    cerr &lt;&lt; <span class="Constant">&quot;missing type &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>curr<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
-    exit<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
-  <span class="Delimiter">}</span>
-  assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-&gt;</span>value<span class="Delimiter">));</span>
+  if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
   trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;type&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;type deduced to be &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-&gt;</span>value<span class="Delimiter">).</span>name &lt;&lt; <span class="Constant">&quot;$&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
   type_tree tmp<span class="Delimiter">(</span>curr<span class="Delimiter">-&gt;</span>value<span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>curr<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span>
diff --git a/html/059shape_shifting_recipe.cc.html b/html/059shape_shifting_recipe.cc.html
index 13c436c4..ce450999 100644
--- a/html/059shape_shifting_recipe.cc.html
+++ b/html/059shape_shifting_recipe.cc.html
@@ -72,34 +72,58 @@ if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-&gt;<
 
 <span class="Comment">//: Make sure we don't match up literals with type ingredients without</span>
 <span class="Comment">//: specialization.</span>
-<span class="Delimiter">:(before &quot;End valid_type_for_literal Special-cases&quot;)</span>
+<span class="Delimiter">:(before &quot;End Matching Types For Literal(lhs)&quot;)</span>
 if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
 
 <span class="Comment">//: We'll be creating recipes without loading them from anywhere by</span>
-<span class="Comment">//: *specializing* existing recipes, so make sure we don't clear any of those</span>
-<span class="Comment">//: when we start running tests.</span>
+<span class="Comment">//: *specializing* existing recipes.</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: Keep track of these new recipes in a separate variable in addition to</span>
+<span class="Comment">//: recently_added_recipes, so that edit/ can clear them before reloading to</span>
+<span class="Comment">//: regenerate errors.</span>
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+vector&lt;recipe_ordinal&gt; recently_added_shape_shifting_recipes<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End Setup&quot;)</span>
+<span class="CommentedCode">//? cerr &lt;&lt; &quot;setup: clearing recently-added shape-shifting recipes\n&quot;;</span>
+recently_added_shape_shifting_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+
+<span class="Comment">//: make sure we don't clear any of these recipes when we start running tests</span>
 <span class="Delimiter">:(before &quot;End Loading .mu Files&quot;)</span>
 recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
 recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+<span class="CommentedCode">//? cerr &lt;&lt; &quot;clearing recently-added shape-shifting recipes\n&quot;;</span>
+recently_added_shape_shifting_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+
+<span class="Comment">//: save original name of specialized recipes</span>
+<span class="Delimiter">:(before &quot;End recipe Fields&quot;)</span>
+string original_name<span class="Delimiter">;</span>
+<span class="Comment">//: original name is only set during load</span>
+<span class="Delimiter">:(before &quot;End recipe Refinements&quot;)</span>
+result<span class="Delimiter">.</span>original_name = result<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
 
 <span class="Delimiter">:(before &quot;End Instruction Dispatch(inst, best_score)&quot;)</span>
 if <span class="Delimiter">(</span>best_score == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-<span class="CommentedCode">//?   if (inst.name == &quot;push-duplex&quot;) Trace_stream = new trace_stream;</span>
   trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;no variant found; searching for variant with suitable type ingredients&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;no variant found for &quot; &lt;&lt; inst.name &lt;&lt; &quot;; searching for variant with suitable type ingredients&quot; &lt;&lt; '\n';</span>
   recipe_ordinal exemplar = pick_matching_shape_shifting_variant<span class="Delimiter">(</span>variants<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> best_score<span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>exemplar<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;found variant to specialize: &quot;</span> &lt;&lt; exemplar &lt;&lt; <span class="Constant">' '</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">).</span>name &lt;&lt; end<span class="Delimiter">();</span>
-    variants<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_variant<span class="Delimiter">(</span>exemplar<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">));</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;found variant to specialize: &quot; &lt;&lt; exemplar &lt;&lt; ' ' &lt;&lt; get(Recipe, exemplar).name &lt;&lt; '\n';</span>
+    recipe_ordinal new_recipe_ordinal = new_variant<span class="Delimiter">(</span>exemplar<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span>
+    variants<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_recipe_ordinal<span class="Delimiter">);</span>
+    <span class="Comment">// perform all transforms on the new specialization</span>
+    const string&amp; new_name = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>back<span class="Delimiter">()).</span>name<span class="Delimiter">;</span>
+    trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;transforming new specialization: &quot;</span> &lt;&lt; new_name &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;transforming new specialization: &quot; &lt;&lt; new_name &lt;&lt; '\n';</span>
+    for <span class="Delimiter">(</span>long long int t = <span class="Constant">0</span><span class="Delimiter">;</span> t &lt; SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">);</span> ++t<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      <span class="Delimiter">(</span>*Transform<span class="Delimiter">.</span>at<span class="Delimiter">(</span>t<span class="Delimiter">))(</span>new_recipe_ordinal<span class="Delimiter">);</span>
+    <span class="Delimiter">}</span>
+    get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">).</span>transformed_until = SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">;</span>
 <span class="CommentedCode">//?     cerr &lt;&lt; &quot;-- replacing &quot; &lt;&lt; inst.name &lt;&lt; &quot; with &quot; &lt;&lt; get(Recipe, variants.back()).name &lt;&lt; '\n' &lt;&lt; debug_string(get(Recipe, variants.back()));</span>
     inst<span class="Delimiter">.</span>name = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>back<span class="Delimiter">()).</span>name<span class="Delimiter">;</span>
     trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;new specialization: &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>name &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;new specialization: &quot; &lt;&lt; inst.name &lt;&lt; '\n';</span>
   <span class="Delimiter">}</span>
-<span class="CommentedCode">//?   if (inst.name == &quot;push-duplex&quot;) {</span>
-<span class="CommentedCode">//?     cerr &lt;&lt; &quot;======== {\n&quot;;</span>
-<span class="CommentedCode">//?     cerr &lt;&lt; inst.to_string() &lt;&lt; '\n';</span>
-<span class="CommentedCode">//?     DUMP(&quot;&quot;);</span>
-<span class="CommentedCode">//?     cerr &lt;&lt; &quot;======== }\n&quot;;</span>
-<span class="CommentedCode">//?   }</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(code)</span>
@@ -126,64 +150,96 @@ long long int shape_shifting_variant_score<span class="Delimiter">(</span>const
 <span class="CommentedCode">//?   cerr &lt;&lt; &quot;======== &quot; &lt;&lt; inst.to_string() &lt;&lt; '\n';</span>
   if <span class="Delimiter">(</span>!any_type_ingredient_in_header<span class="Delimiter">(</span>variant<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;no type ingredients&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;no type ingredients\n&quot;;</span>
     <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   const vector&lt;reagent&gt;&amp; header_ingredients = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> &lt; SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;too few ingredients&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;too few ingredients\n&quot;;</span>
     <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>!deeply_equal_concrete_types<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
       trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;mismatch: ingredient &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;mismatch: ingredient &quot; &lt;&lt; i &lt;&lt; &quot;: &quot; &lt;&lt; debug_string(header_ingredients.at(i)) &lt;&lt; &quot; vs &quot; &lt;&lt; debug_string(inst.ingredients.at(i)) &lt;&lt; '\n';</span>
       <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
   if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">)</span> &gt; SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;too few products&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;too few products\n&quot;;</span>
     <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   const vector&lt;reagent&gt;&amp; header_products = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">;</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>!deeply_equal_concrete_types<span class="Delimiter">(</span>header_products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
       trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;mismatch: product &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;mismatch: product &quot; &lt;&lt; i &lt;&lt; '\n';</span>
       <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
   <span class="Comment">// the greater the number of unused ingredients, the lower the score</span>
   <span class="Identifier">return</span> <span class="Constant">100</span> - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">))</span>
-             - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">));</span>  <span class="Comment">// ok to go negative</span>
+             - <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span>-SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">))</span>  <span class="Comment">// ok to go negative</span>
+             + number_of_concrete_types<span class="Delimiter">(</span>variant<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
 bool any_type_ingredient_in_header<span class="Delimiter">(</span>recipe_ordinal variant<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>
+  const recipe&amp; caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">);</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>
       <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variant<span class="Delimiter">).</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>
       <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
 bool deeply_equal_concrete_types<span class="Delimiter">(</span>reagent lhs<span class="Delimiter">,</span> reagent rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; debug_string(lhs) &lt;&lt; &quot; vs &quot; &lt;&lt; debug_string(rhs) &lt;&lt; '\n';</span>
-<span class="CommentedCode">//?   bool result = deeply_equal_concrete_types(lhs.properties.at(0).second, rhs.properties.at(0).second, rhs);</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;  =&gt; &quot; &lt;&lt; result &lt;&lt; '\n';</span>
-<span class="CommentedCode">//?   return result;</span>
-<span class="CommentedCode">//?   cerr &lt;&lt; &quot;== &quot; &lt;&lt; debug_string(lhs) &lt;&lt; &quot; vs &quot; &lt;&lt; debug_string(rhs) &lt;&lt; '\n';</span>
   canonize_type<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
   canonize_type<span class="Delimiter">(</span>rhs<span class="Delimiter">);</span>
   <span class="Identifier">return</span> deeply_equal_concrete_types<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">,</span> rhs<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">,</span> rhs<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
+long long int number_of_concrete_types<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  const recipe&amp; caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+  long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+    result += number_of_concrete_types<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
+    result += number_of_concrete_types<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+long long int number_of_concrete_types<span class="Delimiter">(</span>const reagent&amp; r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Identifier">return</span> number_of_concrete_types<span class="Delimiter">(</span>r<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+long long int number_of_concrete_types<span class="Delimiter">(</span>const string_tree* type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!type<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+  long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>!type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">.</span>empty<span class="Delimiter">()</span> &amp;&amp; !is_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span>
+    result++<span class="Delimiter">;</span>
+  result += number_of_concrete_types<span class="Delimiter">(</span>type<span class="Delimiter">-&gt;</span>left<span class="Delimiter">);</span>
+  result += number_of_concrete_types<span class="Delimiter">(</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 bool deeply_equal_concrete_types<span class="Delimiter">(</span>const string_tree* lhs<span class="Delimiter">,</span> const string_tree* rhs<span class="Delimiter">,</span> const reagent&amp; rhs_reagent<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>!lhs<span class="Delimiter">)</span> <span class="Identifier">return</span> !rhs<span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>!rhs<span class="Delimiter">)</span> <span class="Identifier">return</span> !lhs<span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>is_type_ingredient_name<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>  <span class="Comment">// type ingredient matches anything</span>
-  if <span class="Delimiter">(</span>Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
-    <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>rhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
+  if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span> &amp;&amp; rhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span>
+    <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span>
+      &amp;&amp; Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>rhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+    <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>rhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span>
+      &amp;&amp; Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+    <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>rhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span> &amp;&amp; lhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;address&quot;</span><span class="Delimiter">)</span>
     <span class="Identifier">return</span> rhs_reagent<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span><span class="Delimiter">;</span>
 <span class="CommentedCode">//?   cerr &lt;&lt; lhs-&gt;value &lt;&lt; &quot; vs &quot; &lt;&lt; rhs-&gt;value &lt;&lt; '\n';</span>
@@ -215,6 +271,7 @@ recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exempla
   assert<span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">));</span>
   assert<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">));</span>
   recently_added_recipes<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_recipe_ordinal<span class="Delimiter">);</span>
+  recently_added_shape_shifting_recipes<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_recipe_ordinal<span class="Delimiter">);</span>
   put<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">));</span>
   recipe&amp; new_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> new_recipe_ordinal<span class="Delimiter">);</span>
   new_recipe<span class="Delimiter">.</span>name = new_name<span class="Delimiter">;</span>
@@ -232,11 +289,6 @@ recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exempla
     if <span class="Delimiter">(</span>error<span class="Delimiter">)</span> <span class="Identifier">return</span> exemplar<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">));</span>
-  <span class="Comment">// finally, perform all transforms on the new specialization</span>
-  for <span class="Delimiter">(</span>long long int t = <span class="Constant">0</span><span class="Delimiter">;</span> t &lt; SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">);</span> ++t<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    <span class="Delimiter">(</span>*Transform<span class="Delimiter">.</span>at<span class="Delimiter">(</span>t<span class="Delimiter">))(</span>new_recipe_ordinal<span class="Delimiter">);</span>
-  <span class="Delimiter">}</span>
-  new_recipe<span class="Delimiter">.</span>transformed_until = SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">)</span>-<span class="Constant">1</span><span class="Delimiter">;</span>
   <span class="Identifier">return</span> new_recipe_ordinal<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
@@ -244,20 +296,20 @@ void compute_type_names<span class="Delimiter">(</span>recipe&amp; variant<span
   trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;compute type names: &quot;</span> &lt;&lt; variant<span class="Delimiter">.</span>name &lt;&lt; end<span class="Delimiter">();</span>
   map&lt;string<span class="Delimiter">,</span> string_tree*&gt; type_names<span class="Delimiter">;</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
-    save_or_deduce_type_name<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type_names<span class="Delimiter">);</span>
+    save_or_deduce_type_name<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type_names<span class="Delimiter">,</span> variant<span class="Delimiter">);</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
-    save_or_deduce_type_name<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type_names<span class="Delimiter">);</span>
+    save_or_deduce_type_name<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> type_names<span class="Delimiter">,</span> variant<span class="Delimiter">);</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     instruction&amp; inst = variant<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;  instruction: &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; end<span class="Delimiter">();</span>
     for <span class="Delimiter">(</span>long long int in = <span class="Constant">0</span><span class="Delimiter">;</span> in &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++in<span class="Delimiter">)</span>
-      save_or_deduce_type_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> type_names<span class="Delimiter">);</span>
+      save_or_deduce_type_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>in<span class="Delimiter">),</span> type_names<span class="Delimiter">,</span> variant<span class="Delimiter">);</span>
     for <span class="Delimiter">(</span>long long int out = <span class="Constant">0</span><span class="Delimiter">;</span> out &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++out<span class="Delimiter">)</span>
-      save_or_deduce_type_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> type_names<span class="Delimiter">);</span>
+      save_or_deduce_type_name<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>out<span class="Delimiter">),</span> type_names<span class="Delimiter">,</span> variant<span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
-void save_or_deduce_type_name<span class="Delimiter">(</span>reagent&amp; x<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> string_tree*&gt;&amp; type_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+void save_or_deduce_type_name<span class="Delimiter">(</span>reagent&amp; x<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> string_tree*&gt;&amp; type_name<span class="Delimiter">,</span> const recipe&amp; variant<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   trace<span class="Delimiter">(</span><span class="Constant">9994</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;    checking &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
   if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second &amp;&amp; contains_key<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second = new string_tree<span class="Delimiter">(</span>*get<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
@@ -265,7 +317,7 @@ void save_or_deduce_type_name<span class="Delimiter">(</span>reagent&amp; x<span
     <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; <span class="Constant">&quot;unknown type for &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+    raise_error &lt;&lt; maybe<span class="Delimiter">(</span>variant<span class="Delimiter">.</span>original_name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;unknown type for &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>original_string &lt;&lt; <span class="Constant">&quot; (check the name for typos)</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
@@ -306,6 +358,7 @@ void accumulate_type_ingredients<span class="Delimiter">(</span>const reagent&am
 void accumulate_type_ingredients<span class="Delimiter">(</span>const string_tree* exemplar_type<span class="Delimiter">,</span> const string_tree* refinement_type<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> const string_tree*&gt;&amp; mappings<span class="Delimiter">,</span> const recipe&amp; exemplar<span class="Delimiter">,</span> const reagent&amp; exemplar_reagent<span class="Delimiter">,</span> const instruction&amp; call_instruction<span class="Delimiter">,</span> const recipe&amp; caller_recipe<span class="Delimiter">,</span> bool* error<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>!exemplar_type<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>!refinement_type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    <span class="Comment">// todo: make this smarter; only warn if exemplar_type contains some *new* type ingredient</span>
     raise_error &lt;&lt; maybe<span class="Delimiter">(</span>exemplar<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;missing type ingredient in &quot;</span> &lt;&lt; exemplar_reagent<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
@@ -317,10 +370,7 @@ void accumulate_type_ingredients<span class="Delimiter">(</span>const string_tre
     <span class="Delimiter">}</span>
     if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
       trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;adding mapping from &quot;</span> &lt;&lt; exemplar_type<span class="Delimiter">-&gt;</span>value &lt;&lt; <span class="Constant">&quot; to &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>refinement_type<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
-      if <span class="Delimiter">(</span>refinement_type<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span>
-        put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span><span class="Constant">&quot;number&quot;</span><span class="Delimiter">));</span>
-      else
-        put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">));</span>
+      put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">));</span>
     <span class="Delimiter">}</span>
     else <span class="Delimiter">{</span>
       if <span class="Delimiter">(</span>!deeply_equal_types<span class="Delimiter">(</span>get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">),</span> refinement_type<span class="Delimiter">))</span> <span class="Delimiter">{</span>
@@ -329,6 +379,11 @@ void accumulate_type_ingredients<span class="Delimiter">(</span>const string_tre
         *error = <span class="Constant">true</span><span class="Delimiter">;</span>
         <span class="Identifier">return</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
+<span class="CommentedCode">//?       cerr &lt;&lt; exemplar_type-&gt;value &lt;&lt; &quot;: &quot; &lt;&lt; debug_string(get(mappings, exemplar_type-&gt;value)) &lt;&lt; &quot; &lt;= &quot; &lt;&lt; debug_string(refinement_type) &lt;&lt; '\n';</span>
+      if <span class="Delimiter">(</span>get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+        delete get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">);</span>
+        put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">));</span>
+      <span class="Delimiter">}</span>
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
   else <span class="Delimiter">{</span>
@@ -342,20 +397,20 @@ void replace_type_ingredients<span class="Delimiter">(</span>recipe&amp; new_rec
   if <span class="Delimiter">(</span>mappings<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;replacing in recipe header ingredients&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
-    replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span>
+    replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> mappings<span class="Delimiter">,</span> new_recipe<span class="Delimiter">);</span>
   trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;replacing in recipe header products&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
-    replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span>
+    replace_type_ingredients<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> mappings<span class="Delimiter">,</span> new_recipe<span class="Delimiter">);</span>
   <span class="Comment">// update its body</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     instruction&amp; inst = new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;replacing in instruction '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;'&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span>
-      replace_type_ingredients<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span>
+      replace_type_ingredients<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> mappings<span class="Delimiter">,</span> new_recipe<span class="Delimiter">);</span>
     for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span>
-      replace_type_ingredients<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> mappings<span class="Delimiter">);</span>
+      replace_type_ingredients<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> mappings<span class="Delimiter">,</span> new_recipe<span class="Delimiter">);</span>
     <span class="Comment">// special-case for new: replace type ingredient in first ingredient *value*</span>
-    if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;new&quot;</span> &amp;&amp; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> != <span class="Constant">'['</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>name == <span class="Constant">&quot;new&quot;</span> &amp;&amp; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">-&gt;</span>value != <span class="Constant">&quot;literal-string&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
       string_tree* type_name = parse_string_tree<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">);</span>
       replace_type_ingredients<span class="Delimiter">(</span>type_name<span class="Delimiter">,</span> mappings<span class="Delimiter">);</span>
       inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name = type_name<span class="Delimiter">-&gt;</span>to_string<span class="Delimiter">();</span>
@@ -364,10 +419,13 @@ void replace_type_ingredients<span class="Delimiter">(</span>recipe&amp; new_rec
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
-void replace_type_ingredients<span class="Delimiter">(</span>reagent&amp; x<span class="Delimiter">,</span> const map&lt;string<span class="Delimiter">,</span> const string_tree*&gt;&amp; mappings<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+void replace_type_ingredients<span class="Delimiter">(</span>reagent&amp; x<span class="Delimiter">,</span> const map&lt;string<span class="Delimiter">,</span> const string_tree*&gt;&amp; mappings<span class="Delimiter">,</span> const recipe&amp; caller<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;replacing in ingredient &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>original_string &lt;&lt; end<span class="Delimiter">();</span>
   <span class="Comment">// replace properties</span>
-  assert<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    raise_error &lt;&lt; <span class="Constant">&quot;specializing &quot;</span> &lt;&lt; caller<span class="Delimiter">.</span>original_name &lt;&lt; <span class="Constant">&quot;: missing type for &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+    <span class="Identifier">return</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
   replace_type_ingredients<span class="Delimiter">(</span>x<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">,</span> mappings<span class="Delimiter">);</span>
   <span class="Comment">// refresh types from properties</span>
   delete x<span class="Delimiter">.</span>type<span class="Delimiter">;</span>
@@ -381,7 +439,10 @@ void replace_type_ingredients<span class="Delimiter">(</span>string_tree* type<s
   if <span class="Delimiter">(</span>is_type_ingredient_name<span class="Delimiter">(</span>type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> &amp;&amp; contains_key<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     const string_tree* replacement = get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">);</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; type<span class="Delimiter">-&gt;</span>value &lt;&lt; <span class="Constant">&quot; =&gt; &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>replacement<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
-    type<span class="Delimiter">-&gt;</span>value = replacement<span class="Delimiter">-&gt;</span>value<span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>replacement<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span>
+      type<span class="Delimiter">-&gt;</span>value = <span class="Constant">&quot;number&quot;</span><span class="Delimiter">;</span>
+    else
+      type<span class="Delimiter">-&gt;</span>value = replacement<span class="Delimiter">-&gt;</span>value<span class="Delimiter">;</span>
     if <span class="Delimiter">(</span>replacement<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span> type<span class="Delimiter">-&gt;</span>left = new string_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">-&gt;</span>left<span class="Delimiter">);</span>
     if <span class="Delimiter">(</span>replacement<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> type<span class="Delimiter">-&gt;</span>right = new string_tree<span class="Delimiter">(</span>*replacement<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
@@ -684,6 +745,80 @@ container d2:_elem [
 ]
 <span class="traceContains">+mem: storing 34 in location 1</span>
 <span class="traceContains">+mem: storing 35 in location 2</span>
+
+<span class="Delimiter">:(scenario missing_type_in_shape_shifting_recipe)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  a:d1:number<span class="Special"> &lt;- </span>merge <span class="Constant">3</span>
+  foo a
+]
+recipe foo a:d1:_elem <span class="Delimiter">-&gt;</span> b:number [
+  local-scope
+  load-ingredients
+  copy e  <span class="Comment"># no such variable</span>
+  reply <span class="Constant">34</span>
+]
+container d1:_elem [
+  x:_elem
+]
+<span class="traceContains">+error: foo: unknown type for e (check the name for typos)</span>
+<span class="traceContains">+error: specializing foo: missing type for e</span>
+<span class="Comment"># and it doesn't crash</span>
+
+<span class="Delimiter">:(scenario missing_type_in_shape_shifting_recipe_2)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  a:d1:number<span class="Special"> &lt;- </span>merge <span class="Constant">3</span>
+  foo a
+]
+recipe foo a:d1:_elem <span class="Delimiter">-&gt;</span> b:number [
+  local-scope
+  load-ingredients
+  get e<span class="Delimiter">,</span> x:offset  <span class="Comment"># unknown variable in a 'get', which does some extra checking</span>
+  reply <span class="Constant">34</span>
+]
+container d1:_elem [
+  x:_elem
+]
+<span class="traceContains">+error: foo: unknown type for e (check the name for typos)</span>
+<span class="traceContains">+error: specializing foo: missing type for e</span>
+<span class="Comment"># and it doesn't crash</span>
+
+<span class="Delimiter">:(scenarios transform)</span>
+<span class="Delimiter">:(scenario specialize_recursive_shape_shifting_recipe)</span>
+recipe main [
+  <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>foo <span class="Constant">1</span>:number
+]
+recipe foo x:_elem <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  <span class="Delimiter">{</span>
+    <span class="Identifier">break</span>
+    y:number<span class="Special"> &lt;- </span>foo x
+  <span class="Delimiter">}</span>
+  reply y
+]
+<span class="traceContains">+transform: new specialization: foo_2</span>
+<span class="Comment"># transform terminates</span>
+
+<span class="Delimiter">:(scenarios run)</span>
+<span class="Delimiter">:(scenario specialize_most_similar_variant)</span>
+recipe main [
+  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>new number:type
+  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>foo <span class="Constant">1</span>:address:number
+]
+recipe foo x:_elem <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">34</span>
+]
+recipe foo x:address:_elem <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">35</span>
+]
+<span class="traceContains">+mem: storing 35 in location 2</span>
 </pre>
 </body>
 </html>
diff --git a/html/070string.mu.html b/html/070text.mu.html
index 08edff08..38851b6c 100644
--- a/html/070string.mu.html
+++ b/html/070text.mu.html
@@ -2,7 +2,7 @@
 <html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
-<title>Mu - 070string.mu</title>
+<title>Mu - 070text.mu</title>
 <meta name="Generator" content="Vim/7.4">
 <meta name="plugin-version" content="vim7.4_v1">
 <meta name="syntax" content="none">
@@ -20,6 +20,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .Comment { color: #9090ff; }
 .Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
+.CommentedCode { color: #6c6c6c; }
 .Delimiter { color: #a04060; }
 -->
 </style>
@@ -32,23 +33,38 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 </head>
 <body>
 <pre id='vimCodeElement'>
-<span class="Comment"># Some useful helpers for dealing with strings.</span>
+<span class="Comment"># Some useful helpers for dealing with text (arrays of characters)</span>
 
-<span class="muRecipe">recipe</span> string-equal [
+<span class="Comment"># to-text-line gets called implicitly in various places</span>
+<span class="Comment"># define it to be identical to 'to-text' by default</span>
+<span class="muRecipe">recipe</span> to-text-line x:_elem<span class="muRecipe"> -&gt; </span>y:address:array:character [
   <span class="Constant">local-scope</span>
-  a:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
+  y<span class="Special"> &lt;- </span>to-text x
+]
+
+<span class="Comment"># to-text on text is just the identity function</span>
+<span class="muRecipe">recipe</span> to-text x:address:array:character<span class="muRecipe"> -&gt; </span>y:address:array:character [
+  <span class="Constant">local-scope</span>
+  <span class="Constant">load-ingredients</span>
+<span class="CommentedCode">#?   $print [to-text text], 10/newline</span>
+  <span class="muControl">reply</span> x
+]
+
+<span class="muRecipe">recipe</span> equal a:address:array:character, b:address:array:character<span class="muRecipe"> -&gt; </span>result:boolean [
+  <span class="Constant">local-scope</span>
+  <span class="Constant">load-ingredients</span>
   a-len:number<span class="Special"> &lt;- </span>length *a
-  b:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   b-len:number<span class="Special"> &lt;- </span>length *b
   <span class="Comment"># compare lengths</span>
   <span class="Delimiter">{</span>
-    trace <span class="Constant">99</span>, <span class="Constant">[string-equal]</span>, <span class="Constant">[comparing lengths]</span>
+    trace <span class="Constant">99</span>, <span class="Constant">[text-equal]</span>, <span class="Constant">[comparing lengths]</span>
     length-equal?:boolean<span class="Special"> &lt;- </span>equal a-len, b-len
     <span class="muControl">break-if</span> length-equal?
     <span class="muControl">reply</span> <span class="Constant">0</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># compare each corresponding character</span>
-  trace <span class="Constant">99</span>, <span class="Constant">[string-equal]</span>, <span class="Constant">[comparing characters]</span>
+  trace <span class="Constant">99</span>, <span class="Constant">[text-equal]</span>, <span class="Constant">[comparing characters]</span>
   i:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   <span class="Delimiter">{</span>
     done?:boolean<span class="Special"> &lt;- </span>greater-or-equal i, a-len
@@ -66,92 +82,91 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply</span> <span class="Constant">1</span>
 ]
 
-<span class="muScenario">scenario</span> string-equal-reflexive [
+<span class="muScenario">scenario</span> text-equal-reflexive [
   run [
     <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span>
     x:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
-    <span class="Constant">3</span>:boolean/<span class="Special">raw &lt;- </span>string-equal x, x
+    <span class="Constant">3</span>:boolean/<span class="Special">raw &lt;- </span>equal x, x
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">1</span>  <span class="Comment"># x == x for all x</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> string-equal-identical [
+<span class="muScenario">scenario</span> text-equal-identical [
   run [
     <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span>
     x:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
     y:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
-    <span class="Constant">3</span>:boolean/<span class="Special">raw &lt;- </span>string-equal x, y
+    <span class="Constant">3</span>:boolean/<span class="Special">raw &lt;- </span>equal x, y
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">1</span>  <span class="Comment"># abc == abc</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> string-equal-distinct-lengths [
+<span class="muScenario">scenario</span> text-equal-distinct-lengths [
   run [
     <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span>
     x:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
     y:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcd]</span>
-    <span class="Constant">3</span>:boolean/<span class="Special">raw &lt;- </span>string-equal x, y
+    <span class="Constant">3</span>:boolean/<span class="Special">raw &lt;- </span>equal x, y
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># abc != abcd</span>
   ]
   trace-should-contain [
-    string-equal: comparing lengths
+    text-equal: comparing lengths
   ]
   trace-should-not-contain [
-    string-equal: comparing characters
+    text-equal: comparing characters
   ]
 ]
 
-<span class="muScenario">scenario</span> string-equal-with-empty [
+<span class="muScenario">scenario</span> text-equal-with-empty [
   run [
     <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span>
     x:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
     y:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcd]</span>
-    <span class="Constant">3</span>:boolean/<span class="Special">raw &lt;- </span>string-equal x, y
+    <span class="Constant">3</span>:boolean/<span class="Special">raw &lt;- </span>equal x, y
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># &quot;&quot; != abcd</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> string-equal-common-lengths-but-distinct [
+<span class="muScenario">scenario</span> text-equal-common-lengths-but-distinct [
   run [
     <span class="Constant">default-space</span>:address:array:location<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, <span class="Constant">30</span>
     x:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
     y:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abd]</span>
-    <span class="Constant">3</span>:boolean/<span class="Special">raw &lt;- </span>string-equal x, y
+    <span class="Constant">3</span>:boolean/<span class="Special">raw &lt;- </span>equal x, y
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># abc != abd</span>
   ]
 ]
 
-<span class="Comment"># A new type to help incrementally construct strings.</span>
+<span class="Comment"># A new type to help incrementally construct texts.</span>
 <span class="muData">container</span> buffer [
   length:number
   data:address:array:character
 ]
 
-<span class="muRecipe">recipe</span> new-buffer [
+<span class="muRecipe">recipe</span> new-buffer capacity:number<span class="muRecipe"> -&gt; </span>result:address:buffer [
   <span class="Constant">local-scope</span>
-  result:address:buffer<span class="Special"> &lt;- </span>new <span class="Constant">buffer:type</span>
+  <span class="Constant">load-ingredients</span>
+  result<span class="Special"> &lt;- </span>new <span class="Constant">buffer:type</span>
   len:address:number<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">length:offset</span>
   *len:address:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   s:address:address:array:character<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">data:offset</span>
-  capacity:number, found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  assert found?, <span class="Constant">[new-buffer must get a capacity argument]</span>
   *s<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, capacity
   <span class="muControl">reply</span> result
 ]
 
-<span class="muRecipe">recipe</span> grow-buffer [
+<span class="muRecipe">recipe</span> grow-buffer in:address:buffer<span class="muRecipe"> -&gt; </span>in:address:buffer [
   <span class="Constant">local-scope</span>
-  in:address:buffer<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># double buffer size</span>
   x:address:address:array:character<span class="Special"> &lt;- </span>get-address *in, <span class="Constant">data:offset</span>
   oldlen:number<span class="Special"> &lt;- </span>length **x
@@ -169,33 +184,48 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     i<span class="Special"> &lt;- </span>add i, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> in
 ]
 
-<span class="muRecipe">recipe</span> buffer-full? [
+<span class="muRecipe">recipe</span> buffer-full? in:address:buffer<span class="muRecipe"> -&gt; </span>result:boolean [
   <span class="Constant">local-scope</span>
-  in:address:buffer<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   len:number<span class="Special"> &lt;- </span>get *in, <span class="Constant">length:offset</span>
   s:address:array:character<span class="Special"> &lt;- </span>get *in, <span class="Constant">data:offset</span>
   capacity:number<span class="Special"> &lt;- </span>length *s
-  result:boolean<span class="Special"> &lt;- </span>greater-or-equal len, capacity
-  <span class="muControl">reply</span> result
+  result<span class="Special"> &lt;- </span>greater-or-equal len, capacity
+]
+
+<span class="Comment"># most broadly applicable definition of append to a buffer: just call to-text</span>
+<span class="muRecipe">recipe</span> append buf:address:buffer, x:_elem<span class="muRecipe"> -&gt; </span>buf:address:buffer [
+  <span class="Constant">local-scope</span>
+<span class="CommentedCode">#?   $print [append _elem to buffer], 10/newline</span>
+  <span class="Constant">load-ingredients</span>
+  text:address:array:character<span class="Special"> &lt;- </span>to-text x
+  len:number<span class="Special"> &lt;- </span>length *text
+  i:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
+  <span class="Delimiter">{</span>
+    done?:boolean<span class="Special"> &lt;- </span>greater-or-equal i, len
+    <span class="muControl">break-if</span> done?
+    c:character<span class="Special"> &lt;- </span>index *text, i
+    buf<span class="Special"> &lt;- </span>append buf, c
+    i<span class="Special"> &lt;- </span>add i, <span class="Constant">1</span>
+    <span class="muControl">loop</span>
+  <span class="Delimiter">}</span>
 ]
 
-<span class="Comment"># in &lt;- buffer-append in:address:buffer, c:character</span>
-<span class="muRecipe">recipe</span> buffer-append [
+<span class="muRecipe">recipe</span> append in:address:buffer, c:character<span class="muRecipe"> -&gt; </span>in:address:buffer [
   <span class="Constant">local-scope</span>
-  in:address:buffer<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  c:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+<span class="CommentedCode">#?   $print [append character to buffer], 10/newline</span>
+  <span class="Constant">load-ingredients</span>
   len:address:number<span class="Special"> &lt;- </span>get-address *in, <span class="Constant">length:offset</span>
   <span class="Delimiter">{</span>
     <span class="Comment"># backspace? just drop last character if it exists and return</span>
     backspace?:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">8/backspace</span>
     <span class="muControl">break-unless</span> backspace?
     empty?:boolean<span class="Special"> &lt;- </span>lesser-or-equal *len, <span class="Constant">0</span>
-    <span class="muControl">reply-if</span> empty?, in/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">reply-if</span> empty?
     *len<span class="Special"> &lt;- </span>subtract *len, <span class="Constant">1</span>
-    <span class="muControl">reply</span> in/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Delimiter">{</span>
     <span class="Comment"># grow buffer if necessary</span>
@@ -207,7 +237,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   dest:address:character<span class="Special"> &lt;- </span>index-address *s, *len
   *dest<span class="Special"> &lt;- </span>copy c
   *len<span class="Special"> &lt;- </span>add *len, <span class="Constant">1</span>
-  <span class="muControl">reply</span> in/same-as-ingredient:<span class="Constant">0</span>
 ]
 
 <span class="muScenario">scenario</span> buffer-append-works [
@@ -215,14 +244,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">local-scope</span>
     x:address:buffer<span class="Special"> &lt;- </span>new-buffer <span class="Constant">3</span>
     s1:address:array:character<span class="Special"> &lt;- </span>get *x:address:buffer, <span class="Constant">data:offset</span>
-    x:address:buffer<span class="Special"> &lt;- </span>buffer-append x:address:buffer, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
-    x:address:buffer<span class="Special"> &lt;- </span>buffer-append x:address:buffer, <span class="Constant">98</span>  <span class="Comment"># 'b'</span>
-    x:address:buffer<span class="Special"> &lt;- </span>buffer-append x:address:buffer, <span class="Constant">99</span>  <span class="Comment"># 'c'</span>
+    x:address:buffer<span class="Special"> &lt;- </span>append x:address:buffer, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    x:address:buffer<span class="Special"> &lt;- </span>append x:address:buffer, <span class="Constant">98</span>  <span class="Comment"># 'b'</span>
+    x:address:buffer<span class="Special"> &lt;- </span>append x:address:buffer, <span class="Constant">99</span>  <span class="Comment"># 'c'</span>
     s2:address:array:character<span class="Special"> &lt;- </span>get *x:address:buffer, <span class="Constant">data:offset</span>
     <span class="Constant">1</span>:boolean/<span class="Special">raw &lt;- </span>equal s1:address:array:character, s2:address:array:character
     <span class="Constant">2</span>:array:character/<span class="Special">raw &lt;- </span>copy *s2:address:array:character
 <span class="Constant">    +buffer-filled</span>
-    x:address:buffer<span class="Special"> &lt;- </span>buffer-append x:address:buffer, <span class="Constant">100</span>  <span class="Comment"># 'd'</span>
+    x:address:buffer<span class="Special"> &lt;- </span>append x:address:buffer, <span class="Constant">100</span>  <span class="Comment"># 'd'</span>
     s3:address:array:character<span class="Special"> &lt;- </span>get *x:address:buffer, <span class="Constant">data:offset</span>
     <span class="Constant">10</span>:boolean/<span class="Special">raw &lt;- </span>equal s1:address:array:character, s3:address:array:character
     <span class="Constant">11</span>:number/<span class="Special">raw &lt;- </span>get *x:address:buffer, <span class="Constant">length:offset</span>
@@ -252,9 +281,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   run [
     <span class="Constant">local-scope</span>
     x:address:buffer<span class="Special"> &lt;- </span>new-buffer <span class="Constant">3</span>
-    x<span class="Special"> &lt;- </span>buffer-append x, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
-    x<span class="Special"> &lt;- </span>buffer-append x, <span class="Constant">98</span>  <span class="Comment"># 'b'</span>
-    x<span class="Special"> &lt;- </span>buffer-append x, <span class="Constant">8/backspace</span>
+    x<span class="Special"> &lt;- </span>append x, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    x<span class="Special"> &lt;- </span>append x, <span class="Constant">98</span>  <span class="Comment"># 'b'</span>
+    x<span class="Special"> &lt;- </span>append x, <span class="Constant">8/backspace</span>
     s:address:array:character<span class="Special"> &lt;- </span>buffer-to-array x
     <span class="Constant">1</span>:array:character/<span class="Special">raw &lt;- </span>copy *s
   ]
@@ -265,15 +294,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="Comment"># result:address:array:character &lt;- integer-to-decimal-string n:number</span>
-<span class="muRecipe">recipe</span> integer-to-decimal-string [
+<span class="muRecipe">recipe</span> to-text n:number<span class="muRecipe"> -&gt; </span>result:address:array:character [
   <span class="Constant">local-scope</span>
-  n:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  <span class="Comment"># is it zero?</span>
+  <span class="Constant">load-ingredients</span>
+  <span class="Comment"># is n zero?</span>
   <span class="Delimiter">{</span>
     <span class="muControl">break-if</span> n
-    result:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[0]</span>
-    <span class="muControl">reply</span> result
+    result<span class="Special"> &lt;- </span>new <span class="Constant">[0]</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># save sign</span>
   negate-result:boolean<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
@@ -291,18 +319,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-if</span> done?
     n, digit:number<span class="Special"> &lt;- </span>divide-with-remainder n, <span class="Constant">10</span>
     c:character<span class="Special"> &lt;- </span>add digit-base, digit
-    tmp:address:buffer<span class="Special"> &lt;- </span>buffer-append tmp, c
+    tmp:address:buffer<span class="Special"> &lt;- </span>append tmp, c
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># add sign</span>
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> negate-result:boolean
-    tmp<span class="Special"> &lt;- </span>buffer-append tmp, <span class="Constant">45</span>  <span class="Comment"># '-'</span>
+    tmp<span class="Special"> &lt;- </span>append tmp, <span class="Constant">45</span>  <span class="Comment"># '-'</span>
   <span class="Delimiter">}</span>
-  <span class="Comment"># reverse buffer into string result</span>
+  <span class="Comment"># reverse buffer into text result</span>
   len:number<span class="Special"> &lt;- </span>get *tmp, <span class="Constant">length:offset</span>
   buf:address:array:character<span class="Special"> &lt;- </span>get *tmp, <span class="Constant">data:offset</span>
-  result:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, len
+  result<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, len
   i:number<span class="Special"> &lt;- </span>subtract len, <span class="Constant">1</span>  <span class="Comment"># source index, decreasing</span>
   j:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># destination index, increasing</span>
   <span class="Delimiter">{</span>
@@ -317,12 +345,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     j<span class="Special"> &lt;- </span>add j, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> result
 ]
 
-<span class="muRecipe">recipe</span> buffer-to-array [
+<span class="muRecipe">recipe</span> buffer-to-array in:address:buffer<span class="muRecipe"> -&gt; </span>result:address:array:character [
   <span class="Constant">local-scope</span>
-  in:address:buffer<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     <span class="Comment"># propagate null buffer</span>
     <span class="muControl">break-if</span> in
@@ -331,7 +358,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   len:number<span class="Special"> &lt;- </span>get *in, <span class="Constant">length:offset</span>
   s:address:array:character<span class="Special"> &lt;- </span>get *in, <span class="Constant">data:offset</span>
   <span class="Comment"># we can't just return s because it is usually the wrong length</span>
-  result:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, len
+  result<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, len
   i:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   <span class="Delimiter">{</span>
     done?:boolean<span class="Special"> &lt;- </span>greater-or-equal i, len
@@ -342,32 +369,31 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     i<span class="Special"> &lt;- </span>add i, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> result
 ]
 
 <span class="muScenario">scenario</span> integer-to-decimal-digit-zero [
   run [
-    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>integer-to-decimal-string <span class="Constant">0</span>
+    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>to-text <span class="Constant">0</span>
     <span class="Constant">2</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">2</span>:string<span class="Special"> &lt;- </span><span class="Constant">[0]</span>
+    <span class="Constant">2</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[0]</span>
   ]
 ]
 
 <span class="muScenario">scenario</span> integer-to-decimal-digit-positive [
   run [
-    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>integer-to-decimal-string <span class="Constant">234</span>
+    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>to-text <span class="Constant">234</span>
     <span class="Constant">2</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">2</span>:string<span class="Special"> &lt;- </span><span class="Constant">[234]</span>
+    <span class="Constant">2</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[234]</span>
   ]
 ]
 
 <span class="muScenario">scenario</span> integer-to-decimal-digit-negative [
   run [
-    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>integer-to-decimal-string <span class="Constant">-1</span>
+    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>to-text <span class="Constant">-1</span>
     <span class="Constant">2</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
@@ -377,16 +403,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="Comment"># result:address:array:character &lt;- string-append a:address:array:character, b:address:array:character</span>
-<span class="muRecipe">recipe</span> string-append [
+<span class="muRecipe">recipe</span> append a:address:array:character, b:address:array:character<span class="muRecipe"> -&gt; </span>result:address:array:character [
   <span class="Constant">local-scope</span>
+<span class="CommentedCode">#?   $print [append text to text], 10/newline</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># result = new character[a.length + b.length]</span>
-  a:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   a-len:number<span class="Special"> &lt;- </span>length *a
-  b:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   b-len:number<span class="Special"> &lt;- </span>length *b
   result-len:number<span class="Special"> &lt;- </span>add a-len, b-len
-  result:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, result-len
+  result<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, result-len
   <span class="Comment"># copy a into result</span>
   result-idx:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   i:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
@@ -416,37 +441,34 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     result-idx<span class="Special"> &lt;- </span>add result-idx, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> result
 ]
 
-<span class="muScenario">scenario</span> string-append-1 [
+<span class="muScenario">scenario</span> text-append-1 [
   run [
     <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>new <span class="Constant">[hello,]</span>
     <span class="Constant">2</span>:address:array:character/<span class="Special">raw &lt;- </span>new <span class="Constant">[ world!]</span>
-    <span class="Constant">3</span>:address:array:character/<span class="Special">raw &lt;- </span>string-append <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">2</span>:address:array:character/<span class="Special">raw</span>
+    <span class="Constant">3</span>:address:array:character/<span class="Special">raw &lt;- </span>append <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">2</span>:address:array:character/<span class="Special">raw</span>
     <span class="Constant">4</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">3</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">4</span>:string<span class="Special"> &lt;- </span><span class="Constant">[hello, world!]</span>
+    <span class="Constant">4</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[hello, world!]</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> replace-character-in-string [
+<span class="muScenario">scenario</span> replace-character-in-text [
   run [
     <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>new <span class="Constant">[abc]</span>
-    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>string-replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">98/b</span>, <span class="Constant">122/z</span>
+    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">98/b</span>, <span class="Constant">122/z</span>
     <span class="Constant">2</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">2</span>:string<span class="Special"> &lt;- </span><span class="Constant">[azc]</span>
+    <span class="Constant">2</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[azc]</span>
   ]
 ]
 
-<span class="muRecipe">recipe</span> string-replace [
+<span class="muRecipe">recipe</span> replace s:address:array:character, oldc:character, newc:character<span class="muRecipe"> -&gt; </span>s:address:array:character [
   <span class="Constant">local-scope</span>
-  s:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  oldc:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  newc:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   from:number, _<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>  <span class="Comment"># default to 0</span>
   len:number<span class="Special"> &lt;- </span>length *s
   i:number<span class="Special"> &lt;- </span>find-next s, oldc, from
@@ -455,64 +477,62 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   dest:address:character<span class="Special"> &lt;- </span>index-address *s, i
   *dest<span class="Special"> &lt;- </span>copy newc
   i<span class="Special"> &lt;- </span>add i, <span class="Constant">1</span>
-  s<span class="Special"> &lt;- </span>string-replace s, oldc, newc, i
-  <span class="muControl">reply</span> s/same-as-ingredient:<span class="Constant">0</span>
+  s<span class="Special"> &lt;- </span>replace s, oldc, newc, i
 ]
 
 <span class="muScenario">scenario</span> replace-character-at-start [
   run [
     <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>new <span class="Constant">[abc]</span>
-    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>string-replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">97/a</span>, <span class="Constant">122/z</span>
+    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">97/a</span>, <span class="Constant">122/z</span>
     <span class="Constant">2</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">2</span>:string<span class="Special"> &lt;- </span><span class="Constant">[zbc]</span>
+    <span class="Constant">2</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[zbc]</span>
   ]
 ]
 
 <span class="muScenario">scenario</span> replace-character-at-end [
   run [
     <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>new <span class="Constant">[abc]</span>
-    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>string-replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">99/c</span>, <span class="Constant">122/z</span>
+    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">99/c</span>, <span class="Constant">122/z</span>
     <span class="Constant">2</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">2</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abz]</span>
+    <span class="Constant">2</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abz]</span>
   ]
 ]
 
 <span class="muScenario">scenario</span> replace-character-missing [
   run [
     <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>new <span class="Constant">[abc]</span>
-    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>string-replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">100/d</span>, <span class="Constant">122/z</span>
+    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">100/d</span>, <span class="Constant">122/z</span>
     <span class="Constant">2</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">2</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
+    <span class="Constant">2</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
   ]
 ]
 
 <span class="muScenario">scenario</span> replace-all-characters [
   run [
     <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>new <span class="Constant">[banana]</span>
-    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>string-replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">97/a</span>, <span class="Constant">122/z</span>
+    <span class="Constant">1</span>:address:array:character/<span class="Special">raw &lt;- </span>replace <span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>, <span class="Constant">97/a</span>, <span class="Constant">122/z</span>
     <span class="Constant">2</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">1</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">2</span>:string<span class="Special"> &lt;- </span><span class="Constant">[bznznz]</span>
+    <span class="Constant">2</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[bznznz]</span>
   ]
 ]
 
 <span class="Comment"># replace underscores in first with remaining args</span>
-<span class="Comment"># result:address:array:character &lt;- interpolate template:address:array:character, ...</span>
-<span class="muRecipe">recipe</span> interpolate [
+<span class="muRecipe">recipe</span> interpolate template:address:array:character<span class="muRecipe"> -&gt; </span>result:address:array:character [
   <span class="Constant">local-scope</span>
-  template:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>  <span class="Comment"># consume just the template</span>
   <span class="Comment"># compute result-len, space to allocate for result</span>
   tem-len:number<span class="Special"> &lt;- </span>length *template
   result-len:number<span class="Special"> &lt;- </span>copy tem-len
   <span class="Delimiter">{</span>
-    <span class="Comment"># while arg received</span>
+    <span class="Comment"># while ingredients remain</span>
     a:address:array:character, arg-received?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
     <span class="muControl">break-unless</span> arg-received?
     <span class="Comment"># result-len = result-len + arg.length - 1 (for the 'underscore' being replaced)</span>
@@ -579,7 +599,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     result-idx<span class="Special"> &lt;- </span>add result-idx, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> result
 ]
 
 <span class="muScenario">scenario</span> interpolate-works [
@@ -590,7 +609,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">4</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">3</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">4</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abc def]</span>
+    <span class="Constant">4</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abc def]</span>
   ]
 ]
 
@@ -602,7 +621,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">4</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">3</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">4</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abc, hello!]</span>
+    <span class="Constant">4</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abc, hello!]</span>
     <span class="Constant">16</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># out of bounds</span>
   ]
 ]
@@ -615,77 +634,75 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">4</span>:array:character/<span class="Special">raw &lt;- </span>copy *<span class="Constant">3</span>:address:array:character/<span class="Special">raw</span>
   ]
   memory-should-contain [
-    <span class="Constant">4</span>:string<span class="Special"> &lt;- </span><span class="Constant">[hello, abc]</span>
+    <span class="Constant">4</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[hello, abc]</span>
   ]
 ]
 
 <span class="Comment"># result:boolean &lt;- space? c:character</span>
-<span class="muRecipe">recipe</span> space? [
+<span class="muRecipe">recipe</span> space? c:character<span class="muRecipe"> -&gt; </span>result:boolean [
   <span class="Constant">local-scope</span>
-  c:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># most common case first</span>
-  result:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">32/space</span>
-  <span class="muControl">reply-if</span> result, result
+  result<span class="Special"> &lt;- </span>equal c, <span class="Constant">32/space</span>
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">10/newline</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">9/tab</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">13/carriage-return</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   <span class="Comment"># remaining uncommon cases in sorted order</span>
   <span class="Comment"># <a href="http://unicode.org">http://unicode.org</a> code-points in unicode-set Z and Pattern_White_Space</span>
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">11/ctrl-k</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">12/ctrl-l</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">133/ctrl-0085</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">160/no-break-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">5760/ogham-space-mark</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8192/en-quad</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8193/em-quad</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8194/en-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8195/em-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8196/three-per-em-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8197/four-per-em-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8198/six-per-em-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8199/figure-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8200/punctuation-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8201/thin-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8202/hair-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8206/left-to-right</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8207/right-to-left</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8232/line-separator</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8233/paragraph-separator</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8239/narrow-no-break-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">8287/medium-mathematical-space</span>
-  <span class="muControl">reply-if</span> result, result
+  <span class="muControl">reply-if</span> result
   result<span class="Special"> &lt;- </span>equal c, <span class="Constant">12288/ideographic-space</span>
-  <span class="muControl">reply</span> result
 ]
 
-<span class="Comment"># result:address:array:character &lt;- trim s:address:array:character</span>
-<span class="muRecipe">recipe</span> trim [
+<span class="muRecipe">recipe</span> trim s:address:array:character<span class="muRecipe"> -&gt; </span>result:address:array:character [
   <span class="Constant">local-scope</span>
-  s:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   len:number<span class="Special"> &lt;- </span>length *s
   <span class="Comment"># left trim: compute start</span>
   start:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
@@ -693,8 +710,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Delimiter">{</span>
       at-end?:boolean<span class="Special"> &lt;- </span>greater-or-equal start, len
       <span class="muControl">break-unless</span> at-end?
-      result:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, <span class="Constant">0</span>
-      <span class="muControl">reply</span> result
+      result<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, <span class="Constant">0</span>
+      <span class="muControl">reply</span>
     <span class="Delimiter">}</span>
     curr:character<span class="Special"> &lt;- </span>index *s, start
     whitespace?:boolean<span class="Special"> &lt;- </span>space? curr
@@ -731,7 +748,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     j<span class="Special"> &lt;- </span>add j, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> result
 ]
 
 <span class="muScenario">scenario</span> trim-unmodified [
@@ -741,7 +757,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:character
   ]
   memory-should-contain [
-    <span class="Constant">3</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
+    <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
   ]
 ]
 
@@ -752,7 +768,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:character
   ]
   memory-should-contain [
-    <span class="Constant">3</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
+    <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
   ]
 ]
 
@@ -763,7 +779,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:character
   ]
   memory-should-contain [
-    <span class="Constant">3</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
+    <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
   ]
 ]
 
@@ -774,7 +790,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:character
   ]
   memory-should-contain [
-    <span class="Constant">3</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
+    <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
   ]
 ]
 
@@ -786,12 +802,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:character
   ]
   memory-should-contain [
-    <span class="Constant">3</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
+    <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
   ]
 ]
 
-<span class="Comment"># next-index:number &lt;- find-next text:address:array:character, pattern:character, idx:number</span>
-<span class="muRecipe">recipe</span> find-next [
+<span class="muRecipe">recipe</span> find-next text:address:array:character, pattern:character, idx:number<span class="muRecipe"> -&gt; </span>next-index:number [
   <span class="Constant">local-scope</span>
   text:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   pattern:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
@@ -809,7 +824,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply</span> idx
 ]
 
-<span class="muScenario">scenario</span> string-find-next [
+<span class="muScenario">scenario</span> text-find-next [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a/b]</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span>
@@ -819,7 +834,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> string-find-next-empty [
+<span class="muScenario">scenario</span> text-find-next-empty [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span>
@@ -829,7 +844,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> string-find-next-initial [
+<span class="muScenario">scenario</span> text-find-next-initial [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[/abc]</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span>
@@ -839,7 +854,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> string-find-next-final [
+<span class="muScenario">scenario</span> text-find-next-final [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc/]</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span>
@@ -849,7 +864,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> string-find-next-missing [
+<span class="muScenario">scenario</span> text-find-next-missing [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span>
@@ -859,7 +874,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> string-find-next-invalid-index [
+<span class="muScenario">scenario</span> text-find-next-invalid-index [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">4/start-index</span>
@@ -869,7 +884,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> string-find-next-first [
+<span class="muScenario">scenario</span> text-find-next-first [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[ab/c/]</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">0/start-index</span>
@@ -879,7 +894,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> string-find-next-second [
+<span class="muScenario">scenario</span> text-find-next-second [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[ab/c/]</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>, <span class="Constant">3/start-index</span>
@@ -889,19 +904,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="Comment"># next-index:number &lt;- find-substring text:address:array:character, pattern:address:array:character, idx:number</span>
-<span class="Comment"># like find-next, but searches for multiple characters</span>
+<span class="Comment"># search for a pattern of multiple characters</span>
 <span class="Comment"># fairly dumb algorithm</span>
-<span class="muRecipe">recipe</span> find-substring [
+<span class="muRecipe">recipe</span> find-next text:address:array:character, pattern:address:array:character, idx:number<span class="muRecipe"> -&gt; </span>next-index:number [
   <span class="Constant">local-scope</span>
-  text:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  pattern:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  idx:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   first:character<span class="Special"> &lt;- </span>index *pattern, <span class="Constant">0</span>
   <span class="Comment"># repeatedly check for match at current idx</span>
   len:number<span class="Special"> &lt;- </span>length *text
   <span class="Delimiter">{</span>
-    <span class="Comment"># does some unnecessary work checking for substrings even when there isn't enough of text left</span>
+    <span class="Comment"># does some unnecessary work checking even when there isn't enough of text left</span>
     done?:boolean<span class="Special"> &lt;- </span>greater-or-equal idx, len
     <span class="muControl">break-if</span> done?
     found?:boolean<span class="Special"> &lt;- </span>match-at text, pattern, idx
@@ -914,68 +926,65 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply</span> idx
 ]
 
-<span class="muScenario">scenario</span> find-substring-1 [
+<span class="muScenario">scenario</span> find-next-text-1 [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
     <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[bc]</span>
-    <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>find-substring <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span>
+    <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span>
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">1</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> find-substring-2 [
+<span class="muScenario">scenario</span> find-next-text-2 [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcd]</span>
     <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[bc]</span>
-    <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>find-substring <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">1</span>
+    <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">1</span>
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">1</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> find-substring-no-match [
+<span class="muScenario">scenario</span> find-next-no-match [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
     <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[bd]</span>
-    <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>find-substring <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span>
+    <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span>
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">3</span>  <span class="Comment"># not found</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> find-substring-suffix-match [
+<span class="muScenario">scenario</span> find-next-suffix-match [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcd]</span>
     <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[cd]</span>
-    <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>find-substring <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span>
+    <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span>
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">2</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> find-substring-suffix-match-2 [
+<span class="muScenario">scenario</span> find-next-suffix-match-2 [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcd]</span>
     <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[cde]</span>
-    <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>find-substring <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span>
+    <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>find-next <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">0</span>
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">4</span>  <span class="Comment"># not found</span>
   ]
 ]
 
-<span class="Comment"># result:boolean &lt;- match-at text:address:array:character, pattern:address:array:character, idx:number</span>
-<span class="Comment"># checks if substring matches at index 'idx'</span>
-<span class="muRecipe">recipe</span> match-at [
+<span class="Comment"># checks if pattern matches at index 'idx'</span>
+<span class="muRecipe">recipe</span> match-at text:address:array:character, pattern:address:array:character, idx:number<span class="muRecipe"> -&gt; </span>result:boolean [
   <span class="Constant">local-scope</span>
-  text:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  pattern:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  idx:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   pattern-len:number<span class="Special"> &lt;- </span>length *pattern
   <span class="Comment"># check that there's space left for the pattern</span>
   <span class="Delimiter">{</span>
@@ -1004,7 +1013,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply</span> <span class="Constant">1/found</span>
 ]
 
-<span class="muScenario">scenario</span> match-at-checks-substring-at-index [
+<span class="muScenario">scenario</span> match-at-checks-pattern-at-index [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
     <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[ab]</span>
@@ -1086,7 +1095,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">3</span>:boolean<span class="Special"> &lt;- </span>match-at <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character, <span class="Constant">1</span>
   ]
   memory-should-contain [
-    <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">1</span>  <span class="Comment"># matches inner substring</span>
+    <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">1</span>  <span class="Comment"># match</span>
   ]
 ]
 
@@ -1101,18 +1110,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="Comment"># result:address:array:address:array:character &lt;- split s:address:array:character, delim:character</span>
-<span class="muRecipe">recipe</span> split [
+<span class="muRecipe">recipe</span> split s:address:array:character, delim:character<span class="muRecipe"> -&gt; </span>result:address:array:address:array:character [
   <span class="Constant">local-scope</span>
-  s:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  delim:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  <span class="Comment"># empty string? return empty array</span>
+  <span class="Constant">load-ingredients</span>
+  <span class="Comment"># empty text? return empty array</span>
   len:number<span class="Special"> &lt;- </span>length *s
   <span class="Delimiter">{</span>
     empty?:boolean<span class="Special"> &lt;- </span>equal len, <span class="Constant">0</span>
     <span class="muControl">break-unless</span> empty?
-    result:address:array:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, <span class="Constant">0</span>
-    <span class="muControl">reply</span> result
+    result<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, <span class="Constant">0</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># count #pieces we need room for</span>
   count:number<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>  <span class="Comment"># n delimiters = n+1 pieces</span>
@@ -1126,7 +1133,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># allocate space</span>
-  result:address:array:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, count
+  result<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, count
   <span class="Comment"># repeatedly copy slices start..end until delimiter into result[curr-result]</span>
   curr-result:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   start:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
@@ -1137,16 +1144,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     end:number<span class="Special"> &lt;- </span>find-next s, delim, start
     <span class="Comment"># copy start..end into result[curr-result]</span>
     dest:address:address:array:character<span class="Special"> &lt;- </span>index-address *result, curr-result
-    *dest<span class="Special"> &lt;- </span>string-copy s, start, end
+    *dest<span class="Special"> &lt;- </span>copy s, start, end
     <span class="Comment"># slide over to next slice</span>
     start<span class="Special"> &lt;- </span>add end, <span class="Constant">1</span>
     curr-result<span class="Special"> &lt;- </span>add curr-result, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> result
 ]
 
-<span class="muScenario">scenario</span> string-split-1 [
+<span class="muScenario">scenario</span> text-split-1 [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a/b]</span>
     <span class="Constant">2</span>:address:array:address:array:character<span class="Special"> &lt;- </span>split <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>
@@ -1158,12 +1164,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">2</span>  <span class="Comment"># length of result</span>
-    <span class="Constant">10</span>:string<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
-    <span class="Constant">20</span>:string<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
+    <span class="Constant">10</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
+    <span class="Constant">20</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> string-split-2 [
+<span class="muScenario">scenario</span> text-split-2 [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a/b/c]</span>
     <span class="Constant">2</span>:address:array:address:array:character<span class="Special"> &lt;- </span>split <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>
@@ -1177,13 +1183,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">3</span>  <span class="Comment"># length of result</span>
-    <span class="Constant">10</span>:string<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
-    <span class="Constant">20</span>:string<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
-    <span class="Constant">30</span>:string<span class="Special"> &lt;- </span><span class="Constant">[c]</span>
+    <span class="Constant">10</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
+    <span class="Constant">20</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
+    <span class="Constant">30</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[c]</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> string-split-missing [
+<span class="muScenario">scenario</span> text-split-missing [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
     <span class="Constant">2</span>:address:array:address:array:character<span class="Special"> &lt;- </span>split <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>
@@ -1193,11 +1199,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">1</span>  <span class="Comment"># length of result</span>
-    <span class="Constant">10</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
+    <span class="Constant">10</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abc]</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> string-split-empty [
+<span class="muScenario">scenario</span> text-split-empty [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
     <span class="Constant">2</span>:address:array:address:array:character<span class="Special"> &lt;- </span>split <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>
@@ -1208,7 +1214,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> string-split-empty-piece [
+<span class="muScenario">scenario</span> text-split-empty-piece [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a/b//c]</span>
     <span class="Constant">2</span>:address:array:address:array:character<span class="Special"> &lt;- </span>split <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>
@@ -1224,35 +1230,32 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
   memory-should-contain [
     <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">4</span>  <span class="Comment"># length of result</span>
-    <span class="Constant">10</span>:string<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
-    <span class="Constant">20</span>:string<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
-    <span class="Constant">30</span>:string<span class="Special"> &lt;- </span><span class="Constant">[]</span>
-    <span class="Constant">40</span>:string<span class="Special"> &lt;- </span><span class="Constant">[c]</span>
+    <span class="Constant">10</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
+    <span class="Constant">20</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
+    <span class="Constant">30</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[]</span>
+    <span class="Constant">40</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[c]</span>
   ]
 ]
 
-<span class="Comment"># x:address:array:character, y:address:array:character &lt;- split-first text:address:array:character, delim:character</span>
-<span class="muRecipe">recipe</span> split-first [
+<span class="muRecipe">recipe</span> split-first text:address:array:character, delim:character<span class="muRecipe"> -&gt; </span>x:address:array:character, y:address:array:character [
   <span class="Constant">local-scope</span>
-  text:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  delim:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  <span class="Comment"># empty string? return empty strings</span>
+  <span class="Constant">load-ingredients</span>
+  <span class="Comment"># empty text? return empty texts</span>
   len:number<span class="Special"> &lt;- </span>length *text
   <span class="Delimiter">{</span>
     empty?:boolean<span class="Special"> &lt;- </span>equal len, <span class="Constant">0</span>
     <span class="muControl">break-unless</span> empty?
     x:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
     y:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
-    <span class="muControl">reply</span> x, y
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   idx:number<span class="Special"> &lt;- </span>find-next text, delim, <span class="Constant">0</span>
-  x:address:array:character<span class="Special"> &lt;- </span>string-copy text, <span class="Constant">0</span>, idx
+  x:address:array:character<span class="Special"> &lt;- </span>copy text, <span class="Constant">0</span>, idx
   idx<span class="Special"> &lt;- </span>add idx, <span class="Constant">1</span>
-  y:address:array:character<span class="Special"> &lt;- </span>string-copy text, idx, len
-  <span class="muControl">reply</span> x, y
+  y:address:array:character<span class="Special"> &lt;- </span>copy text, idx, len
 ]
 
-<span class="muScenario">scenario</span> string-split-first [
+<span class="muScenario">scenario</span> text-split-first [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[a/b]</span>
     <span class="Constant">2</span>:address:array:character, <span class="Constant">3</span>:address:array:character<span class="Special"> &lt;- </span>split-first <span class="Constant">1</span>:address:array:character, <span class="Constant">47/slash</span>
@@ -1260,18 +1263,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">20</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">3</span>:address:array:character
   ]
   memory-should-contain [
-    <span class="Constant">10</span>:string<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
-    <span class="Constant">20</span>:string<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
+    <span class="Constant">10</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[a]</span>
+    <span class="Constant">20</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[b]</span>
   ]
 ]
 
-<span class="Comment"># result:address:array:character &lt;- string-copy buf:address:array:character, start:number, end:number</span>
-<span class="Comment"># todo: make this generic</span>
-<span class="muRecipe">recipe</span> string-copy [
+<span class="muRecipe">recipe</span> copy buf:address:array:character, start:number, end:number<span class="muRecipe"> -&gt; </span>result:address:array:character [
   <span class="Constant">local-scope</span>
-  buf:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  start:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  end:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if end is out of bounds, trim it</span>
   len:number<span class="Special"> &lt;- </span>length *buf
   end:number<span class="Special"> &lt;- </span>min len, end
@@ -1291,46 +1290,44 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     dest-idx<span class="Special"> &lt;- </span>add dest-idx, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> result
 ]
 
-<span class="muScenario">scenario</span> string-copy-copies-substring [
+<span class="muScenario">scenario</span> text-copy-copies-partial-text [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
-    <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>string-copy <span class="Constant">1</span>:address:array:character, <span class="Constant">1</span>, <span class="Constant">3</span>
+    <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:address:array:character, <span class="Constant">1</span>, <span class="Constant">3</span>
     <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:character
   ]
   memory-should-contain [
-    <span class="Constant">3</span>:string<span class="Special"> &lt;- </span><span class="Constant">[bc]</span>
+    <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[bc]</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> string-copy-out-of-bounds [
+<span class="muScenario">scenario</span> text-copy-out-of-bounds [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
-    <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>string-copy <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>, <span class="Constant">4</span>
+    <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>, <span class="Constant">4</span>
     <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:character
   ]
   memory-should-contain [
-    <span class="Constant">3</span>:string<span class="Special"> &lt;- </span><span class="Constant">[c]</span>
+    <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[c]</span>
   ]
 ]
 
-<span class="muScenario">scenario</span> string-copy-out-of-bounds-2 [
+<span class="muScenario">scenario</span> text-copy-out-of-bounds-2 [
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
-    <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>string-copy <span class="Constant">1</span>:address:array:character, <span class="Constant">3</span>, <span class="Constant">3</span>
+    <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:address:array:character, <span class="Constant">3</span>, <span class="Constant">3</span>
     <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:character
   ]
   memory-should-contain [
-    <span class="Constant">3</span>:string<span class="Special"> &lt;- </span><span class="Constant">[]</span>
+    <span class="Constant">3</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[]</span>
   ]
 ]
 
-<span class="muRecipe">recipe</span> min [
+<span class="muRecipe">recipe</span> min x:number, y:number<span class="muRecipe"> -&gt; </span>z:number [
   <span class="Constant">local-scope</span>
-  x:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  y:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     return-x?:boolean<span class="Special"> &lt;- </span>lesser-than x, y
     <span class="muControl">break-if</span> return-x?
@@ -1339,10 +1336,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply</span> x
 ]
 
-<span class="muRecipe">recipe</span> max [
+<span class="muRecipe">recipe</span> max x:number, y:number<span class="muRecipe"> -&gt; </span>z:number [
   <span class="Constant">local-scope</span>
-  x:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  y:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     return-x?:boolean<span class="Special"> &lt;- </span>greater-than x, y
     <span class="muControl">break-if</span> return-x?
diff --git a/html/071channel.mu.html b/html/071channel.mu.html
index 1bddb78c..ec4fc68d 100644
--- a/html/071channel.mu.html
+++ b/html/071channel.mu.html
@@ -67,10 +67,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 ]
 
 <span class="Comment"># result:address:channel &lt;- new-channel capacity:number</span>
-<span class="muRecipe">recipe</span> new-channel [
+<span class="muRecipe">recipe</span> new-channel capacity:number<span class="muRecipe"> -&gt; </span>result:address:channel [
   <span class="Constant">local-scope</span>
-  <span class="Comment"># result = new channel</span>
-  result:address:channel<span class="Special"> &lt;- </span>new <span class="Constant">channel:type</span>
+  <span class="Constant">load-ingredients</span>
+  result<span class="Special"> &lt;- </span>new <span class="Constant">channel:type</span>
   <span class="Comment"># result.first-full = 0</span>
   full:address:number<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">first-full:offset</span>
   *full<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
@@ -78,18 +78,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   free:address:number<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">first-free:offset</span>
   *free<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   <span class="Comment"># result.data = new location[ingredient+1]</span>
-  capacity:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   capacity<span class="Special"> &lt;- </span>add capacity, <span class="Constant">1</span>  <span class="Comment"># unused slot for 'full?' below</span>
   dest:address:address:array:character<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">data:offset</span>
   *dest<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, capacity
-  <span class="muControl">reply</span> result
 ]
 
-<span class="Comment"># chan &lt;- write chan:address:channel, val:character</span>
-<span class="muRecipe">recipe</span> write [
+<span class="muRecipe">recipe</span> write chan:address:channel, val:character<span class="muRecipe"> -&gt; </span>chan:address:channel [
   <span class="Constant">local-scope</span>
-  chan:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  val:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     <span class="Comment"># block if chan is full</span>
     full:boolean<span class="Special"> &lt;- </span>channel-full? chan
@@ -111,13 +107,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-unless</span> at-end?
     *free<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> chan/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="Comment"># result:character, chan &lt;- read chan:address:channel</span>
-<span class="muRecipe">recipe</span> read [
+<span class="muRecipe">recipe</span> read chan:address:channel<span class="muRecipe"> -&gt; </span>result:character, chan:address:channel [
   <span class="Constant">local-scope</span>
-  chan:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     <span class="Comment"># block if chan is empty</span>
     empty?:boolean<span class="Special"> &lt;- </span>channel-empty? chan
@@ -128,7 +122,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Comment"># read result</span>
   full:address:number<span class="Special"> &lt;- </span>get-address *chan, <span class="Constant">first-full:offset</span>
   circular-buffer:address:array:character<span class="Special"> &lt;- </span>get *chan, <span class="Constant">data:offset</span>
-  result:character<span class="Special"> &lt;- </span>index *circular-buffer, *full
+  result<span class="Special"> &lt;- </span>index *circular-buffer, *full
   <span class="Comment"># mark its slot as empty</span>
   *full<span class="Special"> &lt;- </span>add *full, <span class="Constant">1</span>
   <span class="Delimiter">{</span>
@@ -138,18 +132,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-unless</span> at-end?
     *full<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> result, chan/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> clear-channel [
+<span class="muRecipe">recipe</span> clear-channel chan:address:channel<span class="muRecipe"> -&gt; </span>chan:address:channel [
   <span class="Constant">local-scope</span>
-  chan:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     empty?:boolean<span class="Special"> &lt;- </span>channel-empty? chan
     <span class="muControl">break-if</span> empty?
     _, chan<span class="Special"> &lt;- </span>read chan
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> chan/same-as-ingredient:<span class="Constant">0</span>
 ]
 
 <span class="muScenario">scenario</span> channel-initialization [
@@ -219,21 +211,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="SalientComment">## helpers</span>
 
 <span class="Comment"># An empty channel has first-empty and first-full both at the same value.</span>
-<span class="muRecipe">recipe</span> channel-empty? [
+<span class="muRecipe">recipe</span> channel-empty? chan:address:channel<span class="muRecipe"> -&gt; </span>result:boolean [
   <span class="Constant">local-scope</span>
-  chan:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># return chan.first-full == chan.first-free</span>
   full:number<span class="Special"> &lt;- </span>get *chan, <span class="Constant">first-full:offset</span>
   free:number<span class="Special"> &lt;- </span>get *chan, <span class="Constant">first-free:offset</span>
-  result:boolean<span class="Special"> &lt;- </span>equal full, free
-  <span class="muControl">reply</span> result
+  result<span class="Special"> &lt;- </span>equal full, free
 ]
 
 <span class="Comment"># A full channel has first-empty just before first-full, wasting one slot.</span>
 <span class="Comment"># (Other alternatives: <a href="https://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction)">https://en.wikipedia.org/wiki/Circular_buffer#Full_.2F_Empty_Buffer_Distinction)</a></span>
-<span class="muRecipe">recipe</span> channel-full? [
+<span class="muRecipe">recipe</span> channel-full? chan:address:channel<span class="muRecipe"> -&gt; </span>result:boolean [
   <span class="Constant">local-scope</span>
-  chan:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># tmp = chan.first-free + 1</span>
   tmp:number<span class="Special"> &lt;- </span>get *chan, <span class="Constant">first-free:offset</span>
   tmp<span class="Special"> &lt;- </span>add tmp, <span class="Constant">1</span>
@@ -246,17 +237,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">}</span>
   <span class="Comment"># return chan.first-full == tmp</span>
   full:number<span class="Special"> &lt;- </span>get *chan, <span class="Constant">first-full:offset</span>
-  result:boolean<span class="Special"> &lt;- </span>equal full, tmp
-  <span class="muControl">reply</span> result
+  result<span class="Special"> &lt;- </span>equal full, tmp
 ]
 
 <span class="Comment"># result:number &lt;- channel-capacity chan:address:channel</span>
-<span class="muRecipe">recipe</span> channel-capacity [
+<span class="muRecipe">recipe</span> channel-capacity chan:address:channel<span class="muRecipe"> -&gt; </span>result:number [
   <span class="Constant">local-scope</span>
-  chan:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   q:address:array:character<span class="Special"> &lt;- </span>get *chan, <span class="Constant">data:offset</span>
-  result:number<span class="Special"> &lt;- </span>length *q
-  <span class="muControl">reply</span> result
+  result<span class="Special"> &lt;- </span>length *q
 ]
 
 <span class="muScenario">scenario</span> channel-new-empty-not-full [
@@ -312,11 +301,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 ]
 
 <span class="Comment"># helper for channels of characters in particular</span>
-<span class="Comment"># out &lt;- buffer-lines in:address:channel, out:address:channel</span>
-<span class="muRecipe">recipe</span> buffer-lines [
+<span class="muRecipe">recipe</span> buffer-lines in:address:channel, out:address:channel<span class="muRecipe"> -&gt; </span>out:address:channel, in:address:channel [
   <span class="Constant">local-scope</span>
-  in:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  out:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># repeat forever</span>
   <span class="Delimiter">{</span>
     line:address:buffer<span class="Special"> &lt;- </span>new-buffer, <span class="Constant">30</span>
@@ -340,7 +327,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
         <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
       <span class="Delimiter">}</span>
       <span class="Comment"># append anything else</span>
-      line<span class="Special"> &lt;- </span>buffer-append line, c
+      line<span class="Special"> &lt;- </span>append line, c
       line-done?:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">10/newline</span>
       <span class="muControl">break-if</span> line-done?
       <span class="Comment"># stop buffering on eof (currently only generated by fake console)</span>
@@ -362,7 +349,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Delimiter">}</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> out/same-as-ingredient:<span class="Constant">1</span>
 ]
 
 <span class="muScenario">scenario</span> buffer-lines-blocks-until-newline [
diff --git a/html/073list.mu.html b/html/073list.mu.html
index c274436b..a14399dd 100644
--- a/html/073list.mu.html
+++ b/html/073list.mu.html
@@ -20,6 +20,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .Comment { color: #9090ff; }
 .Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
+.CommentedCode { color: #6c6c6c; }
 .Delimiter { color: #a04060; }
 -->
 </style>
@@ -85,6 +86,92 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">4</span><span class="Special"> &lt;- </span><span class="Constant">3</span>
   ]
 ]
+
+<span class="muRecipe">recipe</span> to-text in:address:list:_elem<span class="muRecipe"> -&gt; </span>result:address:array:character [
+  <span class="Constant">local-scope</span>
+<span class="CommentedCode">#?   $print [to text: list], 10/newline</span>
+  <span class="Constant">load-ingredients</span>
+  buf:address:buffer<span class="Special"> &lt;- </span>new-buffer <span class="Constant">80</span>
+  buf<span class="Special"> &lt;- </span>to-buffer in, buf
+  result<span class="Special"> &lt;- </span>buffer-to-array buf
+]
+
+<span class="Comment"># variant of 'to-text' which stops printing after a few elements (and so is robust to cycles)</span>
+<span class="muRecipe">recipe</span> to-text-line in:address:list:_elem<span class="muRecipe"> -&gt; </span>result:address:array:character [
+  <span class="Constant">local-scope</span>
+<span class="CommentedCode">#?   $print [to text line: list], 10/newline</span>
+  <span class="Constant">load-ingredients</span>
+  buf:address:buffer<span class="Special"> &lt;- </span>new-buffer <span class="Constant">80</span>
+  buf<span class="Special"> &lt;- </span>to-buffer in, buf, <span class="Constant">6</span>  <span class="Comment"># max elements to display</span>
+  result<span class="Special"> &lt;- </span>buffer-to-array buf
+]
+
+<span class="muRecipe">recipe</span> to-buffer in:address:list:_elem, buf:address:buffer<span class="muRecipe"> -&gt; </span>buf:address:buffer [
+  <span class="Constant">local-scope</span>
+<span class="CommentedCode">#?   $print [to buffer: list], 10/newline</span>
+  <span class="Constant">load-ingredients</span>
+  <span class="Delimiter">{</span>
+    <span class="muControl">break-if</span> in
+    $print <span class="Constant">[000]</span>, <span class="Constant">10/newline</span>
+    buf<span class="Special"> &lt;- </span>append buf, <span class="Constant">48/0</span>
+    <span class="muControl">reply</span>
+  <span class="Delimiter">}</span>
+  <span class="Comment"># append in.value to buf</span>
+  val:_elem<span class="Special"> &lt;- </span>get *in, <span class="Constant">value:offset</span>
+  buf<span class="Special"> &lt;- </span>append buf, val
+  <span class="Comment"># now prepare next</span>
+  next:address:list:_elem<span class="Special"> &lt;- </span>rest in
+  nextn:number<span class="Special"> &lt;- </span>copy next
+<span class="CommentedCode">#?   buf &lt;- append buf, nextn</span>
+  <span class="muControl">reply-unless</span> next
+  space:character<span class="Special"> &lt;- </span>copy <span class="Constant">32/space</span>
+  buf<span class="Special"> &lt;- </span>append buf, space:character
+  s:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[-&gt; ]</span>
+  n:number<span class="Special"> &lt;- </span>length *s
+  buf<span class="Special"> &lt;- </span>append buf, s
+  <span class="Comment"># and recurse</span>
+  remaining:number, optional-ingredient-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Delimiter">{</span>
+    <span class="muControl">break-if</span> optional-ingredient-found?
+    <span class="Comment"># unlimited recursion</span>
+    buf<span class="Special"> &lt;- </span>to-buffer next, buf
+    <span class="muControl">reply</span>
+  <span class="Delimiter">}</span>
+  <span class="Delimiter">{</span>
+    <span class="muControl">break-unless</span> remaining
+    <span class="Comment"># limited recursion</span>
+    remaining<span class="Special"> &lt;- </span>subtract remaining, <span class="Constant">1</span>
+    buf<span class="Special"> &lt;- </span>to-buffer next, buf, remaining
+    <span class="muControl">reply</span>
+  <span class="Delimiter">}</span>
+  <span class="Comment"># past recursion depth; insert ellipses and stop</span>
+  s:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[...]</span>
+  append buf, s
+]
+
+<span class="muScenario">scenario</span> stash-on-list-converts-to-text [
+  run [
+    x:address:list:number<span class="Special"> &lt;- </span>push <span class="Constant">4</span>, <span class="Constant">0</span>
+    x<span class="Special"> &lt;- </span>push <span class="Constant">5</span>, x
+    x<span class="Special"> &lt;- </span>push <span class="Constant">6</span>, x
+    stash <span class="Constant">[foo foo]</span>, x
+  ]
+  trace-should-contain [
+    app: foo foo <span class="Constant">6</span><span class="muRecipe"> -&gt; </span><span class="Constant">5</span><span class="muRecipe"> -&gt; </span><span class="Constant">4</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> stash-handles-list-with-cycle [
+  run [
+    x:address:list:number<span class="Special"> &lt;- </span>push <span class="Constant">4</span>, <span class="Constant">0</span>
+    y:address:address:list:number<span class="Special"> &lt;- </span>get-address *x, <span class="Constant">next:offset</span>
+    *y<span class="Special"> &lt;- </span>copy x
+    stash <span class="Constant">[foo foo]</span>, x
+  ]
+  trace-should-contain [
+    app: foo foo <span class="Constant">4</span><span class="muRecipe"> -&gt; </span><span class="Constant">4</span><span class="muRecipe"> -&gt; </span><span class="Constant">4</span><span class="muRecipe"> -&gt; </span><span class="Constant">4</span><span class="muRecipe"> -&gt; </span><span class="Constant">4</span><span class="muRecipe"> -&gt; </span><span class="Constant">4</span><span class="muRecipe"> -&gt; </span><span class="Constant">4</span><span class="muRecipe"> -&gt; </span>...
+  ]
+]
 </pre>
 </body>
 </html>
diff --git a/html/076stream.mu.html b/html/076stream.mu.html
index feaa978b..91861d7d 100644
--- a/html/076stream.mu.html
+++ b/html/076stream.mu.html
@@ -13,7 +13,6 @@
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 1.05em; }
-.muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
 .muData { color: #ffff00; }
 .Comment { color: #9090ff; }
@@ -30,49 +29,46 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 </head>
 <body>
 <pre id='vimCodeElement'>
-<span class="Comment"># new type to help incrementally read strings</span>
+<span class="Comment"># new type to help incrementally read texts (arrays of characters)</span>
 <span class="muData">container</span> stream [
   index:number
   data:address:array:character
 ]
 
-<span class="muRecipe">recipe</span> new-stream [
+<span class="muRecipe">recipe</span> new-stream s:address:array:character<span class="muRecipe"> -&gt; </span>result:address:stream [
   <span class="Constant">local-scope</span>
-  result:address:stream<span class="Special"> &lt;- </span>new <span class="Constant">stream:type</span>
+  <span class="Constant">load-ingredients</span>
+  result<span class="Special"> &lt;- </span>new <span class="Constant">stream:type</span>
   i:address:number<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">index:offset</span>
   *i<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   d:address:address:array:character<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">data:offset</span>
-  *d<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  <span class="muControl">reply</span> result
+  *d<span class="Special"> &lt;- </span>copy s
 ]
 
-<span class="muRecipe">recipe</span> rewind-stream [
+<span class="muRecipe">recipe</span> rewind-stream in:address:stream<span class="muRecipe"> -&gt; </span>in:address:stream [
   <span class="Constant">local-scope</span>
-  in:address:stream<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   x:address:number<span class="Special"> &lt;- </span>get-address *in, <span class="Constant">index:offset</span>
   *x<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
-  <span class="muControl">reply</span> in/same-as-arg:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> read-line [
+<span class="muRecipe">recipe</span> read-line in:address:stream<span class="muRecipe"> -&gt; </span>result:address:array:character, in:address:stream [
   <span class="Constant">local-scope</span>
-  in:address:stream<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   idx:address:number<span class="Special"> &lt;- </span>get-address *in, <span class="Constant">index:offset</span>
   s:address:array:character<span class="Special"> &lt;- </span>get *in, <span class="Constant">data:offset</span>
   next-idx:number<span class="Special"> &lt;- </span>find-next s, <span class="Constant">10/newline</span>, *idx
-  result:address:array:character<span class="Special"> &lt;- </span>string-copy s, *idx, next-idx
+  result<span class="Special"> &lt;- </span>copy s, *idx, next-idx
   *idx<span class="Special"> &lt;- </span>add next-idx, <span class="Constant">1</span>  <span class="Comment"># skip newline</span>
-  <span class="muControl">reply</span> result
 ]
 
-<span class="muRecipe">recipe</span> end-of-stream? [
+<span class="muRecipe">recipe</span> end-of-stream? in:address:stream<span class="muRecipe"> -&gt; </span>result:boolean [
   <span class="Constant">local-scope</span>
-  in:address:stream<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   idx:number<span class="Special"> &lt;- </span>get *in, <span class="Constant">index:offset</span>
   s:address:array:character<span class="Special"> &lt;- </span>get *in, <span class="Constant">data:offset</span>
   len:number<span class="Special"> &lt;- </span>length *s
-  result:boolean<span class="Special"> &lt;- </span>greater-or-equal idx, len
-  <span class="muControl">reply</span> result
+  result<span class="Special"> &lt;- </span>greater-or-equal idx, len
 ]
 </pre>
 </body>
diff --git a/html/081print.mu.html b/html/081print.mu.html
index 19efbb1c..7bfdc7dc 100644
--- a/html/081print.mu.html
+++ b/html/081print.mu.html
@@ -48,13 +48,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   color:number
 ]
 
-<span class="muRecipe">recipe</span> new-fake-screen [
+<span class="muRecipe">recipe</span> new-fake-screen w:number, h:number<span class="muRecipe"> -&gt; </span>result:address:screen [
   <span class="Constant">local-scope</span>
-  result:address:screen<span class="Special"> &lt;- </span>new <span class="Constant">screen:type</span>
+  <span class="Constant">load-ingredients</span>
+  result<span class="Special"> &lt;- </span>new <span class="Constant">screen:type</span>
   width:address:number<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">num-columns:offset</span>
-  *width<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  *width<span class="Special"> &lt;- </span>copy w
   height:address:number<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">num-rows:offset</span>
-  *height<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  *height<span class="Special"> &lt;- </span>copy h
   row:address:number<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">cursor-row:offset</span>
   *row<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   column:address:number<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">cursor-column:offset</span>
@@ -62,18 +63,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   bufsize:number<span class="Special"> &lt;- </span>multiply *width, *height
   buf:address:address:array:screen-cell<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">data:offset</span>
   *buf<span class="Special"> &lt;- </span>new <span class="Constant">screen-cell:type</span>, bufsize
-  clear-screen result
-  <span class="muControl">reply</span> result
+  result<span class="Special"> &lt;- </span>clear-screen result
 ]
 
-<span class="muRecipe">recipe</span> clear-screen [
+<span class="muRecipe">recipe</span> clear-screen screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sc
+    <span class="muControl">break-unless</span> screen
     <span class="Comment"># clear fake screen</span>
-    buf:address:array:screen-cell<span class="Special"> &lt;- </span>get *sc, <span class="Constant">data:offset</span>
+    buf:address:array:screen-cell<span class="Special"> &lt;- </span>get *screen, <span class="Constant">data:offset</span>
     max:number<span class="Special"> &lt;- </span>length *buf
     i:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
     <span class="Delimiter">{</span>
@@ -88,32 +88,31 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       <span class="muControl">loop</span>
     <span class="Delimiter">}</span>
     <span class="Comment"># reset cursor</span>
-    x:address:number<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-row:offset</span>
+    x:address:number<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-row:offset</span>
     *x<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
-    x<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-column:offset</span>
+    x<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-column:offset</span>
     *x<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
-    <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   clear-display
-  <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> sync-screen [
+<span class="muRecipe">recipe</span> sync-screen screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-if</span> sc
+    <span class="muControl">break-if</span> screen
     sync-display
   <span class="Delimiter">}</span>
   <span class="Comment"># do nothing for fake screens</span>
 ]
 
-<span class="muRecipe">recipe</span> fake-screen-is-empty? [
+<span class="muRecipe">recipe</span> fake-screen-is-empty? screen:address:screen<span class="muRecipe"> -&gt; </span>result:boolean [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  <span class="muControl">reply-unless</span> sc, <span class="Constant">1/true</span>
-  buf:address:array:screen-cell<span class="Special"> &lt;- </span>get *sc, <span class="Constant">data:offset</span>
+  <span class="Constant">load-ingredients</span>
+  <span class="muControl">reply-unless</span> screen, <span class="Constant">1/true</span>
+  buf:address:array:screen-cell<span class="Special"> &lt;- </span>get *screen, <span class="Constant">data:offset</span>
   i:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   len:number<span class="Special"> &lt;- </span>length *buf
   <span class="Delimiter">{</span>
@@ -129,10 +128,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply</span> <span class="Constant">1/true</span>
 ]
 
-<span class="muRecipe">recipe</span> print-character [
+<span class="muRecipe">recipe</span> print screen:address:screen, c:character<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  c:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   color:number, color-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Delimiter">{</span>
     <span class="Comment"># default color to white</span>
@@ -149,20 +147,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">{</span>
     <span class="Comment"># if x exists</span>
     <span class="Comment"># (handle special cases exactly like in the real screen)</span>
-    <span class="muControl">break-unless</span> sc
-    width:number<span class="Special"> &lt;- </span>get *sc, <span class="Constant">num-columns:offset</span>
-    height:number<span class="Special"> &lt;- </span>get *sc, <span class="Constant">num-rows:offset</span>
+    <span class="muControl">break-unless</span> screen
+    width:number<span class="Special"> &lt;- </span>get *screen, <span class="Constant">num-columns:offset</span>
+    height:number<span class="Special"> &lt;- </span>get *screen, <span class="Constant">num-rows:offset</span>
     <span class="Comment"># if cursor is out of bounds, silently exit</span>
-    row:address:number<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-row:offset</span>
+    row:address:number<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-row:offset</span>
     legal?:boolean<span class="Special"> &lt;- </span>greater-or-equal *row, <span class="Constant">0</span>
-    <span class="muControl">reply-unless</span> legal?, sc
+    <span class="muControl">reply-unless</span> legal?
     legal?<span class="Special"> &lt;- </span>lesser-than *row, height
-    <span class="muControl">reply-unless</span> legal?, sc
-    column:address:number<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-column:offset</span>
+    <span class="muControl">reply-unless</span> legal?
+    column:address:number<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-column:offset</span>
     legal?<span class="Special"> &lt;- </span>greater-or-equal *column, <span class="Constant">0</span>
-    <span class="muControl">reply-unless</span> legal?, sc
+    <span class="muControl">reply-unless</span> legal?
     legal?<span class="Special"> &lt;- </span>lesser-than *column, width
-    <span class="muControl">reply-unless</span> legal?, sc
+    <span class="muControl">reply-unless</span> legal?
     <span class="Comment"># special-case: newline</span>
     <span class="Delimiter">{</span>
       newline?:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">10/newline</span>
@@ -176,12 +174,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
         *column<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
         *row<span class="Special"> &lt;- </span>add *row, <span class="Constant">1</span>
       <span class="Delimiter">}</span>
-      <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+      <span class="muControl">reply</span>
     <span class="Delimiter">}</span>
     <span class="Comment"># save character in fake screen</span>
     index:number<span class="Special"> &lt;- </span>multiply *row, width
     index<span class="Special"> &lt;- </span>add index, *column
-    buf:address:array:screen-cell<span class="Special"> &lt;- </span>get *sc, <span class="Constant">data:offset</span>
+    buf:address:array:screen-cell<span class="Special"> &lt;- </span>get *screen, <span class="Constant">data:offset</span>
     len:number<span class="Special"> &lt;- </span>length *buf
     <span class="Comment"># special-case: backspace</span>
     <span class="Delimiter">{</span>
@@ -200,7 +198,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
         cursor-color:address:number<span class="Special"> &lt;- </span>get-address *cursor, <span class="Constant">color:offset</span>
         *cursor-color<span class="Special"> &lt;- </span>copy <span class="Constant">7/white</span>
       <span class="Delimiter">}</span>
-      <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+      <span class="muControl">reply</span>
     <span class="Delimiter">}</span>
     cursor:address:screen-cell<span class="Special"> &lt;- </span>index-address *buf, index
     cursor-contents:address:character<span class="Special"> &lt;- </span>get-address *cursor, <span class="Constant">contents:offset</span>
@@ -214,17 +212,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       <span class="muControl">break-if</span> at-right?
       *column<span class="Special"> &lt;- </span>add *column, <span class="Constant">1</span>
     <span class="Delimiter">}</span>
-    <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   print-character-to-display c, color, bg-color
-  <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
 ]
 
 <span class="muScenario">scenario</span> print-character-at-top-left [
   run [
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
     <span class="Constant">2</span>:address:array:screen-cell<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span>
     <span class="Constant">3</span>:array:screen-cell<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:screen-cell
   ]
@@ -236,10 +233,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> print-character-color [
+<span class="muScenario">scenario</span> print-character-in-color [
   run [
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97/a</span>, <span class="Constant">1/red</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97/a</span>, <span class="Constant">1/red</span>
     <span class="Constant">2</span>:address:array:screen-cell<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span>
     <span class="Constant">3</span>:array:screen-cell<span class="Special"> &lt;- </span>copy *<span class="Constant">2</span>:address:array:screen-cell
   ]
@@ -254,8 +251,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muScenario">scenario</span> print-backspace-character [
   run [
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">8</span>  <span class="Comment"># backspace</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">8</span>  <span class="Comment"># backspace</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span>
     <span class="Constant">3</span>:address:array:screen-cell<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span>
     <span class="Constant">4</span>:array:screen-cell<span class="Special"> &lt;- </span>copy *<span class="Constant">3</span>:address:array:screen-cell
@@ -272,9 +269,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muScenario">scenario</span> print-extra-backspace-character [
   run [
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">8</span>  <span class="Comment"># backspace</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">8</span>  <span class="Comment"># backspace</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">8</span>  <span class="Comment"># backspace</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">8</span>  <span class="Comment"># backspace</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span>
     <span class="Constant">3</span>:address:array:screen-cell<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span>
     <span class="Constant">4</span>:array:screen-cell<span class="Special"> &lt;- </span>copy *<span class="Constant">3</span>:address:array:screen-cell
@@ -288,12 +285,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> print-at-right-margin [
+<span class="muScenario">scenario</span> print-character-at-right-margin [
   run [
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">2/width</span>, <span class="Constant">2/height</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">98</span>  <span class="Comment"># 'b'</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">99</span>  <span class="Comment"># 'c'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">98</span>  <span class="Comment"># 'b'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">99</span>  <span class="Comment"># 'c'</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span>
     <span class="Constant">3</span>:address:array:screen-cell<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span>
     <span class="Constant">4</span>:array:screen-cell<span class="Special"> &lt;- </span>copy *<span class="Constant">3</span>:address:array:screen-cell
@@ -312,8 +309,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muScenario">scenario</span> print-newline-character [
   run [
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-row:offset</span>
     <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span>
     <span class="Constant">4</span>:address:array:screen-cell<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span>
@@ -332,9 +329,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muScenario">scenario</span> print-newline-at-bottom-line [
   run [
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-row:offset</span>
     <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span>
   ]
@@ -344,15 +341,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muScenario">scenario</span> print-at-bottom-right [
+<span class="muScenario">scenario</span> print-character-at-bottom-right [
   run [
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">2/width</span>, <span class="Constant">2/height</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">98</span>  <span class="Comment"># 'b'</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">99</span>  <span class="Comment"># 'c'</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">100</span>  <span class="Comment"># 'd'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">98</span>  <span class="Comment"># 'b'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">99</span>  <span class="Comment"># 'c'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">10/newline</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">100</span>  <span class="Comment"># 'd'</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-row:offset</span>
     <span class="Constant">3</span>:number<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">cursor-column:offset</span>
     <span class="Constant">4</span>:address:array:screen-cell<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span>
@@ -374,70 +371,65 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muRecipe">recipe</span> clear-line [
+<span class="muRecipe">recipe</span> clear-line screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists, clear line in fake screen</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sc
-    width:number<span class="Special"> &lt;- </span>get *sc, <span class="Constant">num-columns:offset</span>
-    column:address:number<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-column:offset</span>
+    <span class="muControl">break-unless</span> screen
+    width:number<span class="Special"> &lt;- </span>get *screen, <span class="Constant">num-columns:offset</span>
+    column:address:number<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-column:offset</span>
     original-column:number<span class="Special"> &lt;- </span>copy *column
     <span class="Comment"># space over the entire line</span>
     <span class="Delimiter">{</span>
       right:number<span class="Special"> &lt;- </span>subtract width, <span class="Constant">1</span>
       done?:boolean<span class="Special"> &lt;- </span>greater-or-equal *column, right
       <span class="muControl">break-if</span> done?
-      print-character sc, <span class="Constant">[ ]</span>  <span class="Comment"># implicitly updates 'column'</span>
+      print screen, <span class="Constant">[ ]</span>  <span class="Comment"># implicitly updates 'column'</span>
       <span class="muControl">loop</span>
     <span class="Delimiter">}</span>
     <span class="Comment"># now back to where the cursor was</span>
     *column<span class="Special"> &lt;- </span>copy original-column
-    <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   clear-line-on-display
-  <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> cursor-position [
+<span class="muRecipe">recipe</span> cursor-position screen:address:screen<span class="muRecipe"> -&gt; </span>row:number, column:number [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists, lookup cursor in fake screen</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sc
-    row:number<span class="Special"> &lt;- </span>get *sc, <span class="Constant">cursor-row:offset</span>
-    column:number<span class="Special"> &lt;- </span>get *sc, <span class="Constant">cursor-column:offset</span>
-    <span class="muControl">reply</span> row, column, sc/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">break-unless</span> screen
+    row:number<span class="Special"> &lt;- </span>get *screen, <span class="Constant">cursor-row:offset</span>
+    column:number<span class="Special"> &lt;- </span>get *screen, <span class="Constant">cursor-column:offset</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   row, column<span class="Special"> &lt;- </span>cursor-position-on-display
-  <span class="muControl">reply</span> row, column, sc/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> move-cursor [
+<span class="muRecipe">recipe</span> move-cursor screen:address:screen, new-row:number, new-column:number<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  new-row:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  new-column:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists, move cursor in fake screen</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sc
-    row:address:number<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-row:offset</span>
+    <span class="muControl">break-unless</span> screen
+    row:address:number<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-row:offset</span>
     *row<span class="Special"> &lt;- </span>copy new-row
-    column:address:number<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-column:offset</span>
+    column:address:number<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-column:offset</span>
     *column<span class="Special"> &lt;- </span>copy new-column
-    <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   move-cursor-on-display new-row, new-column
-  <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
 ]
 
 <span class="muScenario">scenario</span> clear-line-erases-printed-characters [
   run [
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span>
     <span class="Comment"># print a character</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-character <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
     <span class="Comment"># move cursor to start of line</span>
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>move-cursor <span class="Constant">1</span>:address:screen, <span class="Constant">0/row</span>, <span class="Constant">0/column</span>
     <span class="Comment"># clear line</span>
@@ -463,193 +455,180 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muRecipe">recipe</span> cursor-down [
+<span class="muRecipe">recipe</span> cursor-down screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists, move cursor in fake screen</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sc
+    <span class="muControl">break-unless</span> screen
     <span class="Delimiter">{</span>
       <span class="Comment"># increment row unless it's already all the way down</span>
-      height:number<span class="Special"> &lt;- </span>get *sc, <span class="Constant">num-rows:offset</span>
-      row:address:number<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-row:offset</span>
+      height:number<span class="Special"> &lt;- </span>get *screen, <span class="Constant">num-rows:offset</span>
+      row:address:number<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-row:offset</span>
       max:number<span class="Special"> &lt;- </span>subtract height, <span class="Constant">1</span>
       at-bottom?:boolean<span class="Special"> &lt;- </span>greater-or-equal *row, max
       <span class="muControl">break-if</span> at-bottom?
       *row<span class="Special"> &lt;- </span>add *row, <span class="Constant">1</span>
     <span class="Delimiter">}</span>
-    <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   move-cursor-down-on-display
-  <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> cursor-up [
+<span class="muRecipe">recipe</span> cursor-up screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists, move cursor in fake screen</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sc
+    <span class="muControl">break-unless</span> screen
     <span class="Delimiter">{</span>
       <span class="Comment"># decrement row unless it's already all the way up</span>
-      row:address:number<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-row:offset</span>
+      row:address:number<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-row:offset</span>
       at-top?:boolean<span class="Special"> &lt;- </span>lesser-or-equal *row, <span class="Constant">0</span>
       <span class="muControl">break-if</span> at-top?
       *row<span class="Special"> &lt;- </span>subtract *row, <span class="Constant">1</span>
     <span class="Delimiter">}</span>
-    <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   move-cursor-up-on-display
-  <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> cursor-right [
+<span class="muRecipe">recipe</span> cursor-right screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists, move cursor in fake screen</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sc
+    <span class="muControl">break-unless</span> screen
     <span class="Delimiter">{</span>
       <span class="Comment"># increment column unless it's already all the way to the right</span>
-      width:number<span class="Special"> &lt;- </span>get *sc, <span class="Constant">num-columns:offset</span>
-      column:address:number<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-column:offset</span>
+      width:number<span class="Special"> &lt;- </span>get *screen, <span class="Constant">num-columns:offset</span>
+      column:address:number<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-column:offset</span>
       max:number<span class="Special"> &lt;- </span>subtract width, <span class="Constant">1</span>
       at-bottom?:boolean<span class="Special"> &lt;- </span>greater-or-equal *column, max
       <span class="muControl">break-if</span> at-bottom?
       *column<span class="Special"> &lt;- </span>add *column, <span class="Constant">1</span>
     <span class="Delimiter">}</span>
-    <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   move-cursor-right-on-display
-  <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> cursor-left [
+<span class="muRecipe">recipe</span> cursor-left screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists, move cursor in fake screen</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sc
+    <span class="muControl">break-unless</span> screen
     <span class="Delimiter">{</span>
       <span class="Comment"># decrement column unless it's already all the way to the left</span>
-      column:address:number<span class="Special"> &lt;- </span>get-address *sc, <span class="Constant">cursor-column:offset</span>
+      column:address:number<span class="Special"> &lt;- </span>get-address *screen, <span class="Constant">cursor-column:offset</span>
       at-top?:boolean<span class="Special"> &lt;- </span>lesser-or-equal *column, <span class="Constant">0</span>
       <span class="muControl">break-if</span> at-top?
       *column<span class="Special"> &lt;- </span>subtract *column, <span class="Constant">1</span>
     <span class="Delimiter">}</span>
-    <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   move-cursor-left-on-display
-  <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> cursor-to-start-of-line [
+<span class="muRecipe">recipe</span> cursor-to-start-of-line screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  row:number, _, sc<span class="Special"> &lt;- </span>cursor-position sc
+  <span class="Constant">load-ingredients</span>
+  row:number<span class="Special"> &lt;- </span>cursor-position screen
   column:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
-  sc<span class="Special"> &lt;- </span>move-cursor sc, row, column
-  <span class="muControl">reply</span> sc/same-as-ingredient:<span class="Constant">0</span>
+  screen<span class="Special"> &lt;- </span>move-cursor screen, row, column
 ]
 
-<span class="muRecipe">recipe</span> cursor-to-next-line [
+<span class="muRecipe">recipe</span> cursor-to-next-line screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   screen<span class="Special"> &lt;- </span>cursor-down screen
   screen<span class="Special"> &lt;- </span>cursor-to-start-of-line screen
-  <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> screen-width [
+<span class="muRecipe">recipe</span> screen-width screen:address:screen<span class="muRecipe"> -&gt; </span>width:number [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists, move cursor in fake screen</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sc
-    width:number<span class="Special"> &lt;- </span>get *sc, <span class="Constant">num-columns:offset</span>
-    <span class="muControl">reply</span> width
+    <span class="muControl">break-unless</span> screen
+    width<span class="Special"> &lt;- </span>get *screen, <span class="Constant">num-columns:offset</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
-  width:number<span class="Special"> &lt;- </span>display-width
-  <span class="muControl">reply</span> width
+  width<span class="Special"> &lt;- </span>display-width
 ]
 
-<span class="muRecipe">recipe</span> screen-height [
+<span class="muRecipe">recipe</span> screen-height screen:address:screen<span class="muRecipe"> -&gt; </span>height:number [
   <span class="Constant">local-scope</span>
-  sc:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists, move cursor in fake screen</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sc
-    height:number<span class="Special"> &lt;- </span>get *sc, <span class="Constant">num-rows:offset</span>
-    <span class="muControl">reply</span> height
+    <span class="muControl">break-unless</span> screen
+    height<span class="Special"> &lt;- </span>get *screen, <span class="Constant">num-rows:offset</span>
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
-  height:number<span class="Special"> &lt;- </span>display-height
-  <span class="muControl">reply</span> height
+  height<span class="Special"> &lt;- </span>display-height
 ]
 
-<span class="muRecipe">recipe</span> hide-cursor [
+<span class="muRecipe">recipe</span> hide-cursor screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists (not real display), do nothing</span>
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> screen
-    <span class="muControl">reply</span> screen
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   hide-cursor-on-display
-  <span class="muControl">reply</span> screen
 ]
 
-<span class="muRecipe">recipe</span> show-cursor [
+<span class="muRecipe">recipe</span> show-cursor screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists (not real display), do nothing</span>
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> screen
-    <span class="muControl">reply</span> screen
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   show-cursor-on-display
-  <span class="muControl">reply</span> screen
 ]
 
-<span class="muRecipe">recipe</span> hide-screen [
+<span class="muRecipe">recipe</span> hide-screen screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists (not real display), do nothing</span>
   <span class="Comment"># todo: help test this</span>
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> screen
-    <span class="muControl">reply</span> screen
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   hide-display
-  <span class="muControl">reply</span> screen
 ]
 
-<span class="muRecipe">recipe</span> show-screen [
+<span class="muRecipe">recipe</span> show-screen screen:address:screen<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># if x exists (not real display), do nothing</span>
   <span class="Comment"># todo: help test this</span>
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> screen
-    <span class="muControl">reply</span> screen
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># otherwise, real screen</span>
   show-display
-  <span class="muControl">reply</span> screen
 ]
 
-<span class="muRecipe">recipe</span> print-string [
+<span class="muRecipe">recipe</span> print screen:address:screen, s:address:array:character<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  s:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   color:number, color-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   <span class="Delimiter">{</span>
     <span class="Comment"># default color to white</span>
@@ -668,18 +647,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     done?:boolean<span class="Special"> &lt;- </span>greater-or-equal i, len
     <span class="muControl">break-if</span> done?
     c:character<span class="Special"> &lt;- </span>index *s, i
-    print-character screen, c, color, bg-color
+    print screen, c, color, bg-color
     i<span class="Special"> &lt;- </span>add i, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muScenario">scenario</span> print-string-stops-at-right-margin [
+<span class="muScenario">scenario</span> print-text-stops-at-right-margin [
   run [
     <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>new-fake-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span>
     <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abcd]</span>
-    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print-string <span class="Constant">1</span>:address:screen, <span class="Constant">2</span>:address:array:character
+    <span class="Constant">1</span>:address:screen<span class="Special"> &lt;- </span>print <span class="Constant">1</span>:address:screen, <span class="Constant">2</span>:address:array:character
     <span class="Constant">3</span>:address:array:screen-cell<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:screen, <span class="Constant">data:offset</span>
     <span class="Constant">4</span>:array:screen-cell<span class="Special"> &lt;- </span>copy *<span class="Constant">3</span>:address:array:screen-cell
   ]
@@ -695,7 +673,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="muRecipe">recipe</span> print-integer [
+<span class="muRecipe">recipe</span> print-integer screen:address:screen, n:number<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
   screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
   n:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
@@ -712,9 +690,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     bg-color<span class="Special"> &lt;- </span>copy <span class="Constant">0/black</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># todo: other bases besides decimal</span>
-  s:address:array:character<span class="Special"> &lt;- </span>integer-to-decimal-string n
-  print-string screen, s, color, bg-color
-  <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
+  s:address:array:character<span class="Special"> &lt;- </span>to-text n
+  screen<span class="Special"> &lt;- </span>print screen, s, color, bg-color
 ]
 </pre>
 </body>
diff --git a/html/082scenario_screen.cc.html b/html/082scenario_screen.cc.html
index 037fc9ff..bca387d9 100644
--- a/html/082scenario_screen.cc.html
+++ b/html/082scenario_screen.cc.html
@@ -21,6 +21,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
 .Constant { color: #00a0a0; }
+.CommentedCode { color: #6c6c6c; }
 -->
 </style>
 
@@ -43,7 +44,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 scenario screen-in-scenario [
   assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height
   run [
-    screen:address:screen<span class="Special"> &lt;- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    screen:address:screen<span class="Special"> &lt;- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
   ]
   screen-should-contain [
   <span class="Comment">#  01234</span>
@@ -57,8 +58,8 @@ scenario screen-in-scenario [
 scenario screen-in-scenario-unicode-color [
   assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height
   run [
-    screen:address:screen<span class="Special"> &lt;- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red
-    screen:address:screen<span class="Special"> &lt;- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a
+    screen:address:screen<span class="Special"> &lt;- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red
+    screen:address:screen<span class="Special"> &lt;- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a
   ]
   screen-should-contain [
   <span class="Comment">#  01234</span>
@@ -73,8 +74,8 @@ scenario screen-in-scenario-unicode-color [
 scenario screen-in-scenario-color [
   assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height
   run [
-    screen:address:screen<span class="Special"> &lt;- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red
-    screen:address:screen<span class="Special"> &lt;- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">7</span>/white
+    screen:address:screen<span class="Special"> &lt;- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">955</span>/greek-small-lambda<span class="Delimiter">,</span> <span class="Constant">1</span>/red
+    screen:address:screen<span class="Special"> &lt;- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">7</span>/white
   ]
   <span class="Comment"># screen-should-contain shows everything</span>
   screen-should-contain [
@@ -106,7 +107,7 @@ scenario screen-in-scenario-color [
 scenario screen-in-scenario-error [
   assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height
   run [
-    screen:address:screen<span class="Special"> &lt;- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
+    screen:address:screen<span class="Special"> &lt;- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>  <span class="Comment"># 'a'</span>
   ]
   screen-should-contain [
   <span class="Comment">#  01234</span>
@@ -124,7 +125,7 @@ scenario screen-in-scenario-error [
 scenario screen-in-scenario-color [
   assume-screen <span class="Constant">5</span>/width<span class="Delimiter">,</span> <span class="Constant">3</span>/height
   run [
-    screen:address:screen<span class="Special"> &lt;- </span>print-character screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">1</span>/red
+    screen:address:screen<span class="Special"> &lt;- </span>print screen:address:screen<span class="Delimiter">,</span> <span class="Constant">97</span>/a<span class="Delimiter">,</span> <span class="Constant">1</span>/red
   ]
   screen-should-contain-in-color <span class="Constant">2</span>/green<span class="Delimiter">,</span> [
   <span class="Comment">#  01234</span>
@@ -192,6 +193,8 @@ case SCREEN_SHOULD_CONTAIN: <span class="Delimiter">{</span>
 <span class="Delimiter">}</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
 case SCREEN_SHOULD_CONTAIN: <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; SIZE(get(Recipe_variants, &quot;insert&quot;)) &lt;&lt; '\n';</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; debug_string(get(Recipe, get(Recipe_ordinal, &quot;insert_4&quot;))) &lt;&lt; '\n';</span>
   if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
   check_screen<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>name<span class="Delimiter">,</span> -<span class="Constant">1</span><span class="Delimiter">);</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
diff --git a/html/083scenario_screen_test.mu.html b/html/083scenario_screen_test.mu.html
index a93c7c20..2fdd57bc 100644
--- a/html/083scenario_screen_test.mu.html
+++ b/html/083scenario_screen_test.mu.html
@@ -33,7 +33,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muScenario">scenario</span> print-character-at-top-left-2 [
   assume-screen <span class="Constant">3/width</span>, <span class="Constant">2/height</span>
   run [
-    screen:address:screen<span class="Special"> &lt;- </span>print-character screen:address:screen, <span class="Constant">97/a</span>
+    screen:address:screen<span class="Special"> &lt;- </span>print screen:address:screen, <span class="Constant">97/a</span>
   ]
   screen-should-contain [
    <span class="Constant"> .a  .</span>
@@ -45,7 +45,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   assume-screen <span class="Constant">5/width</span>, <span class="Constant">3/height</span>
   run [
     <span class="Comment"># print a character</span>
-    screen:address:screen<span class="Special"> &lt;- </span>print-character screen:address:screen, <span class="Constant">97/a</span>
+    screen:address:screen<span class="Special"> &lt;- </span>print screen:address:screen, <span class="Constant">97/a</span>
     <span class="Comment"># move cursor to start of line</span>
     screen:address:screen<span class="Special"> &lt;- </span>move-cursor screen:address:screen, <span class="Constant">0/row</span>, <span class="Constant">0/column</span>
     <span class="Comment"># clear line</span>
diff --git a/html/084console.mu.html b/html/084console.mu.html
index c91544f9..b8619762 100644
--- a/html/084console.mu.html
+++ b/html/084console.mu.html
@@ -58,45 +58,45 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   data:address:array:event
 ]
 
-<span class="muRecipe">recipe</span> new-fake-console [
+<span class="muRecipe">recipe</span> new-fake-console events:address:array:event<span class="muRecipe"> -&gt; </span>result:address:console [
   <span class="Constant">local-scope</span>
+  <span class="Constant">load-ingredients</span>
   result:address:console<span class="Special"> &lt;- </span>new <span class="Constant">console:type</span>
   buf:address:address:array:event<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">data:offset</span>
-  *buf<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  *buf<span class="Special"> &lt;- </span>copy events
   idx:address:number<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">index:offset</span>
   *idx<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
-  <span class="muControl">reply</span> result
 ]
 
-<span class="muRecipe">recipe</span> read-event [
+<span class="muRecipe">recipe</span> read-event console:address:console<span class="muRecipe"> -&gt; </span>result:event, console:address:console, found?:boolean, quit?:boolean [
   <span class="Constant">local-scope</span>
-  x:address:console<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> x
-    idx:address:number<span class="Special"> &lt;- </span>get-address *x, <span class="Constant">index:offset</span>
-    buf:address:array:event<span class="Special"> &lt;- </span>get *x, <span class="Constant">data:offset</span>
+    <span class="muControl">break-unless</span> console
+    idx:address:number<span class="Special"> &lt;- </span>get-address *console, <span class="Constant">index:offset</span>
+    buf:address:array:event<span class="Special"> &lt;- </span>get *console, <span class="Constant">data:offset</span>
     <span class="Delimiter">{</span>
       max:number<span class="Special"> &lt;- </span>length *buf
       done?:boolean<span class="Special"> &lt;- </span>greater-or-equal *idx, max
       <span class="muControl">break-unless</span> done?
       dummy:address:event<span class="Special"> &lt;- </span>new <span class="Constant">event:type</span>
-      <span class="muControl">reply</span> *dummy, x/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/found</span>, <span class="Constant">1/quit</span>
+      <span class="muControl">reply</span> *dummy, console/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/found</span>, <span class="Constant">1/quit</span>
     <span class="Delimiter">}</span>
-    result:event<span class="Special"> &lt;- </span>index *buf, *idx
+    result<span class="Special"> &lt;- </span>index *buf, *idx
     *idx<span class="Special"> &lt;- </span>add *idx, <span class="Constant">1</span>
-    <span class="muControl">reply</span> result, x/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/found</span>, <span class="Constant">0/quit</span>
+    <span class="muControl">reply</span> result, console/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/found</span>, <span class="Constant">0/quit</span>
   <span class="Delimiter">}</span>
   switch  <span class="Comment"># real event source is infrequent; avoid polling it too much</span>
   result:event, found?:boolean<span class="Special"> &lt;- </span>check-for-interaction
-  <span class="muControl">reply</span> result, x/same-as-ingredient:<span class="Constant">0</span>, found?, <span class="Constant">0/quit</span>
+  <span class="muControl">reply</span> result, console/same-as-ingredient:<span class="Constant">0</span>, found?, <span class="Constant">0/quit</span>
 ]
 
 <span class="Comment"># variant of read-event for just keyboard events. Discards everything that</span>
 <span class="Comment"># isn't unicode, so no arrow keys, page-up/page-down, etc. But you still get</span>
 <span class="Comment"># newlines, tabs, ctrl-d..</span>
-<span class="muRecipe">recipe</span> read-key [
+<span class="muRecipe">recipe</span> read-key console:address:console<span class="muRecipe"> -&gt; </span>result:character, console:address:console, found?:boolean, quit?:boolean [
   <span class="Constant">local-scope</span>
-  console:address:console<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   x:event, console, found?:boolean, quit?:boolean<span class="Special"> &lt;- </span>read-event console
   <span class="muControl">reply-if</span> quit?, <span class="Constant">0</span>, console/same-as-ingredient:<span class="Constant">0</span>, found?, quit?
   <span class="muControl">reply-unless</span> found?, <span class="Constant">0</span>, console/same-as-ingredient:<span class="Constant">0</span>, found?, quit?
@@ -105,44 +105,39 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply</span> *c, console/same-as-ingredient:<span class="Constant">0</span>, <span class="Constant">1/found</span>, <span class="Constant">0/quit</span>
 ]
 
-<span class="muRecipe">recipe</span> send-keys-to-channel [
+<span class="muRecipe">recipe</span> send-keys-to-channel console:address:console, chan:address:channel, screen:address:screen<span class="muRecipe"> -&gt; </span>console:address:console, chan:address:channel, screen:address:screen [
   <span class="Constant">local-scope</span>
-  console:address:console<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  chan:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     c:character, console, found?:boolean, quit?:boolean<span class="Special"> &lt;- </span>read-key console
     <span class="muControl">loop-unless</span> found?
     <span class="muControl">break-if</span> quit?
     assert c, <span class="Constant">[invalid event, expected text]</span>
-    screen<span class="Special"> &lt;- </span>print-character screen, c
+    screen<span class="Special"> &lt;- </span>print screen, c
     chan<span class="Special"> &lt;- </span>write chan, c
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> console/same-as-ingredient:<span class="Constant">0</span>, chan/same-as-ingredient:<span class="Constant">1</span>, screen/same-as-ingredient:<span class="Constant">2</span>
 ]
 
-<span class="muRecipe">recipe</span> wait-for-event [
+<span class="muRecipe">recipe</span> wait-for-event console:address:console<span class="muRecipe"> -&gt; </span>console:address:console [
   <span class="Constant">local-scope</span>
-  console:address:console<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     _, console, found?:boolean<span class="Special"> &lt;- </span>read-event console
     <span class="muControl">loop-unless</span> found?
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> console/same-as-ingredient:<span class="Constant">0</span>
 ]
 
 <span class="Comment"># use this helper to skip rendering if there's lots of other events queued up</span>
-<span class="muRecipe">recipe</span> has-more-events? [
+<span class="muRecipe">recipe</span> has-more-events? console:address:console<span class="muRecipe"> -&gt; </span>result:boolean [
   <span class="Constant">local-scope</span>
-  console:address:console<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> console
     <span class="Comment"># fake consoles should be plenty fast; never skip</span>
     <span class="muControl">reply</span> <span class="Constant">0/false</span>
   <span class="Delimiter">}</span>
-  result:boolean<span class="Special"> &lt;- </span>interactions-left?
-  <span class="muControl">reply</span> result
+  result<span class="Special"> &lt;- </span>interactions-left?
 ]
 </pre>
 </body>
diff --git a/html/090trace_browser.cc.html b/html/090trace_browser.cc.html
index 62aa2fbe..3da39a9b 100644
--- a/html/090trace_browser.cc.html
+++ b/html/090trace_browser.cc.html
@@ -29,6 +29,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 </head>
 <body>
 <pre id='vimCodeElement'>
+<span class="Comment">//: A debugging helper that lets you zoom in/out on a trace.</span>
+
+<span class="Comment">//: browse the trace we just created</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
 _BROWSE_TRACE<span class="Delimiter">,</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
@@ -43,6 +46,14 @@ case _BROWSE_TRACE: <span class="Delimiter">{</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
+<span class="Comment">//: browse a trace loaded from a file</span>
+<span class="Delimiter">:(after &quot;Commandline Parsing&quot;)</span>
+if <span class="Delimiter">(</span>argc == <span class="Constant">3</span> &amp;&amp; is_equal<span class="Delimiter">(</span>argv[<span class="Constant">1</span>]<span class="Delimiter">,</span> <span class="Constant">&quot;browse-trace&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  load_trace<span class="Delimiter">(</span>argv[<span class="Constant">2</span>]<span class="Delimiter">);</span>
+  start_trace_browser<span class="Delimiter">();</span>
+  <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
 set&lt;long long int&gt; Visible<span class="Delimiter">;</span>
 long long int Top_of_screen = <span class="Constant">0</span><span class="Delimiter">;</span>
@@ -242,6 +253,25 @@ void render_line<span class="Delimiter">(</span>int screen_row<span class="Delim
     tb_change_cell<span class="Delimiter">(</span>col<span class="Delimiter">,</span> screen_row<span class="Delimiter">,</span> <span class="Constant">' '</span><span class="Delimiter">,</span> TB_WHITE<span class="Delimiter">,</span> TB_BLACK<span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
+
+void load_trace<span class="Delimiter">(</span>const char* filename<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  ifstream tin<span class="Delimiter">(</span>filename<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>!tin<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    cerr &lt;&lt; <span class="Constant">&quot;no such file: &quot;</span> &lt;&lt; filename &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+    exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+  <span class="Delimiter">}</span>
+  Trace_stream = new trace_stream<span class="Delimiter">;</span>
+  while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>tin<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+    int depth<span class="Delimiter">;</span>
+    tin &gt;&gt; depth<span class="Delimiter">;</span>
+    string label<span class="Delimiter">;</span>
+    tin &gt;&gt; label<span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>*--label<span class="Delimiter">.</span>end<span class="Delimiter">()</span> == <span class="Constant">':'</span><span class="Delimiter">)</span> label<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>--label<span class="Delimiter">.</span>end<span class="Delimiter">());</span>
+    string line<span class="Delimiter">;</span>
+    getline<span class="Delimiter">(</span>tin<span class="Delimiter">,</span> line<span class="Delimiter">);</span>
+    Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>trace_line<span class="Delimiter">(</span>depth<span class="Delimiter">,</span> label<span class="Delimiter">,</span> line<span class="Delimiter">));</span>
+  <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
 </pre>
 </body>
 </html>
diff --git a/html/091run_interactive.cc.html b/html/091run_interactive.cc.html
index b96eeb50..94a1284a 100644
--- a/html/091run_interactive.cc.html
+++ b/html/091run_interactive.cc.html
@@ -15,6 +15,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .cSpecial { color: #008000; }
+.CommentedCode { color: #6c6c6c; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
@@ -45,7 +46,7 @@ recipe main [
 
 <span class="Delimiter">:(scenario run_interactive_empty)</span>
 recipe main [
-  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/<span class="Special">raw</span>
+  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>/unsafe
   <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>run-interactive <span class="Constant">1</span>:address:array:character
 ]
 <span class="Comment"># result is null</span>
@@ -140,6 +141,7 @@ bool run_interactive<span class="Delimiter">(</span>long long int address<span c
 <span class="Delimiter">}</span>
 
 void run_code_begin<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;loading new trace\n&quot;;</span>
   <span class="Comment">// stuff to undo later, in run_code_end()</span>
   Hide_warnings = <span class="Constant">true</span><span class="Delimiter">;</span>
   Hide_errors = <span class="Constant">true</span><span class="Delimiter">;</span>
@@ -152,6 +154,7 @@ void run_code_begin<span class="Delimiter">()</span> <span class="Delimiter">{</
 <span class="Delimiter">}</span>
 
 void run_code_end<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;back to old trace\n&quot;;</span>
   Hide_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
   Hide_errors = <span class="Constant">false</span><span class="Delimiter">;</span>
   Disable_redefine_warnings = <span class="Constant">false</span><span class="Delimiter">;</span>
@@ -160,6 +163,7 @@ void run_code_end<span class="Delimiter">()</span> <span class="Delimiter">{</sp
   Save_trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span>
   Trace_file = Save_trace_file<span class="Delimiter">;</span>
   Save_trace_file<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+  Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;interactive&quot;</span><span class="Delimiter">));</span>  <span class="Comment">// keep past sandboxes from inserting errors</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(before &quot;End Load Recipes&quot;)</span>
@@ -283,7 +287,7 @@ case _CLEANUP_RUN_INTERACTIVE: <span class="Delimiter">{</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-<span class="Delimiter">:(scenario &quot;run_interactive_returns_stringified_result&quot;)</span>
+<span class="Delimiter">:(scenario &quot;run_interactive_converts_result_to_text&quot;)</span>
 recipe main [
   <span class="Comment"># try to interactively add 2 and 2</span>
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new [add <span class="Constant">2</span><span class="Delimiter">,</span> <span class="Constant">2</span>]
@@ -293,13 +297,13 @@ recipe main [
 <span class="Comment"># first letter in the output should be '4' in unicode</span>
 <span class="traceContains">+mem: storing 52 in location 11</span>
 
-<span class="Delimiter">:(scenario &quot;run_interactive_returns_string&quot;)</span>
+<span class="Delimiter">:(scenario &quot;run_interactive_returns_text&quot;)</span>
 recipe main [
   <span class="Comment"># try to interactively add 2 and 2</span>
   <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new [
     x:address:array:character<span class="Special"> &lt;- </span>new [a]
     y:address:array:character<span class="Special"> &lt;- </span>new [b]
-    z:address:array:character<span class="Special"> &lt;- </span>string-append x:address:array:character<span class="Delimiter">,</span> y:address:array:character
+    z:address:array:character<span class="Special"> &lt;- </span>append x:address:array:character<span class="Delimiter">,</span> y:address:array:character
   ]
   <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>run-interactive <span class="Constant">1</span>:address:array:character
   <span class="Constant">10</span>:array:character<span class="Special"> &lt;- </span>copy <span class="Constant">2</span>:address:array:character/lookup
@@ -450,25 +454,45 @@ case RELOAD: <span class="Delimiter">{</span>
 <span class="Delimiter">}</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
 case RELOAD: <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;== reload\n&quot;;</span>
   <span class="Comment">// clear any containers in advance</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     Type_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>name<span class="Delimiter">);</span>
     Type<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
   <span class="Delimiter">}</span>
+  for <span class="Delimiter">(</span>map&lt;string<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt; &gt;::iterator p = Recipe_variants<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe_variants<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; p-&gt;first &lt;&lt; &quot;:\n&quot;;</span>
+    vector&lt;recipe_ordinal&gt;&amp; variants = p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">;</span>
+    for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+      if <span class="Delimiter">(</span>find<span class="Delimiter">(</span>recently_added_shape_shifting_recipes<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> recently_added_shape_shifting_recipes<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> != recently_added_shape_shifting_recipes<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?         cerr &lt;&lt; &quot;  &quot; &lt;&lt; variants.at(i) &lt;&lt; ' ' &lt;&lt; get(Recipe, variants.at(i)).name &lt;&lt; '\n';</span>
+        variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> = -<span class="Constant">1</span><span class="Delimiter">;</span>  <span class="Comment">// ghost</span>
+      <span class="Delimiter">}</span>
+    <span class="Delimiter">}</span>
+  <span class="Delimiter">}</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>recently_added_shape_shifting_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;erasing &quot; &lt;&lt; get(Recipe, recently_added_shape_shifting_recipes.at(i)).name &lt;&lt; '\n';</span>
+    Recipe_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> recently_added_shape_shifting_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>name<span class="Delimiter">);</span>
+    Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recently_added_shape_shifting_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+  <span class="Delimiter">}</span>
+  recently_added_shape_shifting_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
   string code = read_mu_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">));</span>
   run_code_begin<span class="Delimiter">();</span>
   routine* save_current_routine = Current_routine<span class="Delimiter">;</span>
   Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span>
   vector&lt;recipe_ordinal&gt; recipes_reloaded = load<span class="Delimiter">(</span>code<span class="Delimiter">);</span>
-  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>recipes_reloaded<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Comment">// clear a few things from previous runs</span>
+  <span class="Comment">// ad hoc list; we've probably missed a few</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>recipes_reloaded<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
     Name<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recipes_reloaded<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
-  <span class="Delimiter">}</span>
   transform_all<span class="Delimiter">();</span>
   Trace_stream<span class="Delimiter">-&gt;</span>newline<span class="Delimiter">();</span>  <span class="Comment">// flush trace</span>
   Current_routine = save_current_routine<span class="Delimiter">;</span>
   products<span class="Delimiter">.</span>resize<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
   products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>trace_error_warning_contents<span class="Delimiter">());</span>
   run_code_end<span class="Delimiter">();</span>  <span class="Comment">// wait until we're done with the trace contents</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;reload done\n&quot;;</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/092persist.cc.html b/html/092persist.cc.html
index cce4913f..c2056b8c 100644
--- a/html/092persist.cc.html
+++ b/html/092persist.cc.html
@@ -88,7 +88,7 @@ string slurp<span class="Delimiter">(</span>const string&amp; filename<span clas
   if <span class="Delimiter">(</span>!fin<span class="Delimiter">)</span> <span class="Identifier">return</span> result<span class="Delimiter">.</span>str<span class="Delimiter">();</span>  <span class="Comment">// don't bother checking errno</span>
   const int N = <span class="Constant">1024</span><span class="Delimiter">;</span>
   char buf[N]<span class="Delimiter">;</span>
-  while <span class="Delimiter">(</span>!fin<span class="Delimiter">.</span>eof<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+  while <span class="Delimiter">(</span>has_data<span class="Delimiter">(</span>fin<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     bzero<span class="Delimiter">(</span>buf<span class="Delimiter">,</span> N<span class="Delimiter">);</span>
     fin<span class="Delimiter">.</span>read<span class="Delimiter">(</span>buf<span class="Delimiter">,</span> N-<span class="Constant">1</span><span class="Delimiter">);</span>  <span class="Comment">// leave at least one null</span>
     result &lt;&lt; buf<span class="Delimiter">;</span>
diff --git a/html/998check_type_pointers.cc.html b/html/998check_type_pointers.cc.html
index 6532702e..308113a8 100644
--- a/html/998check_type_pointers.cc.html
+++ b/html/998check_type_pointers.cc.html
@@ -13,10 +13,8 @@
 pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 1.05em; }
-.cSpecial { color: #008000; }
-.Constant { color: #00a0a0; }
-.Delimiter { color: #a04060; }
-.Identifier { color: #804000; }
+.Comment { color: #9090ff; }
+.CommentedCode { color: #6c6c6c; }
 -->
 </style>
 
@@ -28,39 +26,42 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 </head>
 <body>
 <pre id='vimCodeElement'>
-<span class="Delimiter">:(before &quot;End Transform All&quot;)</span>
-check_type_pointers<span class="Delimiter">();</span>
-
-<span class="Delimiter">:(code)</span>
-void check_type_pointers<span class="Delimiter">()</span> <span class="Delimiter">{</span>
-  for <span class="Delimiter">(</span>map&lt;recipe_ordinal<span class="Delimiter">,</span> recipe&gt;::iterator p = Recipe<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Recipe<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>any_type_ingredient_in_header<span class="Delimiter">(</span>p<span class="Delimiter">-&gt;</span>first<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
-    const recipe&amp; r = p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">;</span>
-    for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>r<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-      const instruction&amp; inst = r<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
-      for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-        if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-          raise_error &lt;&lt; maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' -- &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot; has no type</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
-          <span class="Identifier">return</span><span class="Delimiter">;</span>
-        <span class="Delimiter">}</span>
-        if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-          raise_error &lt;&lt; maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' -- &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot; has no type name</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
-          <span class="Identifier">return</span><span class="Delimiter">;</span>
-        <span class="Delimiter">}</span>
-      <span class="Delimiter">}</span>
-      for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-        if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-          raise_error &lt;&lt; maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' -- &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot; has no type</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
-          <span class="Identifier">return</span><span class="Delimiter">;</span>
-        <span class="Delimiter">}</span>
-        if <span class="Delimiter">(</span>!inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-          raise_error &lt;&lt; maybe<span class="Delimiter">(</span>r<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot; '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' -- &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot; has no type name</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
-          <span class="Identifier">return</span><span class="Delimiter">;</span>
-        <span class="Delimiter">}</span>
-      <span class="Delimiter">}</span>
-    <span class="Delimiter">}</span>
-  <span class="Delimiter">}</span>
-<span class="Delimiter">}</span>
+<span class="Comment">//: enable this when tracking down null types</span>
+<span class="Comment">//: (but it interferes with edit/; since recipes created in the environment</span>
+<span class="Comment">//: can raise warnings here which will stop running the entire environment)</span>
+<span class="CommentedCode">//? :(before &quot;End Transform All&quot;)</span>
+<span class="CommentedCode">//? check_type_pointers();</span>
+<span class="CommentedCode">//? </span>
+<span class="CommentedCode">//? :(code)</span>
+<span class="CommentedCode">//? void check_type_pointers() {</span>
+<span class="CommentedCode">//?   for (map&lt;recipe_ordinal, recipe&gt;::iterator p = Recipe.begin(); p != Recipe.end(); ++p) {</span>
+<span class="CommentedCode">//?     if (any_type_ingredient_in_header(p-&gt;first)) continue;</span>
+<span class="CommentedCode">//?     const recipe&amp; r = p-&gt;second;</span>
+<span class="CommentedCode">//?     for (long long int i = 0; i &lt; SIZE(r.steps); ++i) {</span>
+<span class="CommentedCode">//?       const instruction&amp; inst = r.steps.at(i);</span>
+<span class="CommentedCode">//?       for (long long int j = 0; j &lt; SIZE(inst.ingredients); ++j) {</span>
+<span class="CommentedCode">//?         if (!inst.ingredients.at(j).type) {</span>
+<span class="CommentedCode">//?           raise_error &lt;&lt; maybe(r.name) &lt;&lt; &quot; '&quot; &lt;&lt; inst.to_string() &lt;&lt; &quot;' -- &quot; &lt;&lt; inst.ingredients.at(j).to_string() &lt;&lt; &quot; has no type\n&quot; &lt;&lt; end();</span>
+<span class="CommentedCode">//?           return;</span>
+<span class="CommentedCode">//?         }</span>
+<span class="CommentedCode">//?         if (!inst.ingredients.at(j).properties.at(0).second) {</span>
+<span class="CommentedCode">//?           raise_error &lt;&lt; maybe(r.name) &lt;&lt; &quot; '&quot; &lt;&lt; inst.to_string() &lt;&lt; &quot;' -- &quot; &lt;&lt; inst.ingredients.at(j).to_string() &lt;&lt; &quot; has no type name\n&quot; &lt;&lt; end();</span>
+<span class="CommentedCode">//?           return;</span>
+<span class="CommentedCode">//?         }</span>
+<span class="CommentedCode">//?       }</span>
+<span class="CommentedCode">//?       for (long long int j = 0; j &lt; SIZE(inst.products); ++j) {</span>
+<span class="CommentedCode">//?         if (!inst.products.at(j).type) {</span>
+<span class="CommentedCode">//?           raise_error &lt;&lt; maybe(r.name) &lt;&lt; &quot; '&quot; &lt;&lt; inst.to_string() &lt;&lt; &quot;' -- &quot; &lt;&lt; inst.products.at(j).to_string() &lt;&lt; &quot; has no type\n&quot; &lt;&lt; end();</span>
+<span class="CommentedCode">//?           return;</span>
+<span class="CommentedCode">//?         }</span>
+<span class="CommentedCode">//?         if (!inst.products.at(j).properties.at(0).second) {</span>
+<span class="CommentedCode">//?           raise_error &lt;&lt; maybe(r.name) &lt;&lt; &quot; '&quot; &lt;&lt; inst.to_string() &lt;&lt; &quot;' -- &quot; &lt;&lt; inst.products.at(j).to_string() &lt;&lt; &quot; has no type name\n&quot; &lt;&lt; end();</span>
+<span class="CommentedCode">//?           return;</span>
+<span class="CommentedCode">//?         }</span>
+<span class="CommentedCode">//?       }</span>
+<span class="CommentedCode">//?     }</span>
+<span class="CommentedCode">//?   }</span>
+<span class="CommentedCode">//? }</span>
 </pre>
 </body>
 </html>
diff --git a/html/999spaces.cc.html b/html/999spaces.cc.html
index dac58e9d..531efb53 100644
--- a/html/999spaces.cc.html
+++ b/html/999spaces.cc.html
@@ -61,6 +61,57 @@ assert<span class="Delimiter">(</span>Next_recipe_ordinal == <span class="Consta
 assert<span class="Delimiter">(</span>Initial_callstack_depth == <span class="Constant">101</span><span class="Delimiter">);</span>
 assert<span class="Delimiter">(</span>Max_callstack_depth == <span class="Constant">9989</span><span class="Delimiter">);</span>
 <span class="Comment">//: 9990-9999 - intra-instruction lines (mostly label mem)</span>
+
+<span class="SalientComment">//:: Summary of transforms and their dependencies</span>
+<span class="Comment">//: begin transforms</span>
+<span class="Comment">//:   begin instruction inserting transforms</span>
+<span class="Comment">//:     52 insert fragments</span>
+<span class="Comment">//:      ↳ 52.2 check fragments</span>
+<span class="Comment">//:   ---</span>
+<span class="Comment">//:     53 rewrite 'stash' instructions</span>
+<span class="Comment">//:   end instruction inserting transforms</span>
+<span class="Comment">//:</span>
+<span class="Comment">//:   begin instruction modifying transforms</span>
+<span class="Comment">//:     56.2 check header ingredients</span>
+<span class="Comment">//:      ↳ 56.4 fill in reply ingredients</span>
+<span class="Comment">//:</span>
+<span class="Comment">//:     begin type modifying transforms</span>
+<span class="Comment">//:       56.3 deduce types from header</span>
+<span class="Comment">//:       48 check or set types by name</span>
+<span class="Comment">//:     ---</span>
+<span class="Comment">//:       30 check or set invalid containers</span>
+<span class="Comment">//:     end type modifying transforms</span>
+<span class="Comment">//:      ↳ 57 static dispatch</span>
+<span class="Comment">//:   ---</span>
+<span class="Comment">//:     13 update instruction operation</span>
+<span class="Comment">//:     40 transform braces</span>
+<span class="Comment">//:     41 transform labels</span>
+<span class="Comment">//:</span>
+<span class="Comment">//:      ↱ 46 collect surrounding spaces</span>
+<span class="Comment">//:     42 transform names</span>
+<span class="Comment">//:   end instruction modifying transforms</span>
+<span class="Comment">//:</span>
+<span class="Comment">//:   begin checks</span>
+<span class="Comment">//:   ---</span>
+<span class="Comment">//:     21 check instruction</span>
+<span class="Comment">//:     ↳ 43 transform 'new' to 'allocate'</span>
+<span class="Comment">//:</span>
+<span class="Comment">//:     56 check reply instructions against header</span>
+<span class="Comment">//:   end checks</span>
+<span class="Comment">//: end transforms</span>
+
+<span class="SalientComment">//:: Summary of type-checking in different phases</span>
+<span class="Comment">//: when dispatching instructions we accept first recipe that:</span>
+<span class="Comment">//:   strictly matches all types</span>
+<span class="Comment">//:   maps literal 0 or literal 1 to boolean for some ingredients</span>
+<span class="Comment">//:   performs some other acceptable type conversion</span>
+<span class="Comment">//:     literal 0 -&gt; address</span>
+<span class="Comment">//:     literal -&gt; character</span>
+<span class="Comment">//: when checking instructions we ensure that types match, and that literals map to some scalar</span>
+<span class="Comment">//:   (address can only map to literal 0)</span>
+<span class="Comment">//:   (boolean can only map to literal 0 or literal 1)</span>
+<span class="Comment">//:     (but conditionals can take any scalar)</span>
+<span class="Comment">//: at runtime we perform no checks</span>
 </pre>
 </body>
 </html>
diff --git a/html/channel.mu.html b/html/channel.mu.html
index 12babbde..15a75d1f 100644
--- a/html/channel.mu.html
+++ b/html/channel.mu.html
@@ -32,10 +32,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <pre id='vimCodeElement'>
 <span class="Comment"># example program: communicating between routines using channels</span>
 
-<span class="muRecipe">recipe</span> producer [
+<span class="muRecipe">recipe</span> producer chan:address:channel<span class="muRecipe"> -&gt; </span>chan:address:channel [
   <span class="Comment"># produce characters 1 to 5 on a channel</span>
   <span class="Constant">local-scope</span>
-  chan:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># n = 0</span>
   n:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   <span class="Delimiter">{</span>
@@ -50,10 +50,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">}</span>
 ]
 
-<span class="muRecipe">recipe</span> consumer [
+<span class="muRecipe">recipe</span> consumer chan:address:channel<span class="muRecipe"> -&gt; </span>chan:address:channel [
   <span class="Comment"># consume and print integers from a channel</span>
   <span class="Constant">local-scope</span>
-  chan:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     <span class="Comment"># read an integer from the channel</span>
     n:character, chan:address:channel<span class="Special"> &lt;- </span>read chan
diff --git a/html/chessboard.mu.html b/html/chessboard.mu.html
index 5e11ad01..338e92dc 100644
--- a/html/chessboard.mu.html
+++ b/html/chessboard.mu.html
@@ -15,14 +15,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 1.05em; }
 .muControl { color: #c0a020; }
 .muRecipe { color: #ff8700; }
-.SalientComment { color: #00ffff; }
+.muScenario { color: #00af00; }
 .muData { color: #ffff00; }
+.Special { color: #ff6060; }
 .Comment { color: #9090ff; }
 .Constant { color: #00a0a0; }
-.Special { color: #ff6060; }
+.SalientComment { color: #00ffff; }
 .CommentedCode { color: #6c6c6c; }
 .Delimiter { color: #a04060; }
-.muScenario { color: #00af00; }
 -->
 </style>
 
@@ -53,7 +53,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Comment">#</span>
   <span class="Comment"># Here the console and screen are both 0, which usually indicates real</span>
   <span class="Comment"># hardware rather than a fake for testing as you'll see below.</span>
-  <span class="Constant">0/screen</span>, <span class="Constant">0/console</span><span class="Special"> &lt;- </span>chessboard <span class="Constant">0/screen</span>, <span class="Constant">0/console</span>
+  chessboard <span class="Constant">0/screen</span>, <span class="Constant">0/console</span>
 
   close-console  <span class="Comment"># cleanup screen, keyboard and mouse</span>
 ]
@@ -72,7 +72,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   run [
     screen:address:screen, console:address:console<span class="Special"> &lt;- </span>chessboard screen:address:screen, console:address:console
     <span class="Comment"># icon for the cursor</span>
-    screen<span class="Special"> &lt;- </span>print-character screen, <span class="Constant">9251/␣</span>
+    screen<span class="Special"> &lt;- </span>print screen, <span class="Constant">9251/␣</span>
   ]
   screen-should-contain [
   <span class="Comment">#            1         2         3         4         5         6         7         8         9         10        11</span>
@@ -102,10 +102,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="SalientComment">## Here's how 'chessboard' is implemented.</span>
 
-<span class="muRecipe">recipe</span> chessboard [
+<span class="muRecipe">recipe</span> chessboard screen:address:screen, console:address:console<span class="muRecipe"> -&gt; </span>screen:address:screen, console:address:console [
   <span class="Constant">local-scope</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  console:address:console<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   board:address:array:address:array:character<span class="Special"> &lt;- </span>initial-position
   <span class="Comment"># hook up stdin</span>
   stdin:address:channel<span class="Special"> &lt;- </span>new-channel <span class="Constant">10/capacity</span>
@@ -116,28 +115,28 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">{</span>
     msg:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[Stupid text-mode chessboard. White pieces in uppercase; black pieces in lowercase. No checking for legal moves.</span>
 <span class="Constant">]</span>
-    print-string screen, msg
+    print screen, msg
     cursor-to-next-line screen
     print-board screen, board
     cursor-to-next-line screen
     msg<span class="Special"> &lt;- </span>new <span class="Constant">[Type in your move as &lt;from square&gt;-&lt;to square&gt;. For example: 'a2-a4'. Then press &lt;enter&gt;.</span>
 <span class="Constant">]</span>
-    print-string screen, msg
+    print screen, msg
     cursor-to-next-line screen
     msg<span class="Special"> &lt;- </span>new <span class="Constant">[Hit 'q' to exit.</span>
 <span class="Constant">]</span>
-    print-string screen, msg
+    print screen, msg
     <span class="Delimiter">{</span>
       cursor-to-next-line screen
       msg<span class="Special"> &lt;- </span>new <span class="Constant">[move: ]</span>
-      print-string screen, msg
+      screen<span class="Special"> &lt;- </span>print screen, msg
       m:address:move, quit:boolean, error:boolean<span class="Special"> &lt;- </span>read-move buffered-stdin, screen
       <span class="muControl">break-if</span> quit, <span class="Constant">+quit:label</span>
       buffered-stdin<span class="Special"> &lt;- </span>clear-channel buffered-stdin  <span class="Comment"># cleanup after error. todo: test this?</span>
       <span class="muControl">loop-if</span> error
     <span class="Delimiter">}</span>
     board<span class="Special"> &lt;- </span>make-move board, m
-    clear-screen screen
+    screen<span class="Special"> &lt;- </span>clear-screen screen
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
 <span class="Constant">  +quit</span>
@@ -145,15 +144,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="SalientComment">## a board is an array of files, a file is an array of characters (squares)</span>
 
-<span class="muRecipe">recipe</span> new-board [
+<span class="muRecipe">recipe</span> new-board initial-position:address:array:character<span class="muRecipe"> -&gt; </span>board:address:array:address:array:character [
   <span class="Constant">local-scope</span>
-  initial-position:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   <span class="Comment"># assert(length(initial-position) == 64)</span>
   len:number<span class="Special"> &lt;- </span>length *initial-position
   correct-length?:boolean<span class="Special"> &lt;- </span>equal len, <span class="Constant">64</span>
   assert correct-length?, <span class="Constant">[chessboard had incorrect size]</span>
   <span class="Comment"># board is an array of pointers to files; file is an array of characters</span>
-  board:address:array:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, <span class="Constant">8</span>
+  board<span class="Special"> &lt;- </span>new <span class="Constant">location:type</span>, <span class="Constant">8</span>
   col:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   <span class="Delimiter">{</span>
     done?:boolean<span class="Special"> &lt;- </span>equal col, <span class="Constant">8</span>
@@ -163,15 +162,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     col<span class="Special"> &lt;- </span>add col, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> board
 ]
 
-<span class="muRecipe">recipe</span> new-file [
+<span class="muRecipe">recipe</span> new-file position:address:array:character, index:number<span class="muRecipe"> -&gt; </span>result:address:array:character [
   <span class="Constant">local-scope</span>
-  position:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  index:number<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   index<span class="Special"> &lt;- </span>multiply index, <span class="Constant">8</span>
-  result:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, <span class="Constant">8</span>
+  result<span class="Special"> &lt;- </span>new <span class="Constant">character:type</span>, <span class="Constant">8</span>
   row:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   <span class="Delimiter">{</span>
     done?:boolean<span class="Special"> &lt;- </span>equal row, <span class="Constant">8</span>
@@ -182,13 +179,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     index<span class="Special"> &lt;- </span>add index, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  <span class="muControl">reply</span> result
 ]
 
-<span class="muRecipe">recipe</span> print-board [
+<span class="muRecipe">recipe</span> print-board screen:address:screen, board:address:array:address:array:character<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  board:address:array:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   row:number<span class="Special"> &lt;- </span>copy <span class="Constant">7</span>  <span class="Comment"># start printing from the top of the board</span>
   <span class="Comment"># print each row</span>
   <span class="Delimiter">{</span>
@@ -198,7 +193,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     rank:number<span class="Special"> &lt;- </span>add row, <span class="Constant">1</span>
     print-integer screen, rank
     s:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[ | ]</span>
-    print-string screen, s
+    print screen, s
     <span class="Comment"># print each square in the row</span>
     col:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
     <span class="Delimiter">{</span>
@@ -206,8 +201,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       <span class="muControl">break-if</span> done?:boolean
       f:address:array:character<span class="Special"> &lt;- </span>index *board, col
       c:character<span class="Special"> &lt;- </span>index *f, row
-      print-character screen, c
-      print-character screen, <span class="Constant">32/space</span>
+      print screen, c
+      print screen, <span class="Constant">32/space</span>
       col<span class="Special"> &lt;- </span>add col, <span class="Constant">1</span>
       <span class="muControl">loop</span>
     <span class="Delimiter">}</span>
@@ -217,15 +212,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">}</span>
   <span class="Comment"># print file letters as legend</span>
   s<span class="Special"> &lt;- </span>new <span class="Constant">[  +----------------]</span>
-  print-string screen, s
+  print screen, s
   screen<span class="Special"> &lt;- </span>cursor-to-next-line screen
   s<span class="Special"> &lt;- </span>new <span class="Constant">[    a b c d e f g h]</span>
-  screen<span class="Special"> &lt;- </span>print-string screen, s
+  screen<span class="Special"> &lt;- </span>print screen, s
   screen<span class="Special"> &lt;- </span>cursor-to-next-line screen
 ]
 
-<span class="Comment"># board:address:array:address:array:character &lt;- initial-position</span>
-<span class="muRecipe">recipe</span> initial-position [
+<span class="muRecipe">recipe</span> initial-position<span class="muRecipe"> -&gt; </span>board:address:array:address:array:character [
   <span class="Constant">local-scope</span>
   <span class="Comment"># layout in memory (in raster order):</span>
   <span class="Comment">#   R P _ _ _ _ p r</span>
@@ -245,8 +239,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="CommentedCode">#?       66/B, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 98/b,</span>
 <span class="CommentedCode">#?       78/N, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 110/n,</span>
 <span class="CommentedCode">#?       82/R, 80/P, 32/blank, 32/blank, 32/blank, 32/blank, 112/p, 114/r</span>
-  board:address:array:address:array:character<span class="Special"> &lt;- </span>new-board initial-position
-  <span class="muControl">reply</span> board
+  board<span class="Special"> &lt;- </span>new-board initial-position
 ]
 
 <span class="muScenario">scenario</span> printing-the-board [
@@ -282,12 +275,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   to-rank:number
 ]
 
-<span class="Comment"># result:address:move, quit?:boolean, error?:boolean &lt;- read-move stdin:address:channel, screen:address:screen</span>
 <span class="Comment"># prints only error messages to screen</span>
-<span class="muRecipe">recipe</span> read-move [
+<span class="muRecipe">recipe</span> read-move stdin:address:channel, screen:address:screen<span class="muRecipe"> -&gt; </span>result:address:move, quit?:boolean, error?:boolean [
   <span class="Constant">local-scope</span>
-  stdin:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   from-file:number, quit?:boolean, error?:boolean<span class="Special"> &lt;- </span>read-file stdin, screen
   <span class="muControl">reply-if</span> quit?, <span class="Constant">0/dummy</span>, quit?, error?
   <span class="muControl">reply-if</span> error?, <span class="Constant">0/dummy</span>, quit?, error?
@@ -314,12 +305,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply</span> result, quit?, error?
 ]
 
-<span class="Comment"># file:number, quit:boolean, error:boolean &lt;- read-file stdin:address:channel, screen:address:screen</span>
 <span class="Comment"># valid values for file: 0-7</span>
-<span class="muRecipe">recipe</span> read-file [
+<span class="muRecipe">recipe</span> read-file stdin:address:channel, screen:address:screen<span class="muRecipe"> -&gt; </span>file:number, quit:boolean, error:boolean [
   <span class="Constant">local-scope</span>
-  stdin:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   c:character, stdin<span class="Special"> &lt;- </span>read stdin
   <span class="Delimiter">{</span>
     q-pressed?:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">81/Q</span>
@@ -340,7 +329,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     newline?:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">10/newline</span>
     <span class="muControl">break-unless</span> newline?
     error-message:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[that's not enough]</span>
-    print-string screen, error-message
+    print screen, error-message
     <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span>
   <span class="Delimiter">}</span>
   file:number<span class="Special"> &lt;- </span>subtract c, <span class="Constant">97/a</span>
@@ -349,8 +338,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     above-min:boolean<span class="Special"> &lt;- </span>greater-or-equal file, <span class="Constant">0</span>
     <span class="muControl">break-if</span> above-min
     error-message:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[file too low: ]</span>
-    print-string screen, error-message
-    print-character screen, c
+    print screen, error-message
+    print screen, c
     cursor-to-next-line screen
     <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span>
   <span class="Delimiter">}</span>
@@ -358,19 +347,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     below-max:boolean<span class="Special"> &lt;- </span>lesser-than file, <span class="Constant">8</span>
     <span class="muControl">break-if</span> below-max
     error-message<span class="Special"> &lt;- </span>new <span class="Constant">[file too high: ]</span>
-    print-string screen, error-message
-    print-character screen, c
+    print screen, error-message
+    print screen, c
     <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span>
   <span class="Delimiter">}</span>
   <span class="muControl">reply</span> file, <span class="Constant">0/quit</span>, <span class="Constant">0/error</span>
 ]
 
-<span class="Comment"># rank:number &lt;- read-rank stdin:address:channel, screen:address:screen</span>
 <span class="Comment"># valid values: 0-7, -1 (quit), -2 (error)</span>
-<span class="muRecipe">recipe</span> read-rank [
+<span class="muRecipe">recipe</span> read-rank stdin:address:channel, screen:address:screen<span class="muRecipe"> -&gt; </span>rank:number, quit?:boolean, error?:boolean, stdin:address:channel, screen:address:screen [
   <span class="Constant">local-scope</span>
-  stdin:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   c:character, stdin<span class="Special"> &lt;- </span>read stdin
   <span class="Delimiter">{</span>
     q-pressed?:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">8/Q</span>
@@ -386,7 +373,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     newline?:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">10</span>  <span class="Comment"># newline</span>
     <span class="muControl">break-unless</span> newline?
     error-message:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[that's not enough]</span>
-    print-string screen, error-message
+    print screen, error-message
     <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span>
   <span class="Delimiter">}</span>
   rank:number<span class="Special"> &lt;- </span>subtract c, <span class="Constant">49/'1'</span>
@@ -395,16 +382,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     above-min:boolean<span class="Special"> &lt;- </span>greater-or-equal rank, <span class="Constant">0</span>
     <span class="muControl">break-if</span> above-min
     error-message<span class="Special"> &lt;- </span>new <span class="Constant">[rank too low: ]</span>
-    print-string screen, error-message
-    print-character screen, c
+    print screen, error-message
+    print screen, c
     <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span>
   <span class="Delimiter">}</span>
   <span class="Delimiter">{</span>
     below-max:boolean<span class="Special"> &lt;- </span>lesser-or-equal rank, <span class="Constant">7</span>
     <span class="muControl">break-if</span> below-max
     error-message<span class="Special"> &lt;- </span>new <span class="Constant">[rank too high: ]</span>
-    print-string screen, error-message
-    print-character screen, c
+    print screen, error-message
+    print screen, c
     <span class="muControl">reply</span> <span class="Constant">0/dummy</span>, <span class="Constant">0/quit</span>, <span class="Constant">1/error</span>
   <span class="Delimiter">}</span>
   <span class="muControl">reply</span> rank, <span class="Constant">0/quit</span>, <span class="Constant">0/error</span>
@@ -412,20 +399,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="Comment"># read a character from the given channel and check that it's what we expect</span>
 <span class="Comment"># return true on error</span>
-<span class="muRecipe">recipe</span> expect-from-channel [
+<span class="muRecipe">recipe</span> expect-from-channel stdin:address:channel, expected:character, screen:address:screen<span class="muRecipe"> -&gt; </span>result:boolean [
   <span class="Constant">local-scope</span>
-  stdin:address:channel<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  expected:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  screen:address:screen<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   c:character, stdin<span class="Special"> &lt;- </span>read stdin
   <span class="Delimiter">{</span>
     match?:boolean<span class="Special"> &lt;- </span>equal c, expected
     <span class="muControl">break-if</span> match?
     s:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[expected character not found]</span>
-    print-string screen, s
+    print screen, s
   <span class="Delimiter">}</span>
-  result:boolean<span class="Special"> &lt;- </span>not match?
-  <span class="muControl">reply</span> result
+  result<span class="Special"> &lt;- </span>not match?
 ]
 
 <span class="muScenario">scenario</span> read-move-blocking [
@@ -592,21 +576,19 @@ F read-move-file: routine failed to pause <span class="muRecipe">after</span> co
   ]
 ]
 
-<span class="muRecipe">recipe</span> make-move [
+<span class="muRecipe">recipe</span> make-move board:address:array:address:array:character, m:address:move<span class="muRecipe"> -&gt; </span>board:address:array:address:array:character [
   <span class="Constant">local-scope</span>
-  b:address:array:address:array:character<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
-  m:address:move<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
+  <span class="Constant">load-ingredients</span>
   from-file:number<span class="Special"> &lt;- </span>get *m, <span class="Constant">from-file:offset</span>
   from-rank:number<span class="Special"> &lt;- </span>get *m, <span class="Constant">from-rank:offset</span>
   to-file:number<span class="Special"> &lt;- </span>get *m, <span class="Constant">to-file:offset</span>
   to-rank:number<span class="Special"> &lt;- </span>get *m, <span class="Constant">to-rank:offset</span>
-  f:address:array:character<span class="Special"> &lt;- </span>index *b, from-file
+  f:address:array:character<span class="Special"> &lt;- </span>index *board, from-file
   src:address:character/square<span class="Special"> &lt;- </span>index-address *f, from-rank
-  f<span class="Special"> &lt;- </span>index *b, to-file
+  f<span class="Special"> &lt;- </span>index *board, to-file
   dest:address:character/square<span class="Special"> &lt;- </span>index-address *f, to-rank
   *dest<span class="Special"> &lt;- </span>copy *src
   *src<span class="Special"> &lt;- </span>copy <span class="Constant">32/space</span>
-  <span class="muControl">reply</span> b/same-as-ingredient:<span class="Constant">0</span>
 ]
 
 <span class="muScenario">scenario</span> making-a-move [
diff --git a/html/edit/001-editor.mu.html b/html/edit/001-editor.mu.html
index cf10dc6c..59982193 100644
--- a/html/edit/001-editor.mu.html
+++ b/html/edit/001-editor.mu.html
@@ -35,7 +35,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <pre id='vimCodeElement'>
 <span class="SalientComment">## the basic editor data structure, and how it displays text to the screen</span>
 
-<span class="Comment"># temporary main for this layer: just render the given string at the given</span>
+<span class="Comment"># temporary main for this layer: just render the given text at the given</span>
 <span class="Comment"># screen dimensions, then stop</span>
 <span class="muRecipe">recipe!</span> main text:address:array:character [
   <span class="Constant">local-scope</span>
@@ -48,7 +48,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   close-console
 ]
 
-<span class="muScenario">scenario</span> editor-initially-prints-string-to-screen [
+<span class="muScenario">scenario</span> editor-initially-prints-text-to-screen [
   assume-screen <span class="Constant">10/width</span>, <span class="Constant">5/height</span>
   run [
     <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
@@ -82,7 +82,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="Comment"># creates a new editor widget and renders its initial appearance to screen</span>
 <span class="Comment">#   top/left/right constrain the screen area available to the new editor</span>
 <span class="Comment">#   right is exclusive</span>
-<span class="muRecipe">recipe</span> new-editor s:address:array:character, screen:address:screen, left:number, right:number<span class="muRecipe"> -&gt; </span>result:address:editor-data [
+<span class="muRecipe">recipe</span> new-editor s:address:array:character, screen:address:screen, left:number, right:number<span class="muRecipe"> -&gt; </span>result:address:editor-data, screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="Comment"># no clipping of bounds</span>
@@ -228,14 +228,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       at-right?:boolean<span class="Special"> &lt;- </span>equal column, right
       <span class="muControl">break-unless</span> at-right?
       <span class="Comment"># print wrap icon</span>
-      print-character screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span>
+      print screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span>
       column<span class="Special"> &lt;- </span>copy left
       row<span class="Special"> &lt;- </span>add row, <span class="Constant">1</span>
       screen<span class="Special"> &lt;- </span>move-cursor screen, row, column
       <span class="Comment"># don't increment curr</span>
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
-    print-character screen, c, color
+    print screen, c, color
     curr<span class="Special"> &lt;- </span>next curr
     prev<span class="Special"> &lt;- </span>next prev
     column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
@@ -259,13 +259,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply</span> row, column, screen/same-as-ingredient:<span class="Constant">0</span>, editor/same-as-ingredient:<span class="Constant">1</span>
 ]
 
-<span class="muRecipe">recipe</span> clear-line-delimited screen:address:screen, column:number, right:number [
+<span class="muRecipe">recipe</span> clear-line-delimited screen:address:screen, column:number, right:number<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
     done?:boolean<span class="Special"> &lt;- </span>greater-than column, right
     <span class="muControl">break-if</span> done?
-    print-character screen, <span class="Constant">32/space</span>
+    screen<span class="Special"> &lt;- </span>print screen, <span class="Constant">32/space</span>
     column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
diff --git a/html/edit/002-typing.mu.html b/html/edit/002-typing.mu.html
index 538bbf5d..efed71b6 100644
--- a/html/edit/002-typing.mu.html
+++ b/html/edit/002-typing.mu.html
@@ -259,7 +259,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     overflow?:boolean<span class="Special"> &lt;- </span>and at-bottom?, at-right?
     <span class="muControl">break-if</span> overflow?
     move-cursor screen, save-row, save-column
-    print-character screen, c
+    print screen, c
     go-render?<span class="Special"> &lt;- </span>copy <span class="Constant">0/false</span>
     <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
@@ -281,7 +281,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       currc:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">value:offset</span>
       at-newline?:boolean<span class="Special"> &lt;- </span>equal currc, <span class="Constant">10/newline</span>
       <span class="muControl">break-if</span> at-newline?
-      print-character screen, currc
+      print screen, currc
       curr-column<span class="Special"> &lt;- </span>add curr-column, <span class="Constant">1</span>
       curr<span class="Special"> &lt;- </span>next curr
       <span class="muControl">loop</span>
@@ -1070,7 +1070,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">{</span>
     continue?:boolean<span class="Special"> &lt;- </span>lesser-or-equal x, right  <span class="Comment"># right is inclusive, to match editor-data semantics</span>
     <span class="muControl">break-unless</span> continue?
-    print-character screen, style, color, bg-color
+    print screen, style, color, bg-color
     x<span class="Special"> &lt;- </span>add x, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
diff --git a/html/edit/003-shortcuts.mu.html b/html/edit/003-shortcuts.mu.html
index aabe23e0..5518a680 100644
--- a/html/edit/003-shortcuts.mu.html
+++ b/html/edit/003-shortcuts.mu.html
@@ -152,13 +152,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     currc:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">value:offset</span>
     at-newline?:boolean<span class="Special"> &lt;- </span>equal currc, <span class="Constant">10/newline</span>
     <span class="muControl">break-if</span> at-newline?
-    screen<span class="Special"> &lt;- </span>print-character screen, currc
+    screen<span class="Special"> &lt;- </span>print screen, currc
     curr-column<span class="Special"> &lt;- </span>add curr-column, <span class="Constant">1</span>
     curr<span class="Special"> &lt;- </span>next curr
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># we're guaranteed not to be at the right margin</span>
-  screen<span class="Special"> &lt;- </span>print-character screen, <span class="Constant">32/space</span>
+  screen<span class="Special"> &lt;- </span>print screen, <span class="Constant">32/space</span>
   go-render?<span class="Special"> &lt;- </span>copy <span class="Constant">0/false</span>
 ]
 
@@ -392,13 +392,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     currc:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">value:offset</span>
     at-newline?:boolean<span class="Special"> &lt;- </span>equal currc, <span class="Constant">10/newline</span>
     <span class="muControl">break-if</span> at-newline?
-    screen<span class="Special"> &lt;- </span>print-character screen, currc
+    screen<span class="Special"> &lt;- </span>print screen, currc
     curr-column<span class="Special"> &lt;- </span>add curr-column, <span class="Constant">1</span>
     curr<span class="Special"> &lt;- </span>next curr
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># we're guaranteed not to be at the right margin</span>
-  screen<span class="Special"> &lt;- </span>print-character screen, <span class="Constant">32/space</span>
+  screen<span class="Special"> &lt;- </span>print screen, <span class="Constant">32/space</span>
   go-render?<span class="Special"> &lt;- </span>copy <span class="Constant">0/false</span>
 ]
 
diff --git a/html/edit/004-programming-environment.mu.html b/html/edit/004-programming-environment.mu.html
index 172b1dcc..a2001520 100644
--- a/html/edit/004-programming-environment.mu.html
+++ b/html/edit/004-programming-environment.mu.html
@@ -20,7 +20,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .Comment { color: #9090ff; }
 .Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
-.CommentedCode { color: #6c6c6c; }
 .Delimiter { color: #a04060; }
 .muScenario { color: #00af00; }
 -->
@@ -70,7 +69,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   assert button-on-screen?, <span class="Constant">[screen too narrow for menu]</span>
   screen<span class="Special"> &lt;- </span>move-cursor screen, <span class="Constant">0/row</span>, button-start
   run-button:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[ run (F4) ]</span>
-  print-string screen, run-button, <span class="Constant">255/white</span>, <span class="Constant">161/reddish</span>
+  print screen, run-button, <span class="Constant">255/white</span>, <span class="Constant">161/reddish</span>
   <span class="Comment"># dotted line down the middle</span>
   divider:number, _<span class="Special"> &lt;- </span>divide-with-remainder width, <span class="Constant">2</span>
   draw-vertical screen, divider, <span class="Constant">1/top</span>, height, <span class="Constant">9482/vertical-dotted</span>
@@ -303,7 +302,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
   <span class="Comment"># show the cursor at the right window</span>
   run [
-    print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
+    print screen:address:screen, <span class="Constant">9251/␣/cursor</span>
   ]
   screen-should-contain [
    <span class="Constant"> .           run (F4)           .</span>
@@ -343,7 +342,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   assume-console <span class="Constant">[]</span>
   run [
     event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
-    print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
+    print screen:address:screen, <span class="Constant">9251/␣/cursor</span>
   ]
   <span class="Comment"># is cursor at the right place?</span>
   screen-should-contain [
@@ -358,7 +357,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
   run [
     event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
-    print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
+    print screen:address:screen, <span class="Constant">9251/␣/cursor</span>
   ]
   <span class="Comment"># cursor should still be right</span>
   screen-should-contain [
@@ -392,7 +391,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
   run [
     event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
-    print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
+    print screen:address:screen, <span class="Constant">9251/␣/cursor</span>
   ]
   <span class="Comment"># cursor moves to end of old line</span>
   screen-should-contain [
@@ -417,7 +416,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   assert button-on-screen?, <span class="Constant">[screen too narrow for menu]</span>
   screen<span class="Special"> &lt;- </span>move-cursor screen, <span class="Constant">0/row</span>, button-start
   run-button:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[ run (F4) ]</span>
-  print-string screen, run-button, <span class="Constant">255/white</span>, <span class="Constant">161/reddish</span>
+  print screen, run-button, <span class="Constant">255/white</span>, <span class="Constant">161/reddish</span>
   <span class="Comment"># dotted line down the middle</span>
   trace <span class="Constant">11</span>, <span class="Constant">[app]</span>, <span class="Constant">[render divider]</span>
   divider:number, _<span class="Special"> &lt;- </span>divide-with-remainder width, <span class="Constant">2</span>
@@ -486,9 +485,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   screen<span class="Special"> &lt;- </span>move-cursor screen, cursor-row, cursor-column
 ]
 
-<span class="Comment"># print a string 's' to 'editor' in 'color' starting at 'row'</span>
+<span class="Comment"># print a text 's' to 'editor' in 'color' starting at 'row'</span>
 <span class="Comment"># clear rest of last line, move cursor to next line</span>
-<span class="muRecipe">recipe</span> render-string screen:address:screen, s:address:array:character, left:number, right:number, color:number, row:number<span class="muRecipe"> -&gt; </span>row:number, screen:address:screen [
+<span class="muRecipe">recipe</span> render screen:address:screen, s:address:array:character, left:number, right:number, color:number, row:number<span class="muRecipe"> -&gt; </span>row:number, screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="muControl">reply-unless</span> s
@@ -509,7 +508,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       at-right?:boolean<span class="Special"> &lt;- </span>equal column, right
       <span class="muControl">break-unless</span> at-right?
       <span class="Comment"># print wrap icon</span>
-      print-character screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span>
+      print screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span>
       column<span class="Special"> &lt;- </span>copy left
       row<span class="Special"> &lt;- </span>add row, <span class="Constant">1</span>
       screen<span class="Special"> &lt;- </span>move-cursor screen, row, column
@@ -524,7 +523,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       <span class="Delimiter">{</span>
         done?:boolean<span class="Special"> &lt;- </span>greater-than column, right
         <span class="muControl">break-if</span> done?
-        print-character screen, <span class="Constant">32/space</span>
+        print screen, <span class="Constant">32/space</span>
         column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
         <span class="muControl">loop</span>
       <span class="Delimiter">}</span>
@@ -533,7 +532,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       screen<span class="Special"> &lt;- </span>move-cursor screen, row, column
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
-    print-character screen, c, color
+    print screen, c, color
     column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
@@ -546,8 +545,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   move-cursor screen, row, left
 ]
 
-<span class="Comment"># like 'render-string' but with colorization for comments like in the editor</span>
-<span class="muRecipe">recipe</span> render-code-string screen:address:screen, s:address:array:character, left:number, right:number, row:number<span class="muRecipe"> -&gt; </span>row:number, screen:address:screen [
+<span class="Comment"># like 'render' for texts, but with colorization for comments like in the editor</span>
+<span class="muRecipe">recipe</span> render-code screen:address:screen, s:address:array:character, left:number, right:number, row:number<span class="muRecipe"> -&gt; </span>row:number, screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="muControl">reply-unless</span> s
@@ -564,13 +563,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     done?<span class="Special"> &lt;- </span>greater-or-equal row, screen-height
     <span class="muControl">break-if</span> done?
     c:character<span class="Special"> &lt;- </span>index *s, i
-    <span class="Constant">&lt;character-c-received&gt;</span>  <span class="Comment"># only line different from render-string</span>
+    <span class="Constant">&lt;character-c-received&gt;</span>  <span class="Comment"># only line different from render</span>
     <span class="Delimiter">{</span>
       <span class="Comment"># at right? wrap.</span>
       at-right?:boolean<span class="Special"> &lt;- </span>equal column, right
       <span class="muControl">break-unless</span> at-right?
       <span class="Comment"># print wrap icon</span>
-      print-character screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span>
+      print screen, <span class="Constant">8617/loop-back-to-left</span>, <span class="Constant">245/grey</span>
       column<span class="Special"> &lt;- </span>copy left
       row<span class="Special"> &lt;- </span>add row, <span class="Constant">1</span>
       screen<span class="Special"> &lt;- </span>move-cursor screen, row, column
@@ -585,7 +584,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       <span class="Delimiter">{</span>
         done?:boolean<span class="Special"> &lt;- </span>greater-than column, right
         <span class="muControl">break-if</span> done?
-        print-character screen, <span class="Constant">32/space</span>
+        print screen, <span class="Constant">32/space</span>
         column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
         <span class="muControl">loop</span>
       <span class="Delimiter">}</span>
@@ -594,7 +593,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       screen<span class="Special"> &lt;- </span>move-cursor screen, row, column
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
-    print-character screen, c, color
+    print screen, c, color
     column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
@@ -632,131 +631,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">}</span>
 ]
 
-<span class="Comment"># ctrl-x - maximize/unmaximize the side with focus</span>
-
-<span class="muScenario">scenario</span> maximize-side [
-  trace-until <span class="Constant">100/app</span>  <span class="Comment"># trace too long</span>
-  assume-screen <span class="Constant">30/width</span>, <span class="Constant">5/height</span>
-  <span class="Comment"># initialize both halves of screen</span>
-  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[abc]</span>
-  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[def]</span>
-  <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> &lt;- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
-  screen<span class="Special"> &lt;- </span>render-all screen, <span class="Constant">3</span>:address:programming-environment-data
-  screen-should-contain [
-   <span class="Constant"> .           run (F4)           .</span>
-   <span class="Constant"> .abc            ┊def           .</span>
-<span class="Constant">    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.</span>
-   <span class="Constant"> .               ┊              .</span>
-  ]
-  <span class="Comment"># hit ctrl-x</span>
-  assume-console [
-    press ctrl-x
-  ]
-  run [
-    event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
-  ]
-  <span class="Comment"># only left side visible</span>
-  screen-should-contain [
-   <span class="Constant"> .           run (F4)           .</span>
-   <span class="Constant"> .abc                           .</span>
-<span class="Constant">    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈.</span>
-   <span class="Constant"> .                              .</span>
-  ]
-  <span class="Comment"># hit any key to toggle back</span>
-  assume-console [
-    press ctrl-x
-  ]
-  run [
-    event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
-  ]
-  screen-should-contain [
-   <span class="Constant"> .           run (F4)           .</span>
-   <span class="Constant"> .abc            ┊def           .</span>
-<span class="Constant">    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━.</span>
-   <span class="Constant"> .               ┊              .</span>
-  ]
-]
-
-<span class="CommentedCode">#? # ctrl-t - browse trace</span>
-<span class="CommentedCode">#? after &lt;global-type&gt; [</span>
-<span class="CommentedCode">#?   {</span>
-<span class="CommentedCode">#?     browse-trace?:boolean &lt;- equal *c, 20/ctrl-t</span>
-<span class="CommentedCode">#?     break-unless browse-trace?</span>
-<span class="CommentedCode">#?     $browse-trace</span>
-<span class="CommentedCode">#?     screen &lt;- render-all screen, env:address:programming-environment-data</span>
-<span class="CommentedCode">#?     loop +next-event:label</span>
-<span class="CommentedCode">#?   }</span>
-<span class="CommentedCode">#? ]</span>
-
-<span class="muData">container</span> programming-environment-data [
-  maximized?:boolean
-]
-
-<span class="muRecipe">after</span> <span class="Constant">&lt;global-type&gt;</span> [
-  <span class="Delimiter">{</span>
-    maximize?:boolean<span class="Special"> &lt;- </span>equal *c, <span class="Constant">24/ctrl-x</span>
-    <span class="muControl">break-unless</span> maximize?
-    screen, console<span class="Special"> &lt;- </span>maximize screen, console, env:address:programming-environment-data
-    <span class="muControl">loop</span> <span class="Constant">+next-event:label</span>
-  <span class="Delimiter">}</span>
-]
-
-<span class="muRecipe">recipe</span> maximize screen:address:screen, console:address:console, env:address:programming-environment-data<span class="muRecipe"> -&gt; </span>screen:address:screen, console:address:console [
-  <span class="Constant">local-scope</span>
-  <span class="Constant">load-ingredients</span>
-  hide-screen screen
-  <span class="Comment"># maximize one of the sides</span>
-  maximized?:address:boolean<span class="Special"> &lt;- </span>get-address *env, <span class="Constant">maximized?:offset</span>
-  *maximized?<span class="Special"> &lt;- </span>copy <span class="Constant">1/true</span>
-  <span class="Comment">#</span>
-  sandbox-in-focus?:boolean<span class="Special"> &lt;- </span>get *env, <span class="Constant">sandbox-in-focus?:offset</span>
-  <span class="Delimiter">{</span>
-    <span class="muControl">break-if</span> sandbox-in-focus?
-    editor:address:editor-data<span class="Special"> &lt;- </span>get *env, <span class="Constant">recipes:offset</span>
-    right:address:number<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">right:offset</span>
-    *right<span class="Special"> &lt;- </span>screen-width screen
-    *right<span class="Special"> &lt;- </span>subtract *right, <span class="Constant">1</span>
-    screen<span class="Special"> &lt;- </span>render-recipes screen, env
-  <span class="Delimiter">}</span>
-  <span class="Delimiter">{</span>
-    <span class="muControl">break-unless</span> sandbox-in-focus?
-    editor:address:editor-data<span class="Special"> &lt;- </span>get *env, <span class="Constant">current-sandbox:offset</span>
-    left:address:number<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">left:offset</span>
-    *left<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
-    screen<span class="Special"> &lt;- </span>render-sandbox-side screen, env
-  <span class="Delimiter">}</span>
-  show-screen screen
-]
-
-<span class="Comment"># when maximized, wait for any event and simply unmaximize</span>
-<span class="muRecipe">after</span> <span class="Constant">&lt;handle-event&gt;</span> [
-  <span class="Delimiter">{</span>
-    maximized?:address:boolean<span class="Special"> &lt;- </span>get-address *env, <span class="Constant">maximized?:offset</span>
-    <span class="muControl">break-unless</span> *maximized?
-    *maximized?<span class="Special"> &lt;- </span>copy <span class="Constant">0/false</span>
-    <span class="Comment"># undo maximize</span>
-    <span class="Delimiter">{</span>
-      <span class="muControl">break-if</span> *sandbox-in-focus?
-      editor:address:editor-data<span class="Special"> &lt;- </span>get *env, <span class="Constant">recipes:offset</span>
-      right:address:number<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">right:offset</span>
-      *right<span class="Special"> &lt;- </span>screen-width screen
-      *right<span class="Special"> &lt;- </span>divide *right, <span class="Constant">2</span>
-      *right<span class="Special"> &lt;- </span>subtract *right, <span class="Constant">1</span>
-    <span class="Delimiter">}</span>
-    <span class="Delimiter">{</span>
-      <span class="muControl">break-unless</span> *sandbox-in-focus?
-      editor:address:editor-data<span class="Special"> &lt;- </span>get *env, <span class="Constant">current-sandbox:offset</span>
-      left:address:number<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">left:offset</span>
-      *left<span class="Special"> &lt;- </span>screen-width screen
-      *left<span class="Special"> &lt;- </span>divide *left, <span class="Constant">2</span>
-      *left<span class="Special"> &lt;- </span>add *left, <span class="Constant">1</span>
-    <span class="Delimiter">}</span>
-    render-all screen, env
-    show-screen screen
-    <span class="muControl">loop</span> <span class="Constant">+next-event:label</span>
-  <span class="Delimiter">}</span>
-]
-
 <span class="SalientComment">## helpers</span>
 
 <span class="muRecipe">recipe</span> draw-vertical screen:address:screen, col:number, y:number, bottom:number [
@@ -777,7 +651,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     continue?:boolean<span class="Special"> &lt;- </span>lesser-than y, bottom
     <span class="muControl">break-unless</span> continue?
     screen<span class="Special"> &lt;- </span>move-cursor screen, y, col
-    print-character screen, style, color
+    print screen, style, color
     y<span class="Special"> &lt;- </span>add y, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
diff --git a/html/edit/005-sandbox.mu.html b/html/edit/005-sandbox.mu.html
index 85fdf7da..9c219526 100644
--- a/html/edit/005-sandbox.mu.html
+++ b/html/edit/005-sandbox.mu.html
@@ -229,7 +229,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   screen<span class="Special"> &lt;- </span>move-cursor screen, <span class="Constant">0</span>, <span class="Constant">2</span>
-  screen<span class="Special"> &lt;- </span>print-string screen, msg, color, <span class="Constant">238/grey/background</span>
+  screen<span class="Special"> &lt;- </span>print screen, msg, color, <span class="Constant">238/grey/background</span>
 ]
 
 <span class="muRecipe">recipe</span> save-sandboxes env:address:programming-environment-data [
@@ -244,12 +244,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> curr
     data:address:array:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">data:offset</span>
-    filename:address:array:character<span class="Special"> &lt;- </span>integer-to-decimal-string idx
+    filename:address:array:character<span class="Special"> &lt;- </span>to-text idx
     save filename, data
     <span class="Delimiter">{</span>
       expected-response:address:array:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">expected-response:offset</span>
       <span class="muControl">break-unless</span> expected-response
-      filename<span class="Special"> &lt;- </span>string-append filename, suffix
+      filename<span class="Special"> &lt;- </span>append filename, suffix
       save filename, expected-response
     <span class="Delimiter">}</span>
     idx<span class="Special"> &lt;- </span>add idx, <span class="Constant">1</span>
@@ -285,7 +285,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   row<span class="Special"> &lt;- </span>add row, <span class="Constant">1</span>
   screen<span class="Special"> &lt;- </span>move-cursor screen, row, left
   clear-line-delimited screen, left, right
-  print-character screen, <span class="Constant">120/x</span>, <span class="Constant">245/grey</span>
+  print screen, <span class="Constant">120/x</span>, <span class="Constant">245/grey</span>
   <span class="Comment"># save menu row so we can detect clicks to it later</span>
   starting-row:address:number<span class="Special"> &lt;- </span>get-address *sandbox, <span class="Constant">starting-row-on-screen:offset</span>
   *starting-row<span class="Special"> &lt;- </span>copy row
@@ -293,7 +293,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   row<span class="Special"> &lt;- </span>add row, <span class="Constant">1</span>
   screen<span class="Special"> &lt;- </span>move-cursor screen, row, left
   sandbox-data:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">data:offset</span>
-  row, screen<span class="Special"> &lt;- </span>render-code-string screen, sandbox-data, left, right, row
+  row, screen<span class="Special"> &lt;- </span>render-code screen, sandbox-data, left, right, row
   code-ending-row:address:number<span class="Special"> &lt;- </span>get-address *sandbox, <span class="Constant">code-ending-row-on-screen:offset</span>
   *code-ending-row<span class="Special"> &lt;- </span>copy row
   <span class="Comment"># render sandbox warnings, screen or response, in that order</span>
@@ -310,7 +310,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-unless</span> empty-screen?
     *response-starting-row<span class="Special"> &lt;- </span>copy row
 <span class="Constant">    &lt;render-sandbox-response&gt;</span>
-    row, screen<span class="Special"> &lt;- </span>render-string screen, sandbox-response, left, right, <span class="Constant">245/grey</span>, row
+    row, screen<span class="Special"> &lt;- </span>render screen, sandbox-response, left, right, <span class="Constant">245/grey</span>, row
   <span class="Delimiter">}</span>
 <span class="Constant">  +render-sandbox-end</span>
   at-bottom?:boolean<span class="Special"> &lt;- </span>greater-or-equal row, screen-height
@@ -331,7 +331,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   idx:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   curr:address:address:sandbox-data<span class="Special"> &lt;- </span>get-address *env, <span class="Constant">sandbox:offset</span>
   <span class="Delimiter">{</span>
-    filename:address:array:character<span class="Special"> &lt;- </span>integer-to-decimal-string idx
+    filename:address:array:character<span class="Special"> &lt;- </span>to-text idx
     contents:address:array:character<span class="Special"> &lt;- </span>restore filename
     <span class="muControl">break-unless</span> contents  <span class="Comment"># stop at first error; assuming file didn't exist</span>
     <span class="Comment"># create new sandbox for file</span>
@@ -340,7 +340,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     *data<span class="Special"> &lt;- </span>copy contents
     <span class="Comment"># restore expected output for sandbox if it exists</span>
     <span class="Delimiter">{</span>
-      filename<span class="Special"> &lt;- </span>string-append filename, suffix
+      filename<span class="Special"> &lt;- </span>append filename, suffix
       contents<span class="Special"> &lt;- </span>restore filename
       <span class="muControl">break-unless</span> contents
       expected-response:address:address:array:character<span class="Special"> &lt;- </span>get-address **curr, <span class="Constant">expected-response:offset</span>
@@ -361,7 +361,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply-unless</span> sandbox-screen
   <span class="Comment"># print 'screen:'</span>
   header:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[screen:]</span>
-  row<span class="Special"> &lt;- </span>render-string screen, header, left, right, <span class="Constant">245/grey</span>, row
+  row<span class="Special"> &lt;- </span>render screen, header, left, right, <span class="Constant">245/grey</span>, row
   screen<span class="Special"> &lt;- </span>move-cursor screen, row, left
   <span class="Comment"># start printing sandbox-screen</span>
   column:number<span class="Special"> &lt;- </span>copy left
@@ -381,9 +381,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     column<span class="Special"> &lt;- </span>copy left
     screen<span class="Special"> &lt;- </span>move-cursor screen, row, column
     <span class="Comment"># initial leader for each row: two spaces and a '.'</span>
-    print-character screen, <span class="Constant">32/space</span>, <span class="Constant">245/grey</span>
-    print-character screen, <span class="Constant">32/space</span>, <span class="Constant">245/grey</span>
-    print-character screen, <span class="Constant">46/full-stop</span>, <span class="Constant">245/grey</span>
+    print screen, <span class="Constant">32/space</span>, <span class="Constant">245/grey</span>
+    print screen, <span class="Constant">32/space</span>, <span class="Constant">245/grey</span>
+    print screen, <span class="Constant">46/full-stop</span>, <span class="Constant">245/grey</span>
     column<span class="Special"> &lt;- </span>add left, <span class="Constant">3</span>
     <span class="Delimiter">{</span>
       <span class="Comment"># print row</span>
@@ -398,19 +398,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
         <span class="muControl">break-unless</span> white?
         color<span class="Special"> &lt;- </span>copy <span class="Constant">245/grey</span>
       <span class="Delimiter">}</span>
-      print-character screen, c, color
+      print screen, c, color
       column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
       i<span class="Special"> &lt;- </span>add i, <span class="Constant">1</span>
       <span class="muControl">loop</span>
     <span class="Delimiter">}</span>
     <span class="Comment"># print final '.'</span>
-    print-character screen, <span class="Constant">46/full-stop</span>, <span class="Constant">245/grey</span>
+    print screen, <span class="Constant">46/full-stop</span>, <span class="Constant">245/grey</span>
     column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
     <span class="Delimiter">{</span>
       <span class="Comment"># clear rest of current line</span>
       line-done?:boolean<span class="Special"> &lt;- </span>greater-than column, right
       <span class="muControl">break-if</span> line-done?
-      print-character screen, <span class="Constant">32/space</span>
+      print screen, <span class="Constant">32/space</span>
       column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
       <span class="muControl">loop</span>
     <span class="Delimiter">}</span>
@@ -514,7 +514,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> curr
     c:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">value:offset</span>
-    buffer-append buf, c
+    buf<span class="Special"> &lt;- </span>append buf, c
     curr<span class="Special"> &lt;- </span>next curr
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
@@ -535,7 +535,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">4</span>:array:character<span class="Special"> &lt;- </span>copy *<span class="Constant">3</span>:address:array:character
   ]
   memory-should-contain [
-    <span class="Constant">4</span>:string<span class="Special"> &lt;- </span><span class="Constant">[abdefc]</span>
+    <span class="Constant">4</span>:array:character<span class="Special"> &lt;- </span><span class="Constant">[abdefc]</span>
   ]
 ]
 </pre>
diff --git a/html/edit/008-sandbox-test.mu.html b/html/edit/008-sandbox-test.mu.html
index 08b62ddc..bdf918e8 100644
--- a/html/edit/008-sandbox-test.mu.html
+++ b/html/edit/008-sandbox-test.mu.html
@@ -79,7 +79,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
   <span class="Comment"># cursor should remain unmoved</span>
   run [
-    print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
+    print screen:address:screen, <span class="Constant">9251/␣/cursor</span>
   ]
   screen-should-contain [
    <span class="Constant"> .                     run (F4)           .</span>
@@ -191,14 +191,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-unless</span> sandbox-response
     expected-response:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">expected-response:offset</span>
     <span class="muControl">break-unless</span> expected-response  <span class="Comment"># fall-through to print in grey</span>
-    response-is-expected?:boolean<span class="Special"> &lt;- </span>string-equal expected-response, sandbox-response
+    response-is-expected?:boolean<span class="Special"> &lt;- </span>equal expected-response, sandbox-response
     <span class="Delimiter">{</span>
       <span class="muControl">break-if</span> response-is-expected?:boolean
-      row, screen<span class="Special"> &lt;- </span>render-string screen, sandbox-response, left, right, <span class="Constant">1/red</span>, row
+      row, screen<span class="Special"> &lt;- </span>render screen, sandbox-response, left, right, <span class="Constant">1/red</span>, row
     <span class="Delimiter">}</span>
     <span class="Delimiter">{</span>
       <span class="muControl">break-unless</span> response-is-expected?:boolean
-      row, screen<span class="Special"> &lt;- </span>render-string screen, sandbox-response, left, right, <span class="Constant">2/green</span>, row
+      row, screen<span class="Special"> &lt;- </span>render screen, sandbox-response, left, right, <span class="Constant">2/green</span>, row
     <span class="Delimiter">}</span>
     <span class="muControl">jump</span> <span class="Constant">+render-sandbox-end:label</span>
   <span class="Delimiter">}</span>
diff --git a/html/edit/009-sandbox-trace.mu.html b/html/edit/009-sandbox-trace.mu.html
index 071f62af..6d5603bd 100644
--- a/html/edit/009-sandbox-trace.mu.html
+++ b/html/edit/009-sandbox-trace.mu.html
@@ -65,7 +65,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
   run [
     event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
-    print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
+    print screen:address:screen, <span class="Constant">9251/␣/cursor</span>
   ]
   <span class="Comment"># trace now printed and cursor shouldn't have budged</span>
   screen-should-contain [
@@ -94,7 +94,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
   run [
     event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
-    print-character screen:address:screen, <span class="Constant">9251/␣/cursor</span>
+    print screen:address:screen, <span class="Constant">9251/␣/cursor</span>
   ]
   <span class="Comment"># trace hidden again</span>
   screen-should-contain [
@@ -238,7 +238,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-unless</span> display-trace?
     sandbox-trace:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">trace:offset</span>
     <span class="muControl">break-unless</span> sandbox-trace  <span class="Comment"># nothing to print; move on</span>
-    row, screen<span class="Special"> &lt;- </span>render-string, screen, sandbox-trace, left, right, <span class="Constant">245/grey</span>, row
+    row, screen<span class="Special"> &lt;- </span>render screen, sandbox-trace, left, right, <span class="Constant">245/grey</span>, row
   <span class="Delimiter">}</span>
 <span class="Constant">  &lt;render-sandbox-trace-done&gt;</span>
 ]
diff --git a/html/edit/010-warnings.mu.html b/html/edit/010-warnings.mu.html
index 335bfb42..6d746bf5 100644
--- a/html/edit/010-warnings.mu.html
+++ b/html/edit/010-warnings.mu.html
@@ -20,6 +20,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .Comment { color: #9090ff; }
 .Constant { color: #00a0a0; }
 .SalientComment { color: #00ffff; }
+.CommentedCode { color: #6c6c6c; }
 .Delimiter { color: #a04060; }
 .muScenario { color: #00af00; }
 -->
@@ -73,7 +74,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">{</span>
     recipe-warnings:address:array:character<span class="Special"> &lt;- </span>get *env, <span class="Constant">recipe-warnings:offset</span>
     <span class="muControl">break-unless</span> recipe-warnings
-    row, screen<span class="Special"> &lt;- </span>render-string screen, recipe-warnings, left, right, <span class="Constant">1/red</span>, row
+    row, screen<span class="Special"> &lt;- </span>render screen, recipe-warnings, left, right, <span class="Constant">1/red</span>, row
   <span class="Delimiter">}</span>
 ]
 
@@ -89,6 +90,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   warnings:address:address:array:character<span class="Special"> &lt;- </span>get-address *sandbox, <span class="Constant">warnings:offset</span>
   trace:address:address:array:character<span class="Special"> &lt;- </span>get-address *sandbox, <span class="Constant">trace:offset</span>
   fake-screen:address:address:screen<span class="Special"> &lt;- </span>get-address *sandbox, <span class="Constant">screen:offset</span>
+<span class="CommentedCode">#?   $print [run-interactive], 10/newline</span>
   *response, *warnings, *fake-screen, *trace, completed?:boolean<span class="Special"> &lt;- </span>run-interactive data
   <span class="Delimiter">{</span>
     <span class="muControl">break-if</span> *warnings
@@ -96,6 +98,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     *warnings<span class="Special"> &lt;- </span>new <span class="Constant">[took too long!</span>
 <span class="Constant">]</span>
   <span class="Delimiter">}</span>
+<span class="CommentedCode">#?   $print [done with run-interactive], 10/newline</span>
 ]
 
 <span class="Comment"># make sure we render any trace</span>
@@ -104,7 +107,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     sandbox-warnings:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">warnings:offset</span>
     <span class="muControl">break-unless</span> sandbox-warnings
     *response-starting-row<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># no response</span>
-    row, screen<span class="Special"> &lt;- </span>render-string screen, sandbox-warnings, left, right, <span class="Constant">1/red</span>, row
+    row, screen<span class="Special"> &lt;- </span>render screen, sandbox-warnings, left, right, <span class="Constant">1/red</span>, row
     <span class="Comment"># don't try to print anything more for this sandbox</span>
     <span class="muControl">jump</span> <span class="Constant">+render-sandbox-end:label</span>
   <span class="Delimiter">}</span>
@@ -150,6 +153,88 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
+<span class="muScenario">scenario</span> run-hides-warnings-from-past-sandboxes [
+  trace-until <span class="Constant">100/app</span>  <span class="Comment"># trace too long</span>
+  assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
+  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[]</span>
+  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[get foo, x:offset]</span>  <span class="Comment"># invalid</span>
+  <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> &lt;- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+  assume-console [
+    press F4  <span class="Comment"># generate error</span>
+  ]
+  run [
+    event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+  ]
+  assume-console [
+    left-click <span class="Constant">3</span>, <span class="Constant">80</span>
+    press ctrl-k
+    type <span class="Constant">[add 2, 2]</span>  <span class="Comment"># valid code</span>
+    press F4  <span class="Comment"># error should disappear</span>
+  ]
+  run [
+    event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+  ]
+  screen-should-contain [
+   <span class="Constant"> .                                                                                 run (F4)           .</span>
+   <span class="Constant"> .                                                  ┊                                                 .</span>
+<span class="Constant">    .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+   <span class="Constant"> .                                                  ┊                                                x.</span>
+   <span class="Constant"> .                                                  ┊add 2, 2                                         .</span>
+   <span class="Constant"> .                                                  ┊4                                                .</span>
+   <span class="Constant"> .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+   <span class="Constant"> .                                                  ┊                                                 .</span>
+  ]
+]
+
+<span class="muScenario">scenario</span> run-updates-warnings-for-shape-shifting-recipes [
+  trace-until <span class="Constant">100/app</span>  <span class="Comment"># trace too long</span>
+  assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
+  <span class="Comment"># define a shape-shifting recipe with an error</span>
+  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[recipe foo x:_elem -&gt; z:_elem [</span>
+<span class="Constant">local-scope</span>
+<span class="Constant">load-ingredients</span>
+<span class="Constant">z &lt;- add x, [a]</span>
+]]
+  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[foo 2]</span>
+  <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> &lt;- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
+  assume-console [
+    press F4
+  ]
+  run [
+    event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+  ]
+  screen-should-contain [
+   <span class="Constant"> .                                                                                 run (F4)           .</span>
+   <span class="Constant"> .recipe foo x:_elem -&gt; z:_elem [                   ┊                                                 .</span>
+   <span class="Constant"> .local-scope                                       ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+   <span class="Constant"> .load-ingredients                                  ┊                                                x.</span>
+   <span class="Constant"> .z &lt;- add x, [a]                                   ┊foo 2                                            .</span>
+   <span class="Constant"> .]                                                 ┊foo_2: 'add' requires number ingredients, but go↩.</span>
+   <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊t [a]                                            .</span>
+   <span class="Constant"> .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+   <span class="Constant"> .                                                  ┊                                                 .</span>
+  ]
+  <span class="Comment"># now rerun everything</span>
+  assume-console [
+    press F4
+  ]
+  run [
+    event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+  ]
+  <span class="Comment"># error should remain unchanged</span>
+  screen-should-contain [
+   <span class="Constant"> .                                                                                 run (F4)           .</span>
+   <span class="Constant"> .recipe foo x:_elem -&gt; z:_elem [                   ┊                                                 .</span>
+   <span class="Constant"> .local-scope                                       ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+   <span class="Constant"> .load-ingredients                                  ┊                                                x.</span>
+   <span class="Constant"> .z &lt;- add x, [a]                                   ┊foo 2                                            .</span>
+   <span class="Constant"> .]                                                 ┊foo_2: 'add' requires number ingredients, but go↩.</span>
+   <span class="Constant"> .┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┊t [a]                                            .</span>
+   <span class="Constant"> .                                                  ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.</span>
+   <span class="Constant"> .                                                  ┊                                                 .</span>
+  ]
+]
+
 <span class="muScenario">scenario</span> run-shows-missing-type-warnings [
   trace-until <span class="Constant">100/app</span>  <span class="Comment"># trace too long</span>
   assume-screen <span class="Constant">100/width</span>, <span class="Constant">15/height</span>
@@ -183,7 +268,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="Constant">recipe foo «</span>
 <span class="Constant">  x &lt;- copy 0</span>
 <span class="Constant">]</span>
-  string-replace <span class="Constant">1</span>:address:array:character, <span class="Constant">171/«</span>, <span class="Constant">91</span>  <span class="Comment"># '['</span>
+  replace <span class="Constant">1</span>:address:array:character, <span class="Constant">171/«</span>, <span class="Constant">91</span>  <span class="Comment"># '['</span>
   <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[foo]</span>
   <span class="Constant">3</span>:address:programming-environment-data<span class="Special"> &lt;- </span>new-programming-environment screen:address:screen, <span class="Constant">1</span>:address:array:character, <span class="Constant">2</span>:address:array:character
   assume-console [
diff --git a/html/edit/011-editor-undo.mu.html b/html/edit/011-editor-undo.mu.html
index 5a3f537e..801ca648 100644
--- a/html/edit/011-editor-undo.mu.html
+++ b/html/edit/011-editor-undo.mu.html
@@ -2105,10 +2105,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
    <span class="Constant"> .          .</span>
   ]
 ]
-
-<span class="Comment"># todo:</span>
-<span class="Comment"># operations for recipe side and each sandbox-data</span>
-<span class="Comment"># undo delete sandbox as a separate primitive on the status bar</span>
 </pre>
 </body>
 </html>
diff --git a/html/screen.mu.html b/html/screen.mu.html
index 6efea923..ea2b0232 100644
--- a/html/screen.mu.html
+++ b/html/screen.mu.html
@@ -35,12 +35,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muRecipe">recipe</span> main [
   open-console
-  print-character <span class="Constant">0/screen</span>, <span class="Constant">97/a</span>, <span class="Constant">2/red</span>
+  print <span class="Constant">0/screen</span>, <span class="Constant">97/a</span>, <span class="Constant">2/red</span>
   <span class="Constant">1</span>:number/<span class="Special">raw</span>, <span class="Constant">2</span>:number/<span class="Special">raw &lt;- </span>cursor-position <span class="Constant">0/screen</span>
   wait-for-event <span class="Constant">0/console</span>
   clear-screen <span class="Constant">0/screen</span>
   move-cursor <span class="Constant">0/screen</span>, <span class="Constant">0/row</span>, <span class="Constant">4/column</span>
-  print-character <span class="Constant">0/screen</span>, <span class="Constant">98/b</span>
+  print <span class="Constant">0/screen</span>, <span class="Constant">98/b</span>
   wait-for-event <span class="Constant">0/console</span>
   move-cursor <span class="Constant">0/screen</span>, <span class="Constant">0/row</span>, <span class="Constant">0/column</span>
   clear-line <span class="Constant">0/screen</span>
diff --git a/index.html b/index.html
index 24b8e0c0..e498b82f 100644
--- a/index.html
+++ b/index.html
@@ -166,7 +166,7 @@ various address spaces in the core, and the conventions that regulate their
 use in previous layers.
 
 <p><b>Part IV</b>: beginnings of a standard library
-<p/><a href='html/070string.mu.html'>070string.mu</a>: strings in Mu are
+<p/><a href='html/070text.mu.html'>070text.mu</a>: strings in Mu are
 bounds-checked rather than null-terminated. They're also unicode-aware (code
 points only; no control characters, no combining characters, no normalization).
 <br/><a href='html/071channel.mu.html'>071channel.mu</a>: channels are Mu's
@@ -239,7 +239,8 @@ golden/expected. Any future changes to the output will then be flagged in red.
 <br/><a href='html/edit/009-sandbox-trace.mu.html'>edit/009-sandbox-trace.mu</a>:
 click on code in a sandbox to open up a drawer containing its trace. The trace
 can be added to using the <span style='font-family:courier,fixed'>stash</span>
-command.
+command, which renders arbitrary data structures using <span style='font-family:courier,fixed'>to-text</span>
+with the appropriate recipe header.
 <br/><a href='html/edit/010-warnings.mu.html'>edit/010-warnings.mu</a>:
 support for rendering warnings on both the left and in each sandbox.
 <br/><a href='html/edit/011-editor-undo.mu.html'>edit/011-editor-undo.mu</a>: