about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--html/010vm.cc.html21
-rw-r--r--html/021check_instruction.cc.html14
-rw-r--r--html/029tools.cc.html1
-rw-r--r--html/035call_ingredient.cc.html15
-rw-r--r--html/041jump_target.cc.html2
-rw-r--r--html/057static_dispatch.cc.html22
-rw-r--r--html/058shape_shifting_container.cc.html3
-rw-r--r--html/059shape_shifting_recipe.cc.html252
-rw-r--r--html/073list.mu.html11
-rw-r--r--html/075duplex_list.mu.html338
-rw-r--r--html/091run_interactive.cc.html3
-rw-r--r--html/edit/001-editor.mu.html20
-rw-r--r--html/edit/002-typing.mu.html28
-rw-r--r--html/edit/003-shortcuts.mu.html60
-rw-r--r--html/edit/005-sandbox.mu.html6
-rw-r--r--html/edit/006-sandbox-edit.mu.html2
-rw-r--r--html/edit/011-editor-undo.mu.html38
17 files changed, 523 insertions, 313 deletions
diff --git a/html/010vm.cc.html b/html/010vm.cc.html
index 20c502ba..f476aa61 100644
--- a/html/010vm.cc.html
+++ b/html/010vm.cc.html
@@ -467,11 +467,11 @@ string instruction::to_string<span class="Delimiter">()</span> const <span class
 
 string debug_string<span class="Delimiter">(</span>const recipe&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   ostringstream out<span class="Delimiter">;</span>
-  out &lt;&lt; <span class="Constant">&quot;recipe &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+  out &lt;&lt; <span class="Constant">&quot;- recipe &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
   <span class="Comment">// Begin debug_string(recipe x)</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>x<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     const instruction&amp; inst = x<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
-    out &lt;&lt; <span class="Constant">&quot;  inst: &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
+    out &lt;&lt; <span class="Constant">&quot;inst: &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>to_string<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</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>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
       out &lt;&lt; <span class="Constant">&quot;    &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
@@ -518,6 +518,23 @@ bool deeply_equal<span class="Delimiter">(</span>const string_tree* a<span class
       &amp;&amp; deeply_equal<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
+<span class="Delimiter">:(before &quot;End Globals&quot;)</span>
+set&lt;string&gt; Literal_type_names<span class="Delimiter">;</span>
+<span class="Delimiter">:(before &quot;End One-time Setup&quot;)</span>
+Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;literal&quot;</span><span class="Delimiter">);</span>
+Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;number&quot;</span><span class="Delimiter">);</span>
+Literal_type_names<span class="Delimiter">.</span>insert<span class="Delimiter">(</span><span class="Constant">&quot;character&quot;</span><span class="Delimiter">);</span>
+<span class="Delimiter">:(code)</span>
+bool deeply_equal_types<span class="Delimiter">(</span>const string_tree* a<span class="Delimiter">,</span> const string_tree* b<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!a<span class="Delimiter">)</span> <span class="Identifier">return</span> !b<span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>!b<span class="Delimiter">)</span> <span class="Identifier">return</span> !a<span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+    <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>b<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
+  <span class="Identifier">return</span> a<span class="Delimiter">-&gt;</span>value == b<span class="Delimiter">-&gt;</span>value
+      &amp;&amp; deeply_equal_types<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span>
+      &amp;&amp; deeply_equal_types<span class="Delimiter">(</span>a<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> b<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
 void dump_memory<span class="Delimiter">()</span> <span class="Delimiter">{</span>
   for <span class="Delimiter">(</span>map&lt;long long int<span class="Delimiter">,</span> double&gt;::iterator p = Memory<span class="Delimiter">.</span>begin<span class="Delimiter">();</span> p != Memory<span class="Delimiter">.</span>end<span class="Delimiter">();</span> ++p<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     cout &lt;&lt; p<span class="Delimiter">-&gt;</span>first &lt;&lt; <span class="Constant">&quot;: &quot;</span> &lt;&lt; no_scientific<span class="Delimiter">(</span>p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
diff --git a/html/021check_instruction.cc.html b/html/021check_instruction.cc.html
index f0238926..e203a386 100644
--- a/html/021check_instruction.cc.html
+++ b/html/021check_instruction.cc.html
@@ -113,13 +113,19 @@ bool types_match<span class="Delimiter">(</span>reagent lhs<span class="Delimite
   <span class="Comment">// to sidestep type-checking, use /raw in the source.</span>
   <span class="Comment">// this is unsafe, and will be highlighted in red inside vim. just for some tests.</span>
   if <span class="Delimiter">(</span>is_raw<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-  <span class="Comment">// allow writing 0 to any address</span>
-  if <span class="Delimiter">(</span>rhs<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span> &amp;&amp; is_mu_address<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> !is_mu_array<span class="Delimiter">(</span>lhs<span class="Delimiter">)</span> &amp;&amp; !is_mu_address<span class="Delimiter">(</span>lhs<span class="Delimiter">)</span> &amp;&amp; size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>is_literal<span class="Delimiter">(</span>rhs<span class="Delimiter">))</span> <span class="Identifier">return</span> valid_type_for_literal<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<span class="Delimiter">)</span> &amp;&amp; size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>!lhs<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Identifier">return</span> !rhs<span class="Delimiter">.</span>type<span class="Delimiter">;</span>
   <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>type<span class="Delimiter">,</span> rhs<span class="Delimiter">.</span>type<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
+bool valid_type_for_literal<span class="Delimiter">(</span>const reagent&amp; lhs<span class="Delimiter">,</span> const reagent&amp; literal_rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>is_mu_array<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+  <span class="Comment">// End valid_type_for_literal Special-cases</span>
+  <span class="Comment">// allow writing 0 to any address</span>
+  if <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> literal_rhs<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span><span class="Delimiter">;</span>
+  <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 <span class="Comment">// two types match if the second begins like the first</span>
 <span class="Comment">// (trees perform the same check recursively on each subtree)</span>
 bool types_match<span class="Delimiter">(</span>type_tree* lhs<span class="Delimiter">,</span> type_tree* rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -129,6 +135,8 @@ bool types_match<span class="Delimiter">(</span>type_tree* lhs<span class="Delim
     if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;address&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
     <span class="Identifier">return</span> size_of<span class="Delimiter">(</span>rhs<span class="Delimiter">)</span> == size_of<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
+  if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;character&quot;</span><span class="Delimiter">)</span> &amp;&amp; rhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;number&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;number&quot;</span><span class="Delimiter">)</span> &amp;&amp; rhs<span class="Delimiter">-&gt;</span>value == get<span class="Delimiter">(</span>Type_ordinal<span class="Delimiter">,</span> <span class="Constant">&quot;character&quot;</span><span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value != rhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-&gt;</span>left<span class="Delimiter">)</span> &amp;&amp; types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-&gt;</span>right<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
diff --git a/html/029tools.cc.html b/html/029tools.cc.html
index 018e0f01..4f5242fe 100644
--- a/html/029tools.cc.html
+++ b/html/029tools.cc.html
@@ -285,6 +285,7 @@ case _PRINT: <span class="Delimiter">{</span>
       <span class="Delimiter">}</span>
     <span class="Delimiter">}</span>
   <span class="Delimiter">}</span>
+  cout<span class="Delimiter">.</span>flush<span class="Delimiter">();</span>
   <span class="Identifier">break</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
diff --git a/html/035call_ingredient.cc.html b/html/035call_ingredient.cc.html
index 104c66dc..ff46da6f 100644
--- a/html/035call_ingredient.cc.html
+++ b/html/035call_ingredient.cc.html
@@ -91,11 +91,16 @@ case NEXT_INGREDIENT: <span class="Delimiter">{</span>
   if <span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process &lt; SIZE<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     reagent product = current_instruction<span class="Delimiter">().</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
     canonize_type<span class="Delimiter">(</span>product<span class="Delimiter">);</span>
-    if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span>
-                     current_call<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">),</span>
-                     current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">)</span>
-                     <span class="Delimiter">))</span> <span class="Delimiter">{</span>
-      raise_error &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;wrong type for ingredient &quot;</span> &lt;&lt; current_instruction<span class="Delimiter">().</span>products<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>
+    if <span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">()</span> == <span class="Constant">&quot;main&quot;</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+      <span class="Comment">// no ingredient types since the call might be implicit; assume ingredients are always strings</span>
+      <span class="Comment">// todo: how to test this?</span>
+      if <span class="Delimiter">(</span>!is_mu_string<span class="Delimiter">(</span>product<span class="Delimiter">))</span>
+        raise_error &lt;&lt; <span class="Constant">&quot;main: wrong type for ingredient &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+    <span class="Delimiter">}</span>
+    else if <span class="Delimiter">(</span>!types_match<span class="Delimiter">(</span>product<span class="Delimiter">,</span>
+                          current_call<span class="Delimiter">().</span>ingredient_types<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">),</span>
+                          current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+      raise_error &lt;&lt; maybe<span class="Delimiter">(</span>current_recipe_name<span class="Delimiter">())</span> &lt;&lt; <span class="Constant">&quot;wrong type for ingredient &quot;</span> &lt;&lt; product<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Delimiter">}</span>
     products<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>
         current_call<span class="Delimiter">().</span>ingredient_atoms<span class="Delimiter">.</span>at<span class="Delimiter">(</span>current_call<span class="Delimiter">().</span>next_ingredient_to_process<span class="Delimiter">));</span>
diff --git a/html/041jump_target.cc.html b/html/041jump_target.cc.html
index 53f93910..e85829db 100644
--- a/html/041jump_target.cc.html
+++ b/html/041jump_target.cc.html
@@ -98,7 +98,7 @@ void replace_offset<span class="Delimiter">(</span>reagent&amp; x<span class="De
     x<span class="Delimiter">.</span>set_value<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>  <span class="Comment">// no jump by default</span>
     <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  assert<span class="Delimiter">(</span>!x<span class="Delimiter">.</span>initialized<span class="Delimiter">);</span>
+  if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>initialized<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>is_integer<span class="Delimiter">(</span>x<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Identifier">return</span><span class="Delimiter">;</span>  <span class="Comment">// non-labels will be handled like other number operands</span>
   if <span class="Delimiter">(</span>!is_jump_target<span class="Delimiter">(</span>x<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;can't jump to label &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>name &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
diff --git a/html/057static_dispatch.cc.html b/html/057static_dispatch.cc.html
index ec362d4a..243b9c28 100644
--- a/html/057static_dispatch.cc.html
+++ b/html/057static_dispatch.cc.html
@@ -14,10 +14,11 @@ pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-
 body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 * { font-size: 1.05em; }
 .traceContains { color: #008000; }
+.Identifier { color: #804000; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
 .Special { color: #ff6060; }
-.Identifier { color: #804000; }
+.CommentedCode { color: #6c6c6c; }
 .Constant { color: #00a0a0; }
 -->
 </style>
@@ -64,8 +65,9 @@ for <span class="Delimiter">(</span>map&lt;string<span class="Delimiter">,</span
 <span class="Delimiter">:(before &quot;End Load Recipe Header(result)&quot;)</span>
 if <span class="Delimiter">(</span>contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">))</span> <span class="Delimiter">{</span>
   const recipe_ordinal r = get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
+<span class="CommentedCode">//?   if (variant_already_exists(result)) cerr &lt;&lt; &quot;AAAAAAAAAAAAAAAAAA variant already exists &quot; &lt;&lt; result.name &lt;&lt; '\n';</span>
   if <span class="Delimiter">((</span>!contains_key<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">)</span> || get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">).</span>has_header<span class="Delimiter">)</span>
-      &amp;&amp; !header_already_exists<span class="Delimiter">(</span>result<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+      &amp;&amp; !variant_already_exists<span class="Delimiter">(</span>result<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     string new_name = next_unused_recipe_name<span class="Delimiter">(</span>result<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
     put<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">,</span> Next_recipe_ordinal++<span class="Delimiter">);</span>
     get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> result<span class="Delimiter">.</span>name<span class="Delimiter">).</span>push_back<span class="Delimiter">(</span>get<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> new_name<span class="Delimiter">));</span>
@@ -79,10 +81,10 @@ else <span class="Delimiter">{</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(code)</span>
-bool header_already_exists<span class="Delimiter">(</span>const recipe&amp; rr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+bool variant_already_exists<span class="Delimiter">(</span>const recipe&amp; rr<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   const vector&lt;recipe_ordinal&gt;&amp; variants = get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> rr<span class="Delimiter">.</span>name<span class="Delimiter">);</span>
   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>Recipe<span class="Delimiter">.</span>find<span class="Delimiter">(</span>variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">))</span> != Recipe<span class="Delimiter">.</span>end<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>
@@ -94,12 +96,16 @@ bool all_reagents_match<span class="Delimiter">(</span>const recipe&amp; r1<span
   if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>ingredients<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>r2<span class="Delimiter">.</span>ingredients<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
   if <span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>products<span class="Delimiter">)</span> != SIZE<span class="Delimiter">(</span>r2<span class="Delimiter">.</span>products<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</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>r1<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>!exact_match<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span> r2<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">))</span>
+    if <span class="Delimiter">(</span>!deeply_equal_types<span class="Delimiter">(</span>r1<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>
+                            r2<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> <span class="Delimiter">{</span>
       <span class="Identifier">return</span> <span class="Constant">false</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>r1<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>!exact_match<span class="Delimiter">(</span>r1<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">,</span> r2<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">))</span>
+    if <span class="Delimiter">(</span>!deeply_equal_types<span class="Delimiter">(</span>r1<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>
+                            r2<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> <span class="Delimiter">{</span>
       <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+    <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>
@@ -115,7 +121,7 @@ string next_unused_recipe_name<span class="Delimiter">(</span>const string&amp;
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">2</span><span class="Delimiter">;</span> <span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     ostringstream out<span class="Delimiter">;</span>
     out &lt;&lt; recipe_name &lt;&lt; <span class="Constant">'_'</span> &lt;&lt; i<span class="Delimiter">;</span>
-    if <span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">.</span>find<span class="Delimiter">(</span>out<span class="Delimiter">.</span>str<span class="Delimiter">())</span> == Recipe_ordinal<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+    if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Recipe_ordinal<span class="Delimiter">,</span> out<span class="Delimiter">.</span>str<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">}</span>
@@ -143,7 +149,6 @@ Transform<span class="Delimiter">.</span>push_back<span class="Delimiter">(</spa
 <span class="Delimiter">:(code)</span>
 void resolve_ambiguous_calls<span class="Delimiter">(</span>recipe_ordinal r<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   recipe&amp; caller_recipe = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> r<span class="Delimiter">);</span>
-  if <span class="Delimiter">(</span>!caller_recipe<span class="Delimiter">.</span>has_header<span class="Delimiter">)</span> <span class="Identifier">return</span><span class="Delimiter">;</span>
   trace<span class="Delimiter">(</span><span class="Constant">9991</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;--- resolve ambiguous calls for recipe &quot;</span> &lt;&lt; caller_recipe<span class="Delimiter">.</span>name &lt;&lt; end<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_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++index<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     instruction&amp; inst = caller_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>index<span class="Delimiter">);</span>
@@ -152,6 +157,7 @@ void resolve_ambiguous_calls<span class="Delimiter">(</span>recipe_ordinal r<spa
     assert<span class="Delimiter">(</span>!get<span class="Delimiter">(</span>Recipe_variants<span class="Delimiter">,</span> inst<span class="Delimiter">.</span>name<span class="Delimiter">).</span>empty<span class="Delimiter">());</span>
     replace_best_variant<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
+<span class="CommentedCode">//?   if (caller_recipe.name == &quot;main&quot;) cerr &lt;&lt; &quot;=============== &quot; &lt;&lt; debug_string(caller_recipe) &lt;&lt; '\n';</span>
 <span class="Delimiter">}</span>
 
 void replace_best_variant<span class="Delimiter">(</span>instruction&amp; inst<span class="Delimiter">,</span> const recipe&amp; caller_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
diff --git a/html/058shape_shifting_container.cc.html b/html/058shape_shifting_container.cc.html
index 4a4fb2cc..0402d54b 100644
--- a/html/058shape_shifting_container.cc.html
+++ b/html/058shape_shifting_container.cc.html
@@ -21,6 +21,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
 .Identifier { color: #804000; }
+.CommentedCode { color: #6c6c6c; }
 -->
 </style>
 
@@ -131,7 +132,7 @@ long long int size_of_type_ingredient<span class="Delimiter">(</span>const type_
   assert<span class="Delimiter">(</span>!curr<span class="Delimiter">-&gt;</span>left<span class="Delimiter">);</span>  <span class="Comment">// unimplemented</span>
   if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>Type<span class="Delimiter">,</span> curr<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     <span class="Comment">// temporarily while we're still ironing out kinks; eventually replace with a raise_error</span>
-    DUMP<span class="Delimiter">(</span><span class="Constant">&quot;&quot;</span><span class="Delimiter">);</span>
+<span class="CommentedCode">//?     DUMP(&quot;&quot;);</span>
     cerr &lt;&lt; <span class="Constant">&quot;missing type &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>curr<span class="Delimiter">)</span> &lt;&lt; <span class="cSpecial">'\n'</span><span class="Delimiter">;</span>
     exit<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
diff --git a/html/059shape_shifting_recipe.cc.html b/html/059shape_shifting_recipe.cc.html
index 2df37fa3..13c436c4 100644
--- a/html/059shape_shifting_recipe.cc.html
+++ b/html/059shape_shifting_recipe.cc.html
@@ -16,6 +16,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 .traceContains { color: #008000; }
 .Special { color: #ff6060; }
 .cSpecial { color: #008000; }
+.CommentedCode { color: #6c6c6c; }
 .Comment { color: #9090ff; }
 .Delimiter { color: #a04060; }
 .SalientComment { color: #00ffff; }
@@ -54,11 +55,26 @@ recipe foo a:_t <span class="Delimiter">-&gt;</span> result:_t [
 <span class="traceContains">+mem: storing 14 in location 11</span>
 <span class="traceContains">+mem: storing 15 in location 12</span>
 
-<span class="Comment">//: Before anything else, disable transforms for shape-shifting recipes.</span>
+<span class="Comment">//: Before anything else, disable transforms for shape-shifting recipes and</span>
+<span class="Comment">//: make sure we never try to actually run a shape-shifting recipe. We should</span>
+<span class="Comment">//: be rewriting such instructions to *specializations* with the type</span>
+<span class="Comment">//: ingredients filled in.</span>
 
 <span class="Delimiter">:(before &quot;End Transform Checks&quot;)</span>
 if <span class="Delimiter">(</span>any_type_ingredient_in_header<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">recipe_ordinal</span><span class="Comment">*/</span>p<span class="Delimiter">-&gt;</span>first<span class="Delimiter">))</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>
 
+<span class="Delimiter">:(after &quot;Running One Instruction&quot;)</span>
+if <span class="Delimiter">(</span>Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_step_index == <span class="Constant">0</span>
+    &amp;&amp; any_type_ingredient_in_header<span class="Delimiter">(</span>Current_routine<span class="Delimiter">-&gt;</span>calls<span class="Delimiter">.</span>front<span class="Delimiter">().</span>running_recipe<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   DUMP(&quot;&quot;);</span>
+  raise_error &lt;&lt; <span class="Constant">&quot;ran into unspecialized shape-shifting recipe &quot;</span> &lt;&lt; current_recipe_name<span class="Delimiter">()</span> &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+<span class="Delimiter">}</span>
+
+<span class="Comment">//: Make sure we don't match up literals with type ingredients without</span>
+<span class="Comment">//: specialization.</span>
+<span class="Delimiter">:(before &quot;End valid_type_for_literal Special-cases&quot;)</span>
+if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
+
 <span class="Comment">//: We'll be creating recipes without loading them from anywhere by</span>
 <span class="Comment">//: *specializing* existing recipes, so make sure we don't clear any of those</span>
 <span class="Comment">//: when we start running tests.</span>
@@ -68,24 +84,35 @@ recently_added_types<span class="Delimiter">.</span>clear<span class="Delimiter"
 
 <span class="Delimiter">:(before &quot;End Instruction Dispatch(inst, best_score)&quot;)</span>
 if <span class="Delimiter">(</span>best_score == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   if (inst.name == &quot;push-duplex&quot;) Trace_stream = new trace_stream;</span>
   trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;no variant found; searching for variant with suitable type ingredients&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
   recipe_ordinal exemplar = pick_matching_shape_shifting_variant<span class="Delimiter">(</span>variants<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> best_score<span class="Delimiter">);</span>
   if <span class="Delimiter">(</span>exemplar<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;found variant to specialize: &quot;</span> &lt;&lt; exemplar &lt;&lt; <span class="Constant">' '</span> &lt;&lt; get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">).</span>name &lt;&lt; end<span class="Delimiter">();</span>
     variants<span class="Delimiter">.</span>push_back<span class="Delimiter">(</span>new_variant<span class="Delimiter">(</span>exemplar<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">));</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;-- replacing &quot; &lt;&lt; inst.name &lt;&lt; &quot; with &quot; &lt;&lt; get(Recipe, variants.back()).name &lt;&lt; '\n' &lt;&lt; debug_string(get(Recipe, variants.back()));</span>
     inst<span class="Delimiter">.</span>name = get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>back<span class="Delimiter">()).</span>name<span class="Delimiter">;</span>
     trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;new specialization: &quot;</span> &lt;&lt; inst<span class="Delimiter">.</span>name &lt;&lt; end<span class="Delimiter">();</span>
   <span class="Delimiter">}</span>
+<span class="CommentedCode">//?   if (inst.name == &quot;push-duplex&quot;) {</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;======== {\n&quot;;</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; inst.to_string() &lt;&lt; '\n';</span>
+<span class="CommentedCode">//?     DUMP(&quot;&quot;);</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;======== }\n&quot;;</span>
+<span class="CommentedCode">//?   }</span>
 <span class="Delimiter">}</span>
 
 <span class="Delimiter">:(code)</span>
 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>
   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>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>  <span class="Comment">// ghost from a previous test</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; &quot;-- variant &quot; &lt;&lt; i &lt;&lt; &quot;\n&quot; &lt;&lt; debug_string(get(Recipe, variants.at(i)));</span>
     trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;checking shape-shifting variant &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
     long long int current_score = shape_shifting_variant_score<span class="Delimiter">(</span>inst<span class="Delimiter">,</span> variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">));</span>
     trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;final score: &quot;</span> &lt;&lt; current_score &lt;&lt; end<span class="Delimiter">();</span>
+<span class="CommentedCode">//?     cerr &lt;&lt; get(Recipe, variants.at(i)).name &lt;&lt; &quot;: &quot; &lt;&lt; current_score &lt;&lt; '\n';</span>
     if <span class="Delimiter">(</span>current_score &gt; best_score<span class="Delimiter">)</span> <span class="Delimiter">{</span>
       trace<span class="Delimiter">(</span><span class="Constant">9992</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;matches&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
       result = variants<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
@@ -96,6 +123,7 @@ recipe_ordinal pick_matching_shape_shifting_variant<span class="Delimiter">(</sp
 <span class="Delimiter">}</span>
 
 long long int shape_shifting_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>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;======== &quot; &lt;&lt; inst.to_string() &lt;&lt; '\n';</span>
   if <span class="Delimiter">(</span>!any_type_ingredient_in_header<span class="Delimiter">(</span>variant<span class="Delimiter">))</span> <span class="Delimiter">{</span>
     trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;no type ingredients&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
@@ -106,7 +134,7 @@ long long int shape_shifting_variant_score<span class="Delimiter">(</span>const
     <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    if <span class="Delimiter">(</span>!non_type_ingredients_match<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
+    if <span class="Delimiter">(</span>!deeply_equal_concrete_types<span class="Delimiter">(</span>header_ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">)))</span> <span class="Delimiter">{</span>
       trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;mismatch: ingredient &quot;</span> &lt;&lt; i &lt;&lt; end<span class="Delimiter">();</span>
       <span class="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
@@ -117,7 +145,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>!non_type_ingredients_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>
+    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="Identifier">return</span> -<span class="Constant">1</span><span class="Delimiter">;</span>
     <span class="Delimiter">}</span>
@@ -139,9 +167,29 @@ bool any_type_ingredient_in_header<span class="Delimiter">(</span>recipe_ordinal
   <span class="Identifier">return</span> <span class="Constant">false</span><span class="Delimiter">;</span>
 <span class="Delimiter">}</span>
 
-bool non_type_ingredients_match<span class="Delimiter">(</span>const reagent&amp; lhs<span class="Delimiter">,</span> const reagent&amp; rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>contains_type_ingredient_name<span class="Delimiter">(</span>lhs<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>
-  <span class="Identifier">return</span> types_match<span class="Delimiter">(</span>lhs<span class="Delimiter">,</span> rhs<span class="Delimiter">);</span>
+bool deeply_equal_concrete_types<span class="Delimiter">(</span>reagent lhs<span class="Delimiter">,</span> reagent rhs<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; debug_string(lhs) &lt;&lt; &quot; vs &quot; &lt;&lt; debug_string(rhs) &lt;&lt; '\n';</span>
+<span class="CommentedCode">//?   bool result = deeply_equal_concrete_types(lhs.properties.at(0).second, rhs.properties.at(0).second, rhs);</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;  =&gt; &quot; &lt;&lt; result &lt;&lt; '\n';</span>
+<span class="CommentedCode">//?   return result;</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; &quot;== &quot; &lt;&lt; debug_string(lhs) &lt;&lt; &quot; vs &quot; &lt;&lt; debug_string(rhs) &lt;&lt; '\n';</span>
+  canonize_type<span class="Delimiter">(</span>lhs<span class="Delimiter">);</span>
+  canonize_type<span class="Delimiter">(</span>rhs<span class="Delimiter">);</span>
+  <span class="Identifier">return</span> deeply_equal_concrete_types<span class="Delimiter">(</span>lhs<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">,</span> rhs<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">,</span> rhs<span class="Delimiter">);</span>
+<span class="Delimiter">}</span>
+
+bool deeply_equal_concrete_types<span class="Delimiter">(</span>const string_tree* lhs<span class="Delimiter">,</span> const string_tree* rhs<span class="Delimiter">,</span> const reagent&amp; rhs_reagent<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!lhs<span class="Delimiter">)</span> <span class="Identifier">return</span> !rhs<span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>!rhs<span class="Delimiter">)</span> <span class="Identifier">return</span> !lhs<span class="Delimiter">;</span>
+  if <span class="Delimiter">(</span>is_type_ingredient_name<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span> <span class="Identifier">return</span> <span class="Constant">true</span><span class="Delimiter">;</span>  <span class="Comment">// type ingredient matches anything</span>
+  if <span class="Delimiter">(</span>Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">())</span>
+    <span class="Identifier">return</span> Literal_type_names<span class="Delimiter">.</span>find<span class="Delimiter">(</span>rhs<span class="Delimiter">-&gt;</span>value<span class="Delimiter">)</span> != Literal_type_names<span class="Delimiter">.</span>end<span class="Delimiter">();</span>
+  if <span class="Delimiter">(</span>rhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span> &amp;&amp; lhs<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;address&quot;</span><span class="Delimiter">)</span>
+    <span class="Identifier">return</span> rhs_reagent<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span><span class="Delimiter">;</span>
+<span class="CommentedCode">//?   cerr &lt;&lt; lhs-&gt;value &lt;&lt; &quot; vs &quot; &lt;&lt; rhs-&gt;value &lt;&lt; '\n';</span>
+  <span class="Identifier">return</span> lhs<span class="Delimiter">-&gt;</span>value == rhs<span class="Delimiter">-&gt;</span>value
+      &amp;&amp; deeply_equal_concrete_types<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> rhs<span class="Delimiter">-&gt;</span>left<span class="Delimiter">,</span> rhs_reagent<span class="Delimiter">)</span>
+      &amp;&amp; deeply_equal_concrete_types<span class="Delimiter">(</span>lhs<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> rhs<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> rhs_reagent<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
 bool contains_type_ingredient_name<span class="Delimiter">(</span>const reagent&amp; x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
@@ -183,7 +231,7 @@ recipe_ordinal new_variant<span class="Delimiter">(</span>recipe_ordinal exempla
       delete p<span class="Delimiter">-&gt;</span>second<span class="Delimiter">;</span>
     if <span class="Delimiter">(</span>error<span class="Delimiter">)</span> <span class="Identifier">return</span> exemplar<span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">);</span>
+  ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">,</span> get<span class="Delimiter">(</span>Recipe<span class="Delimiter">,</span> exemplar<span class="Delimiter">));</span>
   <span class="Comment">// finally, perform all transforms on the new specialization</span>
   for <span class="Delimiter">(</span>long long int t = <span class="Constant">0</span><span class="Delimiter">;</span> t &lt; SIZE<span class="Delimiter">(</span>Transform<span class="Delimiter">);</span> ++t<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     <span class="Delimiter">(</span>*Transform<span class="Delimiter">.</span>at<span class="Delimiter">(</span>t<span class="Delimiter">))(</span>new_recipe_ordinal<span class="Delimiter">);</span>
@@ -227,14 +275,17 @@ void save_or_deduce_type_name<span class="Delimiter">(</span>reagent&amp; x<span
 <span class="Delimiter">}</span>
 
 void compute_type_ingredient_mappings<span class="Delimiter">(</span>const recipe&amp; exemplar<span class="Delimiter">,</span> const instruction&amp; inst<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> const string_tree*&gt;&amp; mappings<span class="Delimiter">,</span> const recipe&amp; caller_recipe<span class="Delimiter">,</span> bool* error<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>exemplar<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  long long int limit = min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>exemplar<span class="Delimiter">.</span>ingredients<span class="Delimiter">));</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; limit<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     const reagent&amp; exemplar_reagent = exemplar<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     reagent ingredient = inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     assert<span class="Delimiter">(</span>ingredient<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>
     canonize_type<span class="Delimiter">(</span>ingredient<span class="Delimiter">);</span>
+    if <span class="Delimiter">(</span>is_mu_address<span class="Delimiter">(</span>exemplar_reagent<span class="Delimiter">)</span> &amp;&amp; ingredient<span class="Delimiter">.</span>name == <span class="Constant">&quot;0&quot;</span><span class="Delimiter">)</span> <span class="Identifier">continue</span><span class="Delimiter">;</span>  <span class="Comment">// assume it matches</span>
     accumulate_type_ingredients<span class="Delimiter">(</span>exemplar_reagent<span class="Delimiter">,</span> ingredient<span class="Delimiter">,</span> mappings<span class="Delimiter">,</span> exemplar<span class="Delimiter">,</span> inst<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">,</span> error<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>exemplar<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  limit = min<span class="Delimiter">(</span>SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">),</span> SIZE<span class="Delimiter">(</span>exemplar<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; limit<span class="Delimiter">;</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
     const reagent&amp; exemplar_reagent = exemplar<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     reagent product = inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     assert<span class="Delimiter">(</span>product<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>
@@ -243,6 +294,10 @@ void compute_type_ingredient_mappings<span class="Delimiter">(</span>const recip
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
+inline long long int min<span class="Delimiter">(</span>long long int a<span class="Delimiter">,</span> long long int b<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  <span class="Identifier">return</span> <span class="Delimiter">(</span>a &lt; b<span class="Delimiter">)</span> ? a : b<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 void accumulate_type_ingredients<span class="Delimiter">(</span>const reagent&amp; exemplar_reagent<span class="Delimiter">,</span> reagent&amp; refinement<span class="Delimiter">,</span> map&lt;string<span class="Delimiter">,</span> const string_tree*&gt;&amp; mappings<span class="Delimiter">,</span> const recipe&amp; exemplar<span class="Delimiter">,</span> const instruction&amp; call_instruction<span class="Delimiter">,</span> const recipe&amp; caller_recipe<span class="Delimiter">,</span> bool* error<span class="Delimiter">)</span> <span class="Delimiter">{</span>
   assert<span class="Delimiter">(</span>refinement<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>
   accumulate_type_ingredients<span class="Delimiter">(</span>exemplar_reagent<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> refinement<span class="Delimiter">.</span>properties<span class="Delimiter">.</span>at<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">).</span>second<span class="Delimiter">,</span> mappings<span class="Delimiter">,</span> exemplar<span class="Delimiter">,</span> exemplar_reagent<span class="Delimiter">,</span> call_instruction<span class="Delimiter">,</span> caller_recipe<span class="Delimiter">,</span> error<span class="Delimiter">);</span>
@@ -262,11 +317,15 @@ void accumulate_type_ingredients<span class="Delimiter">(</span>const string_tre
     <span class="Delimiter">}</span>
     if <span class="Delimiter">(</span>!contains_key<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">))</span> <span class="Delimiter">{</span>
       trace<span class="Delimiter">(</span><span class="Constant">9993</span><span class="Delimiter">,</span> <span class="Constant">&quot;transform&quot;</span><span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;adding mapping from &quot;</span> &lt;&lt; exemplar_type<span class="Delimiter">-&gt;</span>value &lt;&lt; <span class="Constant">&quot; to &quot;</span> &lt;&lt; debug_string<span class="Delimiter">(</span>refinement_type<span class="Delimiter">)</span> &lt;&lt; end<span class="Delimiter">();</span>
-      put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">));</span>
+      if <span class="Delimiter">(</span>refinement_type<span class="Delimiter">-&gt;</span>value == <span class="Constant">&quot;literal&quot;</span><span class="Delimiter">)</span>
+        put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span><span class="Constant">&quot;number&quot;</span><span class="Delimiter">));</span>
+      else
+        put<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">,</span> new string_tree<span class="Delimiter">(</span>*refinement_type<span class="Delimiter">));</span>
     <span class="Delimiter">}</span>
     else <span class="Delimiter">{</span>
-      if <span class="Delimiter">(</span>!deeply_equal<span class="Delimiter">(</span>get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">),</span> refinement_type<span class="Delimiter">))</span> <span class="Delimiter">{</span>
+      if <span class="Delimiter">(</span>!deeply_equal_types<span class="Delimiter">(</span>get<span class="Delimiter">(</span>mappings<span class="Delimiter">,</span> exemplar_type<span class="Delimiter">-&gt;</span>value<span class="Delimiter">),</span> refinement_type<span class="Delimiter">))</span> <span class="Delimiter">{</span>
         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;no call found for '&quot;</span> &lt;&lt; call_instruction<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="CommentedCode">//?         cerr &lt;&lt; exemplar_type-&gt;value &lt;&lt; &quot;: &quot; &lt;&lt; debug_string(get(mappings, exemplar_type-&gt;value)) &lt;&lt; &quot; vs &quot; &lt;&lt; debug_string(refinement_type) &lt;&lt; '\n';</span>
         *error = <span class="Constant">true</span><span class="Delimiter">;</span>
         <span class="Identifier">return</span><span class="Delimiter">;</span>
       <span class="Delimiter">}</span>
@@ -330,31 +389,39 @@ void replace_type_ingredients<span class="Delimiter">(</span>string_tree* type<s
   replace_type_ingredients<span class="Delimiter">(</span>type<span class="Delimiter">-&gt;</span>right<span class="Delimiter">,</span> mappings<span class="Delimiter">);</span>
 <span class="Delimiter">}</span>
 
-void ensure_all_concrete_types<span class="Delimiter">(</span>const recipe&amp; new_recipe<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+void ensure_all_concrete_types<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">const</span><span class="Comment">*/</span> recipe&amp; new_recipe<span class="Delimiter">,</span> const recipe&amp; exemplar<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>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
-    ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+    ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> exemplar<span class="Delimiter">);</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span>
-    ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+    ensure_all_concrete_types<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">),</span> exemplar<span class="Delimiter">);</span>
   for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">);</span> ++i<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    const instruction&amp; inst = new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
+    instruction&amp; inst = new_recipe<span class="Delimiter">.</span>steps<span class="Delimiter">.</span>at<span class="Delimiter">(</span>i<span class="Delimiter">);</span>
     for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span>
-      ensure_all_concrete_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+      ensure_all_concrete_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>ingredients<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> exemplar<span class="Delimiter">);</span>
     for <span class="Delimiter">(</span>long long int j = <span class="Constant">0</span><span class="Delimiter">;</span> j &lt; SIZE<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">);</span> ++j<span class="Delimiter">)</span>
-      ensure_all_concrete_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">).</span>type<span class="Delimiter">);</span>
+      ensure_all_concrete_types<span class="Delimiter">(</span>inst<span class="Delimiter">.</span>products<span class="Delimiter">.</span>at<span class="Delimiter">(</span>j<span class="Delimiter">),</span> exemplar<span class="Delimiter">);</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
-void ensure_all_concrete_types<span class="Delimiter">(</span>const type_tree* x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-  if <span class="Delimiter">(</span>!x<span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; <span class="Constant">&quot;null type</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+void ensure_all_concrete_types<span class="Delimiter">(</span><span class="Comment">/*</span><span class="Comment">const</span><span class="Comment">*/</span> reagent&amp; x<span class="Delimiter">,</span> const recipe&amp; exemplar<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  if <span class="Delimiter">(</span>!x<span class="Delimiter">.</span>type<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    raise_error &lt;&lt; maybe<span class="Delimiter">(</span>exemplar<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;failed to map a type to &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
+    x<span class="Delimiter">.</span>type = new type_tree<span class="Delimiter">(</span><span class="Constant">0</span><span class="Delimiter">);</span>  <span class="Comment">// just to prevent crashes later</span>
     <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
-  if <span class="Delimiter">(</span>x<span class="Delimiter">-&gt;</span>value == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
-    raise &lt;&lt; <span class="Constant">&quot;unknown type</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> &lt;&lt; end<span class="Delimiter">();</span>
+  if <span class="Delimiter">(</span>x<span class="Delimiter">.</span>type<span class="Delimiter">-&gt;</span>value == -<span class="Constant">1</span><span class="Delimiter">)</span> <span class="Delimiter">{</span>
+    raise_error &lt;&lt; maybe<span class="Delimiter">(</span>exemplar<span class="Delimiter">.</span>name<span class="Delimiter">)</span> &lt;&lt; <span class="Constant">&quot;failed to map a type to the unknown &quot;</span> &lt;&lt; x<span class="Delimiter">.</span>original_string &lt;&lt; <span class="cSpecial">'\n'</span> &lt;&lt; end<span class="Delimiter">();</span>
     <span class="Identifier">return</span><span class="Delimiter">;</span>
   <span class="Delimiter">}</span>
 <span class="Delimiter">}</span>
 
+long long int non_ghost_size<span class="Delimiter">(</span>vector&lt;recipe_ordinal&gt;&amp; variants<span class="Delimiter">)</span> <span class="Delimiter">{</span>
+  long long int result = <span class="Constant">0</span><span class="Delimiter">;</span>
+  for <span class="Delimiter">(</span>long long int i = <span class="Constant">0</span><span class="Delimiter">;</span> i &lt; SIZE<span class="Delimiter">(</span>variants<span class="Delimiter">);</span> ++i<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> ++result<span class="Delimiter">;</span>
+  <span class="Identifier">return</span> result<span class="Delimiter">;</span>
+<span class="Delimiter">}</span>
+
 <span class="Delimiter">:(scenario shape_shifting_recipe_2)</span>
 recipe main [
   <span class="Constant">10</span>:point<span class="Special"> &lt;- </span>merge <span class="Constant">14</span><span class="Delimiter">,</span> <span class="Constant">15</span>
@@ -476,6 +543,147 @@ recipe foo a:_t <span class="Delimiter">-&gt;</span> b:_t [
   b<span class="Special"> &lt;- </span>copy a
 ]
 <span class="traceContains">+error: main: no call found for 'b:address:number &lt;- foo a'</span>
+
+<span class="Delimiter">:(scenario specialize_inside_recipe_without_header)</span>
+recipe main [
+  foo <span class="Constant">3</span>
+]
+recipe foo [
+  local-scope
+  x:number<span class="Special"> &lt;- </span>next-ingredient  <span class="Comment"># ensure no header</span>
+  <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>bar x  <span class="Comment"># call a shape-shifting recipe</span>
+]
+recipe bar x:_elem <span class="Delimiter">-&gt;</span> y:_elem [
+  local-scope
+  load-ingredients
+  y<span class="Special"> &lt;- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span>
+]
+<span class="traceContains">+mem: storing 4 in location 1</span>
+
+<span class="Delimiter">:(scenario specialize_with_literal)</span>
+recipe main [
+  local-scope
+  <span class="Comment"># permit literal to map to number</span>
+  <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>foo <span class="Constant">3</span>
+]
+recipe foo x:_elem <span class="Delimiter">-&gt;</span> y:_elem [
+  local-scope
+  load-ingredients
+  y<span class="Special"> &lt;- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span>
+]
+<span class="traceContains">+mem: storing 4 in location 1</span>
+
+<span class="Delimiter">:(scenario specialize_with_literal_2)</span>
+recipe main [
+  local-scope
+  <span class="Comment"># permit literal to map to character</span>
+  <span class="Constant">1</span>:character/<span class="Special">raw &lt;- </span>foo <span class="Constant">3</span>
+]
+recipe foo x:_elem <span class="Delimiter">-&gt;</span> y:_elem [
+  local-scope
+  load-ingredients
+  y<span class="Special"> &lt;- </span>add x<span class="Delimiter">,</span> <span class="Constant">1</span>
+]
+<span class="traceContains">+mem: storing 4 in location 1</span>
+
+<span class="Delimiter">:(scenario specialize_with_literal_3)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  local-scope
+  <span class="Comment"># permit '0' to map to address to shape-shifting type-ingredient</span>
+  <span class="Constant">1</span>:address:character/<span class="Special">raw &lt;- </span>foo <span class="Constant">0</span>
+]
+recipe foo x:address:_elem <span class="Delimiter">-&gt;</span> y:address:_elem [
+  local-scope
+  load-ingredients
+  y<span class="Special"> &lt;- </span>copy x
+]
+<span class="traceContains">+mem: storing 0 in location 1</span>
+$error: <span class="Constant">0</span>
+
+<span class="Delimiter">:(scenario specialize_with_literal_4)</span>
+<span class="Special">% Hide_errors = true;</span>
+recipe main [
+  local-scope
+  <span class="Comment"># ambiguous call: what's the type of its ingredient?!</span>
+  foo <span class="Constant">0</span>
+]
+recipe foo x:address:_elem <span class="Delimiter">-&gt;</span> y:address:_elem [
+  local-scope
+  load-ingredients
+  y<span class="Special"> &lt;- </span>copy x
+]
+<span class="traceContains">+error: foo: failed to map a type to x</span>
+<span class="traceContains">+error: foo: failed to map a type to y</span>
+
+<span class="Delimiter">:(scenario specialize_with_literal_5)</span>
+recipe main [
+  foo <span class="Constant">3</span><span class="Delimiter">,</span> <span class="Constant">4</span>  <span class="Comment"># recipe mapping two variables to literals</span>
+]
+recipe foo x:_elem<span class="Delimiter">,</span> y:_elem [
+  local-scope
+  load-ingredients
+  <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>add x<span class="Delimiter">,</span> y
+]
+<span class="traceContains">+mem: storing 7 in location 1</span>
+
+<span class="Delimiter">:(scenario multiple_shape_shifting_variants)</span>
+<span class="Comment"># try to call two different shape-shifting recipes with the same name</span>
+recipe main [
+  e1:d1:number<span class="Special"> &lt;- </span>merge <span class="Constant">3</span>
+  e2:d2:number<span class="Special"> &lt;- </span>merge <span class="Constant">4</span><span class="Delimiter">,</span> <span class="Constant">5</span>
+  <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>foo e1
+  <span class="Constant">2</span>:number/<span class="Special">raw &lt;- </span>foo e2
+]
+<span class="Comment"># the two shape-shifting definitions</span>
+recipe foo a:d1:_elem <span class="Delimiter">-&gt;</span> b:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">34</span>
+]
+recipe foo a:d2:_elem <span class="Delimiter">-&gt;</span> b:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">35</span>
+]
+<span class="Comment"># the shape-shifting containers they use</span>
+container d1:_elem [
+  x:_elem
+]
+container d2:_elem [
+  x:number
+  y:_elem
+]
+<span class="traceContains">+mem: storing 34 in location 1</span>
+<span class="traceContains">+mem: storing 35 in location 2</span>
+
+<span class="Delimiter">:(scenario multiple_shape_shifting_variants_2)</span>
+<span class="Comment"># static dispatch between shape-shifting variants, _including pointer lookups_</span>
+recipe main [
+  e1:d1:number<span class="Special"> &lt;- </span>merge <span class="Constant">3</span>
+  e2:address:d2:number<span class="Special"> &lt;- </span>new <span class="Delimiter">{(</span>d2 number<span class="Delimiter">)</span>: type<span class="Delimiter">}</span>
+  <span class="Constant">1</span>:number/<span class="Special">raw &lt;- </span>foo e1
+  <span class="Constant">2</span>:number/<span class="Special">raw &lt;- </span>foo *e2  <span class="Comment"># different from previous scenario</span>
+]
+recipe foo a:d1:_elem <span class="Delimiter">-&gt;</span> b:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">34</span>
+]
+recipe foo a:d2:_elem <span class="Delimiter">-&gt;</span> b:number [
+  local-scope
+  load-ingredients
+  reply <span class="Constant">35</span>
+]
+container d1:_elem [
+  x:_elem
+]
+container d2:_elem [
+  x:number
+  y:_elem
+]
+<span class="traceContains">+mem: storing 34 in location 1</span>
+<span class="traceContains">+mem: storing 35 in location 2</span>
 </pre>
 </body>
 </html>
diff --git a/html/073list.mu.html b/html/073list.mu.html
index 5db8f8af..c274436b 100644
--- a/html/073list.mu.html
+++ b/html/073list.mu.html
@@ -66,18 +66,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   result<span class="Special"> &lt;- </span>get *in, <span class="Constant">next:offset</span>
 ]
 
-<span class="muRecipe">recipe</span> force-specialization-list-number [
-  <span class="Constant">1</span>:address:list:number<span class="Special"> &lt;- </span>push <span class="Constant">2</span>:number, <span class="Constant">1</span>:address:list:number
-  <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>first <span class="Constant">1</span>:address:list:number
-  <span class="Constant">1</span>:address:list:number<span class="Special"> &lt;- </span>rest <span class="Constant">1</span>:address:list:number
-]
-
-<span class="Comment"># todo: automatically specialize code in scenarios</span>
 <span class="muScenario">scenario</span> list-handling [
   run [
-    <span class="Constant">1</span>:address:list:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
-    <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>
-    <span class="Constant">1</span>:address:list:number<span class="Special"> &lt;- </span>push <span class="Constant">2</span>:number, <span class="Constant">1</span>:address:list:number
+    <span class="Constant">1</span>:address:list:number<span class="Special"> &lt;- </span>push <span class="Constant">3</span>, <span class="Constant">0</span>
     <span class="Constant">1</span>:address:list:number<span class="Special"> &lt;- </span>push <span class="Constant">4</span>, <span class="Constant">1</span>:address:list:number
     <span class="Constant">1</span>:address:list:number<span class="Special"> &lt;- </span>push <span class="Constant">5</span>, <span class="Constant">1</span>:address:list:number
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>first <span class="Constant">1</span>:address:list:number
diff --git a/html/075duplex_list.mu.html b/html/075duplex_list.mu.html
index c7452600..f2094cde 100644
--- a/html/075duplex_list.mu.html
+++ b/html/075duplex_list.mu.html
@@ -40,7 +40,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   prev:address:duplex-list:_elem
 ]
 
-<span class="muRecipe">recipe</span> push-duplex x:_elem, in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result: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="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>
@@ -53,21 +53,21 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   *prev<span class="Special"> &lt;- </span>copy result
 ]
 
-<span class="muRecipe">recipe</span> first-duplex in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result:_elem [
+<span class="muRecipe">recipe</span> first in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result:_elem [
   <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">value:offset</span>
 ]
 
-<span class="muRecipe">recipe</span> next-duplex 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 [
   <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-duplex 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 [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="muControl">reply-unless</span> in, <span class="Constant">0</span>
@@ -80,24 +80,23 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Comment"># reserve locations 0, 1 and 2 to check for missing null check</span>
     <span class="Constant">1</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">34</span>
     <span class="Constant">2</span>:number<span class="Special"> &lt;- </span>copy <span class="Constant">35</span>
-    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
-    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">3</span>:address:duplex-list:character
-    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">4</span>, <span class="Constant">3</span>:address:duplex-list:character
-    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">5</span>, <span class="Constant">3</span>:address:duplex-list:character
+    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">3</span>, <span class="Constant">0</span>
+    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">4</span>, <span class="Constant">3</span>:address:duplex-list:character
+    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">5</span>, <span class="Constant">3</span>:address:duplex-list:character
     <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">3</span>:address:duplex-list:character
-    <span class="Constant">5</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">4</span>:address:duplex-list:character
-    <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">4</span>:address:duplex-list:character
-    <span class="Constant">6</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">4</span>:address:duplex-list:character
-    <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">4</span>:address:duplex-list:character
-    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">4</span>:address:duplex-list:character
-    <span class="Constant">8</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">4</span>:address:duplex-list:character
-    <span class="Constant">9</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">8</span>:address:duplex-list:character
-    <span class="Constant">10</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">8</span>:address:duplex-list:character
-    <span class="Constant">11</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">8</span>:address:duplex-list:character
-    <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">4</span>:address:duplex-list:character
-    <span class="Constant">12</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">4</span>:address:duplex-list:character
-    <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">4</span>:address:duplex-list:character
-    <span class="Constant">13</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">4</span>:address:duplex-list:character
+    <span class="Constant">5</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">4</span>:address:duplex-list:character
+    <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">4</span>:address:duplex-list:character
+    <span class="Constant">6</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">4</span>:address:duplex-list:character
+    <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">4</span>:address:duplex-list:character
+    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">4</span>:address:duplex-list:character
+    <span class="Constant">8</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">4</span>:address:duplex-list:character
+    <span class="Constant">9</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">8</span>:address:duplex-list:character
+    <span class="Constant">10</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">8</span>:address:duplex-list:character
+    <span class="Constant">11</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">8</span>:address:duplex-list:character
+    <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">4</span>:address:duplex-list:character
+    <span class="Constant">12</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">4</span>:address:duplex-list:character
+    <span class="Constant">4</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">4</span>:address:duplex-list:character
+    <span class="Constant">13</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">4</span>:address:duplex-list:character
     <span class="Constant">14</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">3</span>:address:duplex-list:character, <span class="Constant">4</span>:address:duplex-list:character
   ]
   memory-should-contain [
@@ -118,7 +117,7 @@ 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-duplex x:_elem, in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>new-node:address:duplex-list:_elem [
+<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="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>
@@ -144,27 +143,26 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> inserting-into-duplex-list [
   run [
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># 1 points to head of list</span>
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3</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-duplex <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-duplex <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-duplex <span class="Constant">1</span>:address:duplex-list:character  <span class="Comment"># 2 points inside list</span>
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>insert-duplex <span class="Constant">6</span>, <span class="Constant">2</span>:address:duplex-list:character
+    <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>next <span class="Constant">1</span>:address:duplex-list:character  <span class="Comment"># 2 points inside list</span>
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>insert <span class="Constant">6</span>, <span class="Constant">2</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-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">5</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">6</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">8</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">9</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</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
+    <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">4</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</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">5</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</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">6</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">8</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">9</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
     <span class="Constant">10</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
   ]
   memory-should-contain [
@@ -181,28 +179,27 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> inserting-at-end-of-duplex-list [
   run [
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># 1 points to head of list</span>
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3</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-duplex <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-duplex <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-duplex <span class="Constant">1</span>:address:duplex-list:character  <span class="Comment"># 2 points inside list</span>
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character  <span class="Comment"># now at end of list</span>
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>insert-duplex <span class="Constant">6</span>, <span class="Constant">2</span>:address:duplex-list:character
+    <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>next <span class="Constant">1</span>:address:duplex-list:character  <span class="Comment"># 2 points inside list</span>
+    <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="Comment"># now at end of list</span>
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>insert <span class="Constant">6</span>, <span class="Constant">2</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-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">5</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">6</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">8</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">9</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</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
+    <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">4</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</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">5</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</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">6</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">8</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">9</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
     <span class="Constant">10</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
   ]
   memory-should-contain [
@@ -219,26 +216,25 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> inserting-after-start-of-duplex-list [
   run [
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># 1 points to head of list</span>
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3</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-duplex <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-duplex <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-duplex <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>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="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-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">5</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">6</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">8</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">9</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</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
+    <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">4</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</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">5</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</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">6</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">8</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">9</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
     <span class="Constant">10</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
   ]
   memory-should-contain [
@@ -258,7 +254,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <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-duplex in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>next-node:address:duplex-list:_elem [
+<span class="muRecipe">recipe</span> remove in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>next-node: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>
@@ -290,21 +286,20 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> removing-from-duplex-list [
   run [
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># 1 points to head of list</span>
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3</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-duplex <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-duplex <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-duplex <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-duplex <span class="Constant">2</span>:address:duplex-list:character
+    <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>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">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
-    <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">5</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">6</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</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">5</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">6</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>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
     <span class="Constant">8</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
   ]
   memory-should-contain [
@@ -319,20 +314,19 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> removing-from-start-of-duplex-list [
   run [
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># 1 points to head of list</span>
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3</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-duplex <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-duplex <span class="Constant">5</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">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-duplex <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="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-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">6</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</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
+    <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">4</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">5</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>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">6</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
     <span class="Constant">7</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
   ]
   memory-should-contain [
@@ -346,23 +340,22 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> removing-from-end-of-duplex-list [
   run [
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># 1 points to head of list</span>
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3</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-duplex <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-duplex <span class="Constant">5</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">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"># delete last element</span>
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove-duplex <span class="Constant">2</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="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">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
-    <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">5</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">6</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</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">5</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">6</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>prev <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">7</span>:character<span class="Special"> &lt;- </span>first <span class="Constant">2</span>:address:duplex-list:character
     <span class="Constant">8</span>:boolean<span class="Special"> &lt;- </span>equal <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
   ]
   memory-should-contain [
@@ -377,9 +370,8 @@ 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>copy <span class="Constant">0</span>  <span class="Comment"># 1 points to singleton list</span>
-    <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">3</span>, <span class="Constant">1</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove-duplex <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">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>
   ]
@@ -390,11 +382,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   ]
 ]
 
-<span class="Comment"># l:address:duplex-list &lt;- remove-duplex-between start:address:duplex-list, end:address:duplex-list</span>
-<span class="Comment"># Remove values between 'start' and 'end' (both exclusive). Returns some valid</span>
-<span class="Comment"># pointer into the rest of the list.</span>
-<span class="Comment"># Also clear pointers back out from start/end for hygiene.</span>
-<span class="muRecipe">recipe</span> remove-duplex-between start:address:duplex-list:_elem, end:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>start:address:duplex-list:_elem [
+<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="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="muControl">reply-unless</span> start
@@ -417,26 +407,25 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> remove-range [
   <span class="Comment"># construct a duplex list with six elements [13, 14, 15, 16, 17, 18]</span>
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># 1 points to singleton list</span>
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">18</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-duplex <span class="Constant">17</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-duplex <span class="Constant">16</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-duplex <span class="Constant">15</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-duplex <span class="Constant">14</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-duplex <span class="Constant">13</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">18</span>, <span class="Constant">0</span>
+  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">17</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">16</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">15</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">14</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">13</span>, <span class="Constant">1</span>:address:duplex-list:character
   run [
     <span class="Comment"># delete 16 onwards</span>
     <span class="Comment"># first pointer: to the third element</span>
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove-duplex-between <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">0</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-between <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">0</span>
     <span class="Comment"># now check the list</span>
     <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
-    <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
+    <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">6</span>:character<span class="Special"> &lt;- </span>get *<span class="Constant">5</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
-    <span class="Constant">7</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">5</span>:address:duplex-list:character
+    <span class="Constant">7</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">5</span>:address:duplex-list:character
     <span class="Constant">8</span>:character<span class="Special"> &lt;- </span>get *<span class="Constant">7</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
-    <span class="Constant">9</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">7</span>:address:duplex-list:character
+    <span class="Constant">9</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">7</span>:address:duplex-list:character
   ]
   memory-should-contain [
     <span class="Constant">4</span><span class="Special"> &lt;- </span><span class="Constant">13</span>
@@ -448,30 +437,29 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> remove-range-to-end [
   <span class="Comment"># construct a duplex list with six elements [13, 14, 15, 16, 17, 18]</span>
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># 1 points to singleton list</span>
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">18</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-duplex <span class="Constant">17</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-duplex <span class="Constant">16</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-duplex <span class="Constant">15</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-duplex <span class="Constant">14</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-duplex <span class="Constant">13</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">18</span>, <span class="Constant">0</span>
+  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">17</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">16</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">15</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">14</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">13</span>, <span class="Constant">1</span>:address:duplex-list:character
   run [
     <span class="Comment"># delete 15, 16 and 17</span>
     <span class="Comment"># first pointer: to the third element</span>
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <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"># second pointer: to the fifth element</span>
-    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">2</span>:address:duplex-list:character
-    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">3</span>:address:duplex-list:character
-    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">3</span>:address:duplex-list:character
-    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">3</span>:address:duplex-list:character
-    remove-duplex-between <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">3</span>:address:duplex-list:character
+    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">2</span>:address:duplex-list:character
+    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">3</span>:address:duplex-list:character
+    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">3</span>:address:duplex-list:character
+    <span class="Constant">3</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">3</span>:address:duplex-list:character
+    remove-between <span class="Constant">2</span>:address:duplex-list:character, <span class="Constant">3</span>:address:duplex-list:character
     <span class="Comment"># now check the list</span>
     <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
-    <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
+    <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">6</span>:character<span class="Special"> &lt;- </span>get *<span class="Constant">5</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
-    <span class="Constant">7</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">5</span>:address:duplex-list:character
+    <span class="Constant">7</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">5</span>:address:duplex-list:character
     <span class="Constant">8</span>:character<span class="Special"> &lt;- </span>get *<span class="Constant">7</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
-    <span class="Constant">9</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">7</span>:address:duplex-list:character
+    <span class="Constant">9</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">7</span>:address:duplex-list:character
   ]
   memory-should-contain [
     <span class="Constant">4</span><span class="Special"> &lt;- </span><span class="Constant">13</span>
@@ -483,19 +471,18 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 
 <span class="muScenario">scenario</span> remove-range-empty [
   <span class="Comment"># construct a duplex list with six elements [13, 14, 15, 16, 17, 18]</span>
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>  <span class="Comment"># 1 points to singleton list</span>
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">14</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-duplex <span class="Constant">13</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">14</span>, <span class="Constant">0</span>
+  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push <span class="Constant">13</span>, <span class="Constant">1</span>:address:duplex-list:character
   run [
     <span class="Comment"># delete 16 onwards</span>
     <span class="Comment"># first pointer: to the third element</span>
-    <span class="Constant">2</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
-    remove-duplex-between <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</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
+    remove-between <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">2</span>:address:duplex-list:character
     <span class="Comment"># now check the list</span>
     <span class="Constant">4</span>:character<span class="Special"> &lt;- </span>get *<span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
-    <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
+    <span class="Constant">5</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">1</span>:address:duplex-list:character
     <span class="Constant">6</span>:character<span class="Special"> &lt;- </span>get *<span class="Constant">5</span>:address:duplex-list:character, <span class="Constant">value:offset</span>
-    <span class="Constant">7</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">5</span>:address:duplex-list:character
+    <span class="Constant">7</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next <span class="Constant">5</span>:address:duplex-list:character
   ]
   memory-should-contain [
     <span class="Constant">4</span><span class="Special"> &lt;- </span><span class="Constant">13</span>
@@ -505,19 +492,19 @@ 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-duplex-range in:address:duplex-list:_elem, start:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>in:address:duplex-list:_elem [
+<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="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   <span class="muControl">reply-unless</span> in
   <span class="muControl">reply-unless</span> start
   end:address:duplex-list:_elem<span class="Special"> &lt;- </span>copy start
   <span class="Delimiter">{</span>
-    next:address:duplex-list:_elem<span class="Special"> &lt;- </span>next-duplex end/insert-range
+    next:address:duplex-list:_elem<span class="Special"> &lt;- </span>next end/insert-range
     <span class="muControl">break-unless</span> next
     end<span class="Special"> &lt;- </span>copy next
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
-  next:address:duplex-list:_elem<span class="Special"> &lt;- </span>next-duplex in
+  next:address:duplex-list:_elem<span class="Special"> &lt;- </span>next in
   dest:address:address:duplex-list:_elem<span class="Special"> &lt;- </span>get-address *end, <span class="Constant">next:offset</span>
   *dest<span class="Special"> &lt;- </span>copy next
   <span class="Delimiter">{</span>
@@ -531,10 +518,10 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   *dest<span class="Special"> &lt;- </span>copy in
 ]
 
-<span class="muRecipe">recipe</span> append-duplex 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<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-duplex in
+  last:address:duplex-list:_elem<span class="Special"> &lt;- </span>last in
   dest:address:address:duplex-list:_elem<span class="Special"> &lt;- </span>get-address *last, <span class="Constant">next:offset</span>
   *dest<span class="Special"> &lt;- </span>copy new
   <span class="muControl">reply-unless</span> new
@@ -542,12 +529,12 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   *dest<span class="Special"> &lt;- </span>copy last
 ]
 
-<span class="muRecipe">recipe</span> last-duplex in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result:address:duplex-list:_elem [
+<span class="muRecipe">recipe</span> last in:address:duplex-list:_elem<span class="muRecipe"> -&gt; </span>result:address:duplex-list:_elem [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   result<span class="Special"> &lt;- </span>copy in
   <span class="Delimiter">{</span>
-    next:address:duplex-list:_elem<span class="Special"> &lt;- </span>next-duplex result
+    next:address:duplex-list:_elem<span class="Special"> &lt;- </span>next result
     <span class="muControl">break-unless</span> next
     result<span class="Special"> &lt;- </span>copy next
     <span class="muControl">loop</span>
@@ -555,7 +542,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 ]
 
 <span class="Comment"># helper for debugging</span>
-<span class="muRecipe">recipe</span> dump-duplex-from x:address:duplex-list:_elem [
+<span class="muRecipe">recipe</span> dump-from x:address:duplex-list:_elem [
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   $print x, <span class="Constant">[: ]</span>
@@ -563,7 +550,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-unless</span> x
     c:_elem<span class="Special"> &lt;- </span>get *x, <span class="Constant">value:offset</span>
     $print c, <span class="Constant">[ ]</span>
-    x<span class="Special"> &lt;- </span>next-duplex x
+    x<span class="Special"> &lt;- </span>next x
     <span class="Delimiter">{</span>
       is-newline?:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">10/newline</span>
       <span class="muControl">break-unless</span> is-newline?
@@ -574,19 +561,6 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Delimiter">}</span>
   $print <span class="Constant">10/newline</span>, <span class="Constant">[---]</span>, <span class="Constant">10/newline</span>
 ]
-
-<span class="muRecipe">recipe</span> force-specialization-duplex-list-character [
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>push-duplex <span class="Constant">2</span>:character, <span class="Constant">1</span>:address:duplex-list:character
-  <span class="Constant">2</span>:character<span class="Special"> &lt;- </span>first-duplex <span class="Constant">1</span>:address:duplex-list:character
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex <span class="Constant">1</span>:address:duplex-list:character
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex <span class="Constant">1</span>:address:duplex-list:character
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>insert-duplex <span class="Constant">2</span>:character, <span class="Constant">1</span>:address:duplex-list:character
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove-duplex <span class="Constant">1</span>:address:duplex-list:character
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>remove-duplex-between <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">1</span>:address:duplex-list:character
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>insert-duplex-range <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">1</span>:address:duplex-list:character
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>append-duplex <span class="Constant">1</span>:address:duplex-list:character, <span class="Constant">1</span>:address:duplex-list:character
-  <span class="Constant">1</span>:address:duplex-list:character<span class="Special"> &lt;- </span>last-duplex <span class="Constant">1</span>:address:duplex-list:character
-]
 </pre>
 </body>
 </html>
diff --git a/html/091run_interactive.cc.html b/html/091run_interactive.cc.html
index 30490309..b96eeb50 100644
--- a/html/091run_interactive.cc.html
+++ b/html/091run_interactive.cc.html
@@ -111,14 +111,13 @@ bool run_interactive<span class="Delimiter">(</span>long long int address<span c
   <span class="Delimiter">}</span>
   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>
-  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>
   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>
   <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>
   <span class="Comment">// call run(string) but without the scheduling</span>
-  load<span class="Delimiter">(</span>string<span class="Delimiter">(</span><span class="Constant">&quot;recipe interactive [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">)</span> +
+  load<span class="Delimiter">(</span>string<span class="Delimiter">(</span><span class="Constant">&quot;recipe! interactive [</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span><span class="Delimiter">)</span> +
           <span class="Constant">&quot;local-scope</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
           <span class="Constant">&quot;screen:address:screen &lt;- next-ingredient</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
           <span class="Constant">&quot;$start-tracking-products</span><span class="cSpecial">\n</span><span class="Constant">&quot;</span> +
diff --git a/html/edit/001-editor.mu.html b/html/edit/001-editor.mu.html
index 916e93c6..cf10dc6c 100644
--- a/html/edit/001-editor.mu.html
+++ b/html/edit/001-editor.mu.html
@@ -99,7 +99,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   x<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">cursor-column:offset</span>
   *x<span class="Special"> &lt;- </span>copy left
   init:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">data:offset</span>
-  *init<span class="Special"> &lt;- </span>push-duplex <span class="Constant">167/§</span>, <span class="Constant">0/tail</span>
+  *init<span class="Special"> &lt;- </span>push <span class="Constant">167/§</span>, <span class="Constant">0/tail</span>
   top-of-screen:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">top-of-screen:offset</span>
   *top-of-screen<span class="Special"> &lt;- </span>copy *init
   y:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *result, <span class="Constant">before-cursor:offset</span>
@@ -127,9 +127,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     done?:boolean<span class="Special"> &lt;- </span>greater-or-equal idx, len
     <span class="muControl">break-if</span> done?
     c:character<span class="Special"> &lt;- </span>index *text, idx
-    insert-duplex c, curr
+    insert c, curr
     <span class="Comment"># next iter</span>
-    curr<span class="Special"> &lt;- </span>next-duplex curr
+    curr<span class="Special"> &lt;- </span>next curr
     idx<span class="Special"> &lt;- </span>add idx, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
@@ -171,8 +171,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   right:number<span class="Special"> &lt;- </span>get *editor, <span class="Constant">right:offset</span>
   <span class="Comment"># traversing editor</span>
   curr:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
-  prev:address:duplex-list:character<span class="Special"> &lt;- </span>copy curr  <span class="Comment"># just in case curr becomes null and we can't compute prev-duplex</span>
-  curr<span class="Special"> &lt;- </span>next-duplex curr
+  prev:address:duplex-list:character<span class="Special"> &lt;- </span>copy curr  <span class="Comment"># just in case curr becomes null and we can't compute prev</span>
+  curr<span class="Special"> &lt;- </span>next curr
   <span class="Comment"># traversing screen</span>
 <span class="Constant">  +render-loop-initialization</span>
   color:number<span class="Special"> &lt;- </span>copy <span class="Constant">7/white</span>
@@ -210,7 +210,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
         left-of-cursor?:boolean<span class="Special"> &lt;- </span>lesser-than column, *cursor-column
         <span class="muControl">break-unless</span> left-of-cursor?
         *cursor-column<span class="Special"> &lt;- </span>copy column
-        *before-cursor<span class="Special"> &lt;- </span>prev-duplex curr
+        *before-cursor<span class="Special"> &lt;- </span>prev curr
       <span class="Delimiter">}</span>
       <span class="Comment"># clear rest of line in this window</span>
       clear-line-delimited screen, column, right
@@ -218,8 +218,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       row<span class="Special"> &lt;- </span>add row, <span class="Constant">1</span>
       column<span class="Special"> &lt;- </span>copy left
       screen<span class="Special"> &lt;- </span>move-cursor screen, row, column
-      curr<span class="Special"> &lt;- </span>next-duplex curr
-      prev<span class="Special"> &lt;- </span>next-duplex prev
+      curr<span class="Special"> &lt;- </span>next curr
+      prev<span class="Special"> &lt;- </span>next prev
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
     <span class="Delimiter">{</span>
@@ -236,8 +236,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
     print-character screen, c, color
-    curr<span class="Special"> &lt;- </span>next-duplex curr
-    prev<span class="Special"> &lt;- </span>next-duplex prev
+    curr<span class="Special"> &lt;- </span>next curr
+    prev<span class="Special"> &lt;- </span>next prev
     column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
diff --git a/html/edit/002-typing.mu.html b/html/edit/002-typing.mu.html
index c1f1128f..538bbf5d 100644
--- a/html/edit/002-typing.mu.html
+++ b/html/edit/002-typing.mu.html
@@ -114,8 +114,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   screen-height:number<span class="Special"> &lt;- </span>screen-height screen
   <span class="Comment"># count newlines until screen row</span>
   curr:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
-  prev:address:duplex-list:character<span class="Special"> &lt;- </span>copy curr  <span class="Comment"># just in case curr becomes null and we can't compute prev-duplex</span>
-  curr<span class="Special"> &lt;- </span>next-duplex curr
+  prev:address:duplex-list:character<span class="Special"> &lt;- </span>copy curr  <span class="Comment"># just in case curr becomes null and we can't compute prev</span>
+  curr<span class="Special"> &lt;- </span>next curr
   row:number<span class="Special"> &lt;- </span>copy <span class="Constant">1/top</span>
   column:number<span class="Special"> &lt;- </span>copy left
   cursor-row:address:number<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
@@ -155,8 +155,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       <span class="Comment"># skip to next line</span>
       row<span class="Special"> &lt;- </span>add row, <span class="Constant">1</span>
       column<span class="Special"> &lt;- </span>copy left
-      curr<span class="Special"> &lt;- </span>next-duplex curr
-      prev<span class="Special"> &lt;- </span>next-duplex prev
+      curr<span class="Special"> &lt;- </span>next curr
+      prev<span class="Special"> &lt;- </span>next prev
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
     <span class="Delimiter">{</span>
@@ -169,8 +169,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       <span class="Comment"># don't increment curr/prev</span>
       <span class="muControl">loop</span> <span class="Constant">+next-character:label</span>
     <span class="Delimiter">}</span>
-    curr<span class="Special"> &lt;- </span>next-duplex curr
-    prev<span class="Special"> &lt;- </span>next-duplex prev
+    curr<span class="Special"> &lt;- </span>next curr
+    prev<span class="Special"> &lt;- </span>next prev
     column<span class="Special"> &lt;- </span>add column, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
@@ -234,8 +234,8 @@ 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>
-  insert-duplex c, *before-cursor
-  *before-cursor<span class="Special"> &lt;- </span>next-duplex *before-cursor
+  insert c, *before-cursor
+  *before-cursor<span class="Special"> &lt;- </span>next *before-cursor
   cursor-row:address:number<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
   cursor-column:address:number<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
   left:number<span class="Special"> &lt;- </span>get *editor, <span class="Constant">left:offset</span>
@@ -248,7 +248,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="Constant">  &lt;insert-character-special-case&gt;</span>
   <span class="Comment"># but mostly we'll just move the cursor right</span>
   *cursor-column<span class="Special"> &lt;- </span>add *cursor-column, <span class="Constant">1</span>
-  next:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+  next:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
   <span class="Delimiter">{</span>
     <span class="Comment"># at end of all text? no need to scroll? just print the character and leave</span>
     at-end?:boolean<span class="Special"> &lt;- </span>equal next, <span class="Constant">0/null</span>
@@ -283,7 +283,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       <span class="muControl">break-if</span> at-newline?
       print-character screen, currc
       curr-column<span class="Special"> &lt;- </span>add curr-column, <span class="Constant">1</span>
-      curr<span class="Special"> &lt;- </span>next-duplex curr
+      curr<span class="Special"> &lt;- </span>next curr
       <span class="muControl">loop</span>
     <span class="Delimiter">}</span>
     go-render?<span class="Special"> &lt;- </span>copy <span class="Constant">0/false</span>
@@ -867,8 +867,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   right:number<span class="Special"> &lt;- </span>get *editor, <span class="Constant">right:offset</span>
   screen-height:number<span class="Special"> &lt;- </span>screen-height screen
   <span class="Comment"># insert newline</span>
-  insert-duplex <span class="Constant">10/newline</span>, *before-cursor
-  *before-cursor<span class="Special"> &lt;- </span>next-duplex *before-cursor
+  insert <span class="Constant">10/newline</span>, *before-cursor
+  *before-cursor<span class="Special"> &lt;- </span>next *before-cursor
   *cursor-row<span class="Special"> &lt;- </span>add *cursor-row, <span class="Constant">1</span>
   *cursor-column<span class="Special"> &lt;- </span>copy left
   <span class="Comment"># maybe scroll</span>
@@ -883,7 +883,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   indent?:boolean<span class="Special"> &lt;- </span>get *editor, <span class="Constant">indent?:offset</span>
   <span class="muControl">reply-unless</span> indent?
   d:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">data:offset</span>
-  end-of-previous-line:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex *before-cursor
+  end-of-previous-line:address:duplex-list:character<span class="Special"> &lt;- </span>prev *before-cursor
   indent:number<span class="Special"> &lt;- </span>line-indent end-of-previous-line, d
   i:number<span class="Special"> &lt;- </span>copy <span class="Constant">0</span>
   <span class="Delimiter">{</span>
@@ -905,7 +905,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   at-start?:boolean<span class="Special"> &lt;- </span>equal curr, start
   <span class="muControl">reply-if</span> at-start?
   <span class="Delimiter">{</span>
-    curr<span class="Special"> &lt;- </span>prev-duplex curr
+    curr<span class="Special"> &lt;- </span>prev curr
     <span class="muControl">break-unless</span> curr
     at-start?:boolean<span class="Special"> &lt;- </span>equal curr, start
     <span class="muControl">break-if</span> at-start?
diff --git a/html/edit/003-shortcuts.mu.html b/html/edit/003-shortcuts.mu.html
index 023f8448..aabe23e0 100644
--- a/html/edit/003-shortcuts.mu.html
+++ b/html/edit/003-shortcuts.mu.html
@@ -119,14 +119,14 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <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>
   <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-duplex *before-cursor
+  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>
   <span class="muControl">reply-unless</span> prev
   trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[delete-before-cursor]</span>
   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-duplex *before-cursor  <span class="Comment"># will also neatly trim next/prev pointers in backspaced-cell/*before-cursor</span>
+  remove *before-cursor  <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?
@@ -139,7 +139,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="muControl">reply-unless</span> same-row?
   left:number<span class="Special"> &lt;- </span>get *editor, <span class="Constant">left:offset</span>
   right:number<span class="Special"> &lt;- </span>get *editor, <span class="Constant">right:offset</span>
-  curr:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+  curr:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
   screen<span class="Special"> &lt;- </span>move-cursor screen, cursor-row, cursor-column
   curr-column:number<span class="Special"> &lt;- </span>copy cursor-column
   <span class="Delimiter">{</span>
@@ -154,7 +154,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-if</span> at-newline?
     screen<span class="Special"> &lt;- </span>print-character screen, currc
     curr-column<span class="Special"> &lt;- </span>add curr-column, <span class="Constant">1</span>
-    curr<span class="Special"> &lt;- </span>next-duplex curr
+    curr<span class="Special"> &lt;- </span>next curr
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># we're guaranteed not to be at the right margin</span>
@@ -218,7 +218,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   at-start?:boolean<span class="Special"> &lt;- </span>equal curr, start
   <span class="muControl">reply-if</span> at-start?
   <span class="Delimiter">{</span>
-    curr<span class="Special"> &lt;- </span>prev-duplex curr
+    curr<span class="Special"> &lt;- </span>prev curr
     <span class="muControl">break-unless</span> curr
     at-start?:boolean<span class="Special"> &lt;- </span>equal curr, start
     <span class="muControl">break-if</span> at-start?
@@ -367,16 +367,16 @@ 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>
-  deleted-cell:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+  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-duplex deleted-cell
+  remove deleted-cell
   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?
   <span class="Comment"># wasn't a newline? render rest of line</span>
-  curr:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor  <span class="Comment"># refresh after remove-duplex above</span>
+  curr:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor  <span class="Comment"># refresh after remove above</span>
   cursor-row:address:number<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">cursor-row:offset</span>
   cursor-column:address:number<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
   screen<span class="Special"> &lt;- </span>move-cursor screen, *cursor-row, *cursor-column
@@ -394,7 +394,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-if</span> at-newline?
     screen<span class="Special"> &lt;- </span>print-character screen, currc
     curr-column<span class="Special"> &lt;- </span>add curr-column, <span class="Constant">1</span>
-    curr<span class="Special"> &lt;- </span>next-duplex curr
+    curr<span class="Special"> &lt;- </span>next curr
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># we're guaranteed not to be at the right margin</span>
@@ -431,7 +431,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     move-to-next-character?:boolean<span class="Special"> &lt;- </span>equal *k, <span class="Constant">65514/right-arrow</span>
     <span class="muControl">break-unless</span> move-to-next-character?
     <span class="Comment"># if not at end of text</span>
-    next-cursor:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+    next-cursor:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
     <span class="muControl">break-unless</span> next-cursor
     <span class="Comment"># scan to next character</span>
 <span class="Constant">    &lt;move-cursor-begin&gt;</span>
@@ -474,7 +474,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     at-wrap?:boolean<span class="Special"> &lt;- </span>equal *cursor-column, wrap-column
     <span class="muControl">break-unless</span> at-wrap?
     <span class="Comment"># and if next character isn't newline</span>
-    next:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex before-cursor
+    next:address:duplex-list:character<span class="Special"> &lt;- </span>next before-cursor
     <span class="muControl">break-unless</span> next
     next-character:character<span class="Special"> &lt;- </span>get *next, <span class="Constant">value:offset</span>
     newline?:boolean<span class="Special"> &lt;- </span>equal next-character, <span class="Constant">10/newline</span>
@@ -708,7 +708,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-unless</span> move-to-previous-character?
     trace <span class="Constant">10</span>, <span class="Constant">[app]</span>, <span class="Constant">[left arrow]</span>
     <span class="Comment"># if not at start of text (before-cursor at § sentinel)</span>
-    prev:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex *before-cursor
+    prev:address:duplex-list:character<span class="Special"> &lt;- </span>prev *before-cursor
     go-render?<span class="Special"> &lt;- </span>copy <span class="Constant">0/false</span>
     <span class="muControl">reply-unless</span> prev
 <span class="Constant">    &lt;move-cursor-begin&gt;</span>
@@ -954,7 +954,7 @@ d]
     <span class="Delimiter">{</span>
       done?:boolean<span class="Special"> &lt;- </span>greater-or-equal *cursor-column, target-column
       <span class="muControl">break-if</span> done?
-      curr:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+      curr:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
       <span class="muControl">break-unless</span> curr
       currc:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">value:offset</span>
       at-newline?:boolean<span class="Special"> &lt;- </span>equal currc, <span class="Constant">10/newline</span>
@@ -1171,7 +1171,7 @@ def]
     <span class="Delimiter">{</span>
       done?:boolean<span class="Special"> &lt;- </span>greater-or-equal *cursor-column, target-column
       <span class="muControl">break-if</span> done?
-      curr:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+      curr:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
       <span class="muControl">break-unless</span> curr
       currc:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">value:offset</span>
       at-newline?:boolean<span class="Special"> &lt;- </span>equal currc, <span class="Constant">10/newline</span>
@@ -1295,7 +1295,7 @@ def]
     prev:character<span class="Special"> &lt;- </span>get **before-cursor, <span class="Constant">value:offset</span>
     at-start-of-line?:boolean<span class="Special"> &lt;- </span>equal prev, <span class="Constant">10/newline</span>
     <span class="muControl">break-if</span> at-start-of-line?
-    *before-cursor<span class="Special"> &lt;- </span>prev-duplex *before-cursor
+    *before-cursor<span class="Special"> &lt;- </span>prev *before-cursor
     assert *before-cursor, <span class="Constant">[move-to-start-of-line tried to move before start of text]</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
@@ -1456,7 +1456,7 @@ def]
   cursor-column:address:number<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">cursor-column:offset</span>
   <span class="Comment"># while not at start of line, move </span>
   <span class="Delimiter">{</span>
-    next:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+    next:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
     <span class="muControl">break-unless</span> next  <span class="Comment"># end of text</span>
     nextc:character<span class="Special"> &lt;- </span>get *next, <span class="Constant">value:offset</span>
     at-end-of-line?:boolean<span class="Special"> &lt;- </span>equal nextc, <span class="Constant">10/newline</span>
@@ -1586,20 +1586,20 @@ def]
   init:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">data:offset</span>
   before-cursor:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
   start:address:duplex-list:character<span class="Special"> &lt;- </span>copy *before-cursor
-  end:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+  end:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
   <span class="Delimiter">{</span>
     at-start-of-text?:boolean<span class="Special"> &lt;- </span>equal start, init
     <span class="muControl">break-if</span> at-start-of-text?
     curr:character<span class="Special"> &lt;- </span>get *start, <span class="Constant">value:offset</span>
     at-start-of-line?:boolean<span class="Special"> &lt;- </span>equal curr, <span class="Constant">10/newline</span>
     <span class="muControl">break-if</span> at-start-of-line?
-    start<span class="Special"> &lt;- </span>prev-duplex start
+    start<span class="Special"> &lt;- </span>prev start
     assert start, <span class="Constant">[delete-to-start-of-line tried to move before start of text]</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># snip it out</span>
-  result:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex start
-  remove-duplex-between start, end
+  result:address:duplex-list:character<span class="Special"> &lt;- </span>next start
+  remove-between start, end
   <span class="Comment"># adjust cursor</span>
   *before-cursor<span class="Special"> &lt;- </span>copy start
   left:number<span class="Special"> &lt;- </span>get *editor, <span class="Constant">left:offset</span>
@@ -1718,19 +1718,19 @@ def]
   <span class="Constant">load-ingredients</span>
   <span class="Comment"># compute range to delete</span>
   start:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">before-cursor:offset</span>
-  end:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex start
+  end:address:duplex-list:character<span class="Special"> &lt;- </span>next start
   <span class="Delimiter">{</span>
     at-end-of-text?:boolean<span class="Special"> &lt;- </span>equal end, <span class="Constant">0/null</span>
     <span class="muControl">break-if</span> at-end-of-text?
     curr:character<span class="Special"> &lt;- </span>get *end, <span class="Constant">value:offset</span>
     at-end-of-line?:boolean<span class="Special"> &lt;- </span>equal curr, <span class="Constant">10/newline</span>
     <span class="muControl">break-if</span> at-end-of-line?
-    end<span class="Special"> &lt;- </span>next-duplex end
+    end<span class="Special"> &lt;- </span>next end
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># snip it out</span>
-  result<span class="Special"> &lt;- </span>next-duplex start
-  remove-duplex-between start, end
+  result<span class="Special"> &lt;- </span>next start
+  remove-between start, end
 ]
 
 <span class="muScenario">scenario</span> editor-deletes-to-end-of-line-with-ctrl-k-2 [
@@ -1908,7 +1908,7 @@ def]
     c:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">value:offset</span>
     at-newline?:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">10/newline</span>
     <span class="muControl">break-unless</span> at-newline?
-    curr<span class="Special"> &lt;- </span>next-duplex curr
+    curr<span class="Special"> &lt;- </span>next curr
     count<span class="Special"> &lt;- </span>add count, <span class="Constant">1</span>
   <span class="Delimiter">}</span>
   <span class="Delimiter">{</span>
@@ -1918,7 +1918,7 @@ def]
     c:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">value:offset</span>
     at-newline?:boolean<span class="Special"> &lt;- </span>equal c, <span class="Constant">10/newline</span>
     <span class="muControl">break-if</span> at-newline?
-    curr<span class="Special"> &lt;- </span>next-duplex curr
+    curr<span class="Special"> &lt;- </span>next curr
     count<span class="Special"> &lt;- </span>add count, <span class="Constant">1</span>
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
@@ -2280,7 +2280,7 @@ def]
   <span class="Delimiter">{</span>
     <span class="muControl">break-if</span> len
     <span class="Comment"># empty line; just skip this newline</span>
-    prev:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex curr
+    prev:address:duplex-list:character<span class="Special"> &lt;- </span>prev curr
     <span class="muControl">reply-unless</span> prev, curr
     <span class="muControl">reply</span> prev
   <span class="Delimiter">}</span>
@@ -2296,7 +2296,7 @@ def]
   <span class="Delimiter">{</span>
     done?:boolean<span class="Special"> &lt;- </span>greater-or-equal count, max
     <span class="muControl">break-if</span> done?
-    prev:address:duplex-list:character<span class="Special"> &lt;- </span>prev-duplex curr
+    prev:address:duplex-list:character<span class="Special"> &lt;- </span>prev curr
     <span class="muControl">break-unless</span> prev
     curr<span class="Special"> &lt;- </span>copy prev
     count<span class="Special"> &lt;- </span>add count, <span class="Constant">1</span>
@@ -2682,13 +2682,13 @@ e]
   <span class="muControl">reply-unless</span> bottom-of-screen
   <span class="Comment"># if not, position cursor at final character</span>
   before-cursor:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">before-cursor:offset</span>
-  *before-cursor<span class="Special"> &lt;- </span>prev-duplex bottom-of-screen
+  *before-cursor<span class="Special"> &lt;- </span>prev bottom-of-screen
   <span class="Comment"># keep one line in common with previous page</span>
   <span class="Delimiter">{</span>
     last:character<span class="Special"> &lt;- </span>get **before-cursor, <span class="Constant">value:offset</span>
     newline?:boolean<span class="Special"> &lt;- </span>equal last, <span class="Constant">10/newline</span>
     <span class="muControl">break-unless</span> newline?:boolean
-    *before-cursor<span class="Special"> &lt;- </span>prev-duplex *before-cursor
+    *before-cursor<span class="Special"> &lt;- </span>prev *before-cursor
   <span class="Delimiter">}</span>
   <span class="Comment"># move cursor and top-of-screen to start of that line</span>
   move-to-start-of-line editor
diff --git a/html/edit/005-sandbox.mu.html b/html/edit/005-sandbox.mu.html
index 3fdab8a0..85fdf7da 100644
--- a/html/edit/005-sandbox.mu.html
+++ b/html/edit/005-sandbox.mu.html
@@ -186,7 +186,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     *dest<span class="Special"> &lt;- </span>copy new-sandbox
     <span class="Comment"># clear sandbox editor</span>
     init:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *current-sandbox, <span class="Constant">data:offset</span>
-    *init<span class="Special"> &lt;- </span>push-duplex <span class="Constant">167/§</span>, <span class="Constant">0/tail</span>
+    *init<span class="Special"> &lt;- </span>push <span class="Constant">167/§</span>, <span class="Constant">0/tail</span>
     top-of-screen:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *current-sandbox, <span class="Constant">top-of-screen:offset</span>
     *top-of-screen<span class="Special"> &lt;- </span>copy *init
   <span class="Delimiter">}</span>
@@ -509,13 +509,13 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   curr:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">data:offset</span>
   <span class="Comment"># skip § sentinel</span>
   assert curr, <span class="Constant">[editor without data is illegal; must have at least a sentinel]</span>
-  curr<span class="Special"> &lt;- </span>next-duplex curr
+  curr<span class="Special"> &lt;- </span>next curr
   <span class="muControl">reply-unless</span> curr, <span class="Constant">0</span>
   <span class="Delimiter">{</span>
     <span class="muControl">break-unless</span> curr
     c:character<span class="Special"> &lt;- </span>get *curr, <span class="Constant">value:offset</span>
     buffer-append buf, c
-    curr<span class="Special"> &lt;- </span>next-duplex curr
+    curr<span class="Special"> &lt;- </span>next curr
     <span class="muControl">loop</span>
   <span class="Delimiter">}</span>
   result<span class="Special"> &lt;- </span>buffer-to-array buf
diff --git a/html/edit/006-sandbox-edit.mu.html b/html/edit/006-sandbox-edit.mu.html
index 2381b4bd..2381ec45 100644
--- a/html/edit/006-sandbox-edit.mu.html
+++ b/html/edit/006-sandbox-edit.mu.html
@@ -127,7 +127,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
   <span class="Constant">local-scope</span>
   <span class="Constant">load-ingredients</span>
   head:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">data:offset</span>
-  first:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex head
+  first:address:duplex-list:character<span class="Special"> &lt;- </span>next head
   result<span class="Special"> &lt;- </span>not first
 ]
 
diff --git a/html/edit/011-editor-undo.mu.html b/html/edit/011-editor-undo.mu.html
index b50f0063..5a3f537e 100644
--- a/html/edit/011-editor-undo.mu.html
+++ b/html/edit/011-editor-undo.mu.html
@@ -185,7 +185,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     previous-coalesce-tag:number<span class="Special"> &lt;- </span>get *typing, <span class="Constant">tag:offset</span>
     <span class="muControl">break-unless</span> previous-coalesce-tag
     insert-until:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *typing, <span class="Constant">insert-until:offset</span>
-    *insert-until<span class="Special"> &lt;- </span>next-duplex *before-cursor
+    *insert-until<span class="Special"> &lt;- </span>next *before-cursor
     after-row:address:number<span class="Special"> &lt;- </span>get-address *typing, <span class="Constant">after-row:offset</span>
     *after-row<span class="Special"> &lt;- </span>copy *cursor-row
     after-column:address:number<span class="Special"> &lt;- </span>get-address *typing, <span class="Constant">after-column:offset</span>
@@ -195,8 +195,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break</span> <span class="Constant">+done-adding-insert-operation:label</span>
   <span class="Delimiter">}</span>
   <span class="Comment"># if not, create a new operation</span>
-  insert-from:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex cursor-before
-  insert-to:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex insert-from
+  insert-from:address:duplex-list:character<span class="Special"> &lt;- </span>next cursor-before
+  insert-to:address:duplex-list:character<span class="Special"> &lt;- </span>next insert-from
   op:address:operation<span class="Special"> &lt;- </span>new <span class="Constant">operation:type</span>
   *op<span class="Special"> &lt;- </span>merge <span class="Constant">0/insert-operation</span>, save-row/<span class="muRecipe">before</span>, save-column/<span class="muRecipe">before</span>, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, insert-from, insert-to, <span class="Constant">1/coalesce</span>
   editor<span class="Special"> &lt;- </span>add-operation editor, op
@@ -213,8 +213,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
 <span class="muRecipe">before</span> <span class="Constant">&lt;insert-enter-end&gt;</span> [
   top-after:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
   <span class="Comment"># never coalesce</span>
-  insert-from:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex cursor-before
-  insert-to:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+  insert-from:address:duplex-list:character<span class="Special"> &lt;- </span>next cursor-before
+  insert-to:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
   op:address:operation<span class="Special"> &lt;- </span>new <span class="Constant">operation:type</span>
   *op<span class="Special"> &lt;- </span>merge <span class="Constant">0/insert-operation</span>, cursor-row-before, cursor-column-before, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, insert-from, insert-to, <span class="Constant">0/never-coalesce</span>
   editor<span class="Special"> &lt;- </span>add-operation editor, op
@@ -241,8 +241,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     start:address:duplex-list:character<span class="Special"> &lt;- </span>get *typing, <span class="Constant">insert-from:offset</span>
     end:address:duplex-list:character<span class="Special"> &lt;- </span>get *typing, <span class="Constant">insert-until:offset</span>
     <span class="Comment"># assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen</span>
-    *before-cursor<span class="Special"> &lt;- </span>prev-duplex start
-    remove-duplex-between *before-cursor, end
+    *before-cursor<span class="Special"> &lt;- </span>prev start
+    remove-between *before-cursor, end
     *cursor-row<span class="Special"> &lt;- </span>get *typing, <span class="Constant">before-row:offset</span>
     *cursor-column<span class="Special"> &lt;- </span>get *typing, <span class="Constant">before-column:offset</span>
     top:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">top-of-screen:offset</span>
@@ -436,8 +436,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     typing:address:insert-operation<span class="Special"> &lt;- </span>maybe-convert *op, <span class="Constant">typing:variant</span>
     <span class="muControl">break-unless</span> typing
     insert-from:address:duplex-list:character<span class="Special"> &lt;- </span>get *typing, <span class="Constant">insert-from:offset</span>  <span class="Comment"># ignore insert-to because it's already been spliced away</span>
-    <span class="Comment"># assert insert-to matches next-duplex(*before-cursor)</span>
-    insert-duplex-range *before-cursor, insert-from
+    <span class="Comment"># assert insert-to matches next(*before-cursor)</span>
+    insert-range *before-cursor, insert-from
     <span class="Comment"># assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen</span>
     *cursor-row<span class="Special"> &lt;- </span>get *typing, <span class="Constant">after-row:offset</span>
     *cursor-column<span class="Special"> &lt;- </span>get *typing, <span class="Constant">after-column:offset</span>
@@ -1643,7 +1643,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       delete-from:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *deletion, <span class="Constant">delete-from:offset</span>
       *delete-from<span class="Special"> &lt;- </span>copy *before-cursor
       backspaced-so-far:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *deletion, <span class="Constant">deleted-text:offset</span>
-      insert-duplex-range backspaced-cell, *backspaced-so-far
+      insert-range backspaced-cell, *backspaced-so-far
       *backspaced-so-far<span class="Special"> &lt;- </span>copy backspaced-cell
       after-row:address:number<span class="Special"> &lt;- </span>get-address *deletion, <span class="Constant">after-row:offset</span>
       *after-row<span class="Special"> &lt;- </span>copy *cursor-row
@@ -1655,7 +1655,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Delimiter">}</span>
     <span class="Comment"># if not, create a new operation</span>
     op:address:operation<span class="Special"> &lt;- </span>new <span class="Constant">operation:type</span>
-    deleted-until:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+    deleted-until:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
     *op<span class="Special"> &lt;- </span>merge <span class="Constant">2/delete-operation</span>, save-row/<span class="muRecipe">before</span>, save-column/<span class="muRecipe">before</span>, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, backspaced-cell/deleted, *before-cursor/delete-from, deleted-until, <span class="Constant">1/coalesce-backspace</span>
     editor<span class="Special"> &lt;- </span>add-operation editor, op
 <span class="Constant">    +done-adding-backspace-operation</span>
@@ -1670,8 +1670,8 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     anchor:address:duplex-list:character<span class="Special"> &lt;- </span>get *deletion, <span class="Constant">delete-from:offset</span>
     <span class="muControl">break-unless</span> anchor
     deleted:address:duplex-list:character<span class="Special"> &lt;- </span>get *deletion, <span class="Constant">deleted-text:offset</span>
-    old-cursor:address:duplex-list:character<span class="Special"> &lt;- </span>last-duplex deleted
-    insert-duplex-range anchor, deleted
+    old-cursor:address:duplex-list:character<span class="Special"> &lt;- </span>last deleted
+    insert-range anchor, deleted
     <span class="Comment"># assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen</span>
     *before-cursor<span class="Special"> &lt;- </span>copy old-cursor
     *cursor-row<span class="Special"> &lt;- </span>get *deletion, <span class="Constant">before-row:offset</span>
@@ -1687,7 +1687,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="muControl">break-unless</span> deletion
     start:address:duplex-list:character<span class="Special"> &lt;- </span>get *deletion, <span class="Constant">delete-from:offset</span>
     end:address:duplex-list:character<span class="Special"> &lt;- </span>get *deletion, <span class="Constant">delete-until:offset</span>
-    remove-duplex-between start, end
+    remove-between start, end
     <span class="Comment"># assert cursor-row/cursor-column/top-of-screen match after-row/after-column/after-top-of-screen</span>
     *cursor-row<span class="Special"> &lt;- </span>get *deletion, <span class="Constant">after-row:offset</span>
     *cursor-column<span class="Special"> &lt;- </span>get *deletion, <span class="Constant">after-column:offset</span>
@@ -1863,9 +1863,9 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
       coalesce?:boolean<span class="Special"> &lt;- </span>equal previous-coalesce-tag, <span class="Constant">2/coalesce-delete</span>
       <span class="muControl">break-unless</span> coalesce?
       delete-until:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *deletion, <span class="Constant">delete-until:offset</span>
-      *delete-until<span class="Special"> &lt;- </span>next-duplex *before-cursor
+      *delete-until<span class="Special"> &lt;- </span>next *before-cursor
       deleted-so-far:address:address:duplex-list:character<span class="Special"> &lt;- </span>get-address *deletion, <span class="Constant">deleted-text:offset</span>
-      *deleted-so-far<span class="Special"> &lt;- </span>append-duplex *deleted-so-far, deleted-cell
+      *deleted-so-far<span class="Special"> &lt;- </span>append *deleted-so-far, deleted-cell
       after-row:address:number<span class="Special"> &lt;- </span>get-address *deletion, <span class="Constant">after-row:offset</span>
       *after-row<span class="Special"> &lt;- </span>copy *cursor-row
       after-column:address:number<span class="Special"> &lt;- </span>get-address *deletion, <span class="Constant">after-column:offset</span>
@@ -1876,7 +1876,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     <span class="Delimiter">}</span>
     <span class="Comment"># if not, create a new operation</span>
     op:address:operation<span class="Special"> &lt;- </span>new <span class="Constant">operation:type</span>
-    deleted-until:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+    deleted-until:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
     *op<span class="Special"> &lt;- </span>merge <span class="Constant">2/delete-operation</span>, save-row/<span class="muRecipe">before</span>, save-column/<span class="muRecipe">before</span>, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, deleted-cell/deleted, *before-cursor/delete-from, deleted-until, <span class="Constant">2/coalesce-delete</span>
     editor<span class="Special"> &lt;- </span>add-operation editor, op
 <span class="Constant">    +done-adding-delete-operation</span>
@@ -1977,7 +1977,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     top-after:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
     undo:address:address:list:address:operation<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">undo:offset</span>
     op:address:operation<span class="Special"> &lt;- </span>new <span class="Constant">operation:type</span>
-    deleted-until:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+    deleted-until:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
     *op<span class="Special"> &lt;- </span>merge <span class="Constant">2/delete-operation</span>, save-row/<span class="muRecipe">before</span>, save-column/<span class="muRecipe">before</span>, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, deleted-cells/deleted, *before-cursor/delete-from, deleted-until, <span class="Constant">0/never-coalesce</span>
     editor<span class="Special"> &lt;- </span>add-operation editor, op
 <span class="Constant">    +done-adding-delete-operation</span>
@@ -2078,7 +2078,7 @@ body { font-family: monospace; color: #eeeeee; background-color: #080808; }
     top-after:address:duplex-list:character<span class="Special"> &lt;- </span>get *editor, <span class="Constant">top-of-screen:offset</span>
     undo:address:address:list:address:operation<span class="Special"> &lt;- </span>get-address *editor, <span class="Constant">undo:offset</span>
     op:address:operation<span class="Special"> &lt;- </span>new <span class="Constant">operation:type</span>
-    deleted-until:address:duplex-list:character<span class="Special"> &lt;- </span>next-duplex *before-cursor
+    deleted-until:address:duplex-list:character<span class="Special"> &lt;- </span>next *before-cursor
     *op<span class="Special"> &lt;- </span>merge <span class="Constant">2/delete-operation</span>, save-row/<span class="muRecipe">before</span>, save-column/<span class="muRecipe">before</span>, top-before, *cursor-row/<span class="muRecipe">after</span>, *cursor-column/<span class="muRecipe">after</span>, top-after, deleted-cells/deleted, *before-cursor/delete-from, deleted-until, <span class="Constant">0/never-coalesce</span>
     editor<span class="Special"> &lt;- </span>add-operation editor, op
 <span class="Constant">    +done-adding-delete-operation</span>