diff --git a/infra.bs b/infra.bs
index a5662fd..2d8bc04 100644
--- a/infra.bs
+++ b/infra.bs
@@ -1319,6 +1319,12 @@ out-of-bounds, except when used with exists.
"b
", "c
", "a
" ». Then |example|[1] is the string
"b
".
+
Lists can also have holes, which mark the location of a deleted value. Holes are not exposed to any algorithm unless explicitly called out; in all other cases, holes are treated as if they did not exist and are automatically skipped over. There is no literal syntax for holes. + +
For example, if the list « 0
, 1
, 2
» has the item at index 1 [=list/removed=], it leaves behind a hole in its position. Subsequent requests for the item at index 1 will now return 2
, as index counting skips over holes unless otherwise specified; similarly, the list will report its [=list/size=] as 2 rather than 3.
+
+Note: Holes exist to make [=list/iteration=] stable and predictable when the list can be mutated during the iteration, matching ECMAScript behavior. If the [=list=] is read-only or not currently being iterated by anything, [=list/holes=] can be omitted or removed.
+
To append to a list that is not an ordered set is to @@ -1356,7 +1362,7 @@ index is to add the given item to the list between the given index − 1 and the given index is 0, then prepend the given item to the list.
To remove zero or more items from a list is -to remove all items from the list that match a given condition, or do nothing if none do. +to remove all items from the list that match a given condition, replacing each with a [=list/hole=], or do nothing if none do.
Removing |x| from the list « |x|, |y|, |z|, |x| » is to remove all @@ -1369,7 +1375,7 @@ to remove all items from the list that match a given condition, or do nothing if
To empty a list is to remove -all of its items. +all of its items, replacing all of them with [=list/holes=].
A list contains an item if it appears in the list. We can also denote this by saying that, for a @@ -1385,15 +1391,30 @@ its size is zero. list, return the range from 0 to the list's size, exclusive. -
To iterate over a list, performing a -set of steps on each item in order, use phrasing of the form -"For each |item| of list", and then operate on |item| in the -subsequent prose. +
To iterate over a list |list|, +performing a set of steps |steps| on each item in order, perform [=list iteration=] +using |list| and |steps|. This can also be (and usually is) written as "[=list/For each=] +|item| of |list|: |steps|". + +
To clone a list |list| is to create a new list |clone|, of the same designation, and, for each |item| of |list|, append |item| to |clone|, so that |clone| contains the same -items, in the same order as |list|. +items, in the same order as |list|, omitting any [=list/holes=] that |list| contains.
This is a "shallow clone", as the items themselves are not cloned in
any way.
@@ -1539,6 +1560,10 @@ entries with a comma.
"a
" → `x
`, "b
" → `y
` ]». Then
|example|["a
"] is the byte sequence `x
`.
+
[=Maps=] can have holes, which mark the location of a deleted value. A hole is considered to have a key and value which are also holes. Holes are not exposed to any algorithm unless explicitly called out; in all other cases, holes are treated as if they did not exist and are automatically skipped over. There is no literal syntax for holes. + +Note: As with [=list=] [=list/holes=], these exist solely to make [=map/iteration=] stable and predictable, and to match ECMAScript Map iteration. If the [=map=] is read-only, or nothing is iterating the map, [=map/holes=] can be omitted or removed. +
To get the value of an entry in an @@ -1565,12 +1590,12 @@ also denote this by saying, for an ordered map |map|, key |key|, and valu "set |map|[|key|] to |value|".
To remove an entry from an ordered map is to remove -all entries from the map that match a given condition, or do nothing if none do. If +all entries from the map that match a given condition, replacing them with [=map/holes=], or do nothing if none do. If the condition is having a certain key, then we can also denote this by saying, for an ordered map |map| and key |key|, "remove |map|[|key|]".
To clear an ordered map is to remove all entries -from the map. +from the map, leaving [=map/holes=] in their places.
An ordered map contains an entry with a given key if there exists an entry with that key. @@ -1591,10 +1616,25 @@ of running get the keys on the map.
An ordered map is empty if its size is zero. -
To iterate over an ordered map, performing -a set of steps on each entry in order, use phrasing of the form -"For each |key| → |value| of |map|", and then operate on |key| and |value| in the -subsequent prose. +
To iterate over an ordered map |map|, +performing a set of steps |steps| on each [=map/entry=] in order, perform [=map iteration=] +using |map| and |steps|. This can also be (and usually is) written as "[=map/For each=] +|key| → |value| of |map|: |steps|". + +
To clone an ordered map |map| is to create a new ordered map |clone|, and, for each |key| → |value| of |map|,