Could these be used as Racket definitions for cons, first, and rest? - closures

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?

#lang racket
(define (cons f r) (lambda (b) (if b f r)))
Here cons has been redefined to be a procedure which takes two arguments f and r, and returns a procedure which takes one argument b. Let's try it:
cons-func.rkt> (define a-cons (cons 1 2))
Now we have called the cons procedure with the values 1 and 2; cons has returned a procedure which we have named a-cons.
cons-func.rkt> a-cons
#<procedure:...ratch/cons-func.rkt:3:19>
Now, a-cons is a procedure that takes a single argument; if that argument is true, then the first of two values passed in the earlier call to cons is returned; if instead the argument to a-cons is false, then the second of the two earlier arguments is returned:
cons-func.rkt> (a-cons true)
1
cons-func.rkt> (a-cons false)
2
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. Here first and rest just do what we did by hand a moment ago:
(define (first lst) (lst true))
(define (rest lst) (lst false))
Now we can access the two parts of our cons cell in the usual way:
cons-func.rkt> (first a-cons)
1
cons-func.rkt> (rest a-cons)
2
This new implementation of cons cells is not compatible with the old one. For example, we have not redefined car and cdr, and the normal implementation of those procedures will not work with our new cons cells:
cons-func.rkt> (car a-cons)
; car: contract violation
; expected: pair?
; given: #<procedure:...ratch/cons-func.rkt:3:19>
We can use our new cons cells to define list:
(define (list . xs)
(if (null? xs)
'()
(cons (car xs)
(apply list (cdr xs)))))
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 car and cdr to take this list apart (because they work with regular lists), and reassemble it with the new cons into a closure-based list.
cons-func.rkt> (define a-list (list 'a 'b 'c))
cons-func.rkt> a-list
#<procedure:...ratch/cons-func.rkt:3:19>
Here you can see that the list created by our new list procedure, named a-list, is itself a procedure. We can call our first and rest procedures on a-list:
cons-func.rkt> (first a-list)
'a
cons-func.rkt> (rest a-list)
#<procedure:...ratch/cons-func.rkt:3:19>
cons-func.rkt> (first (rest a-list))
'b
cons-func.rkt> (first (rest (rest a-list)))
'c
cons-func.rkt> (rest (rest (rest a-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.

Defining a data structure is a process of 2 steps.
defining the axioms of the data structure, i.e. the abstract data structure
defining the implementation which must obey the axioms.
Whatever implementation you create is correct as time as the axioms are true in that implementation.
The axioms for the lisp constructor differ from implementation to implementation. In scheme they are so
(CAR (CONS x y)) = x
(CDR (CONS x y)) = y
Each implementation that creates the functions CONS, CAR, CDR that obey this is correct and can be used as implementation for cons cells contructor.
The things are not so direct however, as the axioms of CONS can interact with other axioms of the system. For example, some systems impose the axiom:
(EQ (CONS x y) (CONS X Y))
and in this case you need to take care in the implementation such that cons to check if there is already a (X . Y) pair allocated, and not duplicate the memory.
The other answers detail the implementation of cons with functions.

Explanation through the substitution method:
The results you want are
(first (cons a b))
—> a
and
(rest (cons a b))
—> b
These are all the requirements for the three primitives.
Now consider (cons x y): replace f and r in the definition of cons with x and y – that is,
(cons x y)
—> (lambda (b) (if b x y))
Now, (first (cons x y)) is
(first (lambda (b) (if b x y)))
—> ((lambda (b) (if b x y)) true)
—> (if true x y)
—> x
and (rest (cons x y)) is
(first (lambda (b) (if b x y)))
—> ((lambda (b) (if b x y)) false)
—> (if false x y)
—> y

Related

SICP exercise 3.13 - make-cycle

I am doing exercise 3.13 from SICP but I am unsure of my answer.
Exercise 3.13: Consider the following make-cycle procedure, which uses
the last-pair procedure defined in Exercise 3.12:
(define (make-cycle x) (set-cdr! (last-pair x) x) x)
Draw a box-and-pointer diagram that shows the structure z created by
(define z (make-cycle (list 'a 'b 'c)))
What happens if we try to compute (last-pair z)?
I'm trying to understand why
(last-pair z)
becomes an infinite loop. Ignoring the box-and-pointer diagram, here is how I understand it:
(set-cdr! (last-pair x) x)
(last-pair x) would be the pair (cons 'c '()), then when we do set-cdr! the pair would become:
(cons 'c (cons 'a (cons 'b (cons 'c (cons 'a (cons 'b (cons 'c (cons 'a (cons 'b (cons 'c ...))))))))))
is my understanding correct?
No.
Your answer appears to indicate that (last-pair x) is the result of calling cons infinitely many times.
Not so.
x is still just 3 cons cells, but the last one points to the first one, creating a loop (a snake biting itself on the tail).

delete! function for R5RS

I'm trying to write a delete! function that mutates a list and removes from it a specified value. This is the code I have so far.
(define (extend! l . xs)
(if (null? (cdr l))
(set-cdr! l xs)
(apply extend! (cdr l) xs)))
(define (delete! lis y)
(define returnLis '())
(for-each (lambda(x) (if(not(eq? x y))
(extend! returnLis x))) lis)
returnLis)
The problem I am having is that I am trying to add to an empty list which can't be done in Scheme.
Desired outcome:
(delete! '(1 2 3 4 5) 3)
=> (1 2 4 5)
Your extend function use actually would make a copy of each element in a fresh pair, but since the initial value is '() it cannot be set-cdr!. The whole point of mutating something is that old variables will continue point to the changed data and making a copy won't do that.
You need to see the pairs. You want to remove 3
[1,-]->[2,-]->[3,-]->[4,-]->[5,-]->()
So When you have found 3, you need to change the cdr of the pair that holds 2 and pint it the pair that holds 3s cdr like this:
[1,-]->[2,-]->[4,-]->[5,-]->()
Something like this then:
(define (delete lst e)
(if (and (not (null? lst)) (not (null? (cdr lst))))
(if (equal? (cadr lst) e)
(set-cdr! lst (cddr lst))
(delete (cdr lst) e))
'undefined))
(define test (list 1 2 3 4 5))
(delete lst 3)
lst ; ==> (1 2 4 5)
Notice I'm using list since a quoted literal cannot be used here since you are not allowed to change constant data like '(1 2 3 4 5). The result will be undefined or it will signal an error.
It won't work if the element in question is the first. It's because the variable points to the first pair and this only changes the pointers in pairs, not bindings. One could just switch the two first and delete the second, but in the event you have a one element list you are still stuck. Scheme implementations of mutable queues usually have a head consisting of a dummy element not considered part of the list to delete the first element.
All you need is a head-sentinel technique:
(define (delete! lis y)
(define returnLis (list 1))
(for-each (lambda(x) (if(not(eq? x y))
(extend! returnLis x))) lis)
(cdr returnLis))
Well, not all... because as it is, this is a quadratic algorithm. It re-searches the returnLis from top anew while adding each new element with extend!. Better just maintain the last cdr cell and update it:
(define (delete! lis y)
(define returnLis (list 1))
(define last-cell returnLis)
(for-each (lambda(x) (cond ((not(eq? x y))
; (extend! last-cell x)
(set-cdr! last-cell (list x))
(set! last-cell (cdr last-cell)))))
lis)
(cdr returnLis))
But, as #Sylwester points out, with this approach you shouldn't use an exclamation mark in the name, as this will return a freshly built list instead of mutating the argument's structure.

Streams and the substitution model

I am wondering how the substitution model can be used to show certain things about infinite streams. For example, say you have a stream that puts n in the nth spot and so on inductively. I define it below:
(define all-ints
(lambda ((n <integer>))
(stream-cons n (all-ints (+ 1 n)))))
(define integers (all-ints 1))
It is pretty clear that this does what it is supposed to, but how would someone go about proving it? I decided to use induction. Specifically, induction on k where
(last (stream-to-list integers k))
provides the last value of the first k values of the stream provided, in this case integers. I define stream-to-list below:
(define stream-to-list
(lambda ((s <stream>) (n <integer>))
(cond ((or (zero? n) (stream-empty? s)) '())
(else (cons (stream-first s)
(stream-to-list (stream-rest s) (- n 1)))))))
What I'd like to prove, specifically, is the property that k = (last (stream-to-list integers k)) for all k > 1.
Getting the base case is fairly easy and I can do that, but how would I go about showing the "inductive case" as thoroughly as possible? Since computing the item in the k+1th spot requires that the previous k items also be computed, I don't know how this could be shown. Could someone give me some hints?
In particular, if someone could explain how, exactly, streams are interpreted using the substitution model, I'd really appreciate it. I know they have to be different from the other constructs a regular student would have learned before streams, because they delay computation and I feel like that means they can't be evaluated completely. In turn this would man, I think, the substitution model's apply eval apply etc pattern would not be followed.
stream-cons is a special form. It equalent to wrapping both arguments in lambdas, making them thunks. like this:
(stream-cons n (all-ints (+ 1 n))) ; ==>
(cons (lambda () n) (lambda () (all-ints (+ n 1))))
These procedures are made with the lexical scopes so here n is the initial value while when forcing the tail would call all-ints again in a new lexical scope giving a new n that is then captured in the the next stream-cons. The procedures steam-first and stream-rest are something like this:
(define (stream-first s)
(if (null? (car s))
'()
((car s))))
(define (stream-rest s)
(if (null? (cdr s))
'()
((cdr s))))
Now all of this are half truths. The fact is they are not functional since they mutates (memoize) the value so the same value is not computed twice, but this is not a problem for the substitution model since side effects are off limits anyway. To get a feel for how it's really done see the SICP wizards in action. Notice that the original streams only delayed the tail while modern stream libraries delay both head and tail.

Comparing two lists of symbols in lisp

Let's say I have two lisp lists that are the same but in different sequence: '(A B C) and '(C B A).
How can I check if they are the same (in the sense that the elements are the same)?
CL-USER> (equal '(a b c) '(c b a))
NIL
Like this:
(not (set-exclusive-or '(a b c) '(c b a)))
which returns T if the two sets are equal, NIL otherwise.
[Edit] If they are not truly sets then you could use this:
(not (set-exclusive-or
(remove-duplicates '(a b c))
(remove-duplicates '(c b a))))
If the lists are not sets and repeated items are important, one could use a function like this:
(defun same-elements-p (a b)
(loop (when (and (null a) (null b))
(return t))
(when (or (null a) (null b))
(return nil))
(setf b (remove (pop a) b :count 1))))
If both lists are empty, they are the same. We remove all items of one list from the other and see what happens. Note the :count 1 argument to REMOVE. It makes sure than only one item is removed.
We can define the functions perm-equal and perm-equalp which are similar to EQUAL and EQUALP except that if the arguments are lists, then their permutation doesn't matter. The list (1 1 2 3) is perm-equal to (2 1 3 1), but not to (2 3 1).
The implementation works by normalizing values into a canonical permutation by sorting. This brings up the ugly spectre of requiring an inequality comparison. However, we can hide that by providing a predefined one which works for numbers, symbols and strings. (Why doesn't the sort function do something like this, the way eql is defaulted as the :key parameter?)
(defun less (a b)
(if (realp a)
(< a b)
(string< a b)))
(defun lessp (a b)
(if (realp a)
(< a b)
(string-lessp a b)))
(defun perm-equal (a b &optional (pred #'less))
(if (or (atom a) (atom b))
(equal a b)
(let ((as (sort (copy-list a) pred))
(bs (sort (copy-list b) pred)))
(equal as bs))))
(defun perm-equalp (a b &optional (pred #'lessp))
(if (or (atom a) (atom b))
(equalp a b)
(let ((as (sort (copy-list a) pred))
(bs (sort (copy-list b) pred)))
(equalp as bs))))
Notes:
Doesn't handle improper lists: it just tries to sort them and it's game over.
Even though equalp compares vectors, perm-equalp doesn't extend its permutation-squashing logic over vectors.
realp is used to test for numbers because complex numbers satisfy numberp, yet cannot be compared with <.
The trivial answer for non-sets is to sort both lists. CL's default sort is destructive, so you'll need copies if you want to keep them afterwards.
(defun sorted (a-list predicate)
(sort (copy-list a-list) predicate))
(defun same-list-p (list-a list-b predicate)
(equalp (sorted list-a predicate) (sorted list-b predicate)))
It doesn't have the best performance, but is simple and functional.
This looks to me like an O(n) variant:
(defun equal-elementwise (a b &key (test #'eq))
(loop with hash = (make-hash-table :test test)
for i on a for j on b do
(let ((i (car i)) (j (car j)))
(unless (funcall test i j)
(setf (gethash i hash) (1+ (gethash i hash 0))
(gethash j hash) (1- (gethash j hash 0)))))
finally (return
(unless (or (cdr i) (cdr j))
(loop for value being the hash-value of hash do
(unless (zerop value) (return))
finally (return t))))))
However, this won't be efficient on short lists.

let and flet in emacs lisp

I don't know if you would call it the canonical formulation, but to bind a local function I am advised by the GNU manual to use 'flet':
(defun adder-with-flet (x)
(flet ( (f (x) (+ x 3)) )
(f x))
)
However, by accident I tried (after having played in Scheme for a bit) the following expression, where I bind a lambda expression to a variable using 'let', and it also works if I pass the function to mapcar*:
(defun adder-with-let (x)
(let ( (f (lambda (x) (+ x 3))) )
(car (mapcar* f (list x)) ))
)
And both functions work:
(adder-with-flet 3) ==> 6
(adder-with-let 3) ==> 6
Why does the second one work? I cannot find any documentation where 'let' can be used to bind functions to symbols.
Unlike Scheme, Emacs Lisp is a 2-lisp, which means that each symbol has two separate bindings: the value binding and the function binding. In a function call (a b c d), the first symbol (a) is looked up using a function binding, the rest (b c d) are looked up using the value binding. Special form let creates a new (local) value binding, flet creates a new function binding.
Note that whether value or function binding is used for lookup depends on the position in the (a b c d) function call, not on the type of the looked-up value. In particular, a value binding can resolve to function.
In your first example, you function-bind f (via flet), and then do a function lookup:
(f ...)
In your second example, you value-bind f to a function (via let), and then use a value lookup:
(... f ...)
Both work because you use the same kind of binding and lookup in each case.
http://en.wikipedia.org/wiki/Common_Lisp#Comparison_with_other_Lisps
I did a quick search of the Emacs lisp manual and couldn't find any reference to 'flet, which isn't terribly surprising since that is a part of cl - the common-lisp package.
let will do a local binding as well, but it won't bind to the "function cell" for that symbol.
i.e. This works:
(let ((myf (lambda (x) (list x x))))
(eval (list myf 3)))
but
(let ((myf (lambda (x) (list x x))))
(myf 3))
fails with the error: "Lisp error: (void-function myf)"
flet on the other hand, does do the binding to the function cell, so this works:
(flet ((myf (x) (list x x)))
(myf 3))
Notice the difference being that flet allows you to use the symbol myf directly, whereas the let does not - you have to use some indirection to get the function out of the "value cell" and apply that appropriately.
In your example, the 'mapcar' did the equivalent to my use of 'eval.
#d11wq there is `funcall' for this purpose. The following works:
(defun adder-with-let (x)
(let ((f #'(lambda (x) (+ x 3))))
(funcall f 3)))
(adder-with-let 3) ;=> 6
You don't have to use flet if you do not want to. You place a function in the function cell of a local symbol defined using let as in the following example:
(let ((ALocalSymbol))
(fset 'ALocalSymbol (lambda (x) (* 2 x)))
(ALocalSymbol 4)
)
Evaluating this will return 8. Do notice the quote in front of ALocalSymbol in (let ((ALocalSymbol))...). While setq quotes symbols, fset does not.
flet is a syntactic sugar of sorts. Using a plain-old let to define nil-valued symbols, allows you to choose which "cell" of a symbol to set. You could use setq to set the symbol's value cell or fset to set the function cell.
Hope this helps,
Pablo

Resources