about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--011load.cc4
-rw-r--r--031address.cc34
-rw-r--r--032array.cc12
-rw-r--r--042name.cc4
-rw-r--r--043new.cc10
-rw-r--r--044space.cc14
-rw-r--r--060string.mu254
-rw-r--r--061channel.mu98
-rw-r--r--062array.mu6
-rw-r--r--063list.mu12
-rw-r--r--065duplex_list.mu64
-rw-r--r--066stream.mu28
-rw-r--r--071print.mu228
-rw-r--r--074console.mu24
-rw-r--r--081run_interactive.cc6
-rw-r--r--chessboard.mu68
-rw-r--r--edit.mu652
17 files changed, 759 insertions, 759 deletions
diff --git a/011load.cc b/011load.cc
index c1525014..34d6c457 100644
--- a/011load.cc
+++ b/011load.cc
@@ -342,6 +342,6 @@ recipe main [
 
 :(scenario parse_properties)
 recipe main [
-  1:number:address/deref <- copy 23
+  1:number:address/lookup <- copy 23
 ]
-+parse:   product: {name: "1", properties: ["1": "number":"address", "deref": ]}
++parse:   product: {name: "1", properties: ["1": "number":"address", "lookup": ]}
diff --git a/031address.cc b/031address.cc
index 657b7459..a069f332 100644
--- a/031address.cc
+++ b/031address.cc
@@ -1,12 +1,12 @@
 //: Instructions can read from addresses pointing at other locations using the
-//: 'deref' property.
+//: 'lookup' property.
 
 :(scenario copy_indirect)
 recipe main [
   1:address:number <- copy 2
   2:number <- copy 34
   # This loads location 1 as an address and looks up *that* location.
-  3:number <- copy 1:address:number/deref
+  3:number <- copy 1:address:number/lookup
 ]
 +mem: storing 34 in location 3
 
@@ -14,11 +14,11 @@ recipe main [
 x = canonize(x);
 
 //: similarly, write to addresses pointing at other locations using the
-//: 'deref' property
+//: 'lookup' property
 :(scenario store_indirect)
 recipe main [
   1:address:number <- copy 2
-  1:address:number/deref <- copy 34
+  1:address:number/lookup <- copy 34
 ]
 +mem: storing 34 in location 2
 
@@ -31,22 +31,22 @@ reagent canonize(reagent x) {
 //?   cout << "canonize\n"; //? 1
   reagent r = x;
 //?   cout << x.to_string() << " => " << r.to_string() << '\n'; //? 1
-  while (has_property(r, "deref"))
-    r = deref(r);
+  while (has_property(r, "lookup"))
+    r = lookup_memory(r);
   return r;
 }
 
-reagent deref(reagent x) {
-//?   cout << "deref: " << x.to_string() << "\n"; //? 2
+reagent lookup_memory(reagent x) {
+//?   cout << "lookup_memory: " << x.to_string() << "\n"; //? 2
   static const type_ordinal ADDRESS = Type_ordinal["address"];
   reagent result;
   if (x.types.at(0) != ADDRESS) {
-    raise << current_recipe_name() << ": tried to /deref " << x.original_string << " but it isn't an address\n" << end();
+    raise << current_recipe_name() << ": tried to /lookup " << x.original_string << " but it isn't an address\n" << end();
     return result;
   }
   // compute value
   if (x.value == 0) {
-    raise << current_recipe_name() << ": tried to /deref 0\n" << end();
+    raise << current_recipe_name() << ": tried to /lookup 0\n" << end();
     return result;
   }
   result.set_value(Memory[x.value]);
@@ -55,14 +55,14 @@ reagent deref(reagent x) {
   // populate types
   copy(++x.types.begin(), x.types.end(), inserter(result.types, result.types.begin()));
 
-  // drop-one 'deref'
+  // drop-one 'lookup'
   long long int i = 0;
   long long int len = SIZE(x.properties);
   for (i = 0; i < len; ++i) {
-    if (x.properties.at(i).first == "deref") break;
+    if (x.properties.at(i).first == "lookup") break;
     result.properties.push_back(x.properties.at(i));
   }
-  ++i;  // skip first deref
+  ++i;  // skip first lookup
   for (; i < len; ++i) {
     result.properties.push_back(x.properties.at(i));
   }
@@ -75,16 +75,16 @@ recipe main [
   1:number <- copy 2
   2:number <- copy 34
   3:number <- copy 35
-  4:number <- get 1:address:point/deref, 0:offset
+  4:number <- get 1:address:point/lookup, 0:offset
 ]
 +mem: storing 34 in location 4
 
-:(scenario include_nonderef_properties)
+:(scenario include_nonlookup_properties)
 recipe main [
   1:number <- copy 2
   2:number <- copy 34
   3:number <- copy 35
-  4:number <- get 1:address:point/deref/foo, 0:offset
+  4:number <- get 1:address:point/lookup/foo, 0:offset
 ]
 +mem: storing 34 in location 4
 
@@ -97,7 +97,7 @@ recipe main [
   1:number <- copy 2
   2:number <- copy 34
   3:number <- copy 35
-  4:number <- get-address 1:address:point/deref, 0:offset
+  4:number <- get-address 1:address:point/lookup, 0:offset
 ]
 +mem: storing 2 in location 4
 
diff --git a/032array.cc b/032array.cc
index e7bcd1c9..dc8c04a5 100644
--- a/032array.cc
+++ b/032array.cc
@@ -30,7 +30,7 @@ recipe main [
   3:number <- copy 15
   4:number <- copy 16
   5:address:array:number <- copy 1
-  6:array:number <- copy 5:address:array:number/deref
+  6:array:number <- copy 5:address:array:number/lookup
 ]
 +mem: storing 3 in location 6
 +mem: storing 14 in location 7
@@ -119,7 +119,7 @@ recipe main [
   3:number <- copy 15
   4:number <- copy 16
   5:address:array:number <- copy 1
-  6:number <- index 5:address:array:number/deref, 1
+  6:number <- index 5:address:array:number/lookup, 1
 ]
 +mem: storing 15 in location 6
 
@@ -134,7 +134,7 @@ recipe main [
   6:number <- copy 15
   7:number <- copy 16
   8:address:array:point <- copy 1
-  index 8:address:array:point/deref, 4  # less than size of array in locations, but larger than its length in elements
+  index 8:address:array:point/lookup, 4  # less than size of array in locations, but larger than its length in elements
 ]
 +warn: main: invalid index 4
 
@@ -149,7 +149,7 @@ recipe main [
   6:number <- copy 15
   7:number <- copy 16
   8:address:array:point <- copy 1
-  index 8:address:array:point/deref, -1
+  index 8:address:array:point/lookup, -1
 ]
 +warn: main: invalid index -1
 
@@ -206,7 +206,7 @@ recipe main [
   6:number <- copy 15
   7:number <- copy 16
   8:address:array:point <- copy 1
-  index-address 8:address:array:point/deref, 4  # less than size of array in locations, but larger than its length in elements
+  index-address 8:address:array:point/lookup, 4  # less than size of array in locations, but larger than its length in elements
 ]
 +warn: main: invalid index 4
 
@@ -221,7 +221,7 @@ recipe main [
   6:number <- copy 15
   7:number <- copy 16
   8:address:array:point <- copy 1
-  index-address 8:address:array:point/deref, -1
+  index-address 8:address:array:point/lookup, -1
 ]
 +warn: main: invalid index -1
 
diff --git a/042name.cc b/042name.cc
index a12f6eaa..6a631724 100644
--- a/042name.cc
+++ b/042name.cc
@@ -209,8 +209,8 @@ Type[point].element_names.push_back("y");
 :(scenario convert_names_transforms_container_elements)
 recipe main [
   p:address:point <- copy 0  # unsafe
-  a:number <- get p:address:point/deref, y:offset
-  b:number <- get p:address:point/deref, x:offset
+  a:number <- get p:address:point/lookup, y:offset
+  b:number <- get p:address:point/lookup, x:offset
 ]
 +name: element y of type point is at offset 1
 +name: element x of type point is at offset 0
diff --git a/043new.cc b/043new.cc
index 868910d5..3e256ca7 100644
--- a/043new.cc
+++ b/043new.cc
@@ -133,7 +133,7 @@ void ensure_space(long long int size) {
 % Memory[Memory_allocated_until] = 1;
 recipe main [
   1:address:number <- new number:type
-  2:number <- copy 1:address:number/deref
+  2:number <- copy 1:address:number/lookup
 ]
 +mem: storing 0 in location 2
 
@@ -225,7 +225,7 @@ case ABANDON: {
     raise << current_recipe_name() << ": first ingredient of 'abandon' should be an address, but got " << current_instruction().ingredients.at(0).original_string << '\n' << end();
     break;
   }
-  reagent target_type = deref(types);
+  reagent target_type = lookup_memory(types);
   abandon(address, size_of(target_type));
   break;
 }
@@ -287,7 +287,7 @@ recipe main [
 :(scenario new_string)
 recipe main [
   1:address:array:character <- new [abc def]
-  2:character <- index 1:address:array:character/deref, 5
+  2:character <- index 1:address:array:character/lookup, 5
 ]
 # number code for 'e'
 +mem: storing 101 in location 2
@@ -295,8 +295,8 @@ recipe main [
 :(scenario new_string_handles_unicode)
 recipe main [
   1:address:array:character <- new [a«c]
-  2:number <- length 1:address:array:character/deref
-  3:character <- index 1:address:array:character/deref, 1
+  2:number <- length 1:address:array:character/lookup
+  3:character <- index 1:address:array:character/lookup, 1
 ]
 +mem: storing 3 in location 2
 # unicode for '«'
diff --git a/044space.cc b/044space.cc
index 69c36281..5c3f97c4 100644
--- a/044space.cc
+++ b/044space.cc
@@ -12,7 +12,7 @@ recipe main [
 ]
 +mem: storing 23 in location 12
 
-:(scenario deref_sidesteps_default_space)
+:(scenario lookup_sidesteps_default_space)
 recipe main [
   # pretend pointer from outside
   3:number <- copy 34
@@ -21,7 +21,7 @@ recipe main [
   # actual start of this recipe
   default-space:address:array:location <- copy 1000
   1:address:number <- copy 3
-  8:number/raw <- copy 1:address:number/deref
+  8:number/raw <- copy 1:address:number/lookup
 ]
 +mem: storing 34 in location 8
 
@@ -61,12 +61,12 @@ reagent absolutize(reagent x) {
   assert(is_raw(r));
   return r;
 }
-:(before "return result" following "reagent deref(reagent x)")
+:(before "return result" following "reagent lookup_memory(reagent x)")
 result.properties.push_back(pair<string, vector<string> >("raw", vector<string>()));
 
 //:: fix 'get'
 
-:(scenario deref_sidesteps_default_space_in_get)
+:(scenario lookup_sidesteps_default_space_in_get)
 recipe main [
   # pretend pointer to container from outside
   12:number <- copy 34
@@ -76,7 +76,7 @@ recipe main [
   # actual start of this recipe
   default-space:address:array:location <- copy 1000
   1:address:point <- copy 12
-  9:number/raw <- get 1:address:point/deref, 1:offset
+  9:number/raw <- get 1:address:point/lookup, 1:offset
 ]
 +mem: storing 35 in location 9
 
@@ -85,7 +85,7 @@ tmp.properties.push_back(pair<string, vector<string> >("raw", vector<string>()))
 
 //:: fix 'index'
 
-:(scenario deref_sidesteps_default_space_in_index)
+:(scenario lookup_sidesteps_default_space_in_index)
 recipe main [
   # pretend pointer to array from outside
   12:number <- copy 2
@@ -96,7 +96,7 @@ recipe main [
   # actual start of this recipe
   default-space:address:array:location <- copy 1000
   1:address:array:number <- copy 12
-  9:number/raw <- index 1:address:array:number/deref, 1
+  9:number/raw <- index 1:address:array:number/lookup, 1
 ]
 +mem: storing 35 in location 9
 
diff --git a/060string.mu b/060string.mu
index 16e7bdf2..ddd50f04 100644
--- a/060string.mu
+++ b/060string.mu
@@ -3,9 +3,9 @@
 recipe string-equal [
   local-scope
   a:address:array:character <- next-ingredient
-  a-len:number <- length a:address:array:character/deref
+  a-len:number <- length a:address:array:character/lookup
   b:address:array:character <- next-ingredient
-  b-len:number <- length b:address:array:character/deref
+  b-len:number <- length b:address:array:character/lookup
   # compare lengths
   {
     trace [string-equal], [comparing lengths]
@@ -19,8 +19,8 @@ recipe string-equal [
   {
     done?:boolean <- greater-or-equal i:number, a-len:number
     break-if done?:boolean
-    a2:character <- index a:address:array:character/deref, i:number
-    b2:character <- index b:address:array:character/deref, i:number
+    a2:character <- index a:address:array:character/lookup, i:number
+    b2:character <- index b:address:array:character/lookup, i:number
     {
       chars-match?:boolean <- equal a2:character, b2:character
       break-if chars-match?:boolean
@@ -107,13 +107,13 @@ recipe new-buffer [
   local-scope
 #?   $print default-space:address:array:location, 10/newline
   result:address:buffer <- new buffer:type
-  len:address:number <- get-address result:address:buffer/deref, length:offset
-  len:address:number/deref <- copy 0
-  s:address:address:array:character <- get-address result:address:buffer/deref, data:offset
+  len:address:number <- get-address result:address:buffer/lookup, length:offset
+  len:address:number/lookup <- copy 0
+  s:address:address:array:character <- get-address result:address:buffer/lookup, data:offset
   capacity:number, found?:boolean <- next-ingredient
   assert found?:boolean, [new-buffer must get a capacity argument]
-  s:address:address:array:character/deref <- new character:type, capacity:number
-#?   $print s:address:address:array:character/deref, 10/newline
+  s:address:address:array:character/lookup <- new character:type, capacity:number
+#?   $print s:address:address:array:character/lookup, 10/newline
   reply result:address:buffer
 ]
 
@@ -121,19 +121,19 @@ recipe grow-buffer [
   local-scope
   in:address:buffer <- next-ingredient
   # double buffer size
-  x:address:address:array:character <- get-address in:address:buffer/deref, data:offset
-  oldlen:number <- length x:address:address:array:character/deref/deref
+  x:address:address:array:character <- get-address in:address:buffer/lookup, data:offset
+  oldlen:number <- length x:address:address:array:character/lookup/lookup
   newlen:number <- multiply oldlen:number, 2
-  olddata:address:array:character <- copy x:address:address:array:character/deref
-  x:address:address:array:character/deref <- new character:type, newlen:number
+  olddata:address:array:character <- copy x:address:address:array:character/lookup
+  x:address:address:array:character/lookup <- new character:type, newlen:number
   # copy old contents
   i:number <- copy 0
   {
     done?:boolean <- greater-or-equal i:number, oldlen:number
     break-if done?:boolean
-    src:character <- index olddata:address:array:character/deref, i:number
-    dest:address:character <- index-address x:address:address:array:character/deref/deref, i:number
-    dest:address:character/deref <- copy src:character
+    src:character <- index olddata:address:array:character/lookup, i:number
+    dest:address:character <- index-address x:address:address:array:character/lookup/lookup, i:number
+    dest:address:character/lookup <- copy src:character
     i:number <- add i:number, 1
     loop
   }
@@ -143,9 +143,9 @@ recipe grow-buffer [
 recipe buffer-full? [
   local-scope
   in:address:buffer <- next-ingredient
-  len:number <- get in:address:buffer/deref, length:offset
-  s:address:array:character <- get in:address:buffer/deref, data:offset
-  capacity:number <- length s:address:array:character/deref
+  len:number <- get in:address:buffer/lookup, length:offset
+  s:address:array:character <- get in:address:buffer/lookup, data:offset
+  capacity:number <- length s:address:array:character/lookup
   result:boolean <- greater-or-equal len:number, capacity:number
   reply result:boolean
 ]
@@ -155,14 +155,14 @@ recipe buffer-append [
   local-scope
   in:address:buffer <- next-ingredient
   c:character <- next-ingredient
-  len:address:number <- get-address in:address:buffer/deref, length:offset
+  len:address:number <- get-address in:address:buffer/lookup, length:offset
   {
     # backspace? just drop last character if it exists and return
     backspace?:boolean <- equal c:character, 8/backspace
     break-unless backspace?:boolean
-    empty?:boolean <- lesser-or-equal len:address:number/deref, 0
+    empty?:boolean <- lesser-or-equal len:address:number/lookup, 0
     reply-if empty?:boolean, in:address:buffer/same-as-ingredient:0
-    len:address:number/deref <- subtract len:address:number/deref, 1
+    len:address:number/lookup <- subtract len:address:number/lookup, 1
     reply in:address:buffer/same-as-ingredient:0
   }
   {
@@ -171,13 +171,13 @@ recipe buffer-append [
     break-unless full?:boolean
     in:address:buffer <- grow-buffer in:address:buffer
   }
-  s:address:array:character <- get in:address:buffer/deref, data:offset
+  s:address:array:character <- get in:address:buffer/lookup, data:offset
 #?   $print [array underlying buf: ], s:address:array:character, 10/newline
-#?   $print [index: ], len:address:number/deref, 10/newline
-  dest:address:character <- index-address s:address:array:character/deref, len:address:number/deref
+#?   $print [index: ], len:address:number/lookup, 10/newline
+  dest:address:character <- index-address s:address:array:character/lookup, len:address:number/lookup
 #?   $print [storing ], c:character, [ in ], dest:address:character, 10/newline
-  dest:address:character/deref <- copy c:character
-  len:address:number/deref <- add len:address:number/deref, 1
+  dest:address:character/lookup <- copy c:character
+  len:address:number/lookup <- add len:address:number/lookup, 1
   reply in:address:buffer/same-as-ingredient:0
 ]
 
@@ -185,19 +185,19 @@ scenario buffer-append-works [
   run [
     local-scope
     x:address:buffer <- new-buffer 3
-    s1:address:array:character <- get x:address:buffer/deref, data:offset
+    s1:address:array:character <- get x:address:buffer/lookup, data:offset
     x:address:buffer <- buffer-append x:address:buffer, 97  # 'a'
     x:address:buffer <- buffer-append x:address:buffer, 98  # 'b'
     x:address:buffer <- buffer-append x:address:buffer, 99  # 'c'
-    s2:address:array:character <- get x:address:buffer/deref, data:offset
+    s2:address:array:character <- get x:address:buffer/lookup, data:offset
     1:boolean/raw <- equal s1:address:array:character, s2:address:array:character
-    2:array:character/raw <- copy s2:address:array:character/deref
+    2:array:character/raw <- copy s2:address:array:character/lookup
     +buffer-filled
     x:address:buffer <- buffer-append x:address:buffer, 100  # 'd'
-    s3:address:array:character <- get x:address:buffer/deref, data:offset
+    s3:address:array:character <- get x:address:buffer/lookup, data:offset
     10:boolean/raw <- equal s1:address:array:character, s3:address:array:character
-    11:number/raw <- get x:address:buffer/deref, length:offset
-    12:array:character/raw <- copy s3:address:array:character/deref
+    11:number/raw <- get x:address:buffer/lookup, length:offset
+    12:array:character/raw <- copy s3:address:array:character/lookup
   ]
   memory-should-contain [
     # before +buffer-filled
@@ -227,7 +227,7 @@ scenario buffer-append-handles-backspace [
     x:address:buffer <- buffer-append x:address:buffer, 98  # 'b'
     x:address:buffer <- buffer-append x:address:buffer, 8/backspace
     s:address:array:character <- buffer-to-array x:address:buffer
-    1:array:character/raw <- copy s:address:array:character/deref
+    1:array:character/raw <- copy s:address:array:character/lookup
   ]
   memory-should-contain [
     1 <- 1   # length
@@ -271,8 +271,8 @@ recipe integer-to-decimal-string [
     tmp:address:buffer <- buffer-append tmp:address:buffer, 45  # '-'
   }
   # reverse buffer into string result
-  len:number <- get tmp:address:buffer/deref, length:offset
-  buf:address:array:character <- get tmp:address:buffer/deref, data:offset
+  len:number <- get tmp:address:buffer/lookup, length:offset
+  buf:address:array:character <- get tmp:address:buffer/lookup, data:offset
   result:address:array:character <- new character:type, len:number
   i:number <- subtract len:number, 1
   j:number <- copy 0
@@ -281,9 +281,9 @@ recipe integer-to-decimal-string [
     done?:boolean <- lesser-than i:number, 0
     break-if done?:boolean
     # result[j] = tmp[i]
-    src:character <- index buf:address:array:character/deref, i:number
-    dest:address:character <- index-address result:address:array:character/deref, j:number
-    dest:address:character/deref <- copy src:character
+    src:character <- index buf:address:array:character/lookup, i:number
+    dest:address:character <- index-address result:address:array:character/lookup, j:number
+    dest:address:character/lookup <- copy src:character
     # ++i
     i:number <- subtract i:number, 1
     # --j
@@ -301,9 +301,9 @@ recipe buffer-to-array [
     break-if in:address:buffer
     reply 0
   }
-  len:number <- get in:address:buffer/deref, length:offset
+  len:number <- get in:address:buffer/lookup, length:offset
 #?   $print [size ], len:number, 10/newline
-  s:address:array:character <- get in:address:buffer/deref, data:offset
+  s:address:array:character <- get in:address:buffer/lookup, data:offset
   # we can't just return s because it is usually the wrong length
   result:address:array:character <- new character:type, len:number
   i:number <- copy 0
@@ -311,9 +311,9 @@ recipe buffer-to-array [
 #?     $print i:number #? 1
     done?:boolean <- greater-or-equal i:number, len:number
     break-if done?:boolean
-    src:character <- index s:address:array:character/deref, i:number
-    dest:address:character <- index-address result:address:array:character/deref, i:number
-    dest:address:character/deref <- copy src:character
+    src:character <- index s:address:array:character/lookup, i:number
+    dest:address:character <- index-address result:address:array:character/lookup, i:number
+    dest:address:character/lookup <- copy src:character
     i:number <- add i:number, 1
     loop
   }
@@ -323,7 +323,7 @@ recipe buffer-to-array [
 scenario integer-to-decimal-digit-zero [
   run [
     1:address:array:character/raw <- integer-to-decimal-string 0
-    2:array:character/raw <- copy 1:address:array:character/deref/raw
+    2:array:character/raw <- copy 1:address:array:character/lookup/raw
   ]
   memory-should-contain [
     2:string <- [0]
@@ -333,7 +333,7 @@ scenario integer-to-decimal-digit-zero [
 scenario integer-to-decimal-digit-positive [
   run [
     1:address:array:character/raw <- integer-to-decimal-string 234
-    2:array:character/raw <- copy 1:address:array:character/deref/raw
+    2:array:character/raw <- copy 1:address:array:character/lookup/raw
   ]
   memory-should-contain [
     2:string <- [234]
@@ -343,7 +343,7 @@ scenario integer-to-decimal-digit-positive [
 scenario integer-to-decimal-digit-negative [
   run [
     1:address:array:character/raw <- integer-to-decimal-string -1
-    2:array:character/raw <- copy 1:address:array:character/deref/raw
+    2:array:character/raw <- copy 1:address:array:character/lookup/raw
   ]
   memory-should-contain [
     2 <- 2
@@ -357,9 +357,9 @@ recipe string-append [
   local-scope
   # result = new character[a.length + b.length]
   a:address:array:character <- next-ingredient
-  a-len:number <- length a:address:array:character/deref
+  a-len:number <- length a:address:array:character/lookup
   b:address:array:character <- next-ingredient
-  b-len:number <- length b:address:array:character/deref
+  b-len:number <- length b:address:array:character/lookup
   result-len:number <- add a-len:number, b-len:number
   result:address:array:character <- new character:type, result-len:number
   # copy a into result
@@ -370,9 +370,9 @@ recipe string-append [
     a-done?:boolean <- greater-or-equal i:number, a-len:number
     break-if a-done?:boolean
     # result[result-idx] = a[i]
-    out:address:character <- index-address result:address:array:character/deref, result-idx:number
-    in:character <- index a:address:array:character/deref, i:number
-    out:address:character/deref <- copy in:character
+    out:address:character <- index-address result:address:array:character/lookup, result-idx:number
+    in:character <- index a:address:array:character/lookup, i:number
+    out:address:character/lookup <- copy in:character
     # ++i
     i:number <- add i:number, 1
     # ++result-idx
@@ -386,9 +386,9 @@ recipe string-append [
     b-done?:boolean <- greater-or-equal i:number, b-len:number
     break-if b-done?:boolean
     # result[result-idx] = a[i]
-    out:address:character <- index-address result:address:array:character/deref, result-idx:number
-    in:character <- index b:address:array:character/deref, i:number
-    out:address:character/deref <- copy in:character
+    out:address:character <- index-address result:address:array:character/lookup, result-idx:number
+    in:character <- index b:address:array:character/lookup, i:number
+    out:address:character/lookup <- copy in:character
     # ++i
     i:number <- add i:number, 1
     # ++result-idx
@@ -403,7 +403,7 @@ scenario string-append-1 [
     1:address:array:character/raw <- new [hello,]
     2:address:array:character/raw <- new [ world!]
     3:address:array:character/raw <- string-append 1:address:array:character/raw, 2:address:array:character/raw
-    4:array:character/raw <- copy 3:address:array:character/raw/deref
+    4:array:character/raw <- copy 3:address:array:character/raw/lookup
   ]
   memory-should-contain [
     4:string <- [hello, world!]
@@ -416,14 +416,14 @@ recipe interpolate [
   local-scope
   template:address:array:character <- next-ingredient
   # compute result-len, space to allocate for result
-  tem-len:number <- length template:address:array:character/deref
+  tem-len:number <- length template:address:array:character/lookup
   result-len:number <- copy tem-len:number
   {
     # while arg received
     a:address:array:character, arg-received?:boolean <- next-ingredient
     break-unless arg-received?:boolean
     # result-len = result-len + arg.length - 1 for the 'underscore' being replaced
-    a-len:number <- length a:address:array:character/deref
+    a-len:number <- length a:address:array:character/lookup
     result-len:number <- add result-len:number, a-len:number
     result-len:number <- subtract result-len:number, 1
     loop
@@ -446,12 +446,12 @@ recipe interpolate [
       tem-done?:boolean <- greater-or-equal i:number, tem-len:number
       break-if tem-done?:boolean, +done:label
       # while template[i] != '_'
-      in:character <- index template:address:array:character/deref, i:number
+      in:character <- index template:address:array:character/lookup, i:number
       underscore?:boolean <- equal in:character, 95  # '_'
       break-if underscore?:boolean
       # result[result-idx] = template[i]
-      out:address:character <- index-address result:address:array:character/deref, result-idx:number
-      out:address:character/deref <- copy in:character
+      out:address:character <- index-address result:address:array:character/lookup, result-idx:number
+      out:address:character/lookup <- copy in:character
       # ++i
       i:number <- add i:number, 1
       # ++result-idx
@@ -465,9 +465,9 @@ recipe interpolate [
       arg-done?:boolean <- greater-or-equal j:number, a-len:number
       break-if arg-done?:boolean
       # result[result-idx] = a[j]
-      in:character <- index a:address:array:character/deref, j:number
-      out:address:character <- index-address result:address:array:character/deref, result-idx:number
-      out:address:character/deref <- copy in:character
+      in:character <- index a:address:array:character/lookup, j:number
+      out:address:character <- index-address result:address:array:character/lookup, result-idx:number
+      out:address:character/lookup <- copy in:character
       # ++j
       j:number <- add j:number, 1
       # ++result-idx
@@ -485,9 +485,9 @@ recipe interpolate [
     tem-done?:boolean <- greater-or-equal i:number, tem-len:number
     break-if tem-done?:boolean
     # result[result-idx] = template[i]
-    in:character <- index template:address:array:character/deref, i:number
-    out:address:character <- index-address result:address:array:character/deref, result-idx:number
-    out:address:character/deref <- copy in:character
+    in:character <- index template:address:array:character/lookup, i:number
+    out:address:character <- index-address result:address:array:character/lookup, result-idx:number
+    out:address:character/lookup <- copy in:character
     # ++i
     i:number <- add i:number, 1
     # ++result-idx
@@ -503,7 +503,7 @@ scenario interpolate-works [
     1:address:array:character/raw <- new [abc _]
     2:address:array:character/raw <- new [def]
     3:address:array:character/raw <- interpolate 1:address:array:character/raw, 2:address:array:character/raw
-    4:array:character/raw <- copy 3:address:array:character/raw/deref
+    4:array:character/raw <- copy 3:address:array:character/raw/lookup
   ]
   memory-should-contain [
     4:string <- [abc def]
@@ -515,7 +515,7 @@ scenario interpolate-at-start [
     1:address:array:character/raw <- new [_, hello!]
     2:address:array:character/raw <- new [abc]
     3:address:array:character/raw <- interpolate 1:address:array:character/raw, 2:address:array:character/raw
-    4:array:character/raw <- copy 3:address:array:character/raw/deref
+    4:array:character/raw <- copy 3:address:array:character/raw/lookup
   ]
   memory-should-contain [
     4:string <- [abc, hello!]
@@ -528,7 +528,7 @@ scenario interpolate-at-end [
     1:address:array:character/raw <- new [hello, _]
     2:address:array:character/raw <- new [abc]
     3:address:array:character/raw <- interpolate 1:address:array:character/raw, 2:address:array:character/raw
-    4:array:character/raw <- copy 3:address:array:character/raw/deref
+    4:array:character/raw <- copy 3:address:array:character/raw/lookup
   ]
   memory-should-contain [
     4:string <- [hello, abc]
@@ -604,7 +604,7 @@ recipe space? [
 recipe trim [
   local-scope
   s:address:array:character <- next-ingredient
-  len:number <- length s:address:array:character/deref
+  len:number <- length s:address:array:character/lookup
   # left trim: compute start
   start:number <- copy 0
   {
@@ -614,7 +614,7 @@ recipe trim [
       result:address:array:character <- new character:type, 0
       reply result:address:array:character
     }
-    curr:character <- index s:address:array:character/deref, start:number
+    curr:character <- index s:address:array:character/lookup, start:number
     whitespace?:boolean <- space? curr:character
     break-unless whitespace?:boolean
     start:number <- add start:number, 1
@@ -625,7 +625,7 @@ recipe trim [
   {
     not-at-start?:boolean <- greater-than end:number, start:number
     assert not-at-start?:boolean [end ran up against start]
-    curr:character <- index s:address:array:character/deref, end:number
+    curr:character <- index s:address:array:character/lookup, end:number
     whitespace?:boolean <- space? curr:character
     break-unless whitespace?:boolean
     end:number <- subtract end:number, 1
@@ -642,9 +642,9 @@ recipe trim [
     done?:boolean <- greater-than i:number, end:number
     break-if done?:boolean
     # result[j] = s[i]
-    src:character <- index s:address:array:character/deref, i:number
-    dest:address:character <- index-address result:address:array:character/deref, j:number
-    dest:address:character/deref <- copy src:character
+    src:character <- index s:address:array:character/lookup, i:number
+    dest:address:character <- index-address result:address:array:character/lookup, j:number
+    dest:address:character/lookup <- copy src:character
     # ++i, ++j
     i:number <- add i:number, 1
     j:number <- add j:number, 1
@@ -657,7 +657,7 @@ scenario trim-unmodified [
   run [
     1:address:array:character <- new [abc]
     2:address:array:character <- trim 1:address:array:character
-    3:array:character <- copy 2:address:array:character/deref
+    3:array:character <- copy 2:address:array:character/lookup
   ]
   memory-should-contain [
     3:string <- [abc]
@@ -668,7 +668,7 @@ scenario trim-left [
   run [
     1:address:array:character <- new [  abc]
     2:address:array:character <- trim 1:address:array:character
-    3:array:character <- copy 2:address:array:character/deref
+    3:array:character <- copy 2:address:array:character/lookup
   ]
   memory-should-contain [
     3:string <- [abc]
@@ -679,7 +679,7 @@ scenario trim-right [
   run [
     1:address:array:character <- new [abc  ]
     2:address:array:character <- trim 1:address:array:character
-    3:array:character <- copy 2:address:array:character/deref
+    3:array:character <- copy 2:address:array:character/lookup
   ]
   memory-should-contain [
     3:string <- [abc]
@@ -690,7 +690,7 @@ scenario trim-left-right [
   run [
     1:address:array:character <- new [  abc   ]
     2:address:array:character <- trim 1:address:array:character
-    3:array:character <- copy 2:address:array:character/deref
+    3:array:character <- copy 2:address:array:character/lookup
   ]
   memory-should-contain [
     3:string <- [abc]
@@ -702,7 +702,7 @@ scenario trim-newline-tab [
     1:address:array:character <- new [	abc
 ]
     2:address:array:character <- trim 1:address:array:character
-    3:array:character <- copy 2:address:array:character/deref
+    3:array:character <- copy 2:address:array:character/lookup
   ]
   memory-should-contain [
     3:string <- [abc]
@@ -715,11 +715,11 @@ recipe find-next [
   text:address:array:character <- next-ingredient
   pattern:character <- next-ingredient
   idx:number <- next-ingredient
-  len:number <- length text:address:array:character/deref
+  len:number <- length text:address:array:character/lookup
   {
     eof?:boolean <- greater-or-equal idx:number, len:number
     break-if eof?:boolean
-    curr:character <- index text:address:array:character/deref, idx:number
+    curr:character <- index text:address:array:character/lookup, idx:number
     found?:boolean <- equal curr:character, pattern:character
     break-if found?:boolean
     idx:number <- add idx:number, 1
@@ -815,9 +815,9 @@ recipe find-substring [
   text:address:array:character <- next-ingredient
   pattern:address:array:character <- next-ingredient
   idx:number <- next-ingredient
-  first:character <- index pattern:address:array:character/deref, 0
+  first:character <- index pattern:address:array:character/lookup, 0
   # repeatedly check for match at current idx
-  len:number <- length text:address:array:character/deref
+  len:number <- length text:address:array:character/lookup
   {
     # does some unnecessary work checking for substrings even when there isn't enough of text left
     done?:boolean <- greater-or-equal idx:number, len:number
@@ -894,10 +894,10 @@ recipe match-at [
   text:address:array:character <- next-ingredient
   pattern:address:array:character <- next-ingredient
   idx:number <- next-ingredient
-  pattern-len:number <- length pattern:address:array:character/deref
+  pattern-len:number <- length pattern:address:array:character/lookup
   # check that there's space left for the pattern
   {
-    x:number <- length text:address:array:character/deref
+    x:number <- length text:address:array:character/lookup
     x:number <- subtract x:number, pattern-len:number
     enough-room?:boolean <- lesser-or-equal idx:number, x:number
     break-if enough-room?:boolean
@@ -908,8 +908,8 @@ recipe match-at [
   {
     done?:boolean <- greater-or-equal pattern-idx:number, pattern-len:number
     break-if done?:boolean
-    c:character <- index text:address:array:character/deref, idx:number
-    exp:character <- index pattern:address:array:character/deref, pattern-idx:number
+    c:character <- index text:address:array:character/lookup, idx:number
+    exp:character <- index pattern:address:array:character/lookup, pattern-idx:number
     {
       match?:boolean <- equal c:character, exp:character
       break-if match?:boolean
@@ -1025,7 +1025,7 @@ recipe split [
   s:address:array:character <- next-ingredient
   delim:character <- next-ingredient
   # empty string? return empty array
-  len:number <- length s:address:array:character/deref
+  len:number <- length s:address:array:character/lookup
   {
     empty?:boolean <- equal len:number, 0
     break-unless empty?:boolean
@@ -1054,8 +1054,8 @@ recipe split [
     break-if done?:boolean
     end:number <- find-next s:address:array:character, delim:character, start:number
     # copy start..end into result[curr-result]
-    dest:address:address:array:character <- index-address result:address:array:address:array:character/deref, curr-result:number
-    dest:address:address:array:character/deref <- string-copy s:address:array:character, start:number, end:number
+    dest:address:address:array:character <- index-address result:address:array:address:array:character/lookup, curr-result:number
+    dest:address:address:array:character/lookup <- string-copy s:address:array:character, start:number, end:number
     # slide over to next slice
     start:number <- add end:number, 1
     curr-result:number <- add curr-result:number, 1
@@ -1068,11 +1068,11 @@ scenario string-split-1 [
   run [
     1:address:array:character <- new [a/b]
     2:address:array:address:array:character <- split 1:address:array:character, 47/slash
-    3:number <- length 2:address:array:address:array:character/deref
-    4:address:array:character <- index 2:address:array:address:array:character/deref, 0
-    5:address:array:character <- index 2:address:array:address:array:character/deref, 1
-    10:array:character <- copy 4:address:array:character/deref
-    20:array:character <- copy 5:address:array:character/deref
+    3:number <- length 2:address:array:address:array:character/lookup
+    4:address:array:character <- index 2:address:array:address:array:character/lookup, 0
+    5:address:array:character <- index 2:address:array:address:array:character/lookup, 1
+    10:array:character <- copy 4:address:array:character/lookup
+    20:array:character <- copy 5:address:array:character/lookup
   ]
   memory-should-contain [
     3 <- 2  # length of result
@@ -1085,13 +1085,13 @@ scenario string-split-2 [
   run [
     1:address:array:character <- new [a/b/c]
     2:address:array:address:array:character <- split 1:address:array:character, 47/slash
-    3:number <- length 2:address:array:address:array:character/deref
-    4:address:array:character <- index 2:address:array:address:array:character/deref, 0
-    5:address:array:character <- index 2:address:array:address:array:character/deref, 1
-    6:address:array:character <- index 2:address:array:address:array:character/deref, 2
-    10:array:character <- copy 4:address:array:character/deref
-    20:array:character <- copy 5:address:array:character/deref
-    30:array:character <- copy 6:address:array:character/deref
+    3:number <- length 2:address:array:address:array:character/lookup
+    4:address:array:character <- index 2:address:array:address:array:character/lookup, 0
+    5:address:array:character <- index 2:address:array:address:array:character/lookup, 1
+    6:address:array:character <- index 2:address:array:address:array:character/lookup, 2
+    10:array:character <- copy 4:address:array:character/lookup
+    20:array:character <- copy 5:address:array:character/lookup
+    30:array:character <- copy 6:address:array:character/lookup
   ]
   memory-should-contain [
     3 <- 3  # length of result
@@ -1105,9 +1105,9 @@ scenario string-split-missing [
   run [
     1:address:array:character <- new [abc]
     2:address:array:address:array:character <- split 1:address:array:character, 47/slash
-    3:number <- length 2:address:array:address:array:character/deref
-    4:address:array:character <- index 2:address:array:address:array:character/deref, 0
-    10:array:character <- copy 4:address:array:character/deref
+    3:number <- length 2:address:array:address:array:character/lookup
+    4:address:array:character <- index 2:address:array:address:array:character/lookup, 0
+    10:array:character <- copy 4:address:array:character/lookup
   ]
   memory-should-contain [
     3 <- 1  # length of result
@@ -1119,7 +1119,7 @@ scenario string-split-empty [
   run [
     1:address:array:character <- new []
     2:address:array:address:array:character <- split 1:address:array:character, 47/slash
-    3:number <- length 2:address:array:address:array:character/deref
+    3:number <- length 2:address:array:address:array:character/lookup
   ]
   memory-should-contain [
     3 <- 0  # empty result
@@ -1130,15 +1130,15 @@ scenario string-split-empty-piece [
   run [
     1:address:array:character <- new [a/b//c]
     2:address:array:address:array:character <- split 1:address:array:character, 47/slash
-    3:number <- length 2:address:array:address:array:character/deref
-    4:address:array:character <- index 2:address:array:address:array:character/deref, 0
-    5:address:array:character <- index 2:address:array:address:array:character/deref, 1
-    6:address:array:character <- index 2:address:array:address:array:character/deref, 2
-    7:address:array:character <- index 2:address:array:address:array:character/deref, 3
-    10:array:character <- copy 4:address:array:character/deref
-    20:array:character <- copy 5:address:array:character/deref
-    30:array:character <- copy 6:address:array:character/deref
-    40:array:character <- copy 7:address:array:character/deref
+    3:number <- length 2:address:array:address:array:character/lookup
+    4:address:array:character <- index 2:address:array:address:array:character/lookup, 0
+    5:address:array:character <- index 2:address:array:address:array:character/lookup, 1
+    6:address:array:character <- index 2:address:array:address:array:character/lookup, 2
+    7:address:array:character <- index 2:address:array:address:array:character/lookup, 3
+    10:array:character <- copy 4:address:array:character/lookup
+    20:array:character <- copy 5:address:array:character/lookup
+    30:array:character <- copy 6:address:array:character/lookup
+    40:array:character <- copy 7:address:array:character/lookup
   ]
   memory-should-contain [
     3 <- 4  # length of result
@@ -1155,7 +1155,7 @@ recipe split-first [
   text:address:array:character <- next-ingredient
   delim:character <- next-ingredient
   # empty string? return empty strings
-  len:number <- length text:address:array:character/deref
+  len:number <- length text:address:array:character/lookup
   {
     empty?:boolean <- equal len:number, 0
     break-unless empty?:boolean
@@ -1174,8 +1174,8 @@ scenario string-split-first [
   run [
     1:address:array:character <- new [a/b]
     2:address:array:character, 3:address:array:character <- split-first 1:address:array:character, 47/slash
-    10:array:character <- copy 2:address:array:character/deref
-    20:array:character <- copy 3:address:array:character/deref
+    10:array:character <- copy 2:address:array:character/lookup
+    20:array:character <- copy 3:address:array:character/lookup
   ]
   memory-should-contain [
     10:string <- [a]
@@ -1191,7 +1191,7 @@ recipe string-copy [
   start:number <- next-ingredient
   end:number <- next-ingredient
   # if end is out of bounds, trim it
-  len:number <- length buf:address:array:character/deref
+  len:number <- length buf:address:array:character/lookup
   end:number <- min len:number, end:number
   # allocate space for result
   len:number <- subtract end:number, start:number
@@ -1202,9 +1202,9 @@ recipe string-copy [
   {
     done?:boolean <- greater-or-equal src-idx:number, end:number
     break-if done?:boolean
-    src:character <- index buf:address:array:character/deref, src-idx:number
-    dest:address:character <- index-address result:address:array:character/deref, dest-idx:number
-    dest:address:character/deref <- copy src:character
+    src:character <- index buf:address:array:character/lookup, src-idx:number
+    dest:address:character <- index-address result:address:array:character/lookup, dest-idx:number
+    dest:address:character/lookup <- copy src:character
     src-idx:number <- add src-idx:number, 1
     dest-idx:number <- add dest-idx:number, 1
     loop
@@ -1216,7 +1216,7 @@ scenario string-copy-copies-substring [
   run [
     1:address:array:character <- new [abc]
     2:address:array:character <- string-copy 1:address:array:character, 1, 3
-    3:array:character <- copy 2:address:array:character/deref
+    3:array:character <- copy 2:address:array:character/lookup
   ]
   memory-should-contain [
     3:string <- [bc]
@@ -1227,7 +1227,7 @@ scenario string-copy-out-of-bounds [
   run [
     1:address:array:character <- new [abc]
     2:address:array:character <- string-copy 1:address:array:character, 2, 4
-    3:array:character <- copy 2:address:array:character/deref
+    3:array:character <- copy 2:address:array:character/lookup
   ]
   memory-should-contain [
     3:string <- [c]
@@ -1238,7 +1238,7 @@ scenario string-copy-out-of-bounds-2 [
   run [
     1:address:array:character <- new [abc]
     2:address:array:character <- string-copy 1:address:array:character, 3, 3
-    3:array:character <- copy 2:address:array:character/deref
+    3:array:character <- copy 2:address:array:character/lookup
   ]
   memory-should-contain [
     3:string <- []
diff --git a/061channel.mu b/061channel.mu
index d1f4c55d..302e93c2 100644
--- a/061channel.mu
+++ b/061channel.mu
@@ -37,16 +37,16 @@ recipe new-channel [
   # result = new channel
   result:address:channel <- new channel:type
   # result.first-full = 0
-  full:address:number <- get-address result:address:channel/deref, first-full:offset
-  full:address:number/deref <- copy 0
+  full:address:number <- get-address result:address:channel/lookup, first-full:offset
+  full:address:number/lookup <- copy 0
   # result.first-free = 0
-  free:address:number <- get-address result:address:channel/deref, first-free:offset
-  free:address:number/deref <- copy 0
+  free:address:number <- get-address result:address:channel/lookup, first-free:offset
+  free:address:number/lookup <- copy 0
   # result.data = new location[ingredient+1]
   capacity:number <- next-ingredient
   capacity:number <- add capacity:number, 1  # unused slot for 'full?' below
-  dest:address:address:array:location <- get-address result:address:channel/deref, data:offset
-  dest:address:address:array:location/deref <- new location:type, capacity:number
+  dest:address:address:array:location <- get-address result:address:channel/lookup, data:offset
+  dest:address:address:array:location/lookup <- new location:type, capacity:number
   reply result:address:channel
 ]
 
@@ -59,22 +59,22 @@ recipe write [
     # block if chan is full
     full:boolean <- channel-full? chan:address:channel
     break-unless full:boolean
-    full-address:address:number <- get-address chan:address:channel/deref, first-full:offset
-    wait-for-location full-address:address:number/deref
+    full-address:address:number <- get-address chan:address:channel/lookup, first-full:offset
+    wait-for-location full-address:address:number/lookup
   }
   # store val
-  circular-buffer:address:array:location <- get chan:address:channel/deref, data:offset
-  free:address:number <- get-address chan:address:channel/deref, first-free:offset
-  dest:address:location <- index-address circular-buffer:address:array:location/deref, free:address:number/deref
-  dest:address:location/deref <- copy val:location
+  circular-buffer:address:array:location <- get chan:address:channel/lookup, data:offset
+  free:address:number <- get-address chan:address:channel/lookup, first-free:offset
+  dest:address:location <- index-address circular-buffer:address:array:location/lookup, free:address:number/lookup
+  dest:address:location/lookup <- copy val:location
   # increment free
-  free:address:number/deref <- add free:address:number/deref, 1
+  free:address:number/lookup <- add free:address:number/lookup, 1
   {
     # wrap free around to 0 if necessary
-    len:number <- length circular-buffer:address:array:location/deref
-    at-end?:boolean <- greater-or-equal free:address:number/deref, len:number
+    len:number <- length circular-buffer:address:array:location/lookup
+    at-end?:boolean <- greater-or-equal free:address:number/lookup, len:number
     break-unless at-end?:boolean
-    free:address:number/deref <- copy 0
+    free:address:number/lookup <- copy 0
   }
   reply chan:address:channel/same-as-ingredient:0
 ]
@@ -87,21 +87,21 @@ recipe read [
     # block if chan is empty
     empty:boolean <- channel-empty? chan:address:channel
     break-unless empty:boolean
-    free-address:address:number <- get-address chan:address:channel/deref, first-free:offset
-    wait-for-location free-address:address:number/deref
+    free-address:address:number <- get-address chan:address:channel/lookup, first-free:offset
+    wait-for-location free-address:address:number/lookup
   }
   # read result
-  full:address:number <- get-address chan:address:channel/deref, first-full:offset
-  circular-buffer:address:array:location <- get chan:address:channel/deref, data:offset
-  result:location <- index circular-buffer:address:array:location/deref, full:address:number/deref
+  full:address:number <- get-address chan:address:channel/lookup, first-full:offset
+  circular-buffer:address:array:location <- get chan:address:channel/lookup, data:offset
+  result:location <- index circular-buffer:address:array:location/lookup, full:address:number/lookup
   # increment full
-  full:address:number/deref <- add full:address:number/deref, 1
+  full:address:number/lookup <- add full:address:number/lookup, 1
   {
     # wrap full around to 0 if necessary
-    len:number <- length circular-buffer:address:array:location/deref
-    at-end?:boolean <- greater-or-equal full:address:number/deref, len:number
+    len:number <- length circular-buffer:address:array:location/lookup
+    at-end?:boolean <- greater-or-equal full:address:number/lookup, len:number
     break-unless at-end?:boolean
-    full:address:number/deref <- copy 0
+    full:address:number/lookup <- copy 0
   }
   reply result:location, chan:address:channel/same-as-ingredient:0
 ]
@@ -120,8 +120,8 @@ recipe clear-channel [
 scenario channel-initialization [
   run [
     1:address:channel <- new-channel 3/capacity
-    2:number <- get 1:address:channel/deref, first-full:offset
-    3:number <- get 1:address:channel/deref, first-free:offset
+    2:number <- get 1:address:channel/lookup, first-full:offset
+    3:number <- get 1:address:channel/lookup, first-free:offset
   ]
   memory-should-contain [
     2 <- 0  # first-full
@@ -133,8 +133,8 @@ scenario channel-write-increments-free [
   run [
     1:address:channel <- new-channel 3/capacity
     1:address:channel <- write 1:address:channel, 34
-    2:number <- get 1:address:channel/deref, first-full:offset
-    3:number <- get 1:address:channel/deref, first-free:offset
+    2:number <- get 1:address:channel/lookup, first-full:offset
+    3:number <- get 1:address:channel/lookup, first-free:offset
   ]
   memory-should-contain [
     2 <- 0  # first-full
@@ -147,8 +147,8 @@ scenario channel-read-increments-full [
     1:address:channel <- new-channel 3/capacity
     1:address:channel <- write 1:address:channel, 34
     _, 1:address:channel <- read 1:address:channel
-    2:number <- get 1:address:channel/deref, first-full:offset
-    3:number <- get 1:address:channel/deref, first-free:offset
+    2:number <- get 1:address:channel/lookup, first-full:offset
+    3:number <- get 1:address:channel/lookup, first-free:offset
   ]
   memory-should-contain [
     2 <- 1  # first-full
@@ -164,14 +164,14 @@ scenario channel-wrap [
     1:address:channel <- write 1:address:channel, 34
     _, 1:address:channel <- read 1:address:channel
     # first-free will now be 1
-    2:number <- get 1:address:channel/deref, first-free:offset
-    3:number <- get 1:address:channel/deref, first-free:offset
+    2:number <- get 1:address:channel/lookup, first-free:offset
+    3:number <- get 1:address:channel/lookup, first-free:offset
     # write second value, verify that first-free wraps
     1:address:channel <- write 1:address:channel, 34
-    4:number <- get 1:address:channel/deref, first-free:offset
+    4:number <- get 1:address:channel/lookup, first-free:offset
     # read second value, verify that first-full wraps
     _, 1:address:channel <- read 1:address:channel
-    5:number <- get 1:address:channel/deref, first-full:offset
+    5:number <- get 1:address:channel/lookup, first-full:offset
   ]
   memory-should-contain [
     2 <- 1  # first-free after first write
@@ -188,8 +188,8 @@ recipe channel-empty? [
   local-scope
   chan:address:channel <- next-ingredient
   # return chan.first-full == chan.first-free
-  full:number <- get chan:address:channel/deref, first-full:offset
-  free:number <- get chan:address:channel/deref, first-free:offset
+  full:number <- get chan:address:channel/lookup, first-full:offset
+  free:number <- get chan:address:channel/lookup, first-free:offset
   result:boolean <- equal full:number, free:number
   reply result:boolean
 ]
@@ -200,7 +200,7 @@ recipe channel-full? [
   local-scope
   chan:address:channel <- next-ingredient
   # tmp = chan.first-free + 1
-  tmp:number <- get chan:address:channel/deref, first-free:offset
+  tmp:number <- get chan:address:channel/lookup, first-free:offset
   tmp:number <- add tmp:number, 1
   {
     # if tmp == chan.capacity, tmp = 0
@@ -210,7 +210,7 @@ recipe channel-full? [
     tmp:number <- copy 0
   }
   # return chan.first-full == tmp
-  full:number <- get chan:address:channel/deref, first-full:offset
+  full:number <- get chan:address:channel/lookup, first-full:offset
   result:boolean <- equal full:number, tmp:number
   reply result:boolean
 ]
@@ -219,8 +219,8 @@ recipe channel-full? [
 recipe channel-capacity [
   local-scope
   chan:address:channel <- next-ingredient
-  q:address:array:location <- get chan:address:channel/deref, data:offset
-  result:number <- length q:address:array:location/deref
+  q:address:array:location <- get chan:address:channel/lookup, data:offset
+  result:number <- length q:address:array:location/lookup
   reply result:number
 ]
 
@@ -301,12 +301,12 @@ recipe buffer-lines [
 #?         $print [backspace!
 #? ] #? 1
         {
-          buffer-length:address:number <- get-address line:address:buffer/deref, length:offset
-          buffer-empty?:boolean <- equal buffer-length:address:number/deref, 0
+          buffer-length:address:number <- get-address line:address:buffer/lookup, length:offset
+          buffer-empty?:boolean <- equal buffer-length:address:number/lookup, 0
           break-if buffer-empty?:boolean
-#?           $print [before: ], buffer-length:address:number/deref, 10/newline
-          buffer-length:address:number/deref <- subtract buffer-length:address:number/deref, 1
-#?           $print [after: ], buffer-length:address:number/deref, 10/newline
+#?           $print [before: ], buffer-length:address:number/lookup, 10/newline
+          buffer-length:address:number/lookup <- subtract buffer-length:address:number/lookup, 1
+#?           $print [after: ], buffer-length:address:number/lookup, 10/newline
         }
 #?         $exit #? 2
         # and don't append this one
@@ -327,12 +327,12 @@ recipe buffer-lines [
 #?     $print [buffer-lines: emitting
 #? ]
     i:number <- copy 0
-    line-contents:address:array:character <- get line:address:buffer/deref, data:offset
-    max:number <- get line:address:buffer/deref, length:offset
+    line-contents:address:array:character <- get line:address:buffer/lookup, data:offset
+    max:number <- get line:address:buffer/lookup, length:offset
     {
       done?:boolean <- greater-or-equal i:number, max:number
       break-if done?:boolean
-      c:character <- index line-contents:address:array:character/deref, i:number
+      c:character <- index line-contents:address:array:character/lookup, i:number
       out:address:channel <- write out:address:channel, c:character
 #?       $print [writing ], i:number, [: ], c:character, 10/newline
       i:number <- add i:number, 1
diff --git a/062array.mu b/062array.mu
index e0b72593..dff9d319 100644
--- a/062array.mu
+++ b/062array.mu
@@ -1,7 +1,7 @@
 scenario array-from-args [
   run [
     1:address:array:location <- new-array 0, 1, 2
-    2:array:location <- copy 1:address:array:location/deref
+    2:array:location <- copy 1:address:array:location/lookup
   ]
   memory-should-contain [
     2 <- 3  # array length
@@ -31,8 +31,8 @@ recipe new-array [
     break-if done?:boolean
     curr-value:location, exists?:boolean <- next-ingredient
     assert exists?:boolean, [error in rewinding ingredients to new-array]
-    tmp:address:location <- index-address result:address:array:location/deref, i:number
-    tmp:address:location/deref <- copy curr-value:location
+    tmp:address:location <- index-address result:address:array:location/lookup, i:number
+    tmp:address:location/lookup <- copy curr-value:location
     i:number <- add i:number, 1
     loop
   }
diff --git a/063list.mu b/063list.mu
index fce02c8d..51a33337 100644
--- a/063list.mu
+++ b/063list.mu
@@ -14,10 +14,10 @@ recipe push [
   x:location <- next-ingredient
   in:address:list <- next-ingredient
   result:address:list <- new list:type
-  val:address:location <- get-address result:address:list/deref, value:offset
-  val:address:location/deref <- copy x:location
-  next:address:address:list <- get-address result:address:list/deref, next:offset
-  next:address:address:list/deref <- copy in:address:list
+  val:address:location <- get-address result:address:list/lookup, value:offset
+  val:address:location/lookup <- copy x:location
+  next:address:address:list <- get-address result:address:list/lookup, next:offset
+  next:address:address:list/lookup <- copy in:address:list
   reply result:address:list
 ]
 
@@ -25,7 +25,7 @@ recipe push [
 recipe first [
   local-scope
   in:address:list <- next-ingredient
-  result:location <- get in:address:list/deref, value:offset
+  result:location <- get in:address:list/lookup, value:offset
   reply result:location
 ]
 
@@ -33,7 +33,7 @@ recipe first [
 recipe rest [
   local-scope
   in:address:list <- next-ingredient
-  result:address:list <- get in:address:list/deref, next:offset
+  result:address:list <- get in:address:list/lookup, next:offset
   reply result:address:list
 ]
 
diff --git a/065duplex_list.mu b/065duplex_list.mu
index b1bfb7a8..ba25e303 100644
--- a/065duplex_list.mu
+++ b/065duplex_list.mu
@@ -12,13 +12,13 @@ recipe push-duplex [
   x:location <- next-ingredient
   in:address:duplex-list <- next-ingredient
   result:address:duplex-list <- new duplex-list:type
-  val:address:location <- get-address result:address:duplex-list/deref, value:offset
-  val:address:location/deref <- copy x:location
-  next:address:address:duplex-list <- get-address result:address:duplex-list/deref, next:offset
-  next:address:address:duplex-list/deref <- copy in:address:duplex-list
+  val:address:location <- get-address result:address:duplex-list/lookup, value:offset
+  val:address:location/lookup <- copy x:location
+  next:address:address:duplex-list <- get-address result:address:duplex-list/lookup, next:offset
+  next:address:address:duplex-list/lookup <- copy in:address:duplex-list
   reply-unless in:address:duplex-list, result:address:duplex-list
-  prev:address:address:duplex-list <- get-address in:address:duplex-list/deref, prev:offset
-  prev:address:address:duplex-list/deref <- copy result:address:duplex-list
+  prev:address:address:duplex-list <- get-address in:address:duplex-list/lookup, prev:offset
+  prev:address:address:duplex-list/lookup <- copy result:address:duplex-list
   reply result:address:duplex-list
 ]
 
@@ -27,7 +27,7 @@ recipe first-duplex [
   local-scope
   in:address:duplex-list <- next-ingredient
   reply-unless in:address:duplex-list, 0
-  result:location <- get in:address:duplex-list/deref, value:offset
+  result:location <- get in:address:duplex-list/lookup, value:offset
   reply result:location
 ]
 
@@ -36,7 +36,7 @@ recipe next-duplex [
   local-scope
   in:address:duplex-list <- next-ingredient
   reply-unless in:address:duplex-list, 0
-  result:address:duplex-list <- get in:address:duplex-list/deref, next:offset
+  result:address:duplex-list <- get in:address:duplex-list/lookup, next:offset
   reply result:address:duplex-list
 ]
 
@@ -45,7 +45,7 @@ recipe prev-duplex [
   local-scope
   in:address:duplex-list <- next-ingredient
   reply-unless in:address:duplex-list, 0
-  result:address:duplex-list <- get in:address:duplex-list/deref, prev:offset
+  result:address:duplex-list <- get in:address:duplex-list/lookup, prev:offset
   reply result:address:duplex-list
 ]
 
@@ -99,23 +99,23 @@ recipe insert-duplex [
   x:location <- next-ingredient
   in:address:duplex-list <- next-ingredient
   new-node:address:duplex-list <- new duplex-list:type
-  val:address:location <- get-address new-node:address:duplex-list/deref, value:offset
-  val:address:location/deref <- copy x:location
-  next-node:address:duplex-list <- get in:address:duplex-list/deref, next:offset
+  val:address:location <- get-address new-node:address:duplex-list/lookup, value:offset
+  val:address:location/lookup <- copy x:location
+  next-node:address:duplex-list <- get in:address:duplex-list/lookup, next:offset
   # in.next = new-node
-  y:address:address:duplex-list <- get-address in:address:duplex-list/deref, next:offset
-  y:address:address:duplex-list/deref <- copy new-node:address:duplex-list
+  y:address:address:duplex-list <- get-address in:address:duplex-list/lookup, next:offset
+  y:address:address:duplex-list/lookup <- copy new-node:address:duplex-list
   # new-node.prev = in
-  y:address:address:duplex-list <- get-address new-node:address:duplex-list/deref, prev:offset
-  y:address:address:duplex-list/deref <- copy in:address:duplex-list
+  y:address:address:duplex-list <- get-address new-node:address:duplex-list/lookup, prev:offset
+  y:address:address:duplex-list/lookup <- copy in:address:duplex-list
   # new-node.next = next-node
-  y:address:address:duplex-list <- get-address new-node:address:duplex-list/deref, next:offset
-  y:address:address:duplex-list/deref <- copy next-node:address:duplex-list
+  y:address:address:duplex-list <- get-address new-node:address:duplex-list/lookup, next:offset
+  y:address:address:duplex-list/lookup <- copy next-node:address:duplex-list
   # if next-node is not null
   reply-unless next-node:address:duplex-list, new-node:address:duplex-list
   # next-node.prev = new-node
-  y:address:address:duplex-list <- get-address next-node:address:duplex-list/deref, prev:offset
-  y:address:address:duplex-list/deref <- copy new-node:address:duplex-list
+  y:address:address:duplex-list <- get-address next-node:address:duplex-list/lookup, prev:offset
+  y:address:address:duplex-list/lookup <- copy new-node:address:duplex-list
   reply new-node:address:duplex-list  # just signalling something changed; don't rely on the result
 ]
 
@@ -241,26 +241,26 @@ recipe remove-duplex [
   in:address:duplex-list <- next-ingredient
   # if 'in' is null, return
   reply-unless in:address:duplex-list, in:address:duplex-list
-  next-node:address:duplex-list <- get in:address:duplex-list/deref, next:offset
-  prev-node:address:duplex-list <- get in:address:duplex-list/deref, prev:offset
+  next-node:address:duplex-list <- get in:address:duplex-list/lookup, next:offset
+  prev-node:address:duplex-list <- get in:address:duplex-list/lookup, prev:offset
   # null in's pointers
-  x:address:address:duplex-list <- get-address in:address:duplex-list/deref, next:offset
-  x:address:address:duplex-list/deref <- copy 0
-  x:address:address:duplex-list <- get-address in:address:duplex-list/deref, prev:offset
-  x:address:address:duplex-list/deref <- copy 0
+  x:address:address:duplex-list <- get-address in:address:duplex-list/lookup, next:offset
+  x:address:address:duplex-list/lookup <- copy 0
+  x:address:address:duplex-list <- get-address in:address:duplex-list/lookup, prev:offset
+  x:address:address:duplex-list/lookup <- copy 0
   {
     # if next-node is not null
     break-unless next-node:address:duplex-list
     # next-node.prev = prev-node
-    x:address:address:duplex-list <- get-address next-node:address:duplex-list/deref, prev:offset
-    x:address:address:duplex-list/deref <- copy prev-node:address:duplex-list
+    x:address:address:duplex-list <- get-address next-node:address:duplex-list/lookup, prev:offset
+    x:address:address:duplex-list/lookup <- copy prev-node:address:duplex-list
   }
   {
     # if prev-node is not null
     break-unless prev-node:address:duplex-list
     # prev-node.next = next-node
-    x:address:address:duplex-list <- get-address prev-node:address:duplex-list/deref, next:offset
-    x:address:address:duplex-list/deref <- copy next-node:address:duplex-list
+    x:address:address:duplex-list <- get-address prev-node:address:duplex-list/lookup, next:offset
+    x:address:address:duplex-list/lookup <- copy next-node:address:duplex-list
     reply prev-node:address:duplex-list
   }
   reply next-node:address:duplex-list
@@ -358,8 +358,8 @@ scenario removing-from-singleton-list [
     1:address:duplex-list <- copy 0  # 1 points to singleton list
     1:address:duplex-list <- push-duplex 3, 1:address:duplex-list
     2:address:duplex-list <- remove-duplex 1:address:duplex-list
-    3:address:duplex-list <- get 1:address:duplex-list/deref, next:offset
-    4:address:duplex-list <- get 1:address:duplex-list/deref, prev:offset
+    3:address:duplex-list <- get 1:address:duplex-list/lookup, next:offset
+    4:address:duplex-list <- get 1:address:duplex-list/lookup, prev:offset
   ]
   memory-should-contain [
     2 <- 0  # remove returned null
diff --git a/066stream.mu b/066stream.mu
index 4c77319a..36c311c1 100644
--- a/066stream.mu
+++ b/066stream.mu
@@ -7,38 +7,38 @@ container stream [
 recipe new-stream [
   local-scope
   result:address:stream <- new stream:type
-  i:address:number <- get-address result:address:stream/deref, index:offset
-  i:address:number/deref <- copy 0
-  d:address:address:array:character <- get-address result:address:stream/deref, data:offset
-  d:address:address:array:character/deref <- next-ingredient
+  i:address:number <- get-address result:address:stream/lookup, index:offset
+  i:address:number/lookup <- copy 0
+  d:address:address:array:character <- get-address result:address:stream/lookup, data:offset
+  d:address:address:array:character/lookup <- next-ingredient
   reply result:address:stream
 ]
 
 recipe rewind-stream [
   local-scope
   in:address:stream <- next-ingredient
-  x:address:number <- get-address in:address:stream/deref, index:offset
-  x:address:number/deref <- copy 0
+  x:address:number <- get-address in:address:stream/lookup, index:offset
+  x:address:number/lookup <- copy 0
   reply in:address:stream/same-as-arg:0
 ]
 
 recipe read-line [
   local-scope
   in:address:stream <- next-ingredient
-  idx:address:number <- get-address in:address:stream/deref, index:offset
-  s:address:array:character <- get in:address:stream/deref, data:offset
-  next-idx:number <- find-next s:address:array:character, 10/newline, idx:address:number/deref
-  result:address:array:character <- string-copy s:address:array:character, idx:address:number/deref, next-idx:number
-  idx:address:number/deref <- add next-idx:number, 1  # skip newline
+  idx:address:number <- get-address in:address:stream/lookup, index:offset
+  s:address:array:character <- get in:address:stream/lookup, data:offset
+  next-idx:number <- find-next s:address:array:character, 10/newline, idx:address:number/lookup
+  result:address:array:character <- string-copy s:address:array:character, idx:address:number/lookup, next-idx:number
+  idx:address:number/lookup <- add next-idx:number, 1  # skip newline
   reply result:address:array:character
 ]
 
 recipe end-of-stream? [
   local-scope
   in:address:stream <- next-ingredient
-  idx:number <- get in:address:stream/deref, index:offset
-  s:address:array:character <- get in:address:stream/deref, data:offset
-  len:number <- length s:address:array:character/deref
+  idx:number <- get in:address:stream/lookup, index:offset
+  s:address:array:character <- get in:address:stream/lookup, data:offset
+  len:number <- length s:address:array:character/lookup
   result:boolean <- greater-or-equal idx:number, len:number
   reply result:boolean
 ]
diff --git a/071print.mu b/071print.mu
index a1c7b67d..e60de5f3 100644
--- a/071print.mu
+++ b/071print.mu
@@ -17,18 +17,18 @@ container screen-cell [
 recipe new-fake-screen [
   local-scope
   result:address:screen <- new screen:type
-  width:address:number <- get-address result:address:screen/deref, num-columns:offset
-  width:address:number/deref <- next-ingredient
-  height:address:number <- get-address result:address:screen/deref, num-rows:offset
-  height:address:number/deref <- next-ingredient
-#?   $print height:address:number/deref, 10/newline
-  row:address:number <- get-address result:address:screen/deref, cursor-row:offset
-  row:address:number/deref <- copy 0
-  column:address:number <- get-address result:address:screen/deref, cursor-column:offset
-  column:address:number/deref <- copy 0
-  bufsize:number <- multiply width:address:number/deref, height:address:number/deref
-  buf:address:address:array:screen-cell <- get-address result:address:screen/deref, data:offset
-  buf:address:address:array:screen-cell/deref <- new screen-cell:type, bufsize:number
+  width:address:number <- get-address result:address:screen/lookup, num-columns:offset
+  width:address:number/lookup <- next-ingredient
+  height:address:number <- get-address result:address:screen/lookup, num-rows:offset
+  height:address:number/lookup <- next-ingredient
+#?   $print height:address:number/lookup, 10/newline
+  row:address:number <- get-address result:address:screen/lookup, cursor-row:offset
+  row:address:number/lookup <- copy 0
+  column:address:number <- get-address result:address:screen/lookup, cursor-column:offset
+  column:address:number/lookup <- copy 0
+  bufsize:number <- multiply width:address:number/lookup, height:address:number/lookup
+  buf:address:address:array:screen-cell <- get-address result:address:screen/lookup, data:offset
+  buf:address:address:array:screen-cell/lookup <- new screen-cell:type, bufsize:number
   clear-screen result:address:screen
   reply result:address:screen
 ]
@@ -42,25 +42,25 @@ recipe clear-screen [
   {
     break-unless x:address:screen
     # clear fake screen
-    buf:address:array:screen-cell <- get x:address:screen/deref, data:offset
-    max:number <- length buf:address:array:screen-cell/deref
+    buf:address:array:screen-cell <- get x:address:screen/lookup, data:offset
+    max:number <- length buf:address:array:screen-cell/lookup
     i:number <- copy 0
     {
       done?:boolean <- greater-or-equal i:number, max:number
       break-if done?:boolean
-      curr:address:screen-cell <- index-address buf:address:array:screen-cell/deref, i:number
-      curr-content:address:character <- get-address curr:address:screen-cell/deref, contents:offset
-      curr-content:address:character/deref <- copy [ ]
-      curr-color:address:character <- get-address curr:address:screen-cell/deref, color:offset
-      curr-color:address:character/deref <- copy 7/white
+      curr:address:screen-cell <- index-address buf:address:array:screen-cell/lookup, i:number
+      curr-content:address:character <- get-address curr:address:screen-cell/lookup, contents:offset
+      curr-content:address:character/lookup <- copy [ ]
+      curr-color:address:character <- get-address curr:address:screen-cell/lookup, color:offset
+      curr-color:address:character/lookup <- copy 7/white
       i:number <- add i:number, 1
       loop
     }
     # reset cursor
-    cur:address:number <- get-address x:address:screen/deref, cursor-row:offset
-    cur:address:number/deref <- copy 0
-    cur:address:number <- get-address x:address:screen/deref, cursor-column:offset
-    cur:address:number/deref <- copy 0
+    cur:address:number <- get-address x:address:screen/lookup, cursor-row:offset
+    cur:address:number/lookup <- copy 0
+    cur:address:number <- get-address x:address:screen/lookup, cursor-column:offset
+    cur:address:number/lookup <- copy 0
     reply x:address:screen/same-as-ingredient:0
   }
   # otherwise, real screen
@@ -72,13 +72,13 @@ recipe fake-screen-is-clear? [
   local-scope
   screen:address:screen <- next-ingredient
   reply-unless screen:address:screen, 1/true
-  buf:address:array:screen-cell <- get screen:address:screen/deref, data:offset
+  buf:address:array:screen-cell <- get screen:address:screen/lookup, data:offset
   i:number <- copy 0
-  len:number <- length buf:address:array:screen-cell/deref
+  len:number <- length buf:address:array:screen-cell/lookup
   {
     done?:boolean <- greater-or-equal i:number, len:number
     break-if done?:boolean
-    curr:screen-cell <- index buf:address:array:screen-cell/deref, i:number
+    curr:screen-cell <- index buf:address:array:screen-cell/lookup, i:number
     curr-contents:character <- get curr:screen-cell, contents:offset
     i:number <- add i:number, 1
     loop-unless curr-contents:character
@@ -109,18 +109,18 @@ recipe print-character [
     # if x exists
     # (handle special cases exactly like in the real screen)
     break-unless x:address:screen
-    width:number <- get x:address:screen/deref, num-columns:offset
-    height:number <- get x:address:screen/deref, num-rows:offset
+    width:number <- get x:address:screen/lookup, num-columns:offset
+    height:number <- get x:address:screen/lookup, num-rows:offset
     # if cursor is out of bounds, silently exit
-    row:address:number <- get-address x:address:screen/deref, cursor-row:offset
-    legal?:boolean <- greater-or-equal row:address:number/deref, 0
+    row:address:number <- get-address x:address:screen/lookup, cursor-row:offset
+    legal?:boolean <- greater-or-equal row:address:number/lookup, 0
     reply-unless legal?:boolean, x:address:screen
-    legal?:boolean <- lesser-than row:address:number/deref, height:number
+    legal?:boolean <- lesser-than row:address:number/lookup, height:number
     reply-unless legal?:boolean, x:address:screen
-    column:address:number <- get-address x:address:screen/deref, cursor-column:offset
-    legal?:boolean <- greater-or-equal column:address:number/deref, 0
+    column:address:number <- get-address x:address:screen/lookup, cursor-column:offset
+    legal?:boolean <- greater-or-equal column:address:number/lookup, 0
     reply-unless legal?:boolean, x:address:screen
-    legal?:boolean <- lesser-than column:address:number/deref, width:number
+    legal?:boolean <- lesser-than column:address:number/lookup, width:number
     reply-unless legal?:boolean, x:address:screen
     # special-case: newline
     {
@@ -130,50 +130,50 @@ recipe print-character [
       {
         # unless cursor is already at bottom
         bottom:number <- subtract height:number, 1
-        at-bottom?:boolean <- greater-or-equal row:address:number/deref, bottom:number
+        at-bottom?:boolean <- greater-or-equal row:address:number/lookup, bottom:number
         break-if at-bottom?:boolean
         # move it to the next row
-        column:address:number/deref <- copy 0
-        row:address:number/deref <- add row:address:number/deref, 1
+        column:address:number/lookup <- copy 0
+        row:address:number/lookup <- add row:address:number/lookup, 1
       }
       reply x:address:screen/same-as-ingredient:0
     }
     # save character in fake screen
-    index:number <- multiply row:address:number/deref, width:number
-    index:number <- add index:number, column:address:number/deref
-    buf:address:array:screen-cell <- get x:address:screen/deref, data:offset
-    len:number <- length buf:address:array:screen-cell/deref
+    index:number <- multiply row:address:number/lookup, width:number
+    index:number <- add index:number, column:address:number/lookup
+    buf:address:array:screen-cell <- get x:address:screen/lookup, data:offset
+    len:number <- length buf:address:array:screen-cell/lookup
     # special-case: backspace
     {
       backspace?:boolean <- equal c:character, 8
       break-unless backspace?:boolean
       {
         # unless cursor is already at left margin
-        at-left?:boolean <- lesser-or-equal column:address:number/deref, 0
+        at-left?:boolean <- lesser-or-equal column:address:number/lookup, 0
         break-if at-left?:boolean
         # clear previous location
-        column:address:number/deref <- subtract column:address:number/deref, 1
+        column:address:number/lookup <- subtract column:address:number/lookup, 1
         index:number <- subtract index:number, 1
-        cursor:address:screen-cell <- index-address buf:address:array:screen-cell/deref, index:number
-        cursor-contents:address:character <- get-address cursor:address:screen-cell/deref, contents:offset
-        cursor-color:address:number <- get-address cursor:address:screen-cell/deref, color:offset
-        cursor-contents:address:character/deref <- copy 32/space
-        cursor-color:address:number/deref <- copy 7/white
+        cursor:address:screen-cell <- index-address buf:address:array:screen-cell/lookup, index:number
+        cursor-contents:address:character <- get-address cursor:address:screen-cell/lookup, contents:offset
+        cursor-color:address:number <- get-address cursor:address:screen-cell/lookup, color:offset
+        cursor-contents:address:character/lookup <- copy 32/space
+        cursor-color:address:number/lookup <- copy 7/white
       }
       reply x:address:screen/same-as-ingredient:0
     }
 #?     $print [saving character ], c:character, [ to fake screen ], cursor:address/screen, 10/newline
-    cursor:address:screen-cell <- index-address buf:address:array:screen-cell/deref, index:number
-    cursor-contents:address:character <- get-address cursor:address:screen-cell/deref, contents:offset
-    cursor-color:address:number <- get-address cursor:address:screen-cell/deref, color:offset
-    cursor-contents:address:character/deref <- copy c:character
-    cursor-color:address:number/deref <- copy color:number
+    cursor:address:screen-cell <- index-address buf:address:array:screen-cell/lookup, index:number
+    cursor-contents:address:character <- get-address cursor:address:screen-cell/lookup, contents:offset
+    cursor-color:address:number <- get-address cursor:address:screen-cell/lookup, color:offset
+    cursor-contents:address:character/lookup <- copy c:character
+    cursor-color:address:number/lookup <- copy color:number
     # increment column unless it's already all the way to the right
     {
       right:number <- subtract width:number, 1
-      at-right?:boolean <- greater-or-equal column:address:number/deref, right:number
+      at-right?:boolean <- greater-or-equal column:address:number/lookup, right:number
       break-if at-right?:boolean
-      column:address:number/deref <- add column:address:number/deref, 1
+      column:address:number/lookup <- add column:address:number/lookup, 1
     }
     reply x:address:screen/same-as-ingredient:0
   }
@@ -187,8 +187,8 @@ scenario print-character-at-top-left [
 #?     $start-tracing #? 3
     1:address:screen <- new-fake-screen 3/width, 2/height
     1:address:screen <- print-character 1:address:screen, 97  # 'a'
-    2:address:array:screen-cell <- get 1:address:screen/deref, data:offset
-    3:array:screen-cell <- copy 2:address:array:screen-cell/deref
+    2:address:array:screen-cell <- get 1:address:screen/lookup, data:offset
+    3:array:screen-cell <- copy 2:address:array:screen-cell/lookup
   ]
   memory-should-contain [
     3 <- 6  # width*height
@@ -202,8 +202,8 @@ scenario print-character-color [
   run [
     1:address:screen <- new-fake-screen 3/width, 2/height
     1:address:screen <- print-character 1:address:screen, 97/a, 1/red
-    2:address:array:screen-cell <- get 1:address:screen/deref, data:offset
-    3:array:screen-cell <- copy 2:address:array:screen-cell/deref
+    2:address:array:screen-cell <- get 1:address:screen/lookup, data:offset
+    3:array:screen-cell <- copy 2:address:array:screen-cell/lookup
   ]
   memory-should-contain [
     3 <- 6  # width*height
@@ -219,9 +219,9 @@ scenario print-backspace-character [
     1:address:screen <- new-fake-screen 3/width, 2/height
     1:address:screen <- print-character 1:address:screen, 97  # 'a'
     1:address:screen <- print-character 1:address:screen, 8  # backspace
-    2:number <- get 1:address:screen/deref, cursor-column:offset
-    3:address:array:screen-cell <- get 1:address:screen/deref, data:offset
-    4:array:screen-cell <- copy 3:address:array:screen-cell/deref
+    2:number <- get 1:address:screen/lookup, cursor-column:offset
+    3:address:array:screen-cell <- get 1:address:screen/lookup, data:offset
+    4:array:screen-cell <- copy 3:address:array:screen-cell/lookup
   ]
   memory-should-contain [
     2 <- 0  # cursor column
@@ -238,9 +238,9 @@ scenario print-extra-backspace-character [
     1:address:screen <- print-character 1:address:screen, 97  # 'a'
     1:address:screen <- print-character 1:address:screen, 8  # backspace
     1:address:screen <- print-character 1:address:screen, 8  # backspace
-    2:number <- get 1:address:screen/deref, cursor-column:offset
-    3:address:array:screen-cell <- get 1:address:screen/deref, data:offset
-    4:array:screen-cell <- copy 3:address:array:screen-cell/deref
+    2:number <- get 1:address:screen/lookup, cursor-column:offset
+    3:address:array:screen-cell <- get 1:address:screen/lookup, data:offset
+    4:array:screen-cell <- copy 3:address:array:screen-cell/lookup
   ]
   memory-should-contain [
     2 <- 0  # cursor column
@@ -257,9 +257,9 @@ scenario print-at-right-margin [
     1:address:screen <- print-character 1:address:screen, 97  # 'a'
     1:address:screen <- print-character 1:address:screen, 98  # 'b'
     1:address:screen <- print-character 1:address:screen, 99  # 'c'
-    2:number <- get 1:address:screen/deref, cursor-column:offset
-    3:address:array:screen-cell <- get 1:address:screen/deref, data:offset
-    4:array:screen-cell <- copy 3:address:array:screen-cell/deref
+    2:number <- get 1:address:screen/lookup, cursor-column:offset
+    3:address:array:screen-cell <- get 1:address:screen/lookup, data:offset
+    4:array:screen-cell <- copy 3:address:array:screen-cell/lookup
   ]
   memory-should-contain [
     2 <- 1  # cursor column
@@ -278,10 +278,10 @@ scenario print-newline-character [
     1:address:screen <- new-fake-screen 3/width, 2/height
     1:address:screen <- print-character 1:address:screen, 97  # 'a'
     1:address:screen <- print-character 1:address:screen, 10/newline
-    2:number <- get 1:address:screen/deref, cursor-row:offset
-    3:number <- get 1:address:screen/deref, cursor-column:offset
-    4:address:array:screen-cell <- get 1:address:screen/deref, data:offset
-    5:array:screen-cell <- copy 4:address:array:screen-cell/deref
+    2:number <- get 1:address:screen/lookup, cursor-row:offset
+    3:number <- get 1:address:screen/lookup, cursor-column:offset
+    4:address:array:screen-cell <- get 1:address:screen/lookup, data:offset
+    5:array:screen-cell <- copy 4:address:array:screen-cell/lookup
   ]
   memory-should-contain [
     2 <- 1  # cursor row
@@ -299,8 +299,8 @@ scenario print-newline-at-bottom-line [
     1:address:screen <- print-character 1:address:screen, 10/newline
     1:address:screen <- print-character 1:address:screen, 10/newline
     1:address:screen <- print-character 1:address:screen, 10/newline
-    2:number <- get 1:address:screen/deref, cursor-row:offset
-    3:number <- get 1:address:screen/deref, cursor-column:offset
+    2:number <- get 1:address:screen/lookup, cursor-row:offset
+    3:number <- get 1:address:screen/lookup, cursor-column:offset
   ]
   memory-should-contain [
     2 <- 1  # cursor row
@@ -317,10 +317,10 @@ scenario print-at-bottom-right [
     1:address:screen <- print-character 1:address:screen, 99  # 'c'
     1:address:screen <- print-character 1:address:screen, 10/newline
     1:address:screen <- print-character 1:address:screen, 100  # 'd'
-    2:number <- get 1:address:screen/deref, cursor-row:offset
-    3:number <- get 1:address:screen/deref, cursor-column:offset
-    4:address:array:screen-cell <- get 1:address:screen/deref, data:offset
-    5:array:screen-cell <- copy 4:address:array:screen-cell/deref
+    2:number <- get 1:address:screen/lookup, cursor-row:offset
+    3:number <- get 1:address:screen/lookup, cursor-column:offset
+    4:address:array:screen-cell <- get 1:address:screen/lookup, data:offset
+    5:array:screen-cell <- copy 4:address:array:screen-cell/lookup
   ]
   memory-should-contain [
     2 <- 1  # cursor row
@@ -344,21 +344,21 @@ recipe clear-line [
   # if x exists, clear line in fake screen
   {
     break-unless x:address:screen
-    width:number <- get x:address:screen/deref, num-columns:offset
-    column:address:number <- get-address x:address:screen/deref, cursor-column:offset
-    original-column:number <- copy column:address:number/deref
+    width:number <- get x:address:screen/lookup, num-columns:offset
+    column:address:number <- get-address x:address:screen/lookup, cursor-column:offset
+    original-column:number <- copy column:address:number/lookup
     # space over the entire line
 #?     $start-tracing #? 1
     {
-#?       $print column:address:number/deref, 10/newline
+#?       $print column:address:number/lookup, 10/newline
       right:number <- subtract width:number, 1
-      done?:boolean <- greater-or-equal column:address:number/deref, right:number
+      done?:boolean <- greater-or-equal column:address:number/lookup, right:number
       break-if done?:boolean
       print-character x:address:screen, [ ]  # implicitly updates 'column'
       loop
     }
     # now back to where the cursor was
-    column:address:number/deref <- copy original-column:number
+    column:address:number/lookup <- copy original-column:number
     reply x:address:screen/same-as-ingredient:0
   }
   # otherwise, real screen
@@ -372,8 +372,8 @@ recipe cursor-position [
   # if x exists, lookup cursor in fake screen
   {
     break-unless x:address:screen
-    row:number <- get x:address:screen/deref, cursor-row:offset
-    column:number <- get x:address:screen/deref, cursor-column:offset
+    row:number <- get x:address:screen/lookup, cursor-row:offset
+    column:number <- get x:address:screen/lookup, cursor-column:offset
     reply row:number, column:number, x:address:screen/same-as-ingredient:0
   }
   row:number, column:number <- cursor-position-on-display
@@ -388,10 +388,10 @@ recipe move-cursor [
   # if x exists, move cursor in fake screen
   {
     break-unless x:address:screen
-    row:address:number <- get-address x:address:screen/deref, cursor-row:offset
-    row:address:number/deref <- copy new-row:number
-    column:address:number <- get-address x:address:screen/deref, cursor-column:offset
-    column:address:number/deref <- copy new-column:number
+    row:address:number <- get-address x:address:screen/lookup, cursor-row:offset
+    row:address:number/lookup <- copy new-row:number
+    column:address:number <- get-address x:address:screen/lookup, cursor-column:offset
+    column:address:number/lookup <- copy new-column:number
     reply x:address:screen/same-as-ingredient:0
   }
   # otherwise, real screen
@@ -409,8 +409,8 @@ scenario clear-line-erases-printed-characters [
     1:address:screen <- move-cursor 1:address:screen, 0/row, 0/column
     # clear line
     1:address:screen <- clear-line 1:address:screen
-    2:address:array:screen-cell <- get 1:address:screen/deref, data:offset
-    3:array:screen-cell <- copy 2:address:array:screen-cell/deref
+    2:address:array:screen-cell <- get 1:address:screen/lookup, data:offset
+    3:array:screen-cell <- copy 2:address:array:screen-cell/lookup
   ]
   # screen should be blank
   memory-should-contain [
@@ -438,15 +438,15 @@ recipe cursor-down [
     break-unless x:address:screen
     {
       # if row < height-1
-      height:number <- get x:address:screen/deref, num-rows:offset
-      row:address:number <- get-address x:address:screen/deref, cursor-row:offset
+      height:number <- get x:address:screen/lookup, num-rows:offset
+      row:address:number <- get-address x:address:screen/lookup, cursor-row:offset
       max:number <- subtract height:number, 1
-      at-bottom?:boolean <- greater-or-equal row:address:number/deref, max:number
+      at-bottom?:boolean <- greater-or-equal row:address:number/lookup, max:number
       break-if at-bottom?:boolean
       # row = row+1
-#?       $print [AAA: ], row:address:number, [ -> ], row:address:number/deref, 10/newline
-      row:address:number/deref <- add row:address:number/deref, 1
-#?       $print [BBB: ], row:address:number, [ -> ], row:address:number/deref, 10/newline
+#?       $print [AAA: ], row:address:number, [ -> ], row:address:number/lookup, 10/newline
+      row:address:number/lookup <- add row:address:number/lookup, 1
+#?       $print [BBB: ], row:address:number, [ -> ], row:address:number/lookup, 10/newline
 #?       $start-tracing #? 1
     }
     reply x:address:screen/same-as-ingredient:0
@@ -464,11 +464,11 @@ recipe cursor-up [
     break-unless x:address:screen
     {
       # if row > 0
-      row:address:number <- get-address x:address:screen/deref, cursor-row:offset
-      at-top?:boolean <- lesser-or-equal row:address:number/deref, 0
+      row:address:number <- get-address x:address:screen/lookup, cursor-row:offset
+      at-top?:boolean <- lesser-or-equal row:address:number/lookup, 0
       break-if at-top?:boolean
       # row = row-1
-      row:address:number/deref <- subtract row:address:number/deref, 1
+      row:address:number/lookup <- subtract row:address:number/lookup, 1
     }
     reply x:address:screen/same-as-ingredient:0
   }
@@ -485,13 +485,13 @@ recipe cursor-right [
     break-unless x:address:screen
     {
       # if column < width-1
-      width:number <- get x:address:screen/deref, num-columns:offset
-      column:address:number <- get-address x:address:screen/deref, cursor-column:offset
+      width:number <- get x:address:screen/lookup, num-columns:offset
+      column:address:number <- get-address x:address:screen/lookup, cursor-column:offset
       max:number <- subtract width:number, 1
-      at-bottom?:boolean <- greater-or-equal column:address:number/deref, max:number
+      at-bottom?:boolean <- greater-or-equal column:address:number/lookup, max:number
       break-if at-bottom?:boolean
       # column = column+1
-      column:address:number/deref <- add column:address:number/deref, 1
+      column:address:number/lookup <- add column:address:number/lookup, 1
     }
     reply x:address:screen/same-as-ingredient:0
   }
@@ -508,11 +508,11 @@ recipe cursor-left [
     break-unless x:address:screen
     {
       # if column > 0
-      column:address:number <- get-address x:address:screen/deref, cursor-column:offset
-      at-top?:boolean <- lesser-or-equal column:address:number/deref, 0
+      column:address:number <- get-address x:address:screen/lookup, cursor-column:offset
+      at-top?:boolean <- lesser-or-equal column:address:number/lookup, 0
       break-if at-top?:boolean
       # column = column-1
-      column:address:number/deref <- subtract column:address:number/deref, 1
+      column:address:number/lookup <- subtract column:address:number/lookup, 1
     }
     reply x:address:screen/same-as-ingredient:0
   }
@@ -544,7 +544,7 @@ recipe screen-width [
   # if x exists, move cursor in fake screen
   {
     break-unless x:address:screen
-    width:number <- get x:address:screen/deref, num-columns:offset
+    width:number <- get x:address:screen/lookup, num-columns:offset
     reply width:number
   }
   # otherwise, real screen
@@ -558,7 +558,7 @@ recipe screen-height [
   # if x exists, move cursor in fake screen
   {
     break-unless x:address:screen
-    height:number <- get x:address:screen/deref, num-rows:offset
+    height:number <- get x:address:screen/lookup, num-rows:offset
     reply height:number
   }
   # otherwise, real screen
@@ -634,12 +634,12 @@ recipe print-string [
     break-if bg-color-found?:boolean
     bg-color:number <- copy 0/black
   }
-  len:number <- length s:address:array:character/deref
+  len:number <- length s:address:array:character/lookup
   i:number <- copy 0
   {
     done?:boolean <- greater-or-equal i:number, len:number
     break-if done?:boolean
-    c:character <- index s:address:array:character/deref, i:number
+    c:character <- index s:address:array:character/lookup, i:number
     print-character x:address:screen, c:character, color:number, bg-color:number
     i:number <- add i:number, 1
     loop
@@ -652,8 +652,8 @@ scenario print-string-stops-at-right-margin [
     1:address:screen <- new-fake-screen 3/width, 2/height
     2:address:array:character <- new [abcd]
     1:address:screen <- print-string 1:address:screen, 2:address:array:character
-    3:address:array:screen-cell <- get 1:address:screen/deref, data:offset
-    4:array:screen-cell <- copy 3:address:array:screen-cell/deref
+    3:address:array:screen-cell <- get 1:address:screen/lookup, data:offset
+    4:array:screen-cell <- copy 3:address:array:screen-cell/lookup
   ]
   memory-should-contain [
     4 <- 6  # width*height
diff --git a/074console.mu b/074console.mu
index d405f6bd..031f0781 100644
--- a/074console.mu
+++ b/074console.mu
@@ -22,12 +22,12 @@ container console [
 recipe new-fake-console [
   local-scope
   result:address:console <- new console:type
-  buf:address:address:array:character <- get-address result:address:console/deref, data:offset
+  buf:address:address:array:character <- get-address result:address:console/lookup, data:offset
 #?   $start-tracing #? 1
-  buf:address:address:array:character/deref <- next-ingredient
+  buf:address:address:array:character/lookup <- next-ingredient
 #?   $stop-tracing #? 1
-  idx:address:number <- get-address result:address:console/deref, index:offset
-  idx:address:number/deref <- copy 0
+  idx:address:number <- get-address result:address:console/lookup, index:offset
+  idx:address:number/lookup <- copy 0
   reply result:address:console
 ]
 
@@ -36,17 +36,17 @@ recipe read-event [
   x:address:console <- next-ingredient
   {
     break-unless x:address:console
-    idx:address:number <- get-address x:address:console/deref, index:offset
-    buf:address:array:event <- get x:address:console/deref, data:offset
+    idx:address:number <- get-address x:address:console/lookup, index:offset
+    buf:address:array:event <- get x:address:console/lookup, data:offset
     {
-      max:number <- length buf:address:array:event/deref
-      done?:boolean <- greater-or-equal idx:address:number/deref, max:number
+      max:number <- length buf:address:array:event/lookup
+      done?:boolean <- greater-or-equal idx:address:number/lookup, max:number
       break-unless done?:boolean
       dummy:address:event <- new event:type
-      reply dummy:address:event/deref, x:address:console/same-as-ingredient:0, 1/found, 1/quit
+      reply dummy:address:event/lookup, x:address:console/same-as-ingredient:0, 1/found, 1/quit
     }
-    result:event <- index buf:address:array:event/deref, idx:address:number/deref
-    idx:address:number/deref <- add idx:address:number/deref, 1
+    result:event <- index buf:address:array:event/lookup, idx:address:number/lookup
+    idx:address:number/lookup <- add idx:address:number/lookup, 1
     reply result:event, x:address:console/same-as-ingredient:0, 1/found, 0/quit
   }
   # real event source is infrequent; avoid polling it too much
@@ -73,7 +73,7 @@ recipe read-key [
   c:address:character <- maybe-convert x:event, text:variant
   reply-unless c:address:character, 0, console:address/same-as-ingredient:0, 0/found, 0/quit
 #?   $print [aaa 4] #? 1
-  reply c:address:character/deref, console:address/same-as-ingredient:0, 1/found, 0/quit
+  reply c:address:character/lookup, console:address/same-as-ingredient:0, 1/found, 0/quit
 ]
 
 recipe send-keys-to-channel [
diff --git a/081run_interactive.cc b/081run_interactive.cc
index 0299863e..242578c7 100644
--- a/081run_interactive.cc
+++ b/081run_interactive.cc
@@ -102,7 +102,7 @@ recipe main [
   # try to interactively add 2 and 2
   1:address:array:character <- new [add 2, 2]
   2:address:array:character <- run-interactive 1:address:array:character
-  10:array:character <- copy 2:address:array:character/deref
+  10:array:character <- copy 2:address:array:character/lookup
 ]
 # first letter in the output should be '4' in unicode
 +mem: storing 52 in location 11
@@ -116,7 +116,7 @@ recipe main [
     102:address:array:character <- string-append 100:address:array:character, 101:address:array:character
   ]
   2:address:array:character <- run-interactive 1:address:array:character
-  10:array:character <- copy 2:address:array:character/deref
+  10:array:character <- copy 2:address:array:character/lookup
 ]
 # output contains "ab"
 +mem: storing 97 in location 11
@@ -127,7 +127,7 @@ recipe main [
   # run a command that generates a warning
   1:address:array:character <- new [get 1234:number, foo:offset]
   2:address:array:character, 3:address:array:character <- run-interactive 1:address:array:character
-  10:array:character <- copy 3:address:array:character/deref
+  10:array:character <- copy 3:address:array:character/lookup
 ]
 # warning should be "unknown element foo in container number"
 +mem: storing 117 in location 11
diff --git a/chessboard.mu b/chessboard.mu
index 7a0b9d1a..12c13417 100644
--- a/chessboard.mu
+++ b/chessboard.mu
@@ -118,7 +118,7 @@ recipe new-board [
   local-scope
   initial-position:address:array:number <- next-ingredient
   # assert(length(initial-position) == 64)
-  len:number <- length initial-position:address:array:number/deref
+  len:number <- length initial-position:address:array:number/lookup
   correct-length?:boolean <- equal len:number, 64
   assert correct-length?:boolean, [chessboard had incorrect size]
   # board is an array of pointers to files; file is an array of characters
@@ -127,8 +127,8 @@ recipe new-board [
   {
     done?:boolean <- equal col:number, 8
     break-if done?:boolean
-    file:address:address:array:character <- index-address board:address:array:address:array:character/deref, col:number
-    file:address:address:array:character/deref <- new-file initial-position:address:array:number, col:number
+    file:address:address:array:character <- index-address board:address:array:address:array:character/lookup, col:number
+    file:address:address:array:character/lookup <- new-file initial-position:address:array:number, col:number
     col:number <- add col:number, 1
     loop
   }
@@ -145,8 +145,8 @@ recipe new-file [
   {
     done?:boolean <- equal row:number, 8
     break-if done?:boolean
-    dest:address:character <- index-address result:address:array:character/deref, row:number
-    dest:address:character/deref <- index position:address:array:number/deref, index:number
+    dest:address:character <- index-address result:address:array:character/lookup, row:number
+    dest:address:character/lookup <- index position:address:array:number/lookup, index:number
     row:number <- add row:number, 1
     index:number <- add index:number, 1
     loop
@@ -175,8 +175,8 @@ recipe print-board [
     {
       done?:boolean <- equal col:number, 8
       break-if done?:boolean
-      f:address:array:character <- index board:address:array:address:array:character/deref, col:number
-      c:character <- index f:address:array:character/deref, row:number
+      f:address:array:character <- index board:address:array:address:array:character/lookup, col:number
+      c:character <- index f:address:array:character/lookup, row:number
       print-character screen:address, c:character
       print-character screen:address, 32/space
       col:number <- add col:number, 1
@@ -272,20 +272,20 @@ recipe read-move [
 #?   close-console #? 1
   # construct the move object
   result:address:move <- new move:type
-  x:address:number <- get-address result:address:move/deref, from-file:offset
-  x:address:number/deref <- copy from-file:number
-  x:address:number <- get-address result:address:move/deref, from-rank:offset
-  x:address:number/deref, quit?:boolean, error?:boolean <- read-rank stdin:address:channel, screen:address
+  x:address:number <- get-address result:address:move/lookup, from-file:offset
+  x:address:number/lookup <- copy from-file:number
+  x:address:number <- get-address result:address:move/lookup, from-rank:offset
+  x:address:number/lookup, quit?:boolean, error?:boolean <- read-rank stdin:address:channel, screen:address
   reply-if quit?:boolean, 0/dummy, quit?:boolean, error?:boolean
   reply-if error?:boolean, 0/dummy, quit?:boolean, error?:boolean
   error?:boolean <- expect-from-channel stdin:address:channel, 45/dash, screen:address
   reply-if error?:boolean, 0/dummy, 0/quit, error?:boolean
-  x:address:number <- get-address result:address:move/deref, to-file:offset
-  x:address:number/deref, quit?:boolean, error?:boolean <- read-file stdin:address:channel, screen:address
+  x:address:number <- get-address result:address:move/lookup, to-file:offset
+  x:address:number/lookup, quit?:boolean, error?:boolean <- read-file stdin:address:channel, screen:address
   reply-if quit?:boolean, 0/dummy, quit?:boolean, error?:boolean
   reply-if error?:boolean, 0/dummy, quit?:boolean, error?:boolean
-  x:address:number <- get-address result:address:move/deref, to-rank:offset
-  x:address:number/deref, quit?:boolean, error?:boolean <- read-rank stdin:address:channel, screen:address
+  x:address:number <- get-address result:address:move/lookup, to-rank:offset
+  x:address:number/lookup, quit?:boolean, error?:boolean <- read-rank stdin:address:channel, screen:address
   reply-if quit?:boolean, 0/dummy, quit?:boolean, error?:boolean
   reply-if error?:boolean, 0/dummy, quit?:boolean, error?:boolean
 #?   $exit #? 1
@@ -590,21 +590,21 @@ recipe make-move [
   local-scope
   b:address:array:address:array:character <- next-ingredient
   m:address:move <- next-ingredient
-  from-file:number <- get m:address:move/deref, from-file:offset
+  from-file:number <- get m:address:move/lookup, from-file:offset
 #?   $print from-file:number, 10/newline
-  from-rank:number <- get m:address:move/deref, from-rank:offset
+  from-rank:number <- get m:address:move/lookup, from-rank:offset
 #?   $print from-rank:number, 10/newline
-  to-file:number <- get m:address:move/deref, to-file:offset
+  to-file:number <- get m:address:move/lookup, to-file:offset
 #?   $print to-file:number, 10/newline
-  to-rank:number <- get m:address:move/deref, to-rank:offset
+  to-rank:number <- get m:address:move/lookup, to-rank:offset
 #?   $print to-rank:number, 10/newline
-  f:address:array:character <- index b:address:array:address:array:character/deref, from-file:number
-  src:address:character/square <- index-address f:address:array:character/deref, from-rank:number
-  f:address:array:character <- index b:address:array:address:array:character/deref, to-file:number
-  dest:address:character/square <- index-address f:address:array:character/deref, to-rank:number
-#?   $print src:address:character/deref, 10/newline
-  dest:address:character/deref/square <- copy src:address:character/deref/square
-  src:address:character/deref/square <- copy 32/space
+  f:address:array:character <- index b:address:array:address:array:character/lookup, from-file:number
+  src:address:character/square <- index-address f:address:array:character/lookup, from-rank:number
+  f:address:array:character <- index b:address:array:address:array:character/lookup, to-file:number
+  dest:address:character/square <- index-address f:address:array:character/lookup, to-rank:number
+#?   $print src:address:character/lookup, 10/newline
+  dest:address:character/lookup/square <- copy src:address:character/lookup/square
+  src:address:character/lookup/square <- copy 32/space
   reply b:address:array:address:array:character/same-as-ingredient:0
 ]
 
@@ -613,14 +613,14 @@ scenario making-a-move [
   run [
     2:address:array:address:array:character/board <- initial-position
     3:address:move <- new move:type
-    4:address:number <- get-address 3:address:move/deref, from-file:offset
-    4:address:number/deref <- copy 6/g
-    5:address:number <- get-address 3:address:move/deref, from-rank:offset
-    5:address:number/deref <- copy 1/'2'
-    6:address:number <- get-address 3:address:move/deref, to-file:offset
-    6:address:number/deref <- copy 6/g
-    7:address:number <- get-address 3:address:move/deref, to-rank:offset
-    7:address:number/deref <- copy 3/'4'
+    4:address:number <- get-address 3:address:move/lookup, from-file:offset
+    4:address:number/lookup <- copy 6/g
+    5:address:number <- get-address 3:address:move/lookup, from-rank:offset
+    5:address:number/lookup <- copy 1/'2'
+    6:address:number <- get-address 3:address:move/lookup, to-file:offset
+    6:address:number/lookup <- copy 6/g
+    7:address:number <- get-address 3:address:move/lookup, to-rank:offset
+    7:address:number/lookup <- copy 3/'4'
     2:address:array:address:array:character/board <- make-move 2:address:array:address:array:character/board, 3:address:move
     screen:address <- print-board screen:address, 2:address:array:address:array:character/board
   ]
diff --git a/edit.mu b/edit.mu
index a599fcea..a1e6408a 100644
--- a/edit.mu
+++ b/edit.mu
@@ -41,13 +41,13 @@ recipe new-programming-environment [
   divider:number, _ <- divide-with-remainder width:number, 2
   draw-vertical screen:address, divider:number, 1/top, height:number, 9482/vertical-dotted
   # recipe editor on the left
-  recipes:address:address:editor-data <- get-address result:address:programming-environment-data/deref, recipes:offset
-  recipes:address:address:editor-data/deref <- new-editor initial-recipe-contents:address:array:character, screen:address, 0/left, divider:number/right
+  recipes:address:address:editor-data <- get-address result:address:programming-environment-data/lookup, recipes:offset
+  recipes:address:address:editor-data/lookup <- new-editor initial-recipe-contents:address:array:character, screen:address, 0/left, divider:number/right
   # sandbox editor on the right
   new-left:number <- add divider:number, 1
   new-right:number <- add new-left:number, 5
-  current-sandbox:address:address:editor-data <- get-address result:address:programming-environment-data/deref, current-sandbox:offset
-  current-sandbox:address:address:editor-data/deref <- new-editor initial-sandbox-contents:address:array:character, screen:address, new-left:number, width:number
+  current-sandbox:address:address:editor-data <- get-address result:address:programming-environment-data/lookup, current-sandbox:offset
+  current-sandbox:address:address:editor-data/lookup <- new-editor initial-sandbox-contents:address:array:character, screen:address, new-left:number, width:number
   screen:address <- render-all screen:address, result:address:programming-environment-data
   reply result:address:programming-environment-data
 ]
@@ -97,30 +97,30 @@ recipe new-editor [
   right:number <- subtract right:number, 1
   result:address:editor-data <- new editor-data:type
   # initialize screen-related fields
-  x:address:number <- get-address result:address:editor-data/deref, left:offset
-  x:address:number/deref <- copy left:number
-  x:address:number <- get-address result:address:editor-data/deref, right:offset
-  x:address:number/deref <- copy right:number
+  x:address:number <- get-address result:address:editor-data/lookup, left:offset
+  x:address:number/lookup <- copy left:number
+  x:address:number <- get-address result:address:editor-data/lookup, right:offset
+  x:address:number/lookup <- copy right:number
   # initialize cursor
-  x:address:number <- get-address result:address:editor-data/deref, cursor-row:offset
-  x:address:number/deref <- copy 1/top
-  x:address:number <- get-address result:address:editor-data/deref, cursor-column:offset
-  x:address:number/deref <- copy left:number
-  init:address:address:duplex-list <- get-address result:address:editor-data/deref, data:offset
-  init:address:address:duplex-list/deref <- push-duplex 167/§, 0/tail
-  y:address:address:duplex-list <- get-address result:address:editor-data/deref, before-cursor:offset
-  y:address:address:duplex-list/deref <- copy init:address:address:duplex-list/deref
+  x:address:number <- get-address result:address:editor-data/lookup, cursor-row:offset
+  x:address:number/lookup <- copy 1/top
+  x:address:number <- get-address result:address:editor-data/lookup, cursor-column:offset
+  x:address:number/lookup <- copy left:number
+  init:address:address:duplex-list <- get-address result:address:editor-data/lookup, data:offset
+  init:address:address:duplex-list/lookup <- push-duplex 167/§, 0/tail
+  y:address:address:duplex-list <- get-address result:address:editor-data/lookup, before-cursor:offset
+  y:address:address:duplex-list/lookup <- copy init:address:address:duplex-list/lookup
   # early exit if s is empty
   reply-unless s:address:array:character, result:address:editor-data
-  len:number <- length s:address:array:character/deref
+  len:number <- length s:address:array:character/lookup
   reply-unless len:number, result:address:editor-data
   idx:number <- copy 0
   # now we can start appending the rest, character by character
-  curr:address:duplex-list <- copy init:address:address:duplex-list/deref
+  curr:address:duplex-list <- copy init:address:address:duplex-list/lookup
   {
     done?:boolean <- greater-or-equal idx:number, len:number
     break-if done?:boolean
-    c:character <- index s:address:array:character/deref, idx:number
+    c:character <- index s:address:array:character/lookup, idx:number
     insert-duplex c:character, curr:address:duplex-list
     # next iter
     curr:address:duplex-list <- next-duplex curr:address:duplex-list
@@ -128,8 +128,8 @@ recipe new-editor [
     loop
   }
   # initialize cursor to top of screen
-  y:address:address:duplex-list <- get-address result:address:editor-data/deref, before-cursor:offset
-  y:address:address:duplex-list/deref <- copy init:address:address:duplex-list/deref
+  y:address:address:duplex-list <- get-address result:address:editor-data/lookup, before-cursor:offset
+  y:address:address:duplex-list/lookup <- copy init:address:address:duplex-list/lookup
   # initial render to screen, just for some old tests
   _, screen:address <- render screen:address, result:address:editor-data
   reply result:address:editor-data
@@ -139,7 +139,7 @@ scenario editor-initializes-without-data [
   assume-screen 5/width, 3/height
   run [
     1:address:editor-data <- new-editor 0/data, screen:address, 2/left, 5/right
-    2:editor-data <- copy 1:address:editor-data/deref
+    2:editor-data <- copy 1:address:editor-data/lookup
   ]
   memory-should-contain [
     # 2 (data) <- just the § sentinel
@@ -162,23 +162,23 @@ recipe render [
   screen:address <- next-ingredient
   editor:address:editor-data <- next-ingredient
   reply-unless editor:address:editor-data, 1/top, screen:address/same-as-ingredient:0
-  left:number <- get editor:address:editor-data/deref, left:offset
+  left:number <- get editor:address:editor-data/lookup, left:offset
   screen-height:number <- screen-height screen:address
-  right:number <- get editor:address:editor-data/deref, right:offset
+  right:number <- get editor:address:editor-data/lookup, right:offset
   hide-screen screen:address
   # highlight mu code with color
   color:number <- copy 7/white
   highlighting-state:number <- copy 0/normal
   # traversing editor
-  curr:address:duplex-list <- get editor:address:editor-data/deref, data:offset
+  curr:address:duplex-list <- get editor:address:editor-data/lookup, data:offset
   prev:address:duplex-list <- copy curr:address:duplex-list
   curr:address:duplex-list <- next-duplex curr:address:duplex-list
   # traversing screen
   row:number <- copy 1/top
   column:number <- copy left:number
-  cursor-row:address:number <- get-address editor:address:editor-data/deref, cursor-row:offset
-  cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset
-  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/deref, before-cursor:offset
+  cursor-row:address:number <- get-address editor:address:editor-data/lookup, cursor-row:offset
+  cursor-column:address:number <- get-address editor:address:editor-data/lookup, cursor-column:offset
+  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/lookup, before-cursor:offset
   move-cursor screen:address, row:number, column:number
   {
     +next-character
@@ -189,13 +189,13 @@ recipe render [
     # Doing so at the start of each iteration ensures it stays one step behind
     # the current character.
     {
-      at-cursor-row?:boolean <- equal row:number, cursor-row:address:number/deref
+      at-cursor-row?:boolean <- equal row:number, cursor-row:address:number/lookup
       break-unless at-cursor-row?:boolean
-      at-cursor?:boolean <- equal column:number, cursor-column:address:number/deref
+      at-cursor?:boolean <- equal column:number, cursor-column:address:number/lookup
       break-unless at-cursor?:boolean
-      before-cursor:address:address:duplex-list/deref <- prev-duplex curr:address:duplex-list
+      before-cursor:address:address:duplex-list/lookup <- prev-duplex curr:address:duplex-list
     }
-    c:character <- get curr:address:duplex-list/deref, value:offset
+    c:character <- get curr:address:duplex-list/lookup, value:offset
     color:number, highlighting-state:number <- get-color color:number, highlighting-state:number, c:character
     {
       # newline? move to left rather than 0
@@ -203,12 +203,12 @@ recipe render [
       break-unless newline?:boolean
       # adjust cursor if necessary
       {
-        at-cursor-row?:boolean <- equal row:number, cursor-row:address:number/deref
+        at-cursor-row?:boolean <- equal row:number, cursor-row:address:number/lookup
         break-unless at-cursor-row?:boolean
-        left-of-cursor?:boolean <- lesser-than column:number, cursor-column:address:number/deref
+        left-of-cursor?:boolean <- lesser-than column:number, cursor-column:address:number/lookup
         break-unless left-of-cursor?:boolean
-        cursor-column:address:number/deref <- copy column:number
-        before-cursor:address:address:duplex-list/deref <- prev-duplex curr:address:duplex-list
+        cursor-column:address:number/lookup <- copy column:number
+        before-cursor:address:address:duplex-list/lookup <- prev-duplex curr:address:duplex-list
       }
       # clear rest of line in this window
       clear-line-delimited screen:address, column:number, right:number
@@ -241,24 +241,24 @@ recipe render [
   }
   # is cursor to the right of the last line? move to end
   {
-    at-cursor-row?:boolean <- equal row:number, cursor-row:address:number/deref
-    cursor-outside-line?:boolean <- lesser-or-equal column:number, cursor-column:address:number/deref
+    at-cursor-row?:boolean <- equal row:number, cursor-row:address:number/lookup
+    cursor-outside-line?:boolean <- lesser-or-equal column:number, cursor-column:address:number/lookup
     before-cursor-on-same-line?:boolean <- and at-cursor-row?:boolean, cursor-outside-line?:boolean
-    above-cursor-row?:boolean <- lesser-than row:number, cursor-row:address:number/deref
+    above-cursor-row?:boolean <- lesser-than row:number, cursor-row:address:number/lookup
     before-cursor?:boolean <- or before-cursor-on-same-line?:boolean, above-cursor-row?:boolean
     break-unless before-cursor?:boolean
-    cursor-row:address:number/deref <- copy row:number
-    cursor-column:address:number/deref <- copy column:number
+    cursor-row:address:number/lookup <- copy row:number
+    cursor-column:address:number/lookup <- copy column:number
     # line not wrapped but cursor outside bounds? wrap cursor
     {
-      too-far-right?:boolean <- greater-than cursor-column:address:number/deref, right:number
+      too-far-right?:boolean <- greater-than cursor-column:address:number/lookup, right:number
       break-unless too-far-right?:boolean
-      cursor-column:address:number/deref <- copy left:number
-      cursor-row:address:number/deref <- add cursor-row:address:number/deref, 1
-      above-screen-bottom?:boolean <- lesser-than cursor-row:address:number/deref, screen-height:number
+      cursor-column:address:number/lookup <- copy left:number
+      cursor-row:address:number/lookup <- add cursor-row:address:number/lookup, 1
+      above-screen-bottom?:boolean <- lesser-than cursor-row:address:number/lookup, screen-height:number
       assert above-screen-bottom?:boolean, [unimplemented: wrapping cursor past bottom of screen]
     }
-    before-cursor:address:address:duplex-list/deref <- copy prev:address:duplex-list
+    before-cursor:address:address:duplex-list/lookup <- copy prev:address:duplex-list
   }
   # clear rest of current line
   clear-line-delimited screen:address, column:number, right:number
@@ -283,14 +283,14 @@ recipe render-string [
   move-cursor screen:address, row:number, column:number
   screen-height:number <- screen-height screen:address
   i:number <- copy 0
-  len:number <- length s:address:array:character/deref
+  len:number <- length s:address:array:character/lookup
   {
     +next-character
     done?:boolean <- greater-or-equal i:number, len:number
     break-if done?:boolean
     done?:boolean <- greater-or-equal row:number, screen-height:number
     break-if done?:boolean
-    c:character <- index s:address:array:character/deref, i:number
+    c:character <- index s:address:array:character/lookup, i:number
     {
       # at right? wrap.
       at-right?:boolean <- equal column:number, right:number
@@ -358,11 +358,11 @@ recipe render-screen [
   column:number <- copy left:number
   s-width:number <- screen-width s:address:screen
   s-height:number <- screen-height s:address:screen
-  buf:address:array:screen-cell <- get s:address:screen/deref, data:offset
+  buf:address:array:screen-cell <- get s:address:screen/lookup, data:offset
   stop-printing:number <- add left:number, s-width:number, 3
   max-column:number <- min stop-printing:number, right:number
   i:number <- copy 0
-  len:number <- length buf:address:array:screen-cell/deref
+  len:number <- length buf:address:array:screen-cell/lookup
   screen-height:number <- screen-height screen:address
   {
     done?:boolean <- greater-or-equal i:number, len:number
@@ -380,7 +380,7 @@ recipe render-screen [
       # print row
       row-done?:boolean <- greater-or-equal column:number, max-column:number
       break-if row-done?:boolean
-      curr:screen-cell <- index buf:address:array:screen-cell/deref, i:number
+      curr:screen-cell <- index buf:address:array:screen-cell/lookup, i:number
       c:character <- get curr:screen-cell, contents:offset
       print-character screen:address, c:character, 245/grey
       column:number <- add column:number, 1
@@ -509,8 +509,8 @@ scenario editor-initializes-empty-text [
   run [
     1:address:array:character <- new []
     2:address:editor-data <- new-editor 1:address:array:character, screen:address, 0/left, 5/right
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   screen-should-contain [
     .     .
@@ -636,9 +636,9 @@ recipe event-loop [
   screen:address <- next-ingredient
   console:address <- next-ingredient
   env:address:programming-environment-data <- next-ingredient
-  recipes:address:editor-data <- get env:address:programming-environment-data/deref, recipes:offset
-  current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset
-  sandbox-in-focus?:address:boolean <- get-address env:address:programming-environment-data/deref, sandbox-in-focus?:offset
+  recipes:address:editor-data <- get env:address:programming-environment-data/lookup, recipes:offset
+  current-sandbox:address:editor-data <- get env:address:programming-environment-data/lookup, current-sandbox:offset
+  sandbox-in-focus?:address:boolean <- get-address env:address:programming-environment-data/lookup, sandbox-in-focus?:offset
   {
     # looping over each (keyboard or touch) event as it occurs
     +next-event
@@ -652,12 +652,12 @@ recipe event-loop [
       break-unless k:address:number
       # F4? load all code and run all sandboxes.
       {
-        do-run?:boolean <- equal k:address:number/deref, 65532/F4
+        do-run?:boolean <- equal k:address:number/lookup, 65532/F4
         break-unless do-run?:boolean
         run-sandboxes env:address:programming-environment-data
         # F4 might update warnings and results on both sides
         screen:address <- render-all screen:address, env:address:programming-environment-data
-        update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:address:boolean/deref
+        update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:address:boolean/lookup
         show-screen screen:address
         loop +next-event:label
       }
@@ -667,10 +667,10 @@ recipe event-loop [
       break-unless c:address:character
       # ctrl-n? - switch focus
       {
-        ctrl-n?:boolean <- equal c:address:character/deref, 14/ctrl-n
+        ctrl-n?:boolean <- equal c:address:character/lookup, 14/ctrl-n
         break-unless ctrl-n?:boolean
-        sandbox-in-focus?:address:boolean/deref <- not sandbox-in-focus?:address:boolean/deref
-        update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:address:boolean/deref
+        sandbox-in-focus?:address:boolean/lookup <- not sandbox-in-focus?:address:boolean/lookup
+        update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:address:boolean/lookup
         show-screen screen:address
         loop +next-event:label
       }
@@ -681,32 +681,32 @@ recipe event-loop [
       break-unless t:address:touch-event
       # ignore all but 'left-click' events for now
       # todo: test this
-      touch-type:number <- get t:address:touch-event/deref, type:offset
+      touch-type:number <- get t:address:touch-event/lookup, type:offset
       is-left-click?:boolean <- equal touch-type:number, 65513/mouse-left
       loop-unless is-left-click?:boolean, +next-event:label
       # on a sandbox delete icon? process delete
       {
-        was-delete?:boolean <- delete-sandbox t:address:touch-event/deref, env:address:programming-environment-data
+        was-delete?:boolean <- delete-sandbox t:address:touch-event/lookup, env:address:programming-environment-data
         break-unless was-delete?:boolean
 #?         trace [app], [delete clicked] #? 1
         screen:address <- render-sandbox-side screen:address, env:address:programming-environment-data, 1/clear
-        update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:address:boolean/deref
+        update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:address:boolean/lookup
         show-screen screen:address
         loop +next-event:label
       }
       # if not, send to both editors
-      _ <- move-cursor-in-editor screen:address, recipes:address:editor-data, t:address:touch-event/deref
-      sandbox-in-focus?:address:boolean/deref <- move-cursor-in-editor screen:address, current-sandbox:address:editor-data, t:address:touch-event/deref
+      _ <- move-cursor-in-editor screen:address, recipes:address:editor-data, t:address:touch-event/lookup
+      sandbox-in-focus?:address:boolean/lookup <- move-cursor-in-editor screen:address, current-sandbox:address:editor-data, t:address:touch-event/lookup
       jump +continue:label
     }
     # if it's not global, send to appropriate editor
     {
       {
-        break-if sandbox-in-focus?:address:boolean/deref
+        break-if sandbox-in-focus?:address:boolean/lookup
         handle-event screen:address, console:address, recipes:address:editor-data, e:event
       }
       {
-        break-unless sandbox-in-focus?:address:boolean/deref
+        break-unless sandbox-in-focus?:address:boolean/lookup
         handle-event screen:address, console:address, current-sandbox:address:editor-data, e:event
       }
     }
@@ -741,7 +741,7 @@ recipe editor-event-loop [
     {
       t:address:touch-event <- maybe-convert e:event, touch:variant
       break-unless t:address:touch-event
-      move-cursor-in-editor screen:address, editor:address:editor-data, t:address:touch-event/deref
+      move-cursor-in-editor screen:address, editor:address:editor-data, t:address:touch-event/lookup
       jump +continue:label
     }
     # other events - send to appropriate editor
@@ -749,8 +749,8 @@ recipe editor-event-loop [
     +continue
     row:number, screen:address <- render screen:address, editor:address:editor-data
     # clear next line, in case we just processed a backspace
-    left:number <- get editor:address:editor-data/deref, left:offset
-    right:number <- get editor:address:editor-data/deref, right:offset
+    left:number <- get editor:address:editor-data/lookup, left:offset
+    right:number <- get editor:address:editor-data/lookup, right:offset
     row:number <- add row:number, 1
     move-cursor screen:address, row:number, left:number
     clear-line-delimited screen:address, left:number, right:number
@@ -772,81 +772,81 @@ recipe handle-event [
     ## check for special characters
     # backspace - delete character before cursor
     {
-      backspace?:boolean <- equal c:address:character/deref, 8/backspace
+      backspace?:boolean <- equal c:address:character/lookup, 8/backspace
       break-unless backspace?:boolean
       delete-before-cursor editor:address:editor-data
       reply
     }
     # ctrl-a - move cursor to start of line
     {
-      ctrl-a?:boolean <- equal c:address:character/deref, 1/ctrl-a
+      ctrl-a?:boolean <- equal c:address:character/lookup, 1/ctrl-a
       break-unless ctrl-a?:boolean
       move-to-start-of-line editor:address:editor-data
       reply
     }
     # ctrl-e - move cursor to end of line
     {
-      ctrl-e?:boolean <- equal c:address:character/deref, 5/ctrl-e
+      ctrl-e?:boolean <- equal c:address:character/lookup, 5/ctrl-e
       break-unless ctrl-e?:boolean
       move-to-end-of-line editor:address:editor-data
       reply
     }
     # ctrl-u - delete until start of line (excluding cursor)
     {
-      ctrl-u?:boolean <- equal c:address:character/deref, 21/ctrl-u
+      ctrl-u?:boolean <- equal c:address:character/lookup, 21/ctrl-u
       break-unless ctrl-u?:boolean
       delete-to-start-of-line editor:address:editor-data
       reply
     }
     # ctrl-k - delete until end of line (including cursor)
     {
-      ctrl-k?:boolean <- equal c:address:character/deref, 11/ctrl-k
+      ctrl-k?:boolean <- equal c:address:character/lookup, 11/ctrl-k
       break-unless ctrl-k?:boolean
       delete-to-end-of-line editor:address:editor-data
       reply
     }
     # tab - insert two spaces
     {
-      tab?:boolean <- equal c:address:character/deref, 9/tab
+      tab?:boolean <- equal c:address:character/lookup, 9/tab
       break-unless tab?:boolean
       insert-at-cursor editor:address:editor-data, 32/space, screen:address
       insert-at-cursor editor:address:editor-data, 32/space, screen:address
       reply
     }
     # otherwise type it in
-    insert-at-cursor editor:address:editor-data, c:address:character/deref, screen:address
+    insert-at-cursor editor:address:editor-data, c:address:character/lookup, screen:address
     reply
   }
   # otherwise it's a special key
   k:address:number <- maybe-convert e:event, keycode:variant
   assert k:address:number, [event was of unknown type; neither keyboard nor mouse]
-  d:address:duplex-list <- get editor:address:editor-data/deref, data:offset
-  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/deref, before-cursor:offset
-  cursor-row:address:number <- get-address editor:address:editor-data/deref, cursor-row:offset
-  cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset
+  d:address:duplex-list <- get editor:address:editor-data/lookup, data:offset
+  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/lookup, before-cursor:offset
+  cursor-row:address:number <- get-address editor:address:editor-data/lookup, cursor-row:offset
+  cursor-column:address:number <- get-address editor:address:editor-data/lookup, cursor-column:offset
   screen-height:number <- screen-height screen:address
-  left:number <- get editor:address:editor-data/deref, left:offset
-  right:number <- get editor:address:editor-data/deref, right:offset
+  left:number <- get editor:address:editor-data/lookup, left:offset
+  right:number <- get editor:address:editor-data/lookup, right:offset
   # arrows; update cursor-row and cursor-column, leave before-cursor to 'render'.
   # right arrow
   {
-    move-to-next-character?:boolean <- equal k:address:number/deref, 65514/right-arrow
+    move-to-next-character?:boolean <- equal k:address:number/lookup, 65514/right-arrow
     break-unless move-to-next-character?:boolean
     # if not at end of text
-    old-cursor:address:duplex-list <- next-duplex before-cursor:address:address:duplex-list/deref
+    old-cursor:address:duplex-list <- next-duplex before-cursor:address:address:duplex-list/lookup
     break-unless old-cursor:address:duplex-list
     # scan to next character
-    before-cursor:address:address:duplex-list/deref <- copy old-cursor:address:duplex-list
+    before-cursor:address:address:duplex-list/lookup <- copy old-cursor:address:duplex-list
     # if crossed a newline, move cursor to start of next row
     {
-      old-cursor-character:character <- get before-cursor:address:address:duplex-list/deref/deref, value:offset
+      old-cursor-character:character <- get before-cursor:address:address:duplex-list/lookup/lookup, value:offset
       was-at-newline?:boolean <- equal old-cursor-character:character, 10/newline
       break-unless was-at-newline?:boolean
-      cursor-row:address:number/deref <- add cursor-row:address:number/deref, 1
-      cursor-column:address:number/deref <- copy left:number
+      cursor-row:address:number/lookup <- add cursor-row:address:number/lookup, 1
+      cursor-column:address:number/lookup <- copy left:number
       # todo: what happens when cursor is too far down?
       screen-height:number <- screen-height screen:address
-      above-screen-bottom?:boolean <- lesser-than cursor-row:address:number/deref, screen-height:number
+      above-screen-bottom?:boolean <- lesser-than cursor-row:address:number/lookup, screen-height:number
       assert above-screen-bottom?:boolean, [unimplemented: moving past bottom of screen]
       reply
     }
@@ -854,93 +854,93 @@ recipe handle-event [
     {
       # if we're at the column just before the wrap indicator
       wrap-column:number <- subtract right:number, 1
-      at-wrap?:boolean <- equal cursor-column:address:number/deref, wrap-column:number
+      at-wrap?:boolean <- equal cursor-column:address:number/lookup, wrap-column:number
       break-unless at-wrap?:boolean
       # and if next character isn't newline
       new-cursor:address:duplex-list <- next-duplex old-cursor:address:duplex-list
       break-unless new-cursor:address:duplex-list
-      next-character:character <- get new-cursor:address:duplex-list/deref, value:offset
+      next-character:character <- get new-cursor:address:duplex-list/lookup, value:offset
       newline?:boolean <- equal next-character:character, 10/newline
       break-if newline?:boolean
-      cursor-row:address:number/deref <- add cursor-row:address:number/deref, 1
-      cursor-column:address:number/deref <- copy left:number
+      cursor-row:address:number/lookup <- add cursor-row:address:number/lookup, 1
+      cursor-column:address:number/lookup <- copy left:number
       # todo: what happens when cursor is too far down?
-      above-screen-bottom?:boolean <- lesser-than cursor-row:address:number/deref, screen-height:number
+      above-screen-bottom?:boolean <- lesser-than cursor-row:address:number/lookup, screen-height:number
       assert above-screen-bottom?:boolean, [unimplemented: moving past bottom of screen]
       reply
     }
     # otherwise move cursor one character right
-    cursor-column:address:number/deref <- add cursor-column:address:number/deref, 1
+    cursor-column:address:number/lookup <- add cursor-column:address:number/lookup, 1
   }
   # left arrow
   {
-    move-to-previous-character?:boolean <- equal k:address:number/deref, 65515/left-arrow
+    move-to-previous-character?:boolean <- equal k:address:number/lookup, 65515/left-arrow
     break-unless move-to-previous-character?:boolean
 #?     trace [app], [left arrow] #? 1
     # if not at start of text (before-cursor at § sentinel)
-    prev:address:duplex-list <- prev-duplex before-cursor:address:address:duplex-list/deref
+    prev:address:duplex-list <- prev-duplex before-cursor:address:address:duplex-list/lookup
     break-unless prev:address:duplex-list
     # if cursor not at left margin, move one character left
     {
-      at-left-margin?:boolean <- equal cursor-column:address:number/deref, 0
+      at-left-margin?:boolean <- equal cursor-column:address:number/lookup, 0
       break-if at-left-margin?:boolean
 #?       trace [app], [decrementing] #? 1
-      cursor-column:address:number/deref <- subtract cursor-column:address:number/deref, 1
+      cursor-column:address:number/lookup <- subtract cursor-column:address:number/lookup, 1
       reply
     }
     # if at left margin, there's guaranteed to be a previous line, since we're
     # not at start of text
     {
       # if before-cursor is at newline, figure out how long the previous line is
-      prevc:character <- get before-cursor:address:address:duplex-list/deref/deref, value:offset
+      prevc:character <- get before-cursor:address:address:duplex-list/lookup/lookup, value:offset
       previous-character-is-newline?:boolean <- equal prevc:character, 10/newline
       break-unless previous-character-is-newline?:boolean
 #?       trace [app], [previous line] #? 1
       # compute length of previous line
-      end-of-line:number <- previous-line-length before-cursor:address:address:duplex-list/deref, d:address:duplex-list
-      cursor-row:address:number/deref <- subtract cursor-row:address:number/deref, 1
-      cursor-column:address:number/deref <- copy end-of-line:number
+      end-of-line:number <- previous-line-length before-cursor:address:address:duplex-list/lookup, d:address:duplex-list
+      cursor-row:address:number/lookup <- subtract cursor-row:address:number/lookup, 1
+      cursor-column:address:number/lookup <- copy end-of-line:number
       reply
     }
     # if before-cursor is not at newline, we're just at a wrapped line
-    assert cursor-row:address:number/deref, [unimplemented: moving cursor above top of screen]
-    cursor-row:address:number/deref <- subtract cursor-row:address:number/deref, 1
-    cursor-column:address:number/deref <- subtract right:number, 1  # leave room for wrap icon
+    assert cursor-row:address:number/lookup, [unimplemented: moving cursor above top of screen]
+    cursor-row:address:number/lookup <- subtract cursor-row:address:number/lookup, 1
+    cursor-column:address:number/lookup <- subtract right:number, 1  # leave room for wrap icon
   }
   # down arrow
   {
-    move-to-next-line?:boolean <- equal k:address:number/deref, 65516/down-arrow
+    move-to-next-line?:boolean <- equal k:address:number/lookup, 65516/down-arrow
     break-unless move-to-next-line?:boolean
     # todo: support scrolling
-    already-at-bottom?:boolean <- greater-or-equal cursor-row:address:number/deref, screen-height:number
+    already-at-bottom?:boolean <- greater-or-equal cursor-row:address:number/lookup, screen-height:number
     break-if already-at-bottom?:boolean
 #?     $print [moving down
 #? ] #? 1
-    cursor-row:address:number/deref <- add cursor-row:address:number/deref, 1
+    cursor-row:address:number/lookup <- add cursor-row:address:number/lookup, 1
     # that's it; render will adjust cursor-column as necessary
   }
   # up arrow
   {
-    move-to-previous-line?:boolean <- equal k:address:number/deref, 65517/up-arrow
+    move-to-previous-line?:boolean <- equal k:address:number/lookup, 65517/up-arrow
     break-unless move-to-previous-line?:boolean
     # todo: support scrolling
-    already-at-top?:boolean <- lesser-or-equal cursor-row:address:number/deref, 1/top
+    already-at-top?:boolean <- lesser-or-equal cursor-row:address:number/lookup, 1/top
     break-if already-at-top?:boolean
 #?     $print [moving up
 #? ] #? 1
-    cursor-row:address:number/deref <- subtract cursor-row:address:number/deref, 1
+    cursor-row:address:number/lookup <- subtract cursor-row:address:number/lookup, 1
     # that's it; render will adjust cursor-column as necessary
   }
   # home
   {
-    home?:boolean <- equal k:address:number/deref, 65521/home
+    home?:boolean <- equal k:address:number/lookup, 65521/home
     break-unless home?:boolean
     move-to-start-of-line editor:address:editor-data
     reply
   }
   # end
   {
-    end?:boolean <- equal k:address:number/deref, 65520/end
+    end?:boolean <- equal k:address:number/lookup, 65520/end
     break-unless end?:boolean
     move-to-end-of-line editor:address:editor-data
     reply
@@ -956,17 +956,17 @@ recipe move-cursor-in-editor [
   t:touch-event <- next-ingredient
   reply-unless editor:address:editor-data, 0/false
   click-column:number <- get t:touch-event, column:offset
-  left:number <- get editor:address:editor-data/deref, left:offset
+  left:number <- get editor:address:editor-data/lookup, left:offset
   too-far-left?:boolean <- lesser-than click-column:number, left:number
   reply-if too-far-left?:boolean, 0/false
-  right:number <- get editor:address:editor-data/deref, right:offset
+  right:number <- get editor:address:editor-data/lookup, right:offset
   too-far-right?:boolean <- greater-than click-column:number, right:number
   reply-if too-far-right?:boolean, 0/false
   # update cursor
-  cursor-row:address:number <- get-address editor:address:editor-data/deref, cursor-row:offset
-  cursor-row:address:number/deref <- get t:touch-event, row:offset
-  cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset
-  cursor-column:address:number/deref <- get t:touch-event, column:offset
+  cursor-row:address:number <- get-address editor:address:editor-data/lookup, cursor-row:offset
+  cursor-row:address:number/lookup <- get t:touch-event, row:offset
+  cursor-column:address:number <- get-address editor:address:editor-data/lookup, cursor-column:offset
+  cursor-column:address:number/lookup <- get t:touch-event, column:offset
   # gain focus
   reply 1/true
 ]
@@ -977,24 +977,24 @@ recipe insert-at-cursor [
   c:character <- next-ingredient
   screen:address <- next-ingredient
 #?   $print [insert ], c:character, 10/newline #? 1
-  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/deref, before-cursor:offset
-  insert-duplex c:character, before-cursor:address:address:duplex-list/deref
-  before-cursor:address:address:duplex-list/deref <- next-duplex before-cursor:address:address:duplex-list/deref
-  cursor-row:address:number <- get-address editor:address:editor-data/deref, cursor-row:offset
-  cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset
-  left:number <- get editor:address:editor-data/deref, left:offset
-  right:number <- get editor:address:editor-data/deref, right:offset
+  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/lookup, before-cursor:offset
+  insert-duplex c:character, before-cursor:address:address:duplex-list/lookup
+  before-cursor:address:address:duplex-list/lookup <- next-duplex before-cursor:address:address:duplex-list/lookup
+  cursor-row:address:number <- get-address editor:address:editor-data/lookup, cursor-row:offset
+  cursor-column:address:number <- get-address editor:address:editor-data/lookup, cursor-column:offset
+  left:number <- get editor:address:editor-data/lookup, left:offset
+  right:number <- get editor:address:editor-data/lookup, right:offset
   # update cursor: if newline, move cursor to start of next line
   # todo: bottom of screen
   {
     newline?:boolean <- equal c:character, 10/newline
     break-unless newline?:boolean
-    cursor-row:address:number/deref <- add cursor-row:address:number/deref, 1
-    cursor-column:address:number/deref <- copy left:number
+    cursor-row:address:number/lookup <- add cursor-row:address:number/lookup, 1
+    cursor-column:address:number/lookup <- copy left:number
     # indent if necessary
 #?     $print [computing indent], 10/newline #? 1
-    d:address:duplex-list <- get editor:address:editor-data/deref, data:offset
-    end-of-previous-line:address:duplex-list <- prev-duplex before-cursor:address:address:duplex-list/deref
+    d:address:duplex-list <- get editor:address:editor-data/lookup, data:offset
+    end-of-previous-line:address:duplex-list <- prev-duplex before-cursor:address:address:duplex-list/lookup
     indent:number <- line-indent end-of-previous-line:address:duplex-list, d:address:duplex-list
 #?     $print indent:number, 10/newline #? 1
     i:number <- copy 0
@@ -1011,41 +1011,41 @@ recipe insert-at-cursor [
   {
     # if we're at the column just before the wrap indicator
     wrap-column:number <- subtract right:number, 1
-#?     $print [wrap? ], cursor-column:address:number/deref, [ vs ], wrap-column:number, 10/newline
-    at-wrap?:boolean <- greater-or-equal cursor-column:address:number/deref, wrap-column:number
+#?     $print [wrap? ], cursor-column:address:number/lookup, [ vs ], wrap-column:number, 10/newline
+    at-wrap?:boolean <- greater-or-equal cursor-column:address:number/lookup, wrap-column:number
     break-unless at-wrap?:boolean
 #?     $print [wrap!
 #? ] #? 1
-    cursor-column:address:number/deref <- subtract cursor-column:address:number/deref, wrap-column:number
-    cursor-row:address:number/deref <- add cursor-row:address:number/deref, 1
+    cursor-column:address:number/lookup <- subtract cursor-column:address:number/lookup, wrap-column:number
+    cursor-row:address:number/lookup <- add cursor-row:address:number/lookup, 1
     # todo: what happens when cursor is too far down?
     screen-height:number <- screen-height screen:address
-    above-screen-bottom?:boolean <- lesser-than cursor-row:address:number/deref, screen-height:number
+    above-screen-bottom?:boolean <- lesser-than cursor-row:address:number/lookup, screen-height:number
     assert above-screen-bottom?:boolean, [unimplemented: typing past bottom of screen]
 #?     $print [return
 #? ] #? 1
     reply
   }
   # otherwise move cursor right
-  cursor-column:address:number/deref <- add cursor-column:address:number/deref, 1
+  cursor-column:address:number/lookup <- add cursor-column:address:number/lookup, 1
 ]
 
 recipe delete-before-cursor [
   local-scope
   editor:address:editor-data <- next-ingredient
-  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/deref, before-cursor:offset
-  d:address:duplex-list <- get editor:address:editor-data/deref, data:offset
+  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/lookup, before-cursor:offset
+  d:address:duplex-list <- get editor:address:editor-data/lookup, data:offset
   # unless already at start
-  at-start?:boolean <- equal before-cursor:address:address:duplex-list/deref, d:address:duplex-list
+  at-start?:boolean <- equal before-cursor:address:address:duplex-list/lookup, d:address:duplex-list
   reply-if at-start?:boolean
   # delete character
-  prev:address:duplex-list <- prev-duplex before-cursor:address:address:duplex-list/deref
-  remove-duplex before-cursor:address:address:duplex-list/deref
+  prev:address:duplex-list <- prev-duplex before-cursor:address:address:duplex-list/lookup
+  remove-duplex before-cursor:address:address:duplex-list/lookup
   # update cursor
-  before-cursor:address:address:duplex-list/deref <- copy prev:address:duplex-list
-  cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset
-  cursor-column:address:number/deref <- subtract cursor-column:address:number/deref, 1
-#?   $print [delete-before-cursor: ], cursor-column:address:number/deref, 10/newline
+  before-cursor:address:address:duplex-list/lookup <- copy prev:address:duplex-list
+  cursor-column:address:number <- get-address editor:address:editor-data/lookup, cursor-column:offset
+  cursor-column:address:number/lookup <- subtract cursor-column:address:number/lookup, 1
+#?   $print [delete-before-cursor: ], cursor-column:address:number/lookup, 10/newline
 ]
 
 # takes a pointer 'curr' into the doubly-linked list and its sentinel, counts
@@ -1063,7 +1063,7 @@ recipe previous-line-length [
     break-unless curr:address:duplex-list
     at-start?:boolean <- equal curr:address:duplex-list, start:address:duplex-list
     break-if at-start?:boolean
-    c:character <- get curr:address:duplex-list/deref, value:offset
+    c:character <- get curr:address:duplex-list/lookup, value:offset
     at-newline?:boolean <- equal c:character 10/newline
     break-if at-newline?:boolean
     result:number <- add result:number, 1
@@ -1091,7 +1091,7 @@ recipe line-indent [
     at-start?:boolean <- equal curr:address:duplex-list, start:address:duplex-list
     break-if at-start?:boolean
 #?   $print [a3], 10/newline #? 1
-    c:character <- get curr:address:duplex-list/deref, value:offset
+    c:character <- get curr:address:duplex-list/lookup, value:offset
     at-newline?:boolean <- equal c:character, 10/newline
     break-if at-newline?:boolean
 #?   $print [a4], 10/newline #? 1
@@ -1115,21 +1115,21 @@ recipe move-to-start-of-line [
   local-scope
   editor:address:editor-data <- next-ingredient
   # update cursor column
-  left:number <- get editor:address:editor-data/deref, left:offset
-  cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset
-  cursor-column:address:number/deref <- copy left:number
+  left:number <- get editor:address:editor-data/lookup, left:offset
+  cursor-column:address:number <- get-address editor:address:editor-data/lookup, cursor-column:offset
+  cursor-column:address:number/lookup <- copy left:number
   # update before-cursor
-  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/deref, before-cursor:offset
-  init:address:duplex-list <- get editor:address:editor-data/deref, data:offset
+  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/lookup, before-cursor:offset
+  init:address:duplex-list <- get editor:address:editor-data/lookup, data:offset
   # while not at start of line, move 
   {
-    at-start-of-text?:boolean <- equal before-cursor:address:address:duplex-list/deref, init:address:duplex-list
+    at-start-of-text?:boolean <- equal before-cursor:address:address:duplex-list/lookup, init:address:duplex-list
     break-if at-start-of-text?:boolean
-    prev:character <- get before-cursor:address:address:duplex-list/deref/deref, value:offset
+    prev:character <- get before-cursor:address:address:duplex-list/lookup/lookup, value:offset
     at-start-of-line?:boolean <- equal prev:character, 10/newline
     break-if at-start-of-line?:boolean
-    before-cursor:address:address:duplex-list/deref <- prev-duplex before-cursor:address:address:duplex-list/deref
-    assert before-cursor:address:address:duplex-list/deref, [move-to-start-of-line tried to move before start of text]
+    before-cursor:address:address:duplex-list/lookup <- prev-duplex before-cursor:address:address:duplex-list/lookup
+    assert before-cursor:address:address:duplex-list/lookup, [move-to-start-of-line tried to move before start of text]
     loop
   }
 ]
@@ -1137,35 +1137,35 @@ recipe move-to-start-of-line [
 recipe move-to-end-of-line [
   local-scope
   editor:address:editor-data <- next-ingredient
-  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/deref, before-cursor:offset
-  cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset
+  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/lookup, before-cursor:offset
+  cursor-column:address:number <- get-address editor:address:editor-data/lookup, cursor-column:offset
   # while not at start of line, move 
   {
-    next:address:duplex-list <- next-duplex before-cursor:address:address:duplex-list/deref
+    next:address:duplex-list <- next-duplex before-cursor:address:address:duplex-list/lookup
     break-unless next:address:duplex-list  # end of text
-    nextc:character <- get next:address:duplex-list/deref, value:offset
+    nextc:character <- get next:address:duplex-list/lookup, value:offset
     at-end-of-line?:boolean <- equal nextc:character, 10/newline
     break-if at-end-of-line?:boolean
-    before-cursor:address:address:duplex-list/deref <- copy next:address:duplex-list
-    cursor-column:address:number/deref <- add cursor-column:address:number/deref, 1
+    before-cursor:address:address:duplex-list/lookup <- copy next:address:duplex-list
+    cursor-column:address:number/lookup <- add cursor-column:address:number/lookup, 1
     loop
   }
   # move one past end of line
-  cursor-column:address:number/deref <- add cursor-column:address:number/deref, 1
+  cursor-column:address:number/lookup <- add cursor-column:address:number/lookup, 1
 ]
 
 recipe delete-to-start-of-line [
   local-scope
   editor:address:editor-data <- next-ingredient
   # compute range to delete
-  init:address:duplex-list <- get editor:address:editor-data/deref, data:offset
-  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/deref, before-cursor:offset
-  start:address:duplex-list <- copy before-cursor:address:address:duplex-list/deref
-  end:address:duplex-list <- next-duplex before-cursor:address:address:duplex-list/deref
+  init:address:duplex-list <- get editor:address:editor-data/lookup, data:offset
+  before-cursor:address:address:duplex-list <- get-address editor:address:editor-data/lookup, before-cursor:offset
+  start:address:duplex-list <- copy before-cursor:address:address:duplex-list/lookup
+  end:address:duplex-list <- next-duplex before-cursor:address:address:duplex-list/lookup
   {
     at-start-of-text?:boolean <- equal start:address:duplex-list, init:address:duplex-list
     break-if at-start-of-text?:boolean
-    curr:character <- get start:address:duplex-list/deref, value:offset
+    curr:character <- get start:address:duplex-list/lookup, value:offset
     at-start-of-line?:boolean <- equal curr:character, 10/newline
     break-if at-start-of-line?:boolean
     start:address:duplex-list <- prev-duplex start:address:duplex-list
@@ -1173,39 +1173,39 @@ recipe delete-to-start-of-line [
     loop
   }
   # snip it out
-  start-next:address:address:duplex-list <- get-address start:address:duplex-list/deref, next:offset
-  start-next:address:address:duplex-list/deref <- copy end:address:duplex-list
-  end-prev:address:address:duplex-list <- get-address end:address:duplex-list/deref, prev:offset
-  end-prev:address:address:duplex-list/deref <- copy start:address:duplex-list
+  start-next:address:address:duplex-list <- get-address start:address:duplex-list/lookup, next:offset
+  start-next:address:address:duplex-list/lookup <- copy end:address:duplex-list
+  end-prev:address:address:duplex-list <- get-address end:address:duplex-list/lookup, prev:offset
+  end-prev:address:address:duplex-list/lookup <- copy start:address:duplex-list
   # adjust cursor
-  before-cursor:address:address:duplex-list/deref <- prev-duplex end:address:duplex-list
-  left:number <- get editor:address:editor-data/deref, left:offset
-  cursor-column:address:number <- get-address editor:address:editor-data/deref, cursor-column:offset
-  cursor-column:address:number/deref <- copy left:number
+  before-cursor:address:address:duplex-list/lookup <- prev-duplex end:address:duplex-list
+  left:number <- get editor:address:editor-data/lookup, left:offset
+  cursor-column:address:number <- get-address editor:address:editor-data/lookup, cursor-column:offset
+  cursor-column:address:number/lookup <- copy left:number
 ]
 
 recipe delete-to-end-of-line [
   local-scope
   editor:address:editor-data <- next-ingredient
   # compute range to delete
-  start:address:duplex-list <- get editor:address:editor-data/deref, before-cursor:offset
+  start:address:duplex-list <- get editor:address:editor-data/lookup, before-cursor:offset
   end:address:duplex-list <- next-duplex start:address:duplex-list
   {
     at-end-of-text?:boolean <- equal end:address:duplex-list, 0/null
     break-if at-end-of-text?:boolean
-    curr:character <- get end:address:duplex-list/deref, value:offset
+    curr:character <- get end:address:duplex-list/lookup, value:offset
     at-end-of-line?:boolean <- equal curr:character, 10/newline
     break-if at-end-of-line?:boolean
     end:address:duplex-list <- next-duplex end:address:duplex-list
     loop
   }
   # snip it out
-  start-next:address:address:duplex-list <- get-address start:address:duplex-list/deref, next:offset
-  start-next:address:address:duplex-list/deref <- copy end:address:duplex-list
+  start-next:address:address:duplex-list <- get-address start:address:duplex-list/lookup, next:offset
+  start-next:address:address:duplex-list/lookup <- copy end:address:duplex-list
   {
     break-unless end:address:duplex-list
-    end-prev:address:address:duplex-list <- get-address end:address:duplex-list/deref, prev:offset
-    end-prev:address:address:duplex-list/deref <- copy start:address:duplex-list
+    end-prev:address:address:duplex-list <- get-address end:address:duplex-list/lookup, prev:offset
+    end-prev:address:address:duplex-list/lookup <- copy start:address:duplex-list
   }
 ]
 
@@ -1215,9 +1215,9 @@ recipe render-all [
   env:address:programming-environment-data <- next-ingredient
   screen:address <- render-recipes screen:address, env:address:programming-environment-data, 1/clear-below
   screen:address <- render-sandbox-side screen:address, env:address:programming-environment-data, 1/clear-below
-  recipes:address:editor-data <- get env:address:programming-environment-data/deref, recipes:offset
-  current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset
-  sandbox-in-focus?:boolean <- get env:address:programming-environment-data/deref, sandbox-in-focus?:offset
+  recipes:address:editor-data <- get env:address:programming-environment-data/lookup, recipes:offset
+  current-sandbox:address:editor-data <- get env:address:programming-environment-data/lookup, current-sandbox:offset
+  sandbox-in-focus?:boolean <- get env:address:programming-environment-data/lookup, sandbox-in-focus?:offset
   update-cursor screen:address, recipes:address:editor-data, current-sandbox:address:editor-data, sandbox-in-focus?:boolean
   show-screen screen:address
   reply screen:address/same-as-ingredient:0
@@ -1227,20 +1227,20 @@ recipe render-minimal [
   local-scope
   screen:address <- next-ingredient
   env:address:programming-environment-data <- next-ingredient
-  recipes:address:editor-data <- get env:address:programming-environment-data/deref, recipes:offset
-  current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset
-  sandbox-in-focus?:boolean <- get env:address:programming-environment-data/deref, sandbox-in-focus?:offset
+  recipes:address:editor-data <- get env:address:programming-environment-data/lookup, recipes:offset
+  current-sandbox:address:editor-data <- get env:address:programming-environment-data/lookup, current-sandbox:offset
+  sandbox-in-focus?:boolean <- get env:address:programming-environment-data/lookup, sandbox-in-focus?:offset
   {
     break-if sandbox-in-focus?:boolean
     screen:address <- render-recipes screen:address, env:address:programming-environment-data
-    cursor-row:number <- get recipes:address:editor-data/deref, cursor-row:offset
-    cursor-column:number <- get recipes:address:editor-data/deref, cursor-column:offset
+    cursor-row:number <- get recipes:address:editor-data/lookup, cursor-row:offset
+    cursor-column:number <- get recipes:address:editor-data/lookup, cursor-column:offset
   }
   {
     break-unless sandbox-in-focus?:boolean
     screen:address <- render-sandbox-side screen:address, env:address:programming-environment-data
-    cursor-row:number <- get current-sandbox:address:editor-data/deref, cursor-row:offset
-    cursor-column:number <- get current-sandbox:address:editor-data/deref, cursor-column:offset
+    cursor-row:number <- get current-sandbox:address:editor-data/lookup, cursor-row:offset
+    cursor-column:number <- get current-sandbox:address:editor-data/lookup, cursor-column:offset
   }
   move-cursor screen:address, cursor-row:number, cursor-column:number
   show-screen screen:address
@@ -1252,12 +1252,12 @@ recipe render-recipes [
   screen:address <- next-ingredient
   env:address:programming-environment-data <- next-ingredient
   clear:boolean <- next-ingredient
-  recipes:address:editor-data <- get env:address:programming-environment-data/deref, recipes:offset
+  recipes:address:editor-data <- get env:address:programming-environment-data/lookup, recipes:offset
   # render recipes
-  left:number <- get recipes:address:editor-data/deref, left:offset
-  right:number <- get recipes:address:editor-data/deref, right:offset
+  left:number <- get recipes:address:editor-data/lookup, left:offset
+  right:number <- get recipes:address:editor-data/lookup, right:offset
   row:number, screen:address <- render screen:address, recipes:address:editor-data
-  recipe-warnings:address:array:character <- get env:address:programming-environment-data/deref, recipe-warnings:offset
+  recipe-warnings:address:array:character <- get env:address:programming-environment-data/lookup, recipe-warnings:offset
   {
     # print any warnings
     break-unless recipe-warnings:address:array:character
@@ -1298,15 +1298,15 @@ recipe update-cursor [
     break-if sandbox-in-focus?:boolean
 #?     $print [recipes in focus
 #? ] #? 1
-    cursor-row:number <- get recipes:address:editor-data/deref, cursor-row:offset
-    cursor-column:number <- get recipes:address:editor-data/deref, cursor-column:offset
+    cursor-row:number <- get recipes:address:editor-data/lookup, cursor-row:offset
+    cursor-column:number <- get recipes:address:editor-data/lookup, cursor-column:offset
   }
   {
     break-unless sandbox-in-focus?:boolean
 #?     $print [sandboxes in focus
 #? ] #? 1
-    cursor-row:number <- get current-sandbox:address:editor-data/deref, cursor-row:offset
-    cursor-column:number <- get current-sandbox:address:editor-data/deref, cursor-column:offset
+    cursor-row:number <- get current-sandbox:address:editor-data/lookup, cursor-row:offset
+    cursor-column:number <- get current-sandbox:address:editor-data/lookup, cursor-column:offset
   }
   move-cursor screen:address, cursor-row:number, cursor-column:number
 ]
@@ -1335,8 +1335,8 @@ scenario editor-handles-mouse-clicks [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   screen-should-contain [
     .          .
@@ -1358,8 +1358,8 @@ scenario editor-handles-mouse-clicks-outside-text [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     3 <- 1  # cursor row
@@ -1377,8 +1377,8 @@ def]
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     3 <- 1  # cursor row
@@ -1396,8 +1396,8 @@ def]
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     3 <- 2  # cursor row
@@ -1416,8 +1416,8 @@ scenario editor-handles-mouse-clicks-outside-column [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   screen-should-contain [
     .          .
@@ -1603,8 +1603,8 @@ scenario editor-wraps-cursor-after-inserting-characters [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   screen-should-contain [
     .          .
@@ -1628,8 +1628,8 @@ scenario editor-wraps-cursor-after-inserting-characters-2 [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   screen-should-contain [
     .          .
@@ -1724,8 +1724,8 @@ ef]
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   # cursor should be below start of previous line
   memory-should-contain [
@@ -1746,8 +1746,8 @@ scenario editor-handles-backspace-key [
   replace-in-console 171/«, 3:event/backspace
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    4:number <- get 2:address:editor-data/deref, cursor-row:offset
-    5:number <- get 2:address:editor-data/deref, cursor-column:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    5:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   screen-should-contain [
     .          .
@@ -1877,8 +1877,8 @@ scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   screen-should-contain [
     .          .
@@ -1904,8 +1904,8 @@ scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow-2 [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     3 <- 2
@@ -1917,8 +1917,8 @@ scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow-2 [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     3 <- 2
@@ -1936,8 +1936,8 @@ scenario editor-moves-cursor-to-next-wrapped-line-with-right-arrow-3 [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   screen-should-contain [
     .          .
@@ -2004,8 +2004,8 @@ d]
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     3 <- 1
@@ -2106,8 +2106,8 @@ scenario editor-moves-across-screen-lines-across-wrap-with-left-arrow [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     3 <- 1  # previous row
@@ -2126,8 +2126,8 @@ def]
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     3 <- 1
@@ -2146,8 +2146,8 @@ def]
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   # ..and ends at (2, 0)
   memory-should-contain [
@@ -2167,8 +2167,8 @@ def]
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     3 <- 1
@@ -2187,8 +2187,8 @@ de]
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     3 <- 2
@@ -2210,8 +2210,8 @@ scenario editor-moves-to-start-of-line-with-ctrl-a [
   replace-in-console 97/a, 3:event/ctrl-a
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    4:number <- get 2:address:editor-data/deref, cursor-row:offset
-    5:number <- get 2:address:editor-data/deref, cursor-column:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    5:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   # cursor moves to start of line
   memory-should-contain [
@@ -2234,8 +2234,8 @@ scenario editor-moves-to-start-of-line-with-ctrl-a-2 [
   replace-in-console 97/a, 3:event/ctrl-a
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    4:number <- get 2:address:editor-data/deref, cursor-row:offset
-    5:number <- get 2:address:editor-data/deref, cursor-column:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    5:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   # cursor moves to start of line
   memory-should-contain [
@@ -2256,8 +2256,8 @@ scenario editor-moves-to-start-of-line-with-home [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   # cursor moves to start of line
   memory-should-contain [
@@ -2278,8 +2278,8 @@ scenario editor-moves-to-start-of-line-with-home-2 [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   # cursor moves to start of line
   memory-should-contain [
@@ -2302,8 +2302,8 @@ scenario editor-moves-to-start-of-line-with-ctrl-e [
   replace-in-console 101/e, 3:event/ctrl-e
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    4:number <- get 2:address:editor-data/deref, cursor-row:offset
-    5:number <- get 2:address:editor-data/deref, cursor-column:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    5:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   # cursor moves to end of line
   memory-should-contain [
@@ -2316,8 +2316,8 @@ scenario editor-moves-to-start-of-line-with-ctrl-e [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    4:number <- get 2:address:editor-data/deref, cursor-row:offset
-    5:number <- get 2:address:editor-data/deref, cursor-column:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    5:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     4 <- 1
@@ -2345,8 +2345,8 @@ scenario editor-moves-to-end-of-line-with-ctrl-e-2 [
   replace-in-console 101/e, 3:event/ctrl-e
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    4:number <- get 2:address:editor-data/deref, cursor-row:offset
-    5:number <- get 2:address:editor-data/deref, cursor-column:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    5:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   # cursor moves to end of line
   memory-should-contain [
@@ -2367,8 +2367,8 @@ scenario editor-moves-to-end-of-line-with-end [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   # cursor moves to end of line
   memory-should-contain [
@@ -2389,8 +2389,8 @@ scenario editor-moves-to-end-of-line-with-end-2 [
   ]
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
-    3:number <- get 2:address:editor-data/deref, cursor-row:offset
-    4:number <- get 2:address:editor-data/deref, cursor-column:offset
+    3:number <- get 2:address:editor-data/lookup, cursor-row:offset
+    4:number <- get 2:address:editor-data/lookup, cursor-column:offset
   ]
   # cursor moves to end of line
   memory-should-contain [
@@ -2630,10 +2630,10 @@ scenario point-at-multiple-editors [
   # check cursor column in each
   run [
     event-loop screen:address, console:address, 3:address:programming-environment-data
-    4:address:editor-data <- get 3:address:programming-environment-data/deref, recipes:offset
-    5:number <- get 4:address:editor-data/deref, cursor-column:offset
-    6:address:editor-data <- get 3:address:programming-environment-data/deref, current-sandbox:offset
-    7:number <- get 6:address:editor-data/deref, cursor-column:offset
+    4:address:editor-data <- get 3:address:programming-environment-data/lookup, recipes:offset
+    5:number <- get 4:address:editor-data/lookup, cursor-column:offset
+    6:address:editor-data <- get 3:address:programming-environment-data/lookup, current-sandbox:offset
+    7:number <- get 6:address:editor-data/lookup, cursor-column:offset
   ]
   memory-should-contain [
     5 <- 1
@@ -2657,10 +2657,10 @@ scenario edit-multiple-editors [
   ]
   run [
     event-loop screen:address, console:address, 3:address:programming-environment-data
-    4:address:editor-data <- get 3:address:programming-environment-data/deref, recipes:offset
-    5:number <- get 4:address:editor-data/deref, cursor-column:offset
-    6:address:editor-data <- get 3:address:programming-environment-data/deref, current-sandbox:offset
-    7:number <- get 6:address:editor-data/deref, cursor-column:offset
+    4:address:editor-data <- get 3:address:programming-environment-data/lookup, recipes:offset
+    5:number <- get 4:address:editor-data/lookup, cursor-column:offset
+    6:address:editor-data <- get 3:address:programming-environment-data/lookup, current-sandbox:offset
+    7:number <- get 6:address:editor-data/lookup, cursor-column:offset
   ]
   screen-should-contain [
     .           run (F4)           .  # this line has a different background, but we don't test that yet
@@ -2829,15 +2829,15 @@ scenario run-and-show-results [
 recipe run-sandboxes [
   local-scope
   env:address:programming-environment-data <- next-ingredient
-  recipes:address:editor-data <- get env:address:programming-environment-data/deref, recipes:offset
-  current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset
+  recipes:address:editor-data <- get env:address:programming-environment-data/lookup, recipes:offset
+  current-sandbox:address:editor-data <- get env:address:programming-environment-data/lookup, current-sandbox:offset
   # copy code from recipe editor, persist, load into mu, save any warnings
   in:address:array:character <- editor-contents recipes:address:editor-data
   save [recipes.mu], in:address:array:character
-  recipe-warnings:address:address:array:character <- get-address env:address:programming-environment-data/deref, recipe-warnings:offset
-  recipe-warnings:address:address:array:character/deref <- reload in:address:array:character
+  recipe-warnings:address:address:array:character <- get-address env:address:programming-environment-data/lookup, recipe-warnings:offset
+  recipe-warnings:address:address:array:character/lookup <- reload in:address:array:character
   # if recipe editor has errors, stop
-  reply-if recipe-warnings:address:address:array:character/deref
+  reply-if recipe-warnings:address:address:array:character/lookup
   # check contents of right editor (sandbox)
   {
     sandbox-contents:address:array:character <- editor-contents current-sandbox:address:editor-data
@@ -2845,41 +2845,41 @@ recipe run-sandboxes [
     # if contents exist, first save them
     # run them and turn them into a new sandbox-data
     new-sandbox:address:sandbox-data <- new sandbox-data:type
-    data:address:address:array:character <- get-address new-sandbox:address:sandbox-data/deref, data:offset
-    data:address:address:array:character/deref <- copy sandbox-contents:address:array:character
+    data:address:address:array:character <- get-address new-sandbox:address:sandbox-data/lookup, data:offset
+    data:address:address:array:character/lookup <- copy sandbox-contents:address:array:character
     # push to head of sandbox list
-    dest:address:address:sandbox-data <- get-address env:address:programming-environment-data/deref, sandbox:offset
-    next:address:address:sandbox-data <- get-address new-sandbox:address:sandbox-data/deref, next-sandbox:offset
-    next:address:address:sandbox-data/deref <- copy dest:address:address:sandbox-data/deref
-    dest:address:address:sandbox-data/deref <- copy new-sandbox:address:sandbox-data
+    dest:address:address:sandbox-data <- get-address env:address:programming-environment-data/lookup, sandbox:offset
+    next:address:address:sandbox-data <- get-address new-sandbox:address:sandbox-data/lookup, next-sandbox:offset
+    next:address:address:sandbox-data/lookup <- copy dest:address:address:sandbox-data/lookup
+    dest:address:address:sandbox-data/lookup <- copy new-sandbox:address:sandbox-data
     # clear sandbox editor
-    init:address:address:duplex-list <- get-address current-sandbox:address:editor-data/deref, data:offset
-    init:address:address:duplex-list/deref <- push-duplex 167/§, 0/tail
+    init:address:address:duplex-list <- get-address current-sandbox:address:editor-data/lookup, data:offset
+    init:address:address:duplex-list/lookup <- push-duplex 167/§, 0/tail
   }
   # save all sandboxes before running, just in case we die when running
   # first clear previous versions, in case we deleted some sandbox
   $system [rm lesson/[0-9]*]
-  curr:address:sandbox-data <- get env:address:programming-environment-data/deref, sandbox:offset
+  curr:address:sandbox-data <- get env:address:programming-environment-data/lookup, sandbox:offset
   filename:number <- copy 0
   {
     break-unless curr:address:sandbox-data
-    data:address:address:array:character <- get-address curr:address:sandbox-data/deref, data:offset
-    save filename:number, data:address:address:array:character/deref
+    data:address:address:array:character <- get-address curr:address:sandbox-data/lookup, data:offset
+    save filename:number, data:address:address:array:character/lookup
     filename:number <- add filename:number, 1
-    curr:address:sandbox-data <- get curr:address:sandbox-data/deref, next-sandbox:offset
+    curr:address:sandbox-data <- get curr:address:sandbox-data/lookup, next-sandbox:offset
     loop
   }
   # run all sandboxes
-  curr:address:sandbox-data <- get env:address:programming-environment-data/deref, sandbox:offset
+  curr:address:sandbox-data <- get env:address:programming-environment-data/lookup, sandbox:offset
   {
     break-unless curr:address:sandbox-data
-    data:address:address:array:character <- get-address curr:address:sandbox-data/deref, data:offset
-    response:address:address:array:character <- get-address curr:address:sandbox-data/deref, response:offset
-    warnings:address:address:array:character <- get-address curr:address:sandbox-data/deref, warnings:offset
-    fake-screen:address:address:screen <- get-address curr:address:sandbox-data/deref, screen:offset
-    response:address:address:array:character/deref, warnings:address:address:array:character/deref, fake-screen:address:address:screen/deref <- run-interactive data:address:address:array:character/deref
-#?     $print warnings:address:address:array:character/deref, [ ], warnings:address:address:array:character/deref/deref, 10/newline
-    curr:address:sandbox-data <- get curr:address:sandbox-data/deref, next-sandbox:offset
+    data:address:address:array:character <- get-address curr:address:sandbox-data/lookup, data:offset
+    response:address:address:array:character <- get-address curr:address:sandbox-data/lookup, response:offset
+    warnings:address:address:array:character <- get-address curr:address:sandbox-data/lookup, warnings:offset
+    fake-screen:address:address:screen <- get-address curr:address:sandbox-data/lookup, screen:offset
+    response:address:address:array:character/lookup, warnings:address:address:array:character/lookup, fake-screen:address:address:screen/lookup <- run-interactive data:address:address:array:character/lookup
+#?     $print warnings:address:address:array:character/lookup, [ ], warnings:address:address:array:character/lookup/lookup, 10/newline
+    curr:address:sandbox-data <- get curr:address:sandbox-data/lookup, next-sandbox:offset
     loop
   }
 ]
@@ -2890,13 +2890,13 @@ recipe render-sandbox-side [
   env:address:programming-environment-data <- next-ingredient
   clear:boolean <- next-ingredient
 #?   trace [app], [render sandbox side] #? 1
-  current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset
-  left:number <- get current-sandbox:address:editor-data/deref, left:offset
-  right:number <- get current-sandbox:address:editor-data/deref, right:offset
+  current-sandbox:address:editor-data <- get env:address:programming-environment-data/lookup, current-sandbox:offset
+  left:number <- get current-sandbox:address:editor-data/lookup, left:offset
+  right:number <- get current-sandbox:address:editor-data/lookup, right:offset
   row:number, screen:address <- render screen:address, current-sandbox:address:editor-data
   row:number <- add row:number, 1
   draw-horizontal screen:address, row:number, left:number, right:number, 9473/horizontal-double
-  sandbox:address:sandbox-data <- get env:address:programming-environment-data/deref, sandbox:offset
+  sandbox:address:sandbox-data <- get env:address:programming-environment-data/lookup, sandbox:offset
   row:number, screen:address <- render-sandboxes screen:address, sandbox:address:sandbox-data, left:number, right:number, row:number
   # clear next line, in case we just processed a backspace
   row:number <- add row:number, 1
@@ -2933,15 +2933,15 @@ recipe render-sandboxes [
   clear-line-delimited screen:address, left:number, right:number
   print-character screen:address, 120/x, 245/grey
   # save menu row so we can detect clicks to it later
-  starting-row:address:number <- get-address sandbox:address:sandbox-data/deref, starting-row-on-screen:offset
-  starting-row:address:number/deref <- copy row:number
+  starting-row:address:number <- get-address sandbox:address:sandbox-data/lookup, starting-row-on-screen:offset
+  starting-row:address:number/lookup <- copy row:number
   # render sandbox contents
-  sandbox-data:address:array:character <- get sandbox:address:sandbox-data/deref, data:offset
+  sandbox-data:address:array:character <- get sandbox:address:sandbox-data/lookup, data:offset
   row:number, screen:address <- render-string screen:address, sandbox-data:address:array:character, left:number, right:number, 7/white, row:number
   # render sandbox warnings, screen or response, in that order
-  sandbox-response:address:array:character <- get sandbox:address:sandbox-data/deref, response:offset
-  sandbox-warnings:address:array:character <- get sandbox:address:sandbox-data/deref, warnings:offset
-  sandbox-screen:address <- get sandbox:address:sandbox-data/deref, screen:offset
+  sandbox-response:address:array:character <- get sandbox:address:sandbox-data/lookup, response:offset
+  sandbox-warnings:address:array:character <- get sandbox:address:sandbox-data/lookup, warnings:offset
+  sandbox-screen:address <- get sandbox:address:sandbox-data/lookup, screen:offset
   {
     break-unless sandbox-warnings:address:array:character
     row:number, screen:address <- render-string screen:address, sandbox-warnings:address:array:character, left:number, right:number, 1/red, row:number
@@ -2962,7 +2962,7 @@ recipe render-sandboxes [
   # draw solid line after sandbox
   draw-horizontal screen:address, row:number, left:number, right:number, 9473/horizontal-double
   # draw next sandbox
-  next-sandbox:address:sandbox-data <- get sandbox:address:sandbox-data/deref, next-sandbox:offset
+  next-sandbox:address:sandbox-data <- get sandbox:address:sandbox-data/lookup, next-sandbox:offset
   row:number, screen:address <- render-sandboxes screen:address, next-sandbox:address:sandbox-data, left:number, right:number, row:number
   reply row:number/same-as-ingredient:4, screen:address/same-as-ingredient:0
 ]
@@ -2973,18 +2973,18 @@ recipe restore-sandboxes [
   env:address:programming-environment-data <- next-ingredient
   # read all scenarios, pushing them to end of a list of scenarios
   filename:number <- copy 0
-  curr:address:address:sandbox-data <- get-address env:address:programming-environment-data/deref, sandbox:offset
+  curr:address:address:sandbox-data <- get-address env:address:programming-environment-data/lookup, sandbox:offset
   {
     contents:address:array:character <- restore filename:number
     break-unless contents:address:array:character  # stop at first error; assuming file didn't exist
 #?     $print contents:address:array:character, 10/newline
     # create new sandbox for file
-    curr:address:address:sandbox-data/deref <- new sandbox-data:type
-    data:address:address:array:character <- get-address curr:address:address:sandbox-data/deref/deref, data:offset
-    data:address:address:array:character/deref <- copy contents:address:array:character
+    curr:address:address:sandbox-data/lookup <- new sandbox-data:type
+    data:address:address:array:character <- get-address curr:address:address:sandbox-data/lookup/lookup, data:offset
+    data:address:address:array:character/lookup <- copy contents:address:array:character
     # increment loop variables
     filename:number <- add filename:number, 1
-    curr:address:address:sandbox-data <- get-address curr:address:address:sandbox-data/deref/deref, next-sandbox:offset
+    curr:address:address:sandbox-data <- get-address curr:address:address:sandbox-data/lookup/lookup, next-sandbox:offset
     loop
   }
   reply env:address:programming-environment-data/same-as-ingredient:0
@@ -2996,17 +2996,17 @@ recipe delete-sandbox [
   t:touch-event <- next-ingredient
   env:address:programming-environment-data <- next-ingredient
   click-column:number <- get t:touch-event, column:offset
-  current-sandbox:address:editor-data <- get env:address:programming-environment-data/deref, current-sandbox:offset
-  right:number <- get current-sandbox:address:editor-data/deref, right:offset
+  current-sandbox:address:editor-data <- get env:address:programming-environment-data/lookup, current-sandbox:offset
+  right:number <- get current-sandbox:address:editor-data/lookup, right:offset
 #?   $print [comparing column ], click-column:number, [ vs ], right:number, 10/newline
   at-right?:boolean <- equal click-column:number, right:number
   reply-unless at-right?:boolean, 0/false
 #?   $print [trying to delete
 #? ] #? 1
   click-row:number <- get t:touch-event, row:offset
-  prev:address:address:sandbox-data <- get-address env:address:programming-environment-data/deref, sandbox:offset
-#?   $print [prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/deref, 10/newline
-  curr:address:sandbox-data <- get env:address:programming-environment-data/deref, sandbox:offset
+  prev:address:address:sandbox-data <- get-address env:address:programming-environment-data/lookup, sandbox:offset
+#?   $print [prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/lookup, 10/newline
+  curr:address:sandbox-data <- get env:address:programming-environment-data/lookup, sandbox:offset
   {
 #?     $print [next sandbox
 #? ] #? 1
@@ -3015,20 +3015,20 @@ recipe delete-sandbox [
     {
 #?       $print [checking
 #? ] #? 1
-      target-row:number <- get curr:address:sandbox-data/deref, starting-row-on-screen:offset
+      target-row:number <- get curr:address:sandbox-data/lookup, starting-row-on-screen:offset
 #?       $print [comparing row ], target-row:number, [ vs ], click-row:number, 10/newline
       delete-curr?:boolean <- equal target-row:number, click-row:number
       break-unless delete-curr?:boolean
 #?       $print [found!
 #? ] #? 1
       # delete this sandbox, rerender and stop
-      prev:address:address:sandbox-data/deref <- get curr:address:sandbox-data/deref, next-sandbox:offset
-#?       $print [setting prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/deref, 10/newline
+      prev:address:address:sandbox-data/lookup <- get curr:address:sandbox-data/lookup, next-sandbox:offset
+#?       $print [setting prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/lookup, 10/newline
       reply 1/true
     }
-    prev:address:address:sandbox-data <- get-address curr:address:sandbox-data/deref, next-sandbox:offset
-#?     $print [prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/deref, 10/newline
-    curr:address:sandbox-data <- get curr:address:sandbox-data/deref, next-sandbox:offset
+    prev:address:address:sandbox-data <- get-address curr:address:sandbox-data/lookup, next-sandbox:offset
+#?     $print [prev: ], prev:address:address:sandbox-data, [ -> ], prev:address:address:sandbox-data/lookup, 10/newline
+    curr:address:sandbox-data <- get curr:address:sandbox-data/lookup, next-sandbox:offset
     loop
   }
   reply 0/false
@@ -3277,14 +3277,14 @@ recipe editor-contents [
   local-scope
   editor:address:editor-data <- next-ingredient
   buf:address:buffer <- new-buffer 80
-  curr:address:duplex-list <- get editor:address:editor-data/deref, data:offset
+  curr:address:duplex-list <- get editor:address:editor-data/lookup, data:offset
   # skip § sentinel
   assert curr:address:duplex-list, [editor without data is illegal; must have at least a sentinel]
   curr:address:duplex-list <- next-duplex curr:address:duplex-list
   reply-unless curr:address:duplex-list, 0
   {
     break-unless curr:address:duplex-list
-    c:character <- get curr:address:duplex-list/deref, value:offset
+    c:character <- get curr:address:duplex-list/lookup, value:offset
     buffer-append buf:address:buffer, c:character
     curr:address:duplex-list <- next-duplex curr:address:duplex-list
     loop
@@ -3304,7 +3304,7 @@ scenario editor-provides-edited-contents [
   run [
     editor-event-loop screen:address, console:address, 2:address:editor-data
     3:address:array:character <- editor-contents 2:address:editor-data
-    4:array:character <- copy 3:address:array:character/deref
+    4:array:character <- copy 3:address:array:character/lookup
   ]
   memory-should-contain [
     4:string <- [abdefc]
@@ -3418,7 +3418,7 @@ scenario run-shows-non-literal-get-argument-warnings [
 recipe foo [
   x:number <- copy 0
   y:address:point <- new point:type
-  get y:address:point/deref, x:number
+  get y:address:point/lookup, x:number
 ]]
     y:address:array:character <- new [foo]
     env:address:programming-environment-data <- new-programming-environment screen:address, x:address:array:character, y:address:array:character
@@ -3430,7 +3430,7 @@ recipe foo [
     .recipe foo [                                      ┊━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━.
     .  x:number <- copy 0                              ┊                                                 .
     .  y:address:point <- new point:type               ┊                                                 .
-    .  get y:address:point/deref, x:number             ┊                                                 .
+    .  get y:address:point/lookup, x:number            ┊                                                 .
     .]                                                 ┊                                                 .
     .foo: expected ingredient 1 of 'get' to have type ↩┊                                                 .
     .'offset'; got x:number                            ┊                                                 .
@@ -3595,7 +3595,7 @@ recipe print-string-with-gradient-background [
   color:number <- next-ingredient
   bg-color1:number <- next-ingredient
   bg-color2:number <- next-ingredient
-  len:number <- length s:address:array:character/deref
+  len:number <- length s:address:array:character/lookup
   color-range:number <- subtract bg-color2:number, bg-color1:number
   color-quantum:number <- divide color-range:number, len:number
 #?   close-console #? 2
@@ -3606,7 +3606,7 @@ recipe print-string-with-gradient-background [
   {
     done?:boolean <- greater-or-equal i:number, len:number
     break-if done?:boolean
-    c:character <- index s:address:array:character/deref, i:number
+    c:character <- index s:address:array:character/lookup, i:number
     print-character x:address:screen, c:character, color:number, bg-color:number
     i:number <- add i:number, 1
     bg-color:number <- add bg-color:number, color-quantum:number