`\``

rather than `'` that you could use; but I'm not going to explain that.) If you want to build a *proper* imp, that is, a Scheme list, you can instead use the function/constructor `list`:
(list '- 3 y)
returns the imp whose first member is the symbol `'-` (if you left the quote off, you would instead get the function that this symbol is bound to), whose second member is the number 3, whose third value is whatever value the symbol/variable `y` is bound to, and whose final value is the empty list.
-What if you want to instead build an *improper* imp, such as `(5 0 . y)`, again using the value `y` is bound to rather than the quoted symbol? There is no form in standard Scheme to do this *directly*. But many Scheme implementations do have a special function for doing this. Racket calls it `list*`, so if you write in Racket:
+What if you want to instead build an *improper* imp, such as `(5 0 . y)`, again using the value `y` is bound to rather than the quoted symbol? There is no function in *standard* Scheme to do this *directly*. But many Scheme *implementations* do have a special function for it. Racket calls it `list*`, so if you write in Racket:
(let* ((y #f))
- (cons* 5 0 y))
+ (list* 5 0 y))
You will get the imp whose first member is `5`, whose second member is `0`, and whose final member is `#f` (*not* the symbol `'y`).
Other Scheme implementations that provide this function call it `cons*`, for reasons that will become clearer in a moment.
-I said there was no form in *standard* Scheme to do this *directly*. You can however do it indirectly, and the reason why brings us to our last complication about Scheme imps. This is that in fact, Scheme imps of length greater than two are really all built up out of embedded "dotted pairs" (that is, imps of length two). The length-three imp `'(5 0 . #f)` is really implemented in Scheme as a length-two imp, whose first member is `5`, and whose second member is *another* length-two imp, whose first member is `0` and whose second member is `#f`. It could also be written as `'(5 . (0 . #f))`. (This is *not* the same as the imp `'((5 . 0) . #f)`.) Moreover, standard Scheme *does* have a function/constructor to build the simplest, dotted-pair case of imps. And what it calls this operation is `cons`. Yes, the same name we were using to pronounce our list constructor in the other languages. `cons` does play that role in Scheme, too, given the way that Scheme in fact implements (what it calls) lists. If `ys` is bound to one proper list, of any finite length, and `y` is bound to any value, then `(cons y ys)` will build a new dotted-pair that has these values as elements, and given how Scheme implements proper lists, that just is the longer list whose head is `y`'s value and whose tail is `ys`'s value.
+I said there was no form in *standard* Scheme to do this *directly*. You can however do it indirectly, and the reason why brings us to our last complication about Scheme imps. This is that in fact, Scheme imps of length greater than two are really all built up out of embedded "dotted pairs" (that is, imps of length two). The length-three imp `'(5 0 . #f)` is really implemented in Scheme as a length-two imp, whose first member is `5`, and whose second member is *another* length-two imp, whose first member is `0` and whose second member is `#f`. It could also be written as `'(5 . (0 . #f))`. (This is *not* the same as the imp `'((5 . 0) . #f)`.) Moreover, standard Scheme *does* have a function/constructor to build the simplest, "dotted pair" case of imps. And what it calls this operation is `cons`. Yes, the same name we were using to pronounce our list constructor in the other languages. `cons` does play the list constructor role in Scheme, too, given the way that Scheme in fact implements (what it calls) lists. If `ys` is bound to one proper list, of any finite length, and `y` is bound to any value, then `(cons y ys)` will build a new dotted pair that has those values as elements, and given how Scheme implements proper lists, that *just is* the longer list whose head is `y`'s value and whose tail is `ys`'s value.
-The function that Scheme uses to extract the first element of a dotted-pair (and so also to extract the head of a proper or improper list) is `car`; the function it uses to extract the second element of a dotted-pair (and so also the tail of a proper list) is `cdr`. The reasons for these funny names are historical.
+The function that Scheme uses to extract the first element of a dotted pair (and so also to extract the head of a proper or improper list) is `car`; the function it uses to extract the second element of a dotted pair (and so also the tail of a proper list) is `cdr`. The reasons for these funny names are historical.
-If you grew up learning functional programming and list manipulation from Scheme, all these complexities might seem natural to you, and might shape the way you think about notions like *list* and *ordered pair*. Scheme is a great language, but that would be unfortunate. Conceptually, these quirks about scheme are something of a hack. I think you get a better understanding of the conceptual terrain from the other functional programming languages, and by beginning to think about Scheme's lists and dotted-pairs by starting with the notion of a possibly-improper list, rather than the other way around. Most texts teaching Scheme will go in the other direction, though.
+If you grew up learning functional programming and list manipulation from Scheme, all these complexities might seem natural to you, and might shape the way you think about notions like *list* and *ordered pair*. Scheme is a great language, but that would be unfortunate. Conceptually, these quirks about Scheme are something of a hack. I think you get a better understanding of the conceptual terrain from the other functional programming languages, and by beginning to think about Scheme's lists and dotted pairs by starting with the notion of a *possibly-improper* list, rather than the other way around. Most texts teaching Scheme will go in the other direction, though.
Okay, all of that was just us getting clear about Scheme's *longer* containers, of length at least two. What about the shorter containers?
-Scheme does have vectors of length one: you can write `(vector 5)` or `#(5)`. And that will be distinct from the number `5`. Kapulet is similar: we could have a heavy-weight one-tuple, perhaps `Single 5` (or `Single (5)`, the parentheses make no difference when they contain exactly one syntactic atom), that would be distinct from the number `5`. But there is no difference among light-weight tuples. In Kapulet, `(5)` and `5` would just be notational variants for the number. Although OCaml and Haskell for the most part have tuples corresponding to Kapulet's heavy-weight tuples, in this case they do not. Some subtleties aside, they don't have any one-tuple `(5)` that's distinct from mere `5`.
+Scheme does have vectors of length one: you can write `(vector 5)` or `#(5)`. And that will be distinct from the number `5`. Kapulet is similar: we could have a heavyweight one-tuple, perhaps `Single 5` (or `Single (5)`, the parentheses make no difference when they contain exactly one syntactic atom), that would be distinct from the number `5`. But there is no difference among lightweight tuples. In Kapulet, `(5)` and `5` would just be notational variants for the number. Although OCaml and Haskell for the most part have tuples corresponding to Kapulet's heavyweight tuples, in this case they do not. Some subtleties about their type systems aside, they don't have any native one-tuple `(5)` that's distinct from mere `5`.
-Scheme doesn't have any *imps* of length one, because it builds its imps out of dotted-pairs, so they can't get any smaller than length two.
+Scheme doesn't have any *imps* of length one, because it builds its imps out of dotted pairs, so they can't get any smaller than length two. (Some Schemes do have a separate notion of a *box*, which is isomorphic to vectors of length one.)
-Now how about unit(s)? Here again, Scheme has vectors of that length: you can write `(vector)` or `#()`. And that will in many ways correspond to the heavy-weight Kapulet length-zero tuple `Unit ()`. And here too, there can be no imps that are this short.
+Now how about unit(s)? Here again, Scheme has vectors of that length: you can write `(vector)` or `#()`. And that will in many ways correspond to the heavyweight Kapulet length-zero tuple `Unit ()`. Here too, there can be no imps that are this short.
-But at this point Scheme has *yet another* special value, that in Scheme documentation is usually called *void*. And in many Scheme implementations, there is a special function that generates this value, expressed as `void`. You can call this function with zero or more arguments; they will all be ignored and you will get the special *void* value as a result. Generally Scheme doesn't display this value, if you say:
+But at this point Scheme has *yet another* special value, that in Scheme documentation is usually called *void*. And in many Scheme implementations, there is a special function that generates this value, expressed as `void`. You can apply this function to zero or more arguments; they will all be ignored and you will get the special *void* value as a result. Generally Scheme doesn't display this value. If you say:
(void)
@@ -259,18 +260,18 @@ or:
(let* ((x (void)))
x)
-your Scheme interpreter will probably just not display anything, not even a blank line. If you say this, however:
+your Scheme interpreter will probably just not show any result, not even a blank line. If you wrote this, however:
(display x)
-it might say `#`ω ω`

, that is, `(\x. x x) (\x. x x)`. And also some even scarier terms. We can write these in Kapulet, or we can write other scary terms using `letrec`:
+
+ letrec
+ blackhole match lambda (). blackhole ();
+ fst match lambda (x, y). x
+ in fst (5, blackhole)
+
+If `blackhole` ever gets applied to its `()` argument, computing the result will require re-applying `blackhole` to that same argument, which will require ... and the reduction or computation will never terminate. Some of the vocabulary people use for such expressions is that they involve "infinite loops" or "non-termination" or that they "diverge" or that their "meaning is bottom" (written `⊥`

, as we sometimes use in logic to represent a constant formula that is always false). "Bottom" is a meaning we might assign these terms, but don't say that this is their *value*. Such terms don't have any value. (Sometimes people talk sloppily, and we might even do it ourselves. But the best way to talk here is to say that expressions like `blackhole ()` *don't have any values*, or in other words *don't evaluate to anything*, though our semantics may assign them a *meaning* or denotation. Interestingly, you can't in general assign all non-terminating expressions the same meaning. See ___ for discussion.)
+
+But in the complex expression above, we never do apply `blackhole` to an argument, so no harm comes about. It makes no difference that we were evaluating `fst (5, blackhole)` rather than `snd (blackhole, 5)` (or even `snd (5, blackhole)`). In none of the cases do we ever request the result of computing `blackhole`'s body. So everything is ok.
+
+This is like how in the Lambda Calculus it can be alright to say:
+
+`K I (ω ω)`

+
+--- that is, assuming the lambda term is being evaluated in "normal" or "lazy" order, so that we reduce the leftmost, outermost redex `K I (...)` before we reduce the argument redex `ω ω`

. Since `K I (...)` discards its second argument, the non-terminating computation of `ω ω`

(that is, the result of self-applying self-application) is never demanded.
+