I am trying to follow along this Racket tutorial:
https://cs.uwaterloo.ca/~plragde/flaneries/TYR/Pure_Functional_Programming.html
and it describes these alternatives to the actual implementations. I know what cons, first and rest do, and I understand how lambda functions work, but I cannot figure out how these successfully implement cons, first and rest.
(define (cons f r) (lambda (b) (if b f r)))
(define (first lst) (lst true))
(define (rest lst) (lst false))
Maybe I have misinterpretted what they are supposed to be. Here is what the tutorial says:
As another example of the use of closures, consider the following "alternative" implementation of the basic list primitives.
Could someone clarify?
Here
conshas been redefined to be a procedure which takes two argumentsfandr, and returns a procedure which takes one argumentb. Let's try it:Now we have called the
consprocedure with the values1and2;conshas returned a procedure which we have nameda-cons.Now,
a-consis a procedure that takes a single argument; if that argument istrue, then the first of two values passed in the earlier call toconsis returned; if instead the argument toa-consisfalse, then the second of the two earlier arguments is returned:There are two values stored in the closure returned by our new
cons, and both of them can be retrieved. This is effectively a cons cell. Let's add some sugar to make this nicer to use. Herefirstandrestjust do what we did by hand a moment ago:Now we can access the two parts of our cons cell in the usual way:
This new implementation of cons cells is not compatible with the old one. For example, we have not redefined
carandcdr, and the normal implementation of those procedures will not work with our new cons cells:We can use our new cons cells to define
list:Here we are cheating a bit, using the dot syntax to capture an arbitrary number of arguments in a list (the regular kind). We use
carandcdrto take this list apart (because they work with regular lists), and reassemble it with the newconsinto a closure-based list.Here you can see that the list created by our new
listprocedure, nameda-list, is itself a procedure. We can call ourfirstandrestprocedures ona-list:So, it seems that our closure-based cons cells behave as regular cons cells, though the underlying implementation is not compatible with Rackets own cons and list accessor procedures, and we can use these closure-based cons cells to create closure-based lists. If someone had the time and inclination, they could probably implement a whole Scheme around these closure-based cons cells.