about summary refs log tree commit diff stats
path: root/html
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-12-15 14:32:47 -0800
committerKartik K. Agaram <vc@akkartik.com>2015-12-15 14:32:47 -0800
commit67db19a05335c7fbea3ad6737303c8848fd39e74 (patch)
tree00d9585bf4de231254867d8c7515386934bb3d3f /html
parent62a390ca0a27daa80ce4b6b17934d8d067db8631 (diff)
downloadmu-67db19a05335c7fbea3ad6737303c8848fd39e74.tar.gz
2545
update html
Diffstat (limited to 'html')
-rw-r--r--html/010vm.cc.html15
-rw-r--r--html/011load.cc.html74
-rw-r--r--html/013update_operation.cc.html10
-rw-r--r--html/014literal_string.cc.html3
-rw-r--r--html/020run.cc.html2
-rw-r--r--html/029tools.cc.html27
-rw-r--r--html/030container.cc.html38
-rw-r--r--html/031address.cc.html11
-rw-r--r--html/036call_reply.cc.html101
-rw-r--r--html/042name.cc.html6
-rw-r--r--html/054dilated_reagent.cc.html2
-rw-r--r--html/055parse_tree.cc.html5
-rw-r--r--html/056recipe_header.cc.html48
-rw-r--r--html/057static_dispatch.cc.html129
-rw-r--r--html/059shape_shifting_recipe.cc.html57
-rw-r--r--html/060immutable.cc.html389
-rw-r--r--html/061abandon_checks.cc.html159
-rw-r--r--html/073list.mu.html10
-rw-r--r--html/075duplex_list.mu.html97
-rw-r--r--html/080display.cc.html7
-rw-r--r--html/082scenario_screen.cc.html8
-rw-r--r--html/084console.mu.html18
-rw-r--r--html/090trace_browser.cc.html20
-rw-r--r--html/091run_interactive.cc.html92
-rw-r--r--html/chessboard.mu.html6
-rw-r--r--html/edit/001-editor.mu.html2
-rw-r--r--html/edit/002-typing.mu.html8
-rw-r--r--html/edit/003-shortcuts.mu.html14
-rw-r--r--html/edit/004-programming-environment.mu.html10
-rw-r--r--html/edit/005-sandbox.mu.html6
-rw-r--r--html/edit/006-sandbox-edit.mu.html2
-rw-r--r--html/edit/007-sandbox-delete.mu.html2
-rw-r--r--html/edit/010-warnings.mu.html62
33 files changed, 1180 insertions, 260 deletions
diff --git a/html/010vm.cc.html b/html/010vm.cc.html
index 976edf51..69d5dec0 100644
--- a/html/010vm.cc.html
+++ b/html/010vm.cc.html
@@ -295,7 +295,7 @@ reagent::reagent<span class="Delimiter">(</span>string s<span class="Delimiter">
 <span class="Delimiter">}</span>
 
 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>
+  skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<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>
@@ -557,9 +557,16 @@ void dump<span class="Delimiter">(</span>const string_tree* x<span class="Delimi
   out &lt;&lt; <span class="Constant">')'</span><span class="Delimiter">;</span>
 <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 &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">:(before &quot;End Globals&quot;)</span>
+const string Ignore<span class="Delimiter">(</span><span class="Constant">&quot;,&quot;</span><span class="Delimiter">);</span>  <span class="Comment">// commas are ignored in mu except within [] strings</span>
+<span class="Delimiter">:(code)</span>
+void skip_whitespace_but_not_newline<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>!has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+    else if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="cSpecial">'\n'</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
+    else 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>Ignore<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> in<span class="Delimiter">.</span>get<span class="Delimiter">();</span>
+    else <span class="Identifier">break</span><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 7296d1bb..e3be7973 100644
--- a/html/011load.cc.html
+++ b/html/011load.cc.html
@@ -16,6 +16,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .traceContains { color: #008000; }
 .traceAbsent { color: #c00000; }
 .cSpecial { color: #008000; }
+.CommentedCode { color: #6c6c6c; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
@@ -77,7 +78,7 @@ vector&lt;recipe_ordinal&gt; load<span class="Delimiter">(</span>istream&amp; in
 long long int slurp_recipe<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   recipe result<span class="Delimiter">;</span>
   result<span class="Delimiter">.</span>name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
-  skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   <span class="Comment">// End recipe Refinements</span>
   if <span class="Delimiter">(</span>result<span class="Delimiter">.</span>name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span>
     raise_error &lt;&lt; <span class="Constant">&quot;empty result.name</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
@@ -95,16 +96,17 @@ long long int slurp_recipe<span class="Delimiter">(</span>istream&amp; in<span c
   <span class="Comment">// End recipe Body(result)</span>
   get_or_insert<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">))</span> = result<span class="Delimiter">;</span>
   <span class="Comment">// track added recipes because we may need to undo them in tests; see below</span>
-  recently_added_recipes<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
+<span class="CommentedCode">//?   LOG &lt;&lt; &quot;recently added recipe: &quot; &lt;&lt; result.name &lt;&lt; ' ' &lt;&lt; get(Recipe_ordinal, result.name) &lt;&lt; '\n';</span>
+  Recently_added_recipes<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
   <span class="Identifier">return</span> get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
 void slurp_body<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> recipe&amp; result<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   in &gt;&gt; std::noskipws<span class="Delimiter">;</span>
-  skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>get<span class="Delimiter">()</span> != <span class="Constant">'['</span><span class="Delimiter">)</span>
     raise_error &lt;&lt; <span class="Constant">&quot;recipe body must begin with '['</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
-  skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>  <span class="Comment">// permit trailing comment after '['</span>
   instruction curr<span class="Delimiter">;</span>
   while <span class="Delimiter">(</span>next_instruction<span class="Delimiter">(</span>in<span class="Delimiter">,</span> &amp;curr<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     <span class="Comment">// End Rewrite Instruction(curr, recipe result)</span>
@@ -116,31 +118,22 @@ 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>!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>!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>!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>
+    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>
 
   vector&lt;string&gt; words<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>
+    skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<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>
+      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>
     string word = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     words<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>word<span class="Delimiter">);</span>
-    skip_whitespace<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+    skip_whitespace_but_not_newline<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>SIZE<span class="Delimiter">(</span>words<span class="Delimiter">)</span> == <span class="Constant">1</span> &amp;&amp; words<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)</span> == <span class="Constant">&quot;]&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -193,20 +186,17 @@ bool next_instruction<span class="Delimiter">(</span>istream&amp; in<span class=
 <span class="Delimiter">}</span>
 
 string next_word<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>
-  skip_ignored_characters<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+  skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   <span class="Comment">// End next_word Special-cases</span>
   ostringstream out<span class="Delimiter">;</span>
   slurp_word<span class="Delimiter">(</span>in<span class="Delimiter">,</span> out<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>
+  skip_whitespace_and_comments_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
 <span class="Comment">// word boundaries</span>
-string Terminators<span class="Delimiter">(</span><span class="Constant">&quot;(){}&quot;</span><span class="Delimiter">);</span>
-string Ignore<span class="Delimiter">(</span><span class="Constant">&quot;,&quot;</span><span class="Delimiter">);</span>  <span class="Comment">// meaningless except within [] strings</span>
+const string Terminators<span class="Delimiter">(</span><span class="Constant">&quot;(){}&quot;</span><span class="Delimiter">);</span>
 <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>
@@ -224,17 +214,23 @@ void slurp_word<span class="Delimiter">(</span>istream&amp; in<span class="Delim
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
-void skip_ignored_characters<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  while <span class="Delimiter">(</span>isspace<span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span class="Delimiter">())</span> || Ignore<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<span class="Delimiter">.</span>get<span class="Delimiter">();</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>!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>Ignore<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> 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>
+    else <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
-void skip_whitespace_and_comments<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="Comment">// confusing; move to the next line only to skip a comment, but never otherwise</span>
+void skip_whitespace_and_comments_but_not_newline<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>!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>in<span class="Delimiter">.</span>peek<span class="Delimiter">()</span> == <span class="cSpecial">'\n'</span><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>Ignore<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> 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>
     else <span class="Identifier">break</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
@@ -274,19 +270,23 @@ void show_rest_of_stream<span class="Delimiter">(</span>istream&amp; in<span cla
 
 <span class="Comment">//: Have tests clean up any recipes they added.</span>
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
-vector&lt;recipe_ordinal&gt; recently_added_recipes<span class="Delimiter">;</span>
+vector&lt;recipe_ordinal&gt; Recently_added_recipes<span class="Delimiter">;</span>
 long long int Reserved_for_tests = <span class="Constant">1000</span><span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Setup&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>recently_added_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> &gt;= Reserved_for_tests  <span class="Comment">// don't renumber existing recipes, like 'interactive'</span>
-      &amp;&amp; contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>  <span class="Comment">// in case previous test had duplicate definitions</span>
-    Recipe_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> recently_added_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_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+clear_recently_added_recipes<span class="Delimiter">();</span>
+<span class="Delimiter">:(code)</span>
+void clear_recently_added_recipes<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_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>Recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> &gt;= Reserved_for_tests  <span class="Comment">// don't renumber existing recipes, like 'interactive'</span>
+        &amp;&amp; contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> Recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span>  <span class="Comment">// in case previous test had duplicate definitions</span>
+      Recipe_ordinal<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> Recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>name<span class="Delimiter">);</span>
+<span class="CommentedCode">//?   LOG &lt;&lt; &quot;erase recipe &quot; &lt;&lt; Recently_added_recipes.at(i) &lt;&lt; ' ' &lt;&lt; get(Recipe, Recently_added_recipes.at(i)).name &lt;&lt; '\n';</span>
+    Recipe<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+  <span class="Delimiter">}</span>
+  <span class="Comment">// Clear Other State For Recently_added_recipes</span>
+  Recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
 <span class="Delimiter">}</span>
-<span class="Comment">// Clear Other State For recently_added_recipes</span>
-recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
 
-<span class="Delimiter">:(code)</span>
 <span class="Delimiter">:(scenario parse_comment_outside_recipe)</span>
 <span class="Comment"># this comment will be dropped by the tangler, so we need a dummy recipe to stop that</span>
 recipe f1 [ ]
diff --git a/html/013update_operation.cc.html b/html/013update_operation.cc.html
index 7a6c5f78..a84aff0d 100644
--- a/html/013update_operation.cc.html
+++ b/html/013update_operation.cc.html
@@ -39,15 +39,17 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa
 <span class="Delimiter">:(code)</span>
 void update_instruction_operations<span class="Delimiter">(</span>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;--- compute instruction operations 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;--- compute instruction operations for recipe &quot; &lt;&lt; get(Recipe, r).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>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++index<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>index<span class="Delimiter">);</span>
+  recipe&amp; caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;--- compute instruction operations for recipe &quot; &lt;&lt; caller.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<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<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>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_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<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;instruction &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; has no recipe</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;instruction &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; has no 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="Delimiter">;</span>
     <span class="Delimiter">}</span>
     inst<span class="Delimiter">.</span>operation = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+    <span class="Comment">// End Instruction Operation Checks</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/014literal_string.cc.html b/html/014literal_string.cc.html
index 024a0efc..157b2fa4 100644
--- a/html/014literal_string.cc.html
+++ b/html/014literal_string.cc.html
@@ -57,8 +57,7 @@ put<span class="Delimiter">(</span>Type_ordinal<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>
+  skip_whitespace_and_comments_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   <span class="Identifier">return</span> result<span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/020run.cc.html b/html/020run.cc.html
index e5ee3061..d0213a69 100644
--- a/html/020run.cc.html
+++ b/html/020run.cc.html
@@ -256,7 +256,7 @@ void load_permanently<span class="Delimiter">(</span>string filename<span class=
   load<span class="Delimiter">(</span>fin<span class="Delimiter">);</span>
   fin<span class="Delimiter">.</span>close<span class="Delimiter">();</span>
   <span class="Comment">// freeze everything so it doesn't get cleared by tests</span>
-  recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+  Recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
   <span class="Comment">// End load_permanently.</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/029tools.cc.html b/html/029tools.cc.html
index 4b78fe12..5355d922 100644
--- a/html/029tools.cc.html
+++ b/html/029tools.cc.html
@@ -16,6 +16,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .traceContains { color: #008000; }
 .SalientComment { color: #00ffff; }
 .cSpecial { color: #008000; }
+.CommentedCode { color: #6c6c6c; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
@@ -335,6 +336,32 @@ case _DUMP_MEMORY: <span class="Delimiter">{</span>
   dump_memory<span class="Delimiter">();</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
+
+<span class="Comment">//: In times of real extremis we need to create a whole new modality for debug</span>
+<span class="Comment">//: logs, independent of other changes to the screen or Trace_stream.</span>
+
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+ofstream LOG<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End One-time Setup&quot;)</span>
+<span class="CommentedCode">//? LOG.open(&quot;log&quot;);</span>
+
+<span class="Delimiter">:(before &quot;End Primitive Recipe Declarations&quot;)</span>
+_LOG<span class="Delimiter">,</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Numbers&quot;)</span>
+put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;$log&quot;</span><span class="Delimiter">,</span> _LOG<span class="Delimiter">);</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
+case _LOG: <span class="Delimiter">{</span>
+  <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+<span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
+case _LOG: <span class="Delimiter">{</span>
+  ostringstream out<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>
+    out &lt;&lt; print_mu<span class="Delimiter">(</span>current_instruction<span class="Delimiter">().</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+  <span class="Delimiter">}</span>
+  LOG &lt;&lt; out<span class="Delimiter">.</span>str<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;(length: &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;length&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">'/'</span> &lt;&lt; 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;length&quot;</span><span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;)</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
+  <span class="Identifier">break</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
 </pre>
 </body>
 </html>
diff --git a/html/030container.cc.html b/html/030container.cc.html
index 8ef0dda6..77c582c7 100644
--- a/html/030container.cc.html
+++ b/html/030container.cc.html
@@ -171,7 +171,7 @@ case GET: <span class="Delimiter">{</span>
   <span class="Delimiter">}</span>
   reagent base = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>  <span class="Comment">// new copy for every invocation</span>
   <span class="Comment">// Update GET base in Check</span>
-  if <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type || !base<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">).</span>kind != CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type || !base<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">).</span>kind != CONTAINER<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;first ingredient of 'get' should be a container, but got &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string &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>
@@ -309,7 +309,7 @@ case GET_ADDRESS: <span class="Delimiter">{</span>
   <span class="Delimiter">}</span>
   reagent base = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
   <span class="Comment">// Update GET_ADDRESS base in Check</span>
-  if <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">).</span>kind != CONTAINER<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!base<span class="Delimiter">.</span>type || !base<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value || !contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> base<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">).</span>kind != CONTAINER<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;first ingredient of 'get-address' should be a container, but got &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>original_string &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>
@@ -438,7 +438,7 @@ else if <span class="Delimiter">(</span>command == <span class="Constant">&quot;
 
 <span class="Delimiter">:(code)</span>
 void insert_container<span class="Delimiter">(</span>const string&amp; command<span class="Delimiter">,</span> kind_of_type kind<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>
+  skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   string name = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   <span class="Comment">// End container Name Refinements</span>
   trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">&quot;parse&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;--- defining &quot;</span> &lt;&lt; command &lt;&lt; <span class="Constant">' '</span> &lt;&lt; name &lt;&lt; end<span class="Delimiter">();</span>
@@ -449,7 +449,7 @@ void insert_container<span class="Delimiter">(</span>const string&amp; command<s
   trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;parse&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;type number: &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> name<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
   skip_bracket<span class="Delimiter">(</span>in<span class="Delimiter">,</span> <span class="Constant">&quot;'container' must begin with '['&quot;</span><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>
-  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>
+  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>has_data<span class="Delimiter">(</span>in<span class="Delimiter">))</span> <span class="Delimiter">{</span>
@@ -505,22 +505,22 @@ recipe main [
 
 <span class="Comment">//: ensure types created in one scenario don't leak outside it.</span>
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
-vector&lt;type_ordinal&gt; recently_added_types<span class="Delimiter">;</span>
+vector&lt;type_ordinal&gt; Recently_added_types<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End load_permanently&quot;)</span>  <span class="Comment">//: for non-tests</span>
-recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+Recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
 <span class="Delimiter">:(before &quot;End Setup&quot;)</span>  <span class="Comment">//: for tests</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>
-  if <span class="Delimiter">(</span>!contains_key<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> <span class="Identifier">continue</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>
+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>
+  if <span class="Delimiter">(</span>!contains_key<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> <span class="Identifier">continue</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>
   <span class="Comment">// todo: why do I explicitly need to provide this?</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>Type<span class="Delimiter">.</span>at<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>elements<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    delete Type<span class="Delimiter">.</span>at<span class="Delimiter">(</span>recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<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>Type<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>elements<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    delete Type<span class="Delimiter">.</span>at<span class="Delimiter">(</span>Recently_added_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)).</span>elements<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">);</span>
   <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>
+  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>
-recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+Recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
 <span class="Comment">// delete recent type references</span>
-<span class="Comment">// can't rely on recently_added_types to cleanup Type_ordinal, because of deliberately misbehaving tests with references to undefined types</span>
+<span class="Comment">// can't rely on Recently_added_types to cleanup Type_ordinal, because of deliberately misbehaving tests with references to undefined types</span>
 map&lt;string<span class="Delimiter">,</span> type_ordinal&gt;::iterator p = Type_ordinal<span class="Delimiter">.</span>begin<span class="Delimiter">();</span>
 while<span class="Delimiter">(</span>p != Type_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span> <span class="Delimiter">{</span>
   <span class="Comment">// save current item</span>
@@ -568,17 +568,19 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa
 
 <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>
-  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>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    const 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>index<span class="Delimiter">);</span>
+  recipe&amp; caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</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<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<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>index<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>
       check_or_set_invalid_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>
-                                 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> <span class="Constant">&quot;'&quot;</span>+inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span>+<span class="Constant">&quot;'&quot;</span><span class="Delimiter">);</span>
+                                 maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">),</span> <span class="Constant">&quot;'&quot;</span>+inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span>+<span class="Constant">&quot;'&quot;</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>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       check_or_set_invalid_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>
-                                 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> <span class="Constant">&quot;'&quot;</span>+inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span>+<span class="Constant">&quot;'&quot;</span><span class="Delimiter">);</span>
+                                 maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">),</span> <span class="Constant">&quot;'&quot;</span>+inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span>+<span class="Constant">&quot;'&quot;</span><span class="Delimiter">);</span>
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
+  <span class="Comment">// End check_or_set_invalid_types</span>
 <span class="Delimiter">}</span>
 
 void check_or_set_invalid_types<span class="Delimiter">(</span>type_tree* type<span class="Delimiter">,</span> const string_tree* type_name<span class="Delimiter">,</span> const string&amp; block<span class="Delimiter">,</span> const string&amp; name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
diff --git a/html/031address.cc.html b/html/031address.cc.html
index 5a58fc2f..cabdc541 100644
--- a/html/031address.cc.html
+++ b/html/031address.cc.html
@@ -96,6 +96,13 @@ 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">:(scenario canonize_non_pointer_fails_without_crashing)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe foo [
+  <span class="Constant">1</span>:address:number<span class="Special"> &lt;- </span>get-address *p<span class="Delimiter">,</span> x:offset
+]
+<span class="Comment"># don't crash</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>
@@ -123,6 +130,10 @@ bool canonize_type<span class="Delimiter">(</span>reagent&amp; r<span class="Del
 <span class="Delimiter">}</span>
 
 void drop_address_from_type<span class="Delimiter">(</span>reagent&amp; 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="Delimiter">{</span>
+    raise_error &lt;&lt; <span class="Constant">&quot;can't drop address from &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>r<span class="Delimiter">)</span> &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>
   type_tree* tmp = r<span class="Delimiter">.</span>type<span class="Delimiter">;</span>
   r<span class="Delimiter">.</span>type = tmp<span class="Delimiter">-&gt;</span>right<span class="Delimiter">;</span>
   tmp<span class="Delimiter">-&gt;</span>right = <span class="Constant">NULL</span><span class="Delimiter">;</span>
diff --git a/html/036call_reply.cc.html b/html/036call_reply.cc.html
index 1784c8f9..dac5314a 100644
--- a/html/036call_reply.cc.html
+++ b/html/036call_reply.cc.html
@@ -51,60 +51,29 @@ REPLY<span class="Delimiter">,</span>
 put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;reply&quot;</span><span class="Delimiter">,</span> REPLY<span class="Delimiter">);</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Checks&quot;)</span>
 case REPLY: <span class="Delimiter">{</span>
-  <span class="Identifier">break</span><span class="Delimiter">;</span>  <span class="Comment">// continue to process rest of *caller* instruction</span>
+  <span class="Identifier">break</span><span class="Delimiter">;</span>  <span class="Comment">// checks will be performed by a transform below</span>
 <span class="Delimiter">}</span>
 <span class="Delimiter">:(before &quot;End Primitive Recipe Implementations&quot;)</span>
 case REPLY: <span class="Delimiter">{</span>
   <span class="Comment">// Starting Reply</span>
-  const instruction&amp; reply_inst = current_instruction<span class="Delimiter">();</span>  <span class="Comment">// save pointer into recipe before pop</span>
-  const string&amp; callee = current_recipe_name<span class="Delimiter">();</span>
   if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;trace&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;reply: decrementing callstack depth from &quot;</span> &lt;&lt; Trace_stream<span class="Delimiter">-&gt;</span>callstack_depth &lt;&lt; end<span class="Delimiter">();</span>
     --Trace_stream<span class="Delimiter">-&gt;</span>callstack_depth<span class="Delimiter">;</span>
-    assert<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>callstack_depth &gt;= <span class="Constant">0</span><span class="Delimiter">);</span>
+    if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>callstack_depth &lt; <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+      <span class="Identifier">goto</span> stop_running_current_routine<span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
   Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>pop_front<span class="Delimiter">();</span>
   <span class="Comment">// just in case 'main' returns a value, drop it for now</span>
   if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">goto</span> stop_running_current_routine<span class="Delimiter">;</span>
   const instruction&amp; caller_instruction = current_instruction<span class="Delimiter">();</span>
-  <span class="Comment">// check types with the caller</span>
-  if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">)</span> &gt; SIZE<span class="Delimiter">(</span>ingredients<span class="Delimiter">))</span> <span class="Delimiter">{</span>
-    raise_error &lt;&lt; <span class="Constant">&quot;too few values replied from &quot;</span> &lt;&lt; callee &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>
-  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_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>
+  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>
+    trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;result &quot;</span> &lt;&lt; i &lt;&lt; <span class="Constant">&quot; is &quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> &lt;&lt; end<span class="Delimiter">();</span>
+
   <span class="Comment">// make reply products available to caller</span>
   copy<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> ingredients<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> inserter<span class="Delimiter">(</span>products<span class="Delimiter">,</span> products<span class="Delimiter">.</span>begin<span class="Delimiter">()));</span>
-  <span class="Comment">// check that any reply ingredients with /same-as-ingredient connect up</span>
-  <span class="Comment">// the corresponding ingredient and product in the caller.</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>
-    trace<span class="Delimiter">(</span><span class="Constant">9998</span><span class="Delimiter">,</span> <span class="Constant">&quot;run&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;result &quot;</span> &lt;&lt; i &lt;&lt; <span class="Constant">&quot; is &quot;</span> &lt;&lt; to_string<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> &lt;&lt; end<span class="Delimiter">();</span>
-    if <span class="Delimiter">(</span>has_property<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="Constant">&quot;same-as-ingredient&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
-      string_tree* tmp = property<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="Constant">&quot;same-as-ingredient&quot;</span><span class="Delimiter">);</span>
-      if <span class="Delimiter">(</span>!tmp || tmp<span class="Delimiter">-&gt;</span>right<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;'same-as-ingredient' metadata should take exactly one value in &quot;</span> &lt;&lt; reply_inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
-        <span class="Identifier">goto</span> finish_reply<span class="Delimiter">;</span>
-      <span class="Delimiter">}</span>
-      long long int ingredient_index = to_integer<span class="Delimiter">(</span>tmp<span class="Delimiter">-&gt;</span>value<span class="Delimiter">);</span>
-      if <span class="Delimiter">(</span>ingredient_index &gt;= SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>ingredients<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;'same-as-ingredient' metadata overflows ingredients in: &quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
-      if <span class="Delimiter">(</span>!is_dummy<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> &amp;&amp; caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>value != caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>value<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;'&quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' should write to &quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot; rather than &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>
-    <span class="Delimiter">}</span>
-  <span class="Delimiter">}</span>
   <span class="Comment">// End Reply</span>
-  finish_reply:
   <span class="Identifier">break</span><span class="Delimiter">;</span>  <span class="Comment">// continue to process rest of *caller* instruction</span>
 <span class="Delimiter">}</span>
 
@@ -122,6 +91,60 @@ recipe f [
 <span class="traceContains">+mem: storing 2 in location 3</span>
 <span class="traceContains">+mem: storing 35 in location 4</span>
 
+<span class="Comment">//: Types in reply instructions are checked ahead of time.</span>
+
+<span class="Delimiter">:(before &quot;End Checks&quot;)</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_types_of_reply_instructions<span class="Delimiter">);</span>
+<span class="Delimiter">:(code)</span>
+void check_types_of_reply_instructions<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>
+  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; caller_instruction = 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>caller_instruction<span class="Delimiter">.</span>is_label<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>operation &lt; MAX_PRIMITIVE_RECIPES<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+    const recipe&amp; callee = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> caller_instruction<span class="Delimiter">.</span>operation<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>callee<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      const instruction&amp; reply_inst = callee<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+      if <span class="Delimiter">(</span>reply_inst<span class="Delimiter">.</span>operation != REPLY<span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+      <span class="Comment">// check types with the caller</span>
+      if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">)</span> &gt; SIZE<span class="Delimiter">(</span>reply_inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> <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;too few values replied from &quot;</span> &lt;&lt; callee<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>
+      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_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>name<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_check<span class="Delimiter">;</span>
+        <span class="Delimiter">}</span>
+      <span class="Delimiter">}</span>
+      <span class="Comment">// check that any reply ingredients with /same-as-ingredient connect up</span>
+      <span class="Comment">// the corresponding ingredient and product in the caller.</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>has_property<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="Constant">&quot;same-as-ingredient&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
+          string_tree* tmp = property<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="Constant">&quot;same-as-ingredient&quot;</span><span class="Delimiter">);</span>
+          if <span class="Delimiter">(</span>!tmp || tmp<span class="Delimiter">-&gt;</span>right<span class="Delimiter">)</span> <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;'same-as-ingredient' metadata should take exactly one value in &quot;</span> &lt;&lt; reply_inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+            <span class="Identifier">goto</span> finish_reply_check<span class="Delimiter">;</span>
+          <span class="Delimiter">}</span>
+          long long int ingredient_index = to_integer<span class="Delimiter">(</span>tmp<span class="Delimiter">-&gt;</span>value<span class="Delimiter">);</span>
+          if <span class="Delimiter">(</span>ingredient_index &gt;= SIZE<span class="Delimiter">(</span>caller_instruction<span class="Delimiter">.</span>ingredients<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;'same-as-ingredient' metadata overflows ingredients in: &quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+          if <span class="Delimiter">(</span>!is_dummy<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> &amp;&amp; caller_instruction<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name != caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>name<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;'&quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' should write to &quot;</span> &lt;&lt; caller_instruction<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>original_string &lt;&lt; <span class="Constant">&quot; rather than &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>
+        <span class="Delimiter">}</span>
+      <span class="Delimiter">}</span>
+      finish_reply_check:<span class="Delimiter">;</span>
+    <span class="Delimiter">}</span>
+  <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
 <span class="Delimiter">:(scenario reply_type_mismatch)</span>
 <span class="Special">% Hide_errors = true;</span>
 recipe main [
diff --git a/html/042name.cc.html b/html/042name.cc.html
index aa0a1fe9..08b875ef 100644
--- a/html/042name.cc.html
+++ b/html/042name.cc.html
@@ -59,9 +59,9 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa
 
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
 map&lt;recipe_ordinal<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> long long int&gt; &gt; Name<span class="Delimiter">;</span>
-<span class="Delimiter">:(after &quot;Clear Other State For recently_added_recipes&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>recently_added_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  Name<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
+<span class="Delimiter">:(after &quot;Clear Other State For Recently_added_recipes&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>Recently_added_recipes<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  Name<span class="Delimiter">.</span>erase<span class="Delimiter">(</span>Recently_added_recipes<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(code)</span>
diff --git a/html/054dilated_reagent.cc.html b/html/054dilated_reagent.cc.html
index 02f714e4..1d908069 100644
--- a/html/054dilated_reagent.cc.html
+++ b/html/054dilated_reagent.cc.html
@@ -67,7 +67,7 @@ bool start_of_dilated_reagent<span class="Delimiter">(</span>istream&amp; in<spa
   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>
+  skip_whitespace_but_not_newline<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>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>
diff --git a/html/055parse_tree.cc.html b/html/055parse_tree.cc.html
index 14142686..1d97dee4 100644
--- a/html/055parse_tree.cc.html
+++ b/html/055parse_tree.cc.html
@@ -60,7 +60,7 @@ string_tree* parse_string_tree<span class="Delimiter">(</span>const string&amp;
 <span class="Delimiter">}</span>
 
 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>
+  skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<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>
@@ -76,8 +76,7 @@ string_tree* parse_string_tree<span class="Delimiter">(</span>istream&amp; in<sp
   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>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>
+    skip_whitespace_but_not_newline<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="Delimiter">(</span>*curr<span class="Delimiter">)-&gt;</span>left = parse_string_tree<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     else
diff --git a/html/056recipe_header.cc.html b/html/056recipe_header.cc.html
index a1c6dd82..08cc8fdd 100644
--- a/html/056recipe_header.cc.html
+++ b/html/056recipe_header.cc.html
@@ -13,16 +13,17 @@
 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; }
-.traceContains { color: #008000; }
 .SalientComment { color: #00ffff; }
-.cSpecial { color: #008000; }
+.CommentedCode { color: #6c6c6c; }
+.Error { color: #ffffff; background-color: #ff6060; padding-bottom: 1px; }
+.Delimiter { color: #a04060; }
+.traceContains { color: #008000; }
 .traceAbsent { color: #c00000; }
+.cSpecial { color: #008000; }
 .Comment { color: #9090ff; }
-.Delimiter { color: #a04060; }
+.Constant { color: #00a0a0; }
 .Special { color: #ff6060; }
 .Identifier { color: #804000; }
-.Constant { color: #00a0a0; }
-.CommentedCode { color: #6c6c6c; }
 -->
 </style>
 
@@ -59,7 +60,6 @@ vector&lt;reagent&gt; products<span class="Delimiter">;</span>
 has_header = <span class="Constant">false</span><span class="Delimiter">;</span>
 
 <span class="Delimiter">:(before &quot;End recipe Refinements&quot;)</span>
-skip_whitespace<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="Delimiter">{</span>
   trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;parse&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;recipe has a header; parsing&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
   load_recipe_header<span class="Delimiter">(</span>in<span class="Delimiter">,</span> result<span class="Delimiter">);</span>
@@ -68,18 +68,18 @@ if <span class="Delimiter">(</span>in<span class="Delimiter">.</span>peek<span c
 <span class="Delimiter">:(code)</span>
 void load_recipe_header<span class="Delimiter">(</span>istream&amp; in<span class="Delimiter">,</span> recipe&amp; result<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   result<span class="Delimiter">.</span>has_header = <span class="Constant">true</span><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>
+  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="Constant">'['</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>
     string s = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     if <span class="Delimiter">(</span>s == <span class="Constant">&quot;-&gt;&quot;</span><span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
     result<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span>s<span class="Delimiter">));</span>
     trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;parse&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;header ingredient: &quot;</span> &lt;&lt; result<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>back<span class="Delimiter">().</span>original_string &lt;&lt; end<span class="Delimiter">();</span>
-    skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+    skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   <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>
+  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="Constant">'['</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>
     string s = next_word<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
     result<span class="Delimiter">.</span>products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>reagent<span class="Delimiter">(</span>s<span class="Delimiter">));</span>
     trace<span class="Delimiter">(</span><span class="Constant">9999</span><span class="Delimiter">,</span> <span class="Constant">&quot;parse&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;header product: &quot;</span> &lt;&lt; result<span class="Delimiter">.</span>products<span class="Delimiter">.</span>back<span class="Delimiter">().</span>original_string &lt;&lt; end<span class="Delimiter">();</span>
-    skip_whitespace_and_comments<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
+    skip_whitespace_but_not_newline<span class="Delimiter">(</span>in<span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
   <span class="Comment">// End Load Recipe Header(result)</span>
 <span class="Delimiter">}</span>
@@ -108,6 +108,34 @@ recipe bar [
 ]
 <span class="traceContains">+mem: storing 4 in location 1</span>
 
+<span class="Delimiter">:(scenario recipe_handles_missing_bracket)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main
+<span class="Error">]</span>
+<span class="traceContains">+error: recipe body must begin with '['</span>
+
+<span class="Delimiter">:(scenario recipe_handles_missing_bracket_2)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main
+  local-scope
+  <span class="Delimiter">{</span>
+  <span class="Delimiter">}</span>
+<span class="Error">]</span>
+<span class="Comment"># doesn't overflow line when reading header</span>
+<span class="traceAbsent">-parse: header ingredient: local-scope</span>
+<span class="traceContains">+error: recipe body must begin with '['</span>
+
+<span class="Delimiter">:(scenario recipe_handles_missing_bracket_3)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main  <span class="Comment"># comment</span>
+  local-scope
+  <span class="Delimiter">{</span>
+  <span class="Delimiter">}</span>
+<span class="Error">]</span>
+<span class="Comment"># doesn't overflow line when reading header</span>
+<span class="traceAbsent">-parse: header ingredient: local-scope</span>
+<span class="traceContains">+error: recipe body must begin with '['</span>
+
 <span class="Delimiter">:(after &quot;Begin debug_string(recipe x)&quot;)</span>
 out &lt;&lt; <span class="Constant">&quot;ingredients:</span><span class="cSpecial">\n</span><span class="Constant">&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>x<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
diff --git a/html/057static_dispatch.cc.html b/html/057static_dispatch.cc.html
index 1c7b28b7..04d02ab2 100644
--- a/html/057static_dispatch.cc.html
+++ b/html/057static_dispatch.cc.html
@@ -15,12 +15,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 1.05em; }
 .traceContains { color: #008000; }
 .traceAbsent { color: #c00000; }
+.Identifier { color: #804000; }
 .cSpecial { color: #008000; }
-.CommentedCode { color: #6c6c6c; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.Identifier { color: #804000; }
+.CommentedCode { color: #6c6c6c; }
 .Constant { color: #00a0a0; }
 -->
 </style>
@@ -56,10 +56,10 @@ recipe test a:number<span class="Delimiter">,</span> b:number <span class="Delim
 map&lt;string<span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt; &gt; Recipe_variants<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End One-time Setup&quot;)</span>
 put<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> <span class="Constant">&quot;main&quot;</span><span class="Delimiter">,</span> vector&lt;recipe_ordinal&gt;<span class="Delimiter">());</span>  <span class="Comment">// since we manually added main to Recipe_ordinal</span>
-<span class="Delimiter">:(before &quot;End Setup&quot;)</span>
+<span class="Delimiter">:(before &quot;Clear Other State For Recently_added_recipes&quot;)</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>
   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>p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)</span> &gt;= Reserved_for_tests<span class="Delimiter">)</span>
+    if <span class="Delimiter">(</span>find<span class="Delimiter">(</span>Recently_added_recipes<span class="Delimiter">.</span>begin<span class="Delimiter">(),</span> Recently_added_recipes<span class="Delimiter">.</span>end<span class="Delimiter">(),</span> p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> != Recently_added_recipes<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
       p<span class="Delimiter">-&gt;</span>second<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">// just leave a ghost</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
@@ -67,30 +67,41 @@ 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>
-  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_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>
+<span class="CommentedCode">//?   LOG &lt;&lt; &quot;checking &quot; &lt;&lt; r &lt;&lt; &quot; &quot; &lt;&lt; result.name &lt;&lt; '\n';</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; result.name &lt;&lt; &quot;: &quot; &lt;&lt; contains_key(Recipe, r) &lt;&lt; (contains_key(Recipe, r) ? get(Recipe, r).has_header : 0) &lt;&lt; matching_variant_name(result) &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> <span class="Delimiter">{</span>
+    string new_name = matching_variant_name<span class="Delimiter">(</span>result<span class="Delimiter">);</span>
+    if <span class="Delimiter">(</span>new_name<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+      <span class="Comment">// variant doesn't already exist</span>
+      new_name = next_unused_recipe_name<span class="Delimiter">(</span>result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+<span class="CommentedCode">//?       LOG &lt;&lt; &quot;adding a variant of &quot; &lt;&lt; result.name &lt;&lt; &quot;: &quot; &lt;&lt; new_name &lt;&lt; &quot; is now &quot; &lt;&lt; Next_recipe_ordinal &lt;&lt; '\n';</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_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>
+    <span class="Delimiter">}</span>
     result<span class="Delimiter">.</span>name = new_name<span class="Delimiter">;</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;=&gt; &quot; &lt;&lt; new_name &lt;&lt; '\n';</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 else <span class="Delimiter">{</span>
   <span class="Comment">// save first variant</span>
+<span class="CommentedCode">//?   LOG &lt;&lt; &quot;saving first variant of &quot; &lt;&lt; result.name &lt;&lt; &quot;: &quot; &lt;&lt; Next_recipe_ordinal &lt;&lt; '\n';</span>
   put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">,</span> Next_recipe_ordinal++<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> result<span class="Delimiter">.</span>name<span class="Delimiter">));</span>
 <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>
+string matching_variant_name<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_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>
-      <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-    <span class="Delimiter">}</span>
+<span class="CommentedCode">//?     LOG &lt;&lt; &quot;checking variant &quot; &lt;&lt; variants.at(i) &lt;&lt; &quot; of &quot; &lt;&lt; rr.name &lt;&lt; '\n';</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> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+    const recipe&amp; candidate = 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>
+    if <span class="Delimiter">(</span>!all_reagents_match<span class="Delimiter">(</span>rr<span class="Delimiter">,</span> candidate<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
+<span class="CommentedCode">//?     LOG &lt;&lt; &quot;  exists\n&quot;;</span>
+    <span class="Identifier">return</span> candidate<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+<span class="CommentedCode">//?   LOG &lt;&lt; &quot;  does not exist\n&quot;;</span>
+  <span class="Identifier">return</span> <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
 bool all_reagents_match<span class="Delimiter">(</span>const recipe&amp; r1<span class="Delimiter">,</span> const recipe&amp; r2<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -155,6 +166,17 @@ 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">//: support recipe headers in a previous transform to fill in missing types</span>
+<span class="Delimiter">:(before &quot;End check_or_set_invalid_types&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>caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  check_or_set_invalid_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>type<span class="Delimiter">,</span> caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>
+                             maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">),</span> <span class="Constant">&quot;recipe header ingredient&quot;</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<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  check_or_set_invalid_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>type<span class="Delimiter">,</span> caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<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>
+                             maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">),</span> <span class="Constant">&quot;recipe header product&quot;</span><span class="Delimiter">);</span>
+<span class="Delimiter">}</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;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>
@@ -188,6 +210,9 @@ void replace_best_variant<span class="Delimiter">(</span>instruction&amp; inst<s
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
   <span class="Comment">// End Instruction Dispatch(inst, best_score)</span>
+  if <span class="Delimiter">(</span>best_score == -<span class="Constant">1</span> &amp;&amp; get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &gt;= MAX_PRIMITIVE_RECIPES<span class="Delimiter">)</span> <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;failed to find a matching call for '&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>
 <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>
@@ -235,6 +260,7 @@ long long int variant_score<span class="Delimiter">(</span>const instruction&amp
   <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>is_dummy<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="Identifier">continue</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>
@@ -302,6 +328,55 @@ recipe equal x:number<span class="Delimiter">,</span> y:number <span class="Deli
 <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_works_with_dummy_results_for_containers)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  _<span class="Special"> &lt;- </span>test <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">4</span>
+]
+recipe test a:number <span class="Delimiter">-&gt;</span> z:point [
+  local-scope
+  load-ingredients
+  z<span class="Special"> &lt;- </span>merge a<span class="Delimiter">,</span> <span class="Constant">0</span>
+]
+recipe test a:number<span class="Delimiter">,</span> b:number <span class="Delimiter">-&gt;</span> z:point [
+  local-scope
+  load-ingredients
+  z<span class="Special"> &lt;- </span>merge a<span class="Delimiter">,</span> b
+]
+$error: <span class="Constant">0</span>
+
+<span class="Delimiter">:(scenario static_dispatch_works_with_compound_type_containing_container_defined_after_first_use)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  x:address:foo<span class="Special"> &lt;- </span>new foo:type
+  test x
+]
+container foo [
+  x:number
+]
+recipe test a:address:foo <span class="Delimiter">-&gt;</span> z:number [
+  local-scope
+  load-ingredients
+  z:number<span class="Special"> &lt;- </span>get *a<span class="Delimiter">,</span> x:offset
+]
+$error: <span class="Constant">0</span>
+
+<span class="Delimiter">:(scenario static_dispatch_works_with_compound_type_containing_container_defined_after_second_use)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  x:address:foo<span class="Special"> &lt;- </span>new foo:type
+  test x
+]
+recipe test a:address:foo <span class="Delimiter">-&gt;</span> z:number [
+  local-scope
+  load-ingredients
+  z:number<span class="Special"> &lt;- </span>get *a<span class="Delimiter">,</span> x:offset
+]
+container foo [
+  x:number
+]
+$error: <span class="Constant">0</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>
@@ -428,6 +503,30 @@ string header_label<span class="Delimiter">(</span>recipe_ordinal r<span class="
     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>
+
+<span class="Delimiter">:(scenario reload_variant_retains_other_variants)</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:number <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">34</span>
+]
+recipe foo x:address:number <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">35</span>
+]
+recipe! foo x:address:number <span class="Delimiter">-&gt;</span> y:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">36</span>
+]
+<span class="traceContains">+mem: storing 34 in location 2</span>
+$error: <span class="Constant">0</span>
+$warn: <span class="Constant">0</span>
 </pre>
 </body>
 </html>
diff --git a/html/059shape_shifting_recipe.cc.html b/html/059shape_shifting_recipe.cc.html
index ce450999..4b895042 100644
--- a/html/059shape_shifting_recipe.cc.html
+++ b/html/059shape_shifting_recipe.cc.html
@@ -79,20 +79,20 @@ if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Del
 <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">//: 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>
+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>
+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>
+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>
+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>
@@ -107,26 +107,58 @@ if <span class="Delimiter">(</span>best_score == -<span class="Constant">1</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>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;specializing &quot; &lt;&lt; inst.name &lt;&lt; '\n';</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>
-<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>
+    LOG &lt;&lt; <span class="Constant">&quot;found variant to specialize: &quot;</span> &lt;&lt; exemplar &lt;&lt; <span class="Constant">' '</span> &lt;&lt; header<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</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>
+    LOG &lt;&lt; <span class="Constant">&quot;transforming new specialization: &quot;</span> &lt;&lt; header<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>back<span class="Delimiter">()))</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</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>
+    LOG &lt;&lt; <span class="Constant">&quot;replacing &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; with &quot;</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>back<span class="Delimiter">()).</span>name &lt;&lt; <span class="cSpecial">'\n'</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>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>
+    LOG &lt;&lt; <span class="Constant">&quot;new specialization: &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
+<span class="Comment">//: make sure we have no unspecialized shape-shifting recipes being called</span>
+<span class="Comment">//: before running mu programs</span>
+
+<span class="Delimiter">:(before &quot;End Instruction Operation Checks&quot;)</span>
+<span class="CommentedCode">//? LOG &lt;&lt; inst.operation &lt;&lt; &quot; &quot; &lt;&lt; contains_key(Recipe, inst.operation) &lt;&lt; '\n';</span>
+if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>operation<span class="Delimiter">)</span> &amp;&amp; inst<span class="Delimiter">.</span>operation &gt;= MAX_PRIMITIVE_RECIPES
+    &amp;&amp; any_type_ingredient_in_header<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   LOG &lt;&lt; header(caller) &lt;&lt; &quot;instruction &quot; &lt;&lt; inst.name &lt;&lt; &quot; has no valid specialization\n&quot;;</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;instruction &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; has no valid specialization</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">:(code)</span>
+string header<span class="Delimiter">(</span>const recipe&amp; caller<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!caller<span class="Delimiter">.</span>has_header<span class="Delimiter">)</span> <span class="Identifier">return</span> maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+  ostringstream out<span class="Delimiter">;</span>
+  out &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> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>i &gt; <span class="Constant">0</span><span class="Delimiter">)</span> out &lt;&lt; <span class="Constant">','</span><span class="Delimiter">;</span>
+    out &lt;&lt; <span class="Constant">' '</span> &lt;&lt; debug_string<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="Delimiter">}</span>
+  if <span class="Delimiter">(</span>!caller<span class="Delimiter">.</span>products<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <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> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>i &gt; <span class="Constant">0</span><span class="Delimiter">)</span> out &lt;&lt; <span class="Constant">','</span><span class="Delimiter">;</span>
+      out &lt;&lt; <span class="Constant">' '</span> &lt;&lt; debug_string<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="Delimiter">}</span>
+  <span class="Delimiter">}</span>
+  out &lt;&lt; <span class="Constant">&quot;: &quot;</span><span class="Delimiter">;</span>
+  <span class="Identifier">return</span> out<span class="Delimiter">.</span>str<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
 recipe_ordinal pick_matching_shape_shifting_variant<span class="Delimiter">(</span>vector&lt;recipe_ordinal&gt;&amp; variants<span class="Delimiter">,</span> const instruction&amp; inst<span class="Delimiter">,</span> long long int&amp; best_score<span class="Delimiter">)</span> <span class="Delimiter">{</span>
 <span class="CommentedCode">//?   cerr &lt;&lt; &quot;---- &quot; &lt;&lt; inst.name &lt;&lt; &quot;: &quot; &lt;&lt; non_ghost_size(variants) &lt;&lt; '\n';</span>
   recipe_ordinal result = <span class="Constant">0</span><span class="Delimiter">;</span>
@@ -173,6 +205,7 @@ long long int shape_shifting_variant_score<span class="Delimiter">(</span>const
   <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>is_dummy<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="Identifier">continue</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>
@@ -270,8 +303,8 @@ recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exempla
   <span class="Comment">// make a copy</span>
   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>
+  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>
diff --git a/html/060immutable.cc.html b/html/060immutable.cc.html
new file mode 100644
index 00000000..8d8c7633
--- /dev/null
+++ b/html/060immutable.cc.html
@@ -0,0 +1,389 @@
+<!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 - 060immutable.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; }
+.traceContains { color: #008000; }
+.Identifier { color: #804000; }
+.cSpecial { color: #008000; }
+.Constant { color: #00a0a0; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+.CommentedCode { color: #6c6c6c; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Comment">//: Addresses passed into of a recipe are meant to be immutable unless they're</span>
+<span class="Comment">//: also products. This layer will start enforcing this check.</span>
+
+<span class="Delimiter">:(scenario can_modify_value_ingredients)</span>
+<span class="Special">% Hide_warnings = true;</span>
+recipe main [
+  local-scope
+  p:address:point<span class="Special"> &lt;- </span>new point:type
+  foo *p
+]
+recipe foo p:point [
+  local-scope
+  load-ingredients
+  x:address:number<span class="Special"> &lt;- </span>get-address p<span class="Delimiter">,</span> x:offset
+  *x<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+]
+$warn: <span class="Constant">0</span>
+
+<span class="Delimiter">:(scenario can_modify_ingredients_that_are_also_products)</span>
+<span class="Special">% Hide_warnings = true;</span>
+recipe main [
+  local-scope
+  p:address:point<span class="Special"> &lt;- </span>new point:type
+  p<span class="Special"> &lt;- </span>foo p
+]
+recipe foo p:address:point <span class="Delimiter">-&gt;</span> p:address:point [
+  local-scope
+  load-ingredients
+  x:address:number<span class="Special"> &lt;- </span>get-address *p<span class="Delimiter">,</span> x:offset
+  *x<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+]
+$warn: <span class="Constant">0</span>
+
+<span class="Delimiter">:(scenario ignore_literal_ingredients_for_immutability_checks)</span>
+<span class="Special">% Hide_warnings = true;</span>
+recipe main [
+  local-scope
+  p:address:d1<span class="Special"> &lt;- </span>new d1:type
+  q:number<span class="Special"> &lt;- </span>foo p
+]
+recipe foo p:address:d1 <span class="Delimiter">-&gt;</span> q:number [
+  local-scope
+  load-ingredients
+  x:address:d1<span class="Special"> &lt;- </span>new d1:type
+  y:address:number<span class="Special"> &lt;- </span>get-address *x<span class="Delimiter">,</span> p:offset  <span class="Comment"># ignore this 'p'</span>
+  q<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+]
+container d1 [
+  p:number
+  q:number
+]
+$warn: <span class="Constant">0</span>
+
+<span class="Delimiter">:(scenario cannot_take_address_inside_immutable_ingredients)</span>
+<span class="Special">% Hide_warnings = true;</span>
+recipe main [
+  local-scope
+  p:address:point<span class="Special"> &lt;- </span>new point:type
+  foo p
+]
+recipe foo p:address:point [
+  local-scope
+  load-ingredients
+  x:address:number<span class="Special"> &lt;- </span>get-address *p<span class="Delimiter">,</span> x:offset
+  *x<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+]
+<span class="traceContains">+warn: foo: cannot modify ingredient p after instruction 'x:address:number &lt;- get-address *p, x:offset' because it's not also a product of foo</span>
+
+<span class="Delimiter">:(scenario cannot_call_mutating_recipes_on_immutable_ingredients)</span>
+<span class="Special">% Hide_warnings = true;</span>
+recipe main [
+  local-scope
+  p:address:point<span class="Special"> &lt;- </span>new point:type
+  foo p
+]
+recipe foo p:address:point [
+  local-scope
+  load-ingredients
+  bar p
+]
+recipe bar p:address:point <span class="Delimiter">-&gt;</span> p:address:point [
+  local-scope
+  load-ingredients
+  x:address:number<span class="Special"> &lt;- </span>get-address *p<span class="Delimiter">,</span> x:offset
+  *x<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
+]
+<span class="traceContains">+warn: foo: cannot modify ingredient p at instruction 'bar p' because it's not also a product of foo</span>
+
+<span class="Delimiter">:(scenario cannot_modify_copies_of_immutable_ingredients)</span>
+<span class="Special">% Hide_warnings = true;</span>
+recipe main [
+  local-scope
+  p:address:point<span class="Special"> &lt;- </span>new point:type
+  foo p
+]
+recipe foo p:address:point [
+  local-scope
+  load-ingredients
+  q:address:point<span class="Special"> &lt;- </span>copy p
+  x:address:number<span class="Special"> &lt;- </span>get-address *q<span class="Delimiter">,</span> x:offset
+]
+<span class="traceContains">+warn: foo: cannot modify q after instruction 'x:address:number &lt;- get-address *q, x:offset' because that would modify ingredient p which is not also a product of foo</span>
+
+<span class="Delimiter">:(scenario can_traverse_immutable_ingredients)</span>
+<span class="Special">% Hide_warnings = true;</span>
+container test-list [
+  next:address:test-list
+]
+recipe main [
+  local-scope
+  p:address:test-list<span class="Special"> &lt;- </span>new test-list:type
+  foo p
+]
+recipe foo p:address:test-list [
+  local-scope
+  load-ingredients
+  p2:address:test-list<span class="Special"> &lt;- </span>bar p
+]
+recipe bar x:address:test-list <span class="Delimiter">-&gt;</span> y:address:test-list [
+  local-scope
+  load-ingredients
+  y<span class="Special"> &lt;- </span>get *x<span class="Delimiter">,</span> next:offset
+]
+$warn: <span class="Constant">0</span>
+
+<span class="Delimiter">:(scenario handle_optional_ingredients_in_immutability_checks)</span>
+<span class="Special">% Hide_warnings = true;</span>
+recipe main [
+  k:address:number<span class="Special"> &lt;- </span>new number:type
+  test k
+]
+<span class="Comment"># recipe taking an immutable address ingredient</span>
+recipe test k:address:number [
+  local-scope
+  load-ingredients
+  foo k
+]
+<span class="Comment"># ..calling a recipe with an optional address ingredient</span>
+recipe foo <span class="Delimiter">-&gt;</span> [
+  local-scope
+  load-ingredients
+  k:address:number<span class="Delimiter">,</span> found?:boolean<span class="Special"> &lt;- </span>next-ingredient
+]
+$warn: <span class="Constant">0</span>
+
+<span class="Delimiter">:(before &quot;End Transforms&quot;)</span>
+Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>check_immutable_ingredients<span class="Delimiter">);</span>  <span class="Comment">// idempotent</span>
+
+<span class="Delimiter">:(code)</span>
+void check_immutable_ingredients<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Comment">// to ensure a reagent isn't modified, it suffices to show that we never</span>
+  <span class="Comment">// call get-address or index-address with it, and that any non-primitive</span>
+  <span class="Comment">// recipe calls in the body aren't returning it as a product.</span>
+  const recipe&amp; caller = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; caller.name &lt;&lt; '\n';</span>
+  if <span class="Delimiter">(</span>!caller<span class="Delimiter">.</span>has_header<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>  <span class="Comment">// skip check for old-style recipes calling next-ingredient directly</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>
+    const reagent&amp; current_ingredient = caller<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;  &quot; &lt;&lt; current_ingredient.original_string &lt;&lt; '\n';</span>
+    if <span class="Delimiter">(</span>!is_mu_address<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>  <span class="Comment">// will be copied</span>
+    if <span class="Delimiter">(</span>is_present_in_products<span class="Delimiter">(</span>caller<span class="Delimiter">,</span> current_ingredient<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>  <span class="Comment">// not expected to be immutable</span>
+    <span class="Comment">// End Immutable Ingredients Special-cases</span>
+    set&lt;string&gt; immutable_vars<span class="Delimiter">;</span>
+    immutable_vars<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>current_ingredient<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>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>
+<span class="CommentedCode">//?       cerr &lt;&lt; &quot;    &quot; &lt;&lt; inst.to_string() &lt;&lt; '\n';</span>
+      check_immutable_ingredient_in_instruction<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> immutable_vars<span class="Delimiter">,</span> current_ingredient<span class="Delimiter">.</span>name<span class="Delimiter">,</span> caller<span class="Delimiter">);</span>
+      update_aliases<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> immutable_vars<span class="Delimiter">);</span>
+    <span class="Delimiter">}</span>
+  <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+void update_aliases<span class="Delimiter">(</span>const instruction&amp; inst<span class="Delimiter">,</span> set&lt;string&gt;&amp; current_ingredient_and_aliases<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  set&lt;long long int&gt; current_ingredient_indices = ingredient_indices<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> current_ingredient_and_aliases<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>operation<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+    <span class="Comment">// primitive recipe</span>
+    if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == COPY<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      for <span class="Delimiter">(</span>set&lt;long long int&gt;::iterator p = current_ingredient_indices<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != current_ingredient_indices<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+        current_ingredient_and_aliases<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>*p<span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+      <span class="Delimiter">}</span>
+    <span class="Delimiter">}</span>
+  <span class="Delimiter">}</span>
+  else <span class="Delimiter">{</span>
+    <span class="Comment">// defined recipe</span>
+    set&lt;long long int&gt; contained_in_product_indices = scan_contained_in_product_indices<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> current_ingredient_indices<span class="Delimiter">);</span>
+    for <span class="Delimiter">(</span>set&lt;long long int&gt;::iterator p = contained_in_product_indices<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != contained_in_product_indices<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>*p &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">))</span>
+        current_ingredient_and_aliases<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>*p<span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+    <span class="Delimiter">}</span>
+  <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+set&lt;long long int&gt; scan_contained_in_product_indices<span class="Delimiter">(</span>const instruction&amp; inst<span class="Delimiter">,</span> set&lt;long long int&gt;&amp; ingredient_indices<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  set&lt;string&gt; selected_ingredient_names<span class="Delimiter">;</span>
+  const recipe&amp; callee = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>operation<span class="Delimiter">);</span>
+  for <span class="Delimiter">(</span>set&lt;long long int&gt;::iterator p = ingredient_indices<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != ingredient_indices<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>*p &gt;= SIZE<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>  <span class="Comment">// optional immutable ingredient</span>
+    selected_ingredient_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>*p<span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+  <span class="Delimiter">}</span>
+  set&lt;long long int&gt; result<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>callee<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    const reagent&amp; current_product = callee<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+    const string_tree* contained_in_name = property<span class="Delimiter">(</span>current_product<span class="Delimiter">,</span> <span class="Constant">&quot;contained-in&quot;</span><span class="Delimiter">);</span>
+    if <span class="Delimiter">(</span>contained_in_name &amp;&amp; selected_ingredient_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>contained_in_name<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != selected_ingredient_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+      result<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+  <span class="Delimiter">}</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Delimiter">:(scenarios transform)</span>
+<span class="Delimiter">:(scenario immutability_infects_contained_in_variables)</span>
+<span class="Special">% Hide_warnings = true;</span>
+container test-list [
+  next:address:test-list
+]
+recipe main [
+  local-scope
+  p:address:test-list<span class="Special"> &lt;- </span>new test-list:type
+  foo p
+]
+recipe foo p:address:test-list [  <span class="Comment"># p is immutable</span>
+  local-scope
+  load-ingredients
+  p2:address:test-list<span class="Special"> &lt;- </span>test-next p  <span class="Comment"># p2 is immutable</span>
+  p3:address:address:test-list<span class="Special"> &lt;- </span>get-address *p2<span class="Delimiter">,</span> next:offset  <span class="Comment"># signal modification of p2</span>
+]
+recipe test-next x:address:test-list <span class="Delimiter">-&gt;</span> y:address:test-list/contained-in:x [
+  local-scope
+  load-ingredients
+  y<span class="Special"> &lt;- </span>get *x<span class="Delimiter">,</span> next:offset
+]
+<span class="traceContains">+warn: foo: cannot modify p2 after instruction 'p3:address:address:test-list &lt;- get-address *p2, next:offset' because that would modify ingredient p which is not also a product of foo</span>
+
+<span class="Delimiter">:(code)</span>
+void check_immutable_ingredient_in_instruction<span class="Delimiter">(</span>const instruction&amp; inst<span class="Delimiter">,</span> const set&lt;string&gt;&amp; current_ingredient_and_aliases<span class="Delimiter">,</span> const string&amp; original_ingredient_name<span class="Delimiter">,</span> const recipe&amp; caller<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  set&lt;long long int&gt; current_ingredient_indices = ingredient_indices<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> current_ingredient_and_aliases<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>current_ingredient_indices<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span><span class="Delimiter">;</span>  <span class="Comment">// ingredient not found in call</span>
+  for <span class="Delimiter">(</span>set&lt;long long int&gt;::iterator p = current_ingredient_indices<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != current_ingredient_indices<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    const long long int current_ingredient_index = *p<span class="Delimiter">;</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;      ingredient index: &quot; &lt;&lt; *p &lt;&lt; '\n';</span>
+    reagent current_ingredient = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_ingredient_index<span class="Delimiter">);</span>
+    canonize_type<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">);</span>
+    const string&amp; current_ingredient_name = current_ingredient<span class="Delimiter">.</span>name<span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>operation<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+      <span class="Comment">// primitive recipe</span>
+      if <span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation == GET_ADDRESS || inst<span class="Delimiter">.</span>operation == INDEX_ADDRESS<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+        if <span class="Delimiter">(</span>current_ingredient_name == original_ingredient_name<span class="Delimiter">)</span>
+          raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;cannot modify ingredient &quot;</span> &lt;&lt; current_ingredient_name &lt;&lt; <span class="Constant">&quot; after instruction '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' because it's not also a product of &quot;</span> &lt;&lt; caller<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+        else
+          raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;cannot modify &quot;</span> &lt;&lt; current_ingredient_name &lt;&lt; <span class="Constant">&quot; after instruction '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' because that would modify ingredient &quot;</span> &lt;&lt; original_ingredient_name &lt;&lt; <span class="Constant">&quot; which is not also a product of &quot;</span> &lt;&lt; caller<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+      <span class="Delimiter">}</span>
+    <span class="Delimiter">}</span>
+    else <span class="Delimiter">{</span>
+      <span class="Comment">// defined recipe</span>
+      if <span class="Delimiter">(</span>!is_mu_address<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>  <span class="Comment">// making a copy is ok</span>
+      if <span class="Delimiter">(</span>is_modified_in_recipe<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>operation<span class="Delimiter">,</span> current_ingredient_index<span class="Delimiter">,</span> caller<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+        if <span class="Delimiter">(</span>current_ingredient_name == original_ingredient_name<span class="Delimiter">)</span>
+          raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;cannot modify ingredient &quot;</span> &lt;&lt; current_ingredient_name &lt;&lt; <span class="Constant">&quot; at instruction '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' because it's not also a product of &quot;</span> &lt;&lt; caller<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+        else
+          raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;cannot modify &quot;</span> &lt;&lt; current_ingredient_name &lt;&lt; <span class="Constant">&quot; after instruction '&quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="Constant">&quot;' because that would modify ingredient &quot;</span> &lt;&lt; original_ingredient_name &lt;&lt; <span class="Constant">&quot; which is not also a product of &quot;</span> &lt;&lt; caller<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+      <span class="Delimiter">}</span>
+    <span class="Delimiter">}</span>
+  <span class="Delimiter">}</span>
+<span class="Delimiter">}</span>
+
+bool is_modified_in_recipe<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">,</span> long long int ingredient_index<span class="Delimiter">,</span> const recipe&amp; caller<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  const recipe&amp; callee = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>!callee<span class="Delimiter">.</span>has_header<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    raise &lt;&lt; maybe<span class="Delimiter">(</span>caller<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;can't check mutability of ingredients in &quot;</span> &lt;&lt; callee<span class="Delimiter">.</span>name &lt;&lt; <span class="Constant">&quot; because it uses 'next-ingredient' directly, rather than a recipe header.</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">true</span><span class="Delimiter">;</span>
+  <span class="Delimiter">}</span>
+  if <span class="Delimiter">(</span>ingredient_index &gt;= SIZE<span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>  <span class="Comment">// optional immutable ingredient</span>
+  <span class="Identifier">return</span> is_present_in_products<span class="Delimiter">(</span>callee<span class="Delimiter">,</span> callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>ingredient_index<span class="Delimiter">).</span>name<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+bool is_present_in_products<span class="Delimiter">(</span>const recipe&amp; callee<span class="Delimiter">,</span> const string&amp; ingredient_name<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>callee<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>callee<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name == ingredient_name<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 is_present_in_ingredients<span class="Delimiter">(</span>const recipe&amp; callee<span class="Delimiter">,</span> const string&amp; ingredient_name<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>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>callee<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name == ingredient_name<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>
+
+set&lt;long long int&gt; ingredient_indices<span class="Delimiter">(</span>const instruction&amp; inst<span class="Delimiter">,</span> const set&lt;string&gt;&amp; ingredient_names<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  set&lt;long long int&gt; result<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>is_literal<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="Identifier">continue</span><span class="Delimiter">;</span>
+    if <span class="Delimiter">(</span>ingredient_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>name<span class="Delimiter">)</span> != ingredient_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+      result<span class="Delimiter">.</span>insert<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+  <span class="Delimiter">}</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">//: Sometimes you want to pass in two addresses, one pointing inside the</span>
+<span class="Comment">//: other. For example, you want to delete a node from a linked list. You</span>
+<span class="Comment">//: can't pass both pointers back out, because if a caller tries to make both</span>
+<span class="Comment">//: identical then you can't tell which value will be written on the way out.</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: Experimental solution: just tell mu that one points inside the other.</span>
+<span class="Comment">//: This way we can return just one pointer as high up as necessary to capture</span>
+<span class="Comment">//: all modifications performed by a recipe.</span>
+<span class="Comment">//:</span>
+<span class="Comment">//: We'll see if we end up wanting to abuse /contained-in for other reasons.</span>
+
+<span class="Delimiter">:(scenarios transform)</span>
+<span class="Delimiter">:(scenario can_modify_contained_in_addresses)</span>
+<span class="Special">% Hide_warnings = true;</span>
+container test-list [
+  next:address:test-list
+]
+recipe main [
+  local-scope
+  p:address:test-list<span class="Special"> &lt;- </span>new test-list:type
+  foo p
+]
+recipe foo p:address:test-list <span class="Delimiter">-&gt;</span> p:address:test-list [
+  local-scope
+  load-ingredients
+  p2:address:test-list<span class="Special"> &lt;- </span>test-next p
+  p<span class="Special"> &lt;- </span>test-remove p2<span class="Delimiter">,</span> p
+]
+recipe test-next x:address:test-list <span class="Delimiter">-&gt;</span> y:address:test-list [
+  local-scope
+  load-ingredients
+  y<span class="Special"> &lt;- </span>get *x<span class="Delimiter">,</span> next:offset
+]
+recipe test-remove x:address:test-list/contained-in:from<span class="Delimiter">,</span> from:address:test-list <span class="Delimiter">-&gt;</span> from:address:test-list [
+  local-scope
+  load-ingredients
+  x2:address:address:test-list<span class="Special"> &lt;- </span>get-address *x<span class="Delimiter">,</span> next:offset  <span class="Comment"># pretend modification</span>
+]
+$warn: <span class="Constant">0</span>
+
+<span class="Delimiter">:(before &quot;End Immutable Ingredients Special-cases&quot;)</span>
+if <span class="Delimiter">(</span>has_property<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">,</span> <span class="Constant">&quot;contained-in&quot;</span><span class="Delimiter">))</span> <span class="Delimiter">{</span>
+  const string_tree* tmp = property<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">,</span> <span class="Constant">&quot;contained-in&quot;</span><span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>tmp<span class="Delimiter">-&gt;</span>left || tmp<span class="Delimiter">-&gt;</span>right
+      || !is_present_in_ingredients<span class="Delimiter">(</span>caller<span class="Delimiter">,</span> tmp<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span>
+      || !is_present_in_products<span class="Delimiter">(</span>caller<span class="Delimiter">,</span> tmp<span class="Delimiter">-&gt;</span>value<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;contained-in can only point to another ingredient+product, but got &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>property<span class="Delimiter">(</span>current_ingredient<span class="Delimiter">,</span> <span class="Constant">&quot;contained-in&quot;</span><span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+  <span class="Identifier">continue</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/061abandon_checks.cc.html b/html/061abandon_checks.cc.html
new file mode 100644
index 00000000..9f91f90e
--- /dev/null
+++ b/html/061abandon_checks.cc.html
@@ -0,0 +1,159 @@
+<!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 - 061abandon_checks.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; }
+.Comment { color: #9090ff; }
+.Delimiter { color: #a04060; }
+.Special { color: #ff6060; }
+-->
+</style>
+
+<script type='text/javascript'>
+<!--
+
+-->
+</script>
+</head>
+<body>
+<pre id='vimCodeElement'>
+<span class="Delimiter">:(scenarios transform)</span>  <span class="Comment">// many of the tests below are *extremely* unsafe</span>
+<span class="Delimiter">:(scenario abandon_in_same_recipe_as_new)</span>
+recipe test [
+  x:address:number<span class="Special"> &lt;- </span>new number:type
+  abandon x
+]
+<span class="Comment"># no warnings</span>
+
+<span class="Delimiter">:(scenario abandon_in_separate_recipe_from_new)</span>
+recipe test [
+  x:address:number<span class="Special"> &lt;- </span>test-new
+  test-abandon x
+]
+recipe test-new <span class="Delimiter">-&gt;</span> result:address:number [
+  result<span class="Special"> &lt;- </span>new number:type
+]
+recipe test-abandon x:address:number [
+  load-ingredients
+  abandon x
+]
+<span class="Comment"># no warnings</span>
+
+<span class="Delimiter">:(scenario define_after_abandon_in_same_recipe_as_new)</span>
+recipe test [
+  x:address:number<span class="Special"> &lt;- </span>new number:type
+  abandon x
+  x<span class="Special"> &lt;- </span>new number:type
+  reply x
+]
+<span class="Comment"># no warnings</span>
+
+<span class="Delimiter">:(scenario define_after_abandon_in_separate_recipe_from_new)</span>
+recipe test [
+  x:address:number<span class="Special"> &lt;- </span>test-new
+  test-abandon x
+  x<span class="Special"> &lt;- </span>test-new
+  reply x
+]
+recipe test-new <span class="Delimiter">-&gt;</span> result:address:number [
+  result<span class="Special"> &lt;- </span>new number:type
+]
+recipe test-abandon x:address:number [
+  load-ingredients
+  abandon x
+]
+<span class="Comment"># no warnings</span>
+
+<span class="Delimiter">:(scenario abandon_inside_loop_initializing_variable)</span>
+recipe test [
+  <span class="Delimiter">{</span>
+    x:address:number<span class="Special"> &lt;- </span>new number:type
+    abandon x
+    loop
+  <span class="Delimiter">}</span>
+]
+<span class="Comment"># no warnings</span>
+
+<span class="Delimiter">:(scenario abandon_inside_loop_initializing_variable_2)</span>
+recipe test [
+  <span class="Delimiter">{</span>
+    x:address:number<span class="Special"> &lt;- </span>test-new
+    test-abandon x
+    loop
+  <span class="Delimiter">}</span>
+]
+recipe test-new <span class="Delimiter">-&gt;</span> result:address:number [
+  result<span class="Special"> &lt;- </span>new number:type
+]
+recipe test-abandon x:address:number [
+  load-ingredients
+  abandon x
+]
+<span class="Comment"># no warnings</span>
+
+<span class="Delimiter">:(scenario abandon_inside_loop_initializing_variable_3)</span>
+recipe test [
+  <span class="Delimiter">{</span>
+    x:address:number<span class="Special"> &lt;- </span>test-new
+    test-abandon x
+    x:address:number<span class="Special"> &lt;- </span>test-new  <span class="Comment"># modify x to a new value</span>
+    y:address:number<span class="Special"> &lt;- </span>copy x  <span class="Comment"># use x after reinitialization</span>
+    loop
+  <span class="Delimiter">}</span>
+]
+recipe test-new <span class="Delimiter">-&gt;</span> result:address:number [
+  result<span class="Special"> &lt;- </span>new number:type
+]
+recipe test-abandon x:address:number [
+  load-ingredients
+  abandon x
+]
+<span class="Comment"># no warnings</span>
+
+<span class="Delimiter">:(scenario abandon_inside_loop_initializing_variable_4)</span>
+container test-list [
+  value:number
+  next:address:test-list
+]
+recipe test-cleanup x:address:test-list [
+  load-ingredients
+  <span class="Delimiter">{</span>
+    next:address:test-list<span class="Special"> &lt;- </span>test-next x
+    test-abandon x
+    x<span class="Special"> &lt;- </span>copy next
+    loop
+  <span class="Delimiter">}</span>
+]
+recipe test-next x:address:test-list <span class="Delimiter">-&gt;</span> result:address:test-list/contained-in:x [
+  load-ingredients
+  result<span class="Special"> &lt;- </span>get *x<span class="Delimiter">,</span> next:offset
+]
+recipe test-abandon x:address:test-list [
+  load-ingredients
+  abandon x
+]
+<span class="Comment"># no warnings</span>
+
+<span class="Delimiter">:(scenario abandon_non_unique_address_after_define)</span>
+recipe test [
+  x:address:number<span class="Special"> &lt;- </span>new number:type
+  y:address:number<span class="Special"> &lt;- </span>copy x
+  abandon x
+  y:address:number<span class="Special"> &lt;- </span>new number:type  <span class="Comment"># overwrite alias</span>
+  z:address:number<span class="Special"> &lt;- </span>copy y
+]
+<span class="Comment"># no warnings</span>
+</pre>
+</body>
+</html>
+<!-- vim: set foldmethod=manual : -->
diff --git a/html/073list.mu.html b/html/073list.mu.html
index a14399dd..2097a4e6 100644
--- a/html/073list.mu.html
+++ b/html/073list.mu.html
@@ -43,15 +43,15 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   next:address:list:_elem
 ]
 
-<span class="muRecipe">recipe</span> push x:_elem, in:address:list:_elem<span class="muRecipe"> -&gt; </span>result:address:list:_elem [
+<span class="muRecipe">recipe</span> push x:_elem, in:address:list:_elem<span class="muRecipe"> -&gt; </span>in:address:list:_elem [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
-  result<span class="Special"> &lt;- </span>new <span class="Delimiter">{</span>(list _elem): type<span class="Delimiter">}</span>
+  result:address:list:_elem<span class="Special"> &lt;- </span>new <span class="Delimiter">{</span>(list _elem): type<span class="Delimiter">}</span>
   val:address:_elem<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">value:offset</span>
   *val<span class="Special"> &lt;- </span>copy x
   next:address:address:list:_elem<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">next:offset</span>
   *next<span class="Special"> &lt;- </span>copy in
-  <span class="muControl">reply</span> result
+  <span class="muControl">reply</span> result  <span class="Comment"># needed explicitly because we need to replace 'in' with 'result'</span>
 ]
 
 <span class="muRecipe">recipe</span> first in:address:list:_elem<span class="muRecipe"> -&gt; </span>result:_elem [
@@ -60,8 +60,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   result<span class="Special"> &lt;- </span>get *in, <span class="Constant">value:offset</span>
 ]
 
-<span class="Comment"># result:address:list &lt;- rest in:address:list</span>
-<span class="muRecipe">recipe</span> rest in:address:list:_elem<span class="muRecipe"> -&gt; </span>result:address:list:_elem [
+<span class="muRecipe">recipe</span> rest in:address:list:_elem<span class="muRecipe"> -&gt; </span>result:address:list:_elem/contained-in:in [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   result<span class="Special"> &lt;- </span>get *in, <span class="Constant">next:offset</span>
@@ -112,7 +111,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <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>
diff --git a/html/075duplex_list.mu.html b/html/075duplex_list.mu.html
index f2094cde..4a0abcbb 100644
--- a/html/075duplex_list.mu.html
+++ b/html/075duplex_list.mu.html
@@ -40,17 +40,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   prev:address:duplex-list:_elem
 ]
 
-<span class="muRecipe">recipe</span> push x:_elem, in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result:address:duplex-list:_elem [
+<span class="Comment"># should I say in/contained-in:result, allow ingredients to refer to products?</span>
+<span class="muRecipe">recipe</span> push x:_elem, in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>in:address:duplex-list:_elem [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
-  result<span class="Special"> &lt;- </span>new <span class="Delimiter">{</span>(duplex-list _elem): type<span class="Delimiter">}</span>
+  result:address:duplex-list:_elem<span class="Special"> &lt;- </span>new <span class="Delimiter">{</span>(duplex-list _elem): type<span class="Delimiter">}</span>
   val:address:_elem<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">value:offset</span>
   *val<span class="Special"> &lt;- </span>copy x
   next:address:address:duplex-list:_elem<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">next:offset</span>
   *next<span class="Special"> &lt;- </span>copy in
-  <span class="muControl">reply-unless</span> in
-  prev:address:address:duplex-list:_elem<span class="Special"> &lt;- </span>get-address *in, <span class="Constant">prev:offset</span>
-  *prev<span class="Special"> &lt;- </span>copy result
+  <span class="Delimiter">{</span>
+    <span class="muControl">break-unless</span> in
+    prev:address:address:duplex-list:_elem<span class="Special"> &lt;- </span>get-address *in, <span class="Constant">prev:offset</span>
+    *prev<span class="Special"> &lt;- </span>copy result
+  <span class="Delimiter">}</span>
+  <span class="muControl">reply</span> result  <span class="Comment"># needed explicitly because we need to replace 'in' with 'result'</span>
 ]
 
 <span class="muRecipe">recipe</span> first in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result:_elem [
@@ -60,14 +64,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   result<span class="Special"> &lt;- </span>get *in, <span class="Constant">value:offset</span>
 ]
 
-<span class="muRecipe">recipe</span> next in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result:address:duplex-list:_elem [
+<span class="muRecipe">recipe</span> next in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result:address:duplex-list:_elem/contained-in:in [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="muControl">reply-unless</span> in, <span class="Constant">0</span>
   result<span class="Special"> &lt;- </span>get *in, <span class="Constant">next:offset</span>
 ]
 
-<span class="muRecipe">recipe</span> prev in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result:address:duplex-list:_elem [
+<span class="muRecipe">recipe</span> prev in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result:address:duplex-list:_elem/contained-in:in [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="muControl">reply-unless</span> in, <span class="Constant">0</span>
@@ -116,11 +120,11 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="Comment"># Inserts 'x' after 'in'. Returns some pointer into the list.</span>
-<span class="muRecipe">recipe</span> insert x:_elem, in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>new-node:address:duplex-list:_elem [
+<span class="Comment"># insert 'x' after 'in'</span>
+<span class="muRecipe">recipe</span> insert x:_elem, in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>in:address:duplex-list:_elem [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
-  new-node<span class="Special"> &lt;- </span>new <span class="Delimiter">{</span>(duplex-list _elem): type<span class="Delimiter">}</span>
+  new-node:address:duplex-list:_elem<span class="Special"> &lt;- </span>new <span class="Delimiter">{</span>(duplex-list _elem): type<span class="Delimiter">}</span>
   val:address:_elem<span class="Special"> &lt;- </span>get-address *new-node, <span class="Constant">value:offset</span>
   *val<span class="Special"> &lt;- </span>copy x
   next-node:address:duplex-list:_elem<span class="Special"> &lt;- </span>get *in, <span class="Constant">next:offset</span>
@@ -134,11 +138,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   y<span class="Special"> &lt;- </span>get-address *new-node, <span class="Constant">next:offset</span>
   *y<span class="Special"> &lt;- </span>copy next-node
   <span class="Comment"># if next-node is not null</span>
-  <span class="muControl">reply-unless</span> next-node, new-node
+  <span class="muControl">reply-unless</span> next-node
   <span class="Comment"># next-node.prev = new-node</span>
   y<span class="Special"> &lt;- </span>get-address *next-node, <span class="Constant">prev:offset</span>
   *y<span class="Special"> &lt;- </span>copy new-node
-  <span class="muControl">reply</span> new-node  <span class="Comment"># just signalling something changed; don't rely on the result</span>
 ]
 
 <span class="muScenario">scenario</span> inserting-into-duplex-list [
@@ -219,7 +222,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">3</span>, <span class="Constant">0</span>
     <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>insert <span class="Constant">6</span>, <span class="Constant">1</span>:address:duplex-list:character
+    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>insert <span class="Constant">6</span>, <span class="Constant">1</span>:address:duplex-list:character
     <span class="Comment"># check structure like before</span>
     <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">3</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
@@ -249,38 +252,37 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="Comment"># Removes 'in' from its surrounding list. Returns some valid pointer into the</span>
-<span class="Comment"># rest of the list.</span>
+<span class="Comment"># remove 'x' from its surrounding list 'in'</span>
 <span class="Comment">#</span>
-<span class="Comment"># Returns null if and only if list is empty. Beware: in that case any pointers</span>
-<span class="Comment"># to the head are now invalid.</span>
-<span class="muRecipe">recipe</span> remove in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>next-node:address:duplex-list:_elem [
+<span class="Comment"># Returns null if and only if list is empty. Beware: in that case any other</span>
+<span class="Comment"># pointers to the head are now invalid.</span>
+<span class="muRecipe">recipe</span> remove x:address:duplex-list:_elem/contained-in:in, in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>in:address:duplex-list:_elem [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
-  <span class="Comment"># if 'in' is null, return</span>
-  <span class="muControl">reply-unless</span> in, in
-  next-node:address:duplex-list:_elem<span class="Special"> &lt;- </span>get *in, <span class="Constant">next:offset</span>
-  prev-node:address:duplex-list:_elem<span class="Special"> &lt;- </span>get *in, <span class="Constant">prev:offset</span>
-  <span class="Comment"># null in's pointers</span>
-  x:address:address:duplex-list:_elem<span class="Special"> &lt;- </span>get-address *in, <span class="Constant">next:offset</span>
-  *x<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
-  x<span class="Special"> &lt;- </span>get-address *in, <span class="Constant">prev:offset</span>
-  *x<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
+  <span class="Comment"># if 'x' is null, return</span>
+  <span class="muControl">reply-unless</span> x
+  next-node:address:duplex-list:_elem<span class="Special"> &lt;- </span>get *x, <span class="Constant">next:offset</span>
+  prev-node:address:duplex-list:_elem<span class="Special"> &lt;- </span>get *x, <span class="Constant">prev:offset</span>
+  <span class="Comment"># null x's pointers</span>
+  tmp:address:address:duplex-list:_elem<span class="Special"> &lt;- </span>get-address *x, <span class="Constant">next:offset</span>
+  *tmp<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
+  tmp<span class="Special"> &lt;- </span>get-address *x, <span class="Constant">prev:offset</span>
+  *tmp<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
+  <span class="Comment"># if next-node is not null, set its prev pointer</span>
   <span class="Delimiter">{</span>
-    <span class="Comment"># if next-node is not null</span>
     <span class="muControl">break-unless</span> next-node
-    <span class="Comment"># next-node.prev = prev-node</span>
-    x<span class="Special"> &lt;- </span>get-address *next-node, <span class="Constant">prev:offset</span>
-    *x<span class="Special"> &lt;- </span>copy prev-node
+    tmp<span class="Special"> &lt;- </span>get-address *next-node, <span class="Constant">prev:offset</span>
+    *tmp<span class="Special"> &lt;- </span>copy prev-node
   <span class="Delimiter">}</span>
+  <span class="Comment"># if prev-node is not null, set its next pointer and return</span>
   <span class="Delimiter">{</span>
-    <span class="Comment"># if prev-node is not null</span>
     <span class="muControl">break-unless</span> prev-node
-    <span class="Comment"># prev-node.next = next-node</span>
-    x<span class="Special"> &lt;- </span>get-address *prev-node, <span class="Constant">next:offset</span>
-    *x<span class="Special"> &lt;- </span>copy next-node
-    <span class="muControl">reply</span> prev-node
+    tmp<span class="Special"> &lt;- </span>get-address *prev-node, <span class="Constant">next:offset</span>
+    *tmp<span class="Special"> &lt;- </span>copy next-node
+    <span class="muControl">reply</span>
   <span class="Delimiter">}</span>
+  <span class="Comment"># if prev-node is null, then we removed the node at 'in'</span>
+  <span class="Comment"># return the new head rather than the old 'in'</span>
   <span class="muControl">reply</span> next-node
 ]
 
@@ -290,7 +292,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">1</span>:address:duplex-list:character  <span class="Comment"># 2 points at second element</span>
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">3</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">0</span>
     <span class="Comment"># check structure like before</span>
     <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:address:duplex-list:character
@@ -317,8 +319,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">3</span>, <span class="Constant">0</span>
     <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">4</span>, <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">5</span>, <span class="Constant">1</span>:address:duplex-list:character
-    <span class="Comment"># removing from head? return value matters.</span>
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove <span class="Constant">1</span>:address:duplex-list:character
+    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">1</span>:address:duplex-list:character
     <span class="Comment"># check structure like before</span>
     <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">3</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
@@ -346,7 +347,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Comment"># delete last element</span>
     <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">3</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">0</span>
     <span class="Comment"># check structure like before</span>
     <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">1</span>:address:duplex-list:character
@@ -371,20 +372,16 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muScenario">scenario</span> removing-from-singleton-list [
   run [
     <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">3</span>, <span class="Constant">0</span>
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove <span class="Constant">1</span>:address:duplex-list:character
-    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">next:offset</span>
-    <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">prev:offset</span>
+    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">1</span>:address:duplex-list:character
   ]
   memory-should-contain [
-    <span class="Constant">2</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># remove returned null</span>
-    <span class="Constant">3</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># removed node is also detached</span>
-    <span class="Constant">4</span><span class="Special"> &lt;- </span><span class="Constant">0</span>
+    <span class="Constant">1</span><span class="Special"> &lt;- </span><span class="Constant">0</span>  <span class="Comment"># back to an empty list</span>
   ]
 ]
 
 <span class="Comment"># remove values between 'start' and 'end' (both exclusive)</span>
 <span class="Comment"># also clear pointers back out from start/end for hygiene</span>
-<span class="muRecipe">recipe</span> remove-between start:address:duplex-list:_elem, end:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>start:address:duplex-list:_elem [
+<span class="muRecipe">recipe</span> remove-between start:address:duplex-list:_elem, end:address:duplex-list:_elem/contained-in:start<span class="muRecipe"> -&gt; </span>start:address:duplex-list:_elem [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="muControl">reply-unless</span> start
@@ -491,8 +488,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="Comment"># Inserts list beginning at 'new' after 'in'. Returns some pointer into the list.</span>
-<span class="muRecipe">recipe</span> insert-range in:address:duplex-list:_elem, start:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>in:address:duplex-list:_elem [
+<span class="Comment"># insert list beginning at 'new' after 'in'</span>
+<span class="muRecipe">recipe</span> insert-range in:address:duplex-list:_elem, start:address:duplex-list:_elem/contained-in:in<span class="muRecipe"> -&gt; </span>in:address:duplex-list:_elem [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="muControl">reply-unless</span> in
@@ -518,7 +515,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   *dest<span class="Special"> &lt;- </span>copy in
 ]
 
-<span class="muRecipe">recipe</span> append in:address:duplex-list:_elem, new:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>in:address:duplex-list:_elem [
+<span class="muRecipe">recipe</span> append in:address:duplex-list:_elem, new:address:duplex-list:_elem/contained-in:in<span class="muRecipe"> -&gt; </span>in:address:duplex-list:_elem [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   last:address:duplex-list:_elem<span class="Special"> &lt;- </span>last in
diff --git a/html/080display.cc.html b/html/080display.cc.html
index bf3ad0c8..88a10a41 100644
--- a/html/080display.cc.html
+++ b/html/080display.cc.html
@@ -14,6 +14,7 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 1.05em; }
 .cSpecial { color: #008000; }
+.CommentedCode { color: #6c6c6c; }
 .Constant { color: #00a0a0; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
@@ -444,7 +445,11 @@ case CHECK_FOR_INTERACTION: <span class="Delimiter">{</span>
   <span class="Comment">// treat keys within ascii as unicode characters</span>
   if <span class="Delimiter">(</span>event_type == TB_EVENT_KEY &amp;&amp; event<span class="Delimiter">.</span>key &lt; <span class="Constant">0xff</span><span class="Delimiter">)</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><span class="Comment">/*</span><span class="Comment">text event</span><span class="Comment">*/</span><span class="Constant">0</span><span class="Delimiter">);</span>
-    if <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_CTRL_C<span class="Delimiter">)</span> tb_shutdown<span class="Delimiter">(),</span> exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+    if <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_CTRL_C<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      tb_shutdown<span class="Delimiter">();</span>
+<span class="CommentedCode">//?       LOG &lt;&lt; &quot;exit\n&quot;;</span>
+      exit<span class="Delimiter">(</span><span class="Constant">1</span><span class="Delimiter">);</span>
+    <span class="Delimiter">}</span>
     if <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_BACKSPACE2<span class="Delimiter">)</span> event<span class="Delimiter">.</span>key = TB_KEY_BACKSPACE<span class="Delimiter">;</span>
     if <span class="Delimiter">(</span>event<span class="Delimiter">.</span>key == TB_KEY_CARRIAGE_RETURN<span class="Delimiter">)</span> event<span class="Delimiter">.</span>key = TB_KEY_NEWLINE<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>event<span class="Delimiter">.</span>key<span class="Delimiter">);</span>
diff --git a/html/082scenario_screen.cc.html b/html/082scenario_screen.cc.html
index bca387d9..85ef4880 100644
--- a/html/082scenario_screen.cc.html
+++ b/html/082scenario_screen.cc.html
@@ -196,6 +196,7 @@ 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>
+  assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</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>
 <span class="Delimiter">}</span>
@@ -212,6 +213,7 @@ case SCREEN_SHOULD_CONTAIN_IN_COLOR: <span class="Delimiter">{</span>
 case SCREEN_SHOULD_CONTAIN_IN_COLOR: <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>!Passed<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
   assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">)));</span>
+  assert<span class="Delimiter">(</span>scalar<span class="Delimiter">(</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">1</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">1</span><span class="Delimiter">).</span>name<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>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
@@ -257,12 +259,12 @@ void check_screen<span class="Delimiter">(</span>const string&amp; expected_cont
         <span class="Comment">// filter out other colors</span>
         <span class="Identifier">continue</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
-      if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)</span> != <span class="Constant">0</span> &amp;&amp; Memory[addr] == curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)</span> != <span class="Constant">0</span> &amp;&amp; get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)</span> == curr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
         if <span class="Delimiter">(</span>color == -<span class="Constant">1</span> || color == get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr+cell_color_offset<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
         <span class="Comment">// contents match but color is off</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 screen location (&quot;</span> &lt;&lt; row &lt;&lt; <span class="Constant">&quot;, &quot;</span> &lt;&lt; column &lt;&lt; <span class="Constant">&quot;, address &quot;</span> &lt;&lt; addr &lt;&lt; <span class="Constant">&quot;, value &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;) to be in color &quot;</span> &lt;&lt; color &lt;&lt; <span class="Constant">&quot; instead of &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>Memory[addr+cell_color_offset]<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;</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 screen location (&quot;</span> &lt;&lt; row &lt;&lt; <span class="Constant">&quot;, &quot;</span> &lt;&lt; column &lt;&lt; <span class="Constant">&quot;, address &quot;</span> &lt;&lt; addr &lt;&lt; <span class="Constant">&quot;, value &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">))</span> &lt;&lt; <span class="Constant">&quot;) to be in color &quot;</span> &lt;&lt; color &lt;&lt; <span class="Constant">&quot; instead of &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr+cell_color_offset<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 check_screen</span>
@@ -283,7 +285,7 @@ void check_screen<span class="Delimiter">(</span>const string&amp; expected_cont
         expected_pretty[<span class="Constant">0</span>] = <span class="Constant">' '</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">1</span>] = <span class="Constant">'('</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">2</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">3</span>] = static_cast&lt;unsigned char&gt;<span class="Delimiter">(</span>curr<span class="Delimiter">),</span> expected_pretty[<span class="Constant">4</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">5</span>] = <span class="Constant">')'</span><span class="Delimiter">,</span> expected_pretty[<span class="Constant">6</span>] = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
       char actual_pretty[<span class="Constant">10</span>] = <span class="Delimiter">{</span><span class="Constant">0</span><span class="Delimiter">};</span>
-      if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)</span> &lt; <span class="Constant">256</span> &amp;&amp; !iscntrl<span class="Delimiter">(</span>Memory[addr]<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)</span> &lt; <span class="Constant">256</span> &amp;&amp; !iscntrl<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
         <span class="Comment">// &quot; ('&lt;curr&gt;')&quot;</span>
         actual_pretty[<span class="Constant">0</span>] = <span class="Constant">' '</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">1</span>] = <span class="Constant">'('</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">2</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">3</span>] = static_cast&lt;unsigned char&gt;<span class="Delimiter">(</span>get_or_insert<span class="Delimiter">(</span>Memory<span class="Delimiter">,</span> addr<span class="Delimiter">)),</span> actual_pretty[<span class="Constant">4</span>] = <span class="cSpecial">'\''</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">5</span>] = <span class="Constant">')'</span><span class="Delimiter">,</span> actual_pretty[<span class="Constant">6</span>] = <span class="cSpecial">'\0'</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
diff --git a/html/084console.mu.html b/html/084console.mu.html
index b8619762..4065e18b 100644
--- a/html/084console.mu.html
+++ b/html/084console.mu.html
@@ -54,17 +54,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 ]
 
 <span class="muData">container</span> console [
-  index:number
-  data:address:array:event
+  current-event-index:number
+  events:address:array:event
 ]
 
 <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:address:address:array:event<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">events:offset</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:address:number<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">current-event-index:offset</span>
   *idx<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
 ]
 
@@ -73,17 +73,17 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</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>
+    current-event-index:address:number<span class="Special"> &lt;- </span>get-address *console, <span class="Constant">current-event-index:offset</span>
+    buf:address:array:event<span class="Special"> &lt;- </span>get *console, <span class="Constant">events: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
+      done?:boolean<span class="Special"> &lt;- </span>greater-or-equal *current-event-index, 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, 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<span class="Special"> &lt;- </span>index *buf, *idx
-    *idx<span class="Special"> &lt;- </span>add *idx, <span class="Constant">1</span>
+    result<span class="Special"> &lt;- </span>index *buf, *current-event-index
+    *current-event-index<span class="Special"> &lt;- </span>add *current-event-index, <span class="Constant">1</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>
diff --git a/html/090trace_browser.cc.html b/html/090trace_browser.cc.html
index 3da39a9b..7cc79bce 100644
--- a/html/090trace_browser.cc.html
+++ b/html/090trace_browser.cc.html
@@ -63,14 +63,13 @@ map&lt;int<span class="Delimiter">,</span> long long int&gt; Trace_index<span cl
 <span class="Delimiter">:(code)</span>
 void start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>!Trace_stream<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
-  cerr &lt;&lt; <span class="Constant">&quot;computing depth to display</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
+  cerr &lt;&lt; <span class="Constant">&quot;computing min depth to display</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">;</span>
   long long int min_depth = <span class="Constant">9999</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>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     trace_line&amp; curr_line = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
-    if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
     if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth &lt; min_depth<span class="Delimiter">)</span> min_depth = curr_line<span class="Delimiter">.</span>depth<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  cerr &lt;&lt; <span class="Constant">&quot;depth is &quot;</span> &lt;&lt; min_depth &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+  cerr &lt;&lt; <span class="Constant">&quot;min depth is &quot;</span> &lt;&lt; min_depth &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
   cerr &lt;&lt; <span class="Constant">&quot;computing lines to display</span><span class="cSpecial">\n</span><span class="Constant">&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>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     if <span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>depth == min_depth<span class="Delimiter">)</span>
@@ -123,7 +122,7 @@ void start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter
         while <span class="Delimiter">(</span>Top_of_screen &gt; <span class="Constant">0</span> &amp;&amp; !contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> Top_of_screen<span class="Delimiter">))</span>
           --Top_of_screen<span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
-      if <span class="Delimiter">(</span>Top_of_screen &gt; <span class="Constant">0</span><span class="Delimiter">)</span>
+      if <span class="Delimiter">(</span>Top_of_screen &gt;= <span class="Constant">0</span><span class="Delimiter">)</span>
         refresh_screen_rows<span class="Delimiter">();</span>
     <span class="Delimiter">}</span>
     if <span class="Delimiter">(</span>key == <span class="Constant">'G'</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -150,7 +149,6 @@ void start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter
       for <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index &lt; SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
         if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> index<span class="Delimiter">))</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
         trace_line&amp; curr_line = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
-        if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
         assert<span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth &gt; Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>start_index<span class="Delimiter">).</span>depth<span class="Delimiter">);</span>
         if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth &lt; min_depth<span class="Delimiter">)</span> min_depth = curr_line<span class="Delimiter">.</span>depth<span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
@@ -174,7 +172,6 @@ void start_trace_browser<span class="Delimiter">()</span> <span class="Delimiter
       for <span class="Delimiter">(</span>index = start_index+<span class="Constant">1</span><span class="Delimiter">;</span> index &lt; SIZE<span class="Delimiter">(</span>Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
         if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Visible<span class="Delimiter">,</span> index<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
         trace_line&amp; curr_line = Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
-        if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth == <span class="Constant">0</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
         if <span class="Delimiter">(</span>curr_line<span class="Delimiter">.</span>depth &lt;= initial_depth<span class="Delimiter">)</span> <span class="Identifier">break</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
       long long int end_index = index<span class="Delimiter">;</span>
@@ -215,7 +212,7 @@ void render<span class="Delimiter">()</span> <span class="Delimiter">{</span>
       long long int delta = lines_hidden<span class="Delimiter">(</span>screen_row<span class="Delimiter">);</span>
       <span class="Comment">// home-brew escape sequence for red</span>
       if <span class="Delimiter">(</span>delta &gt; <span class="Constant">999</span><span class="Delimiter">)</span> out &lt;&lt; <span class="Constant">&quot;{&quot;</span><span class="Delimiter">;</span>
-      out &lt;&lt; <span class="Constant">&quot; (&quot;</span> &lt;&lt; lines_hidden<span class="Delimiter">(</span>screen_row<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;)&quot;</span><span class="Delimiter">;</span>
+      out &lt;&lt; <span class="Constant">&quot; (&quot;</span> &lt;&lt; delta &lt;&lt; <span class="Constant">&quot;)&quot;</span><span class="Delimiter">;</span>
       if <span class="Delimiter">(</span>delta &gt; <span class="Constant">999</span><span class="Delimiter">)</span> out &lt;&lt; <span class="Constant">&quot;}&quot;</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
     render_line<span class="Delimiter">(</span>screen_row<span class="Delimiter">,</span> out<span class="Delimiter">.</span>str<span class="Delimiter">());</span>
@@ -262,6 +259,14 @@ void load_trace<span class="Delimiter">(</span>const char* filename<span class="
   <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>
+    tin &gt;&gt; std::noskipws<span class="Delimiter">;</span>
+      skip_whitespace_but_not_newline<span class="Delimiter">(</span>tin<span class="Delimiter">);</span>
+      if <span class="Delimiter">(</span>!isdigit<span class="Delimiter">(</span>tin<span class="Delimiter">.</span>peek<span class="Delimiter">()))</span> <span class="Delimiter">{</span>
+        string dummy<span class="Delimiter">;</span>
+        getline<span class="Delimiter">(</span>tin<span class="Delimiter">,</span> dummy<span class="Delimiter">);</span>
+        <span class="Identifier">continue</span><span class="Delimiter">;</span>
+      <span class="Delimiter">}</span>
+    tin &gt;&gt; std::skipws<span class="Delimiter">;</span>
     int depth<span class="Delimiter">;</span>
     tin &gt;&gt; depth<span class="Delimiter">;</span>
     string label<span class="Delimiter">;</span>
@@ -271,6 +276,7 @@ void load_trace<span class="Delimiter">(</span>const char* filename<span class="
     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>
+  cerr &lt;&lt; <span class="Constant">&quot;lines read: &quot;</span> &lt;&lt; Trace_stream<span class="Delimiter">-&gt;</span>past_lines<span class="Delimiter">.</span>size<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 </pre>
 </body>
diff --git a/html/091run_interactive.cc.html b/html/091run_interactive.cc.html
index 94a1284a..703fd5c1 100644
--- a/html/091run_interactive.cc.html
+++ b/html/091run_interactive.cc.html
@@ -96,6 +96,8 @@ bool Track_most_recent_products = <span class="Constant">false</span><span class
 <span class="Delimiter">:(before &quot;End Tracing&quot;)</span>
 trace_stream* Save_trace_stream = <span class="Constant">NULL</span><span class="Delimiter">;</span>
 string Save_trace_file<span class="Delimiter">;</span>
+vector&lt;recipe_ordinal&gt; Save_recently_added_recipes<span class="Delimiter">;</span>
+vector&lt;recipe_ordinal&gt; Save_recently_added_shape_shifting_recipes<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Setup&quot;)</span>
 Track_most_recent_products = <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="Delimiter">:(code)</span>
@@ -113,7 +115,7 @@ bool run_interactive<span class="Delimiter">(</span>long long int address<span c
   string command = trim<span class="Delimiter">(</span>strip_comments<span class="Delimiter">(</span>read_mu_string<span class="Delimiter">(</span>address<span class="Delimiter">)));</span>
   if <span class="Delimiter">(</span>command<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   Name[get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;interactive&quot;</span><span class="Delimiter">)</span>]<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
-  run_code_begin<span class="Delimiter">();</span>
+  run_code_begin<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">snapshot_recently_added_recipes</span><span class="Comment">*/</span><span class="Constant">true</span><span class="Delimiter">);</span>
   <span class="Comment">// don't kill the current routine on parse errors</span>
   routine* save_current_routine = Current_routine<span class="Delimiter">;</span>
   Current_routine = <span class="Constant">NULL</span><span class="Delimiter">;</span>
@@ -140,12 +142,18 @@ bool run_interactive<span class="Delimiter">(</span>long long int address<span c
   <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-void run_code_begin<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+void run_code_begin<span class="Delimiter">(</span>bool snapshot_recently_added_recipes<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>
   Disable_redefine_warnings = <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>snapshot_recently_added_recipes<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    Save_recently_added_recipes = Recently_added_recipes<span class="Delimiter">;</span>
+    Recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+    Save_recently_added_shape_shifting_recipes = Recently_added_shape_shifting_recipes<span class="Delimiter">;</span>
+    Recently_added_shape_shifting_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+  <span class="Delimiter">}</span>
   Save_trace_stream = Trace_stream<span class="Delimiter">;</span>
   Save_trace_file = Trace_file<span class="Delimiter">;</span>
   Trace_file = <span class="Constant">&quot;&quot;</span><span class="Delimiter">;</span>
@@ -164,6 +172,13 @@ void run_code_end<span class="Delimiter">()</span> <span class="Delimiter">{</sp
   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>
+  if <span class="Delimiter">(</span>!Save_recently_added_recipes<span class="Delimiter">.</span>empty<span class="Delimiter">())</span> <span class="Delimiter">{</span>
+    clear_recently_added_recipes<span class="Delimiter">();</span>
+    Recently_added_recipes = Save_recently_added_recipes<span class="Delimiter">;</span>
+    Save_recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+    Recently_added_shape_shifting_recipes = Save_recently_added_shape_shifting_recipes<span class="Delimiter">;</span>
+    Save_recently_added_shape_shifting_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+  <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(before &quot;End Load Recipes&quot;)</span>
@@ -185,7 +200,7 @@ load<span class="Delimiter">(</span>string<span class="Delimiter">(</span>
   <span class="Constant">&quot;reply output, warnings, screen, stashes, completed?</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
 <span class="Constant">&quot;]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">);</span>
 transform_all<span class="Delimiter">();</span>
-recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
+Recently_added_recipes<span class="Delimiter">.</span>clear<span class="Delimiter">();</span>
 
 <span class="Comment">//: adjust errors/warnings in the sandbox</span>
 <span class="Delimiter">:(after &quot;string maybe(string s)&quot;)</span>
@@ -338,6 +353,31 @@ b:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
 <span class="Comment"># no errors</span>
 <span class="traceContains">+mem: storing 0 in location 3</span>
 
+<span class="Delimiter">:(code)</span>
+void test_run_interactive_cleans_up_any_created_specializations<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  <span class="Comment">// define a generic recipe</span>
+  assert<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;foo&quot;</span><span class="Delimiter">));</span>
+  load<span class="Delimiter">(</span><span class="Constant">&quot;recipe foo x:_elem -&gt; n:number [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       <span class="Constant">&quot;  reply 34</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       <span class="Constant">&quot;]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">);</span>
+  assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Recently_added_recipes<span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">);</span>  <span class="Comment">// foo</span>
+  assert<span class="Delimiter">(</span>variant_count<span class="Delimiter">(</span><span class="Constant">&quot;foo&quot;</span><span class="Delimiter">)</span> == <span class="Constant">1</span><span class="Delimiter">);</span>
+  <span class="Comment">// run-interactive a call that specializes this recipe</span>
+  run<span class="Delimiter">(</span><span class="Constant">&quot;recipe main [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       <span class="Constant">&quot;  1:number/raw &lt;- copy 0</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       <span class="Constant">&quot;  2:address:array:character &lt;- new [foo 1:number/raw]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       <span class="Constant">&quot;  run-interactive 2:address:array:character</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+       <span class="Constant">&quot;]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">);</span>
+  assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Recently_added_recipes<span class="Delimiter">)</span> == <span class="Constant">2</span><span class="Delimiter">);</span>  <span class="Comment">// foo, main</span>
+  <span class="Comment">// check that number of variants doesn't change</span>
+  CHECK_EQ<span class="Delimiter">(</span>variant_count<span class="Delimiter">(</span><span class="Constant">&quot;foo&quot;</span><span class="Delimiter">),</span> <span class="Constant">1</span><span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+long long int variant_count<span class="Delimiter">(</span>string recipe_name<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> recipe_name<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">0</span><span class="Delimiter">;</span>
+  <span class="Identifier">return</span> non_ghost_size<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> recipe_name<span class="Delimiter">));</span>
+<span class="Delimiter">}</span>
+
 <span class="Delimiter">:(before &quot;End Globals&quot;)</span>
 string Most_recent_products<span class="Delimiter">;</span>
 <span class="Delimiter">:(before &quot;End Setup&quot;)</span>
@@ -456,29 +496,29 @@ case RELOAD: <span class="Delimiter">{</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>
+  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>
+      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>
+  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">//?     LOG &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>
+  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>
+  run_code_begin<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">snapshot_recently_added_recipes</span><span class="Comment">*/</span><span class="Constant">false</span><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>
@@ -506,6 +546,32 @@ recipe main [
   <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>copy <span class="Constant">34</span>
 ]
 <span class="traceContains">+mem: storing 34 in location 1</span>
+
+<span class="Delimiter">:(code)</span>
+void test_reload_cleans_up_any_created_specializations<span class="Delimiter">()</span> <span class="Delimiter">{</span>
+  <span class="Comment">// define a generic recipe and a call to it</span>
+  assert<span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;foo&quot;</span><span class="Delimiter">));</span>
+  assert<span class="Delimiter">(</span>variant_count<span class="Delimiter">(</span><span class="Constant">&quot;foo&quot;</span><span class="Delimiter">)</span> == <span class="Constant">0</span><span class="Delimiter">);</span>
+  <span class="Comment">// a call that specializes this recipe</span>
+  run<span class="Delimiter">(</span><span class="Constant">&quot;recipe main [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;  local-scope</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;  x:address:array:character &lt;- new [recipe foo x:_elem -&gt; n:number [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;local-scope</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;load-ingredients</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;reply 34</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;recipe main2 [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;local-scope</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;load-ingredients</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;x:number &lt;- copy 34</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;foo x:number</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;]]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;  reload x</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span>
+      <span class="Constant">&quot;]</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">);</span>
+  <span class="Comment">// check that number of variants includes specialization</span>
+  assert<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>Recently_added_recipes<span class="Delimiter">)</span> == <span class="Constant">4</span><span class="Delimiter">);</span>  <span class="Comment">// foo, main, main2, foo specialization</span>
+  CHECK_EQ<span class="Delimiter">(</span>variant_count<span class="Delimiter">(</span><span class="Constant">&quot;foo&quot;</span><span class="Delimiter">),</span> <span class="Constant">2</span><span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
 </pre>
 </body>
 </html>
diff --git a/html/chessboard.mu.html b/html/chessboard.mu.html
index 338e92dc..16230411 100644
--- a/html/chessboard.mu.html
+++ b/html/chessboard.mu.html
@@ -276,7 +276,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 ]
 
 <span class="Comment"># prints only error messages to screen</span>
-<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="muRecipe">recipe</span> read-move stdin:address:channel, screen:address:screen<span class="muRecipe"> -&gt; </span>result:address:move, quit?:boolean, error?:boolean, stdin:address:channel, screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   from-file:number, quit?:boolean, error?:boolean<span class="Special"> &lt;- </span>read-file stdin, screen
@@ -306,7 +306,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 ]
 
 <span class="Comment"># valid values for file: 0-7</span>
-<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="muRecipe">recipe</span> read-file stdin:address:channel, screen:address:screen<span class="muRecipe"> -&gt; </span>file:number, quit:boolean, error:boolean, stdin:address:channel, screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   c:character, stdin<span class="Special"> &lt;- </span>read stdin
@@ -399,7 +399,7 @@ 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 stdin:address:channel, expected:character, screen:address:screen<span class="muRecipe"> -&gt; </span>result:boolean [
+<span class="muRecipe">recipe</span> expect-from-channel stdin:address:channel, expected:character, screen:address:screen<span class="muRecipe"> -&gt; </span>result:boolean, stdin:address:channel, screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   c:character, stdin<span class="Special"> &lt;- </span>read stdin
diff --git a/html/edit/001-editor.mu.html b/html/edit/001-editor.mu.html
index 59982193..11d1cb9d 100644
--- a/html/edit/001-editor.mu.html
+++ b/html/edit/001-editor.mu.html
@@ -287,7 +287,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply</span> screen/same-as-ingredient:<span class="Constant">0</span>
 ]
 
-<span class="muRecipe">recipe</span> clear-rest-of-screen screen:address:screen, row:number, left:number, right:number [
+<span class="muRecipe">recipe</span> clear-rest-of-screen screen:address:screen, row:number, left:number, right:number<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   row<span class="Special"> &lt;- </span>add row, <span class="Constant">1</span>
diff --git a/html/edit/002-typing.mu.html b/html/edit/002-typing.mu.html
index efed71b6..2585450c 100644
--- a/html/edit/002-typing.mu.html
+++ b/html/edit/002-typing.mu.html
@@ -46,7 +46,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   close-console
 ]
 
-<span class="muRecipe">recipe</span> editor-event-loop screen:address:screen, console:address:console, editor:address:editor-data [
+<span class="muRecipe">recipe</span> editor-event-loop screen:address:screen, console:address:console, editor:address:editor-data<span class="muRecipe"> -&gt; </span>screen:address:screen, console:address:console, editor:address:editor-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="Delimiter">{</span>
@@ -80,7 +80,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 ]
 
 <span class="Comment"># process click, return if it was on current editor</span>
-<span class="muRecipe">recipe</span> move-cursor-in-editor screen:address:screen, editor:address:editor-data, t:touch-event<span class="muRecipe"> -&gt; </span>in-focus?:boolean [
+<span class="muRecipe">recipe</span> move-cursor-in-editor screen:address:screen, editor:address:editor-data, t:touch-event<span class="muRecipe"> -&gt; </span>in-focus?:boolean, editor:address:editor-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="muControl">reply-unless</span> editor, <span class="Constant">0/false</span>
@@ -294,7 +294,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 ]
 
 <span class="Comment"># helper for tests</span>
-<span class="muRecipe">recipe</span> editor-render screen:address:screen, editor:address:editor-data<span class="muRecipe"> -&gt; </span>screen:address:screen [
+<span class="muRecipe">recipe</span> editor-render screen:address:screen, editor:address:editor-data<span class="muRecipe"> -&gt; </span>screen:address:screen, editor:address:editor-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   left:number<span class="Special"> &lt;- </span>get *editor, <span class="Constant">left:offset</span>
@@ -1047,7 +1047,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="SalientComment">## helpers</span>
 
-<span class="muRecipe">recipe</span> draw-horizontal screen:address:screen, row:number, x:number, right:number [
+<span class="muRecipe">recipe</span> draw-horizontal screen:address:screen, row:number, x:number, right:number<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   style:character, style-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
diff --git a/html/edit/003-shortcuts.mu.html b/html/edit/003-shortcuts.mu.html
index 5518a680..0f7a60da 100644
--- a/html/edit/003-shortcuts.mu.html
+++ b/html/edit/003-shortcuts.mu.html
@@ -118,6 +118,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   before-cursor:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+  data:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">data:offset</span>
   <span class="Comment"># if at start of text (before-cursor at § sentinel), return</span>
   prev:address:duplex-list:character<span class="Special"> &lt;- </span>prev *before-cursor
   go-render?, backspaced-cell<span class="Special"> &lt;- </span>copy <span class="Constant">0/no-more-render</span>, <span class="Constant">0/nothing-deleted</span>
@@ -126,7 +127,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   original-row:number<span class="Special"> &lt;- </span>get *editor, <span class="Constant">cursor-row:offset</span>
   editor, scroll?:boolean<span class="Special"> &lt;- </span>move-cursor-coordinates-left editor
   backspaced-cell:address:duplex-list:character<span class="Special"> &lt;- </span>copy *before-cursor
-  remove *before-cursor  <span class="Comment"># will also neatly trim next/prev pointers in backspaced-cell/*before-cursor</span>
+  data<span class="Special"> &lt;- </span>remove *before-cursor, data  <span class="Comment"># will also neatly trim next/prev pointers in backspaced-cell/*before-cursor</span>
   *before-cursor<span class="Special"> &lt;- </span>copy prev
   go-render?<span class="Special"> &lt;- </span>copy <span class="Constant">1/true</span>
   <span class="muControl">reply-if</span> scroll?
@@ -367,11 +368,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   before-cursor:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
+  data:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">data:offset</span>
   deleted-cell:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
   go-render?<span class="Special"> &lt;- </span>copy <span class="Constant">0/false</span>
   <span class="muControl">reply-unless</span> deleted-cell
   currc:character<span class="Special"> &lt;- </span>get *deleted-cell, <span class="Constant">value:offset</span>
-  remove deleted-cell
+  data<span class="Special"> &lt;- </span>remove deleted-cell, data
   deleted-newline?:boolean<span class="Special"> &lt;- </span>equal currc, <span class="Constant">10/newline</span>
   go-render?<span class="Special"> &lt;- </span>copy <span class="Constant">1/true</span>
   <span class="muControl">reply-if</span> deleted-newline?
@@ -1278,7 +1280,7 @@ def]
   <span class="Delimiter">}</span>
 ]
 
-<span class="muRecipe">recipe</span> move-to-start-of-line editor:address:editor-data [
+<span class="muRecipe">recipe</span> move-to-start-of-line editor:address:editor-data<span class="muRecipe"> -&gt; </span>editor:address:editor-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="Comment"># update cursor column</span>
@@ -1449,7 +1451,7 @@ def]
   <span class="Delimiter">}</span>
 ]
 
-<span class="muRecipe">recipe</span> move-to-end-of-line editor:address:editor-data [
+<span class="muRecipe">recipe</span> move-to-end-of-line editor:address:editor-data<span class="muRecipe"> -&gt; </span>editor:address:editor-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   before-cursor:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
@@ -1579,7 +1581,7 @@ def]
   <span class="Delimiter">}</span>
 ]
 
-<span class="muRecipe">recipe</span> delete-to-start-of-line editor:address:editor-data<span class="muRecipe"> -&gt; </span>result:address:duplex-list:character [
+<span class="muRecipe">recipe</span> delete-to-start-of-line editor:address:editor-data<span class="muRecipe"> -&gt; </span>result:address:duplex-list:character, editor:address:editor-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="Comment"># compute range to delete</span>
@@ -1713,7 +1715,7 @@ def]
   <span class="Delimiter">}</span>
 ]
 
-<span class="muRecipe">recipe</span> delete-to-end-of-line editor:address:editor-data<span class="muRecipe"> -&gt; </span>result:address:duplex-list:character [
+<span class="muRecipe">recipe</span> delete-to-end-of-line editor:address:editor-data<span class="muRecipe"> -&gt; </span>result:address:duplex-list:character, editor:address:editor-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="Comment"># compute range to delete</span>
diff --git a/html/edit/004-programming-environment.mu.html b/html/edit/004-programming-environment.mu.html
index a2001520..7b632086 100644
--- a/html/edit/004-programming-environment.mu.html
+++ b/html/edit/004-programming-environment.mu.html
@@ -56,7 +56,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   sandbox-in-focus?:boolean  <span class="Comment"># false =&gt; cursor in recipes; true =&gt; cursor in current-sandbox</span>
 ]
 
-<span class="muRecipe">recipe</span> new-programming-environment screen:address:screen, initial-recipe-contents:address:array:character, initial-sandbox-contents:address:array:character<span class="muRecipe"> -&gt; </span>result:address:programming-environment-data [
+<span class="muRecipe">recipe</span> new-programming-environment screen:address:screen, initial-recipe-contents:address:array:character, initial-sandbox-contents:address:array:character<span class="muRecipe"> -&gt; </span>result:address:programming-environment-data, screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   width:number<span class="Special"> &lt;- </span>screen-width screen
@@ -82,7 +82,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   *current-sandbox<span class="Special"> &lt;- </span>new-editor initial-sandbox-contents, screen, new-left, width/right
 ]
 
-<span class="muRecipe">recipe</span> event-loop screen:address:screen, console:address:console, env:address:programming-environment-data [
+<span class="muRecipe">recipe</span> event-loop screen:address:screen, console:address:console, env:address:programming-environment-data<span class="muRecipe"> -&gt; </span>screen:address:screen, console:address:console, env:address:programming-environment-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   recipes:address:editor-data<span class="Special"> &lt;- </span>get *env, <span class="Constant">recipes:offset</span>
@@ -141,7 +141,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       <span class="Delimiter">}</span>
       <span class="Delimiter">{</span>
         <span class="muControl">break-if</span> more-events?
-        env<span class="Special"> &lt;- </span>resize screen, env
+        env, screen<span class="Special"> &lt;- </span>resize screen, env
         screen<span class="Special"> &lt;- </span>render-all screen, env
         render-all-on-no-more-events?<span class="Special"> &lt;- </span>copy <span class="Constant">0/false</span>  <span class="Comment"># full render done</span>
       <span class="Delimiter">}</span>
@@ -214,7 +214,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">}</span>
 ]
 
-<span class="muRecipe">recipe</span> resize screen:address:screen, env:address:programming-environment-data<span class="muRecipe"> -&gt; </span>env:address:programming-environment-data [
+<span class="muRecipe">recipe</span> resize screen:address:screen, env:address:programming-environment-data<span class="muRecipe"> -&gt; </span>env:address:programming-environment-data, screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   clear-screen screen  <span class="Comment"># update screen dimensions</span>
@@ -633,7 +633,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="SalientComment">## helpers</span>
 
-<span class="muRecipe">recipe</span> draw-vertical screen:address:screen, col:number, y:number, bottom:number [
+<span class="muRecipe">recipe</span> draw-vertical screen:address:screen, col:number, y:number, bottom:number<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   style:character, style-found?:boolean<span class="Special"> &lt;- </span><span class="Constant">next-ingredient</span>
diff --git a/html/edit/005-sandbox.mu.html b/html/edit/005-sandbox.mu.html
index 9c219526..0b3e3926 100644
--- a/html/edit/005-sandbox.mu.html
+++ b/html/edit/005-sandbox.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; }
 -->
@@ -149,6 +150,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">{</span>
     do-run?:boolean<span class="Special"> &lt;- </span>equal *k, <span class="Constant">65532/F4</span>
     <span class="muControl">break-unless</span> do-run?
+<span class="CommentedCode">#?     $log [F4 pressed]</span>
     status:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[running...  ]</span>
     screen<span class="Special"> &lt;- </span>update-status screen, status, <span class="Constant">245/grey</span>
     error?:boolean, env, screen<span class="Special"> &lt;- </span>run-sandboxes env, screen
@@ -261,6 +263,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muRecipe">recipe!</span> render-sandbox-side screen:address:screen, env:address:programming-environment-data<span class="muRecipe"> -&gt; </span>screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
+<span class="CommentedCode">#?   $log [render sandbox side]</span>
   trace <span class="Constant">11</span>, <span class="Constant">[app]</span>, <span class="Constant">[render sandbox side]</span>
   current-sandbox:address:editor-data<span class="Special"> &lt;- </span>get *env, <span class="Constant">current-sandbox:offset</span>
   left:number<span class="Special"> &lt;- </span>get *current-sandbox, <span class="Constant">left:offset</span>
@@ -274,9 +277,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   clear-rest-of-screen screen, row, left, left, right
 ]
 
-<span class="muRecipe">recipe</span> render-sandboxes screen:address:screen, sandbox:address:sandbox-data, left:number, right:number, row:number<span class="muRecipe"> -&gt; </span>row:number, screen:address:screen [
+<span class="muRecipe">recipe</span> render-sandboxes screen:address:screen, sandbox:address:sandbox-data, left:number, right:number, row:number<span class="muRecipe"> -&gt; </span>row:number, screen:address:screen, sandbox:address:sandbox-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
+<span class="CommentedCode">#?   $log [render sandbox]</span>
   <span class="muControl">reply-unless</span> sandbox
   screen-height:number<span class="Special"> &lt;- </span>screen-height screen
   at-bottom?:boolean<span class="Special"> &lt;- </span>greater-or-equal row, screen-height
diff --git a/html/edit/006-sandbox-edit.mu.html b/html/edit/006-sandbox-edit.mu.html
index 2381ec45..d902c4b7 100644
--- a/html/edit/006-sandbox-edit.mu.html
+++ b/html/edit/006-sandbox-edit.mu.html
@@ -131,7 +131,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   result<span class="Special"> &lt;- </span>not first
 ]
 
-<span class="muRecipe">recipe</span> extract-sandbox env:address:programming-environment-data, click-row:number<span class="muRecipe"> -&gt; </span>result:address:sandbox-data [
+<span class="muRecipe">recipe</span> extract-sandbox env:address:programming-environment-data, click-row:number<span class="muRecipe"> -&gt; </span>result:address:sandbox-data, env:address:programming-environment-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="Comment"># assert click-row &gt;= sandbox.starting-row-on-screen</span>
diff --git a/html/edit/007-sandbox-delete.mu.html b/html/edit/007-sandbox-delete.mu.html
index f563b266..6d289afa 100644
--- a/html/edit/007-sandbox-delete.mu.html
+++ b/html/edit/007-sandbox-delete.mu.html
@@ -111,7 +111,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">}</span>
 ]
 
-<span class="muRecipe">recipe</span> delete-sandbox t:touch-event, env:address:programming-environment-data<span class="muRecipe"> -&gt; </span>was-delete?:boolean [
+<span class="muRecipe">recipe</span> delete-sandbox t:touch-event, env:address:programming-environment-data<span class="muRecipe"> -&gt; </span>was-delete?:boolean, env:address:programming-environment-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   click-column:number<span class="Special"> &lt;- </span>get t, <span class="Constant">column:offset</span>
diff --git a/html/edit/010-warnings.mu.html b/html/edit/010-warnings.mu.html
index 6d746bf5..c675b386 100644
--- a/html/edit/010-warnings.mu.html
+++ b/html/edit/010-warnings.mu.html
@@ -44,6 +44,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muRecipe">recipe!</span> update-recipes env:address:programming-environment-data, screen:address:screen<span class="muRecipe"> -&gt; </span>errors-found?:boolean, env:address:programming-environment-data, screen:address:screen [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
+<span class="CommentedCode">#?   $log [update recipes]</span>
   recipes:address:editor-data<span class="Special"> &lt;- </span>get *env, <span class="Constant">recipes:offset</span>
   in:address:array:character<span class="Special"> &lt;- </span>editor-contents recipes
   save <span class="Constant">[recipes.mu]</span>, in
@@ -85,6 +86,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muRecipe">recipe!</span> update-sandbox sandbox:address:sandbox-data<span class="muRecipe"> -&gt; </span>sandbox:address:sandbox-data [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
+<span class="CommentedCode">#?   $log [update sandbox]</span>
   data:address:array:character<span class="Special"> &lt;- </span>get *sandbox, <span class="Constant">data:offset</span>
   response:address:address:array:character<span class="Special"> &lt;- </span>get-address *sandbox, <span class="Constant">response:offset</span>
   warnings:address:address:array:character<span class="Special"> &lt;- </span>get-address *sandbox, <span class="Constant">warnings:offset</span>
@@ -235,6 +237,66 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
+<span class="muScenario">scenario</span> run-avoids-spurious-warnings-on-reloading-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"># overload a well-known shape-shifting recipe</span>
+  <span class="Constant">1</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[recipe length l:address:list:_elem -&gt; n:number [</span>
+<span class="Constant">]</span>]
+  <span class="Comment"># call code that uses other variants of it, but not it itself</span>
+  <span class="Constant">2</span>:address:array:character<span class="Special"> &lt;- </span>new <span class="Constant">[x:address:list:number &lt;- copy 0</span>
+<span class="Constant">to-text x]</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
+  <span class="Comment"># run it once</span>
+  assume-console [
+    press F4
+  ]
+  event-loop screen:address:screen, console:address:console, <span class="Constant">3</span>:address:programming-environment-data
+  <span class="Comment"># no errors anywhere on screen (can't check anything else, since to-text will return an address)</span>
+  screen-should-contain-in-color <span class="Constant">1/red</span>, [
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                         &lt;-                         .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+  ]
+  <span class="Comment"># 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"># still no errors</span>
+  screen-should-contain-in-color <span class="Constant">1/red</span>, [
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                         &lt;-                         .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</span>
+   <span class="Constant"> .                                                                                                    .</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>