I'm having some trouble deciphering this code snippet.
(define (stream n f)
(define (next m)
(cons m (lambda () (next (f m)))))
(next n))
(define even (stream 0 (lambda (n) (+ n 2))))
I understand that 'even' is defined as a variable using the 'stream' function, which contains parameters 0 and '(lambda (n) (+ n 2))'. Inside of 'stream', wouldn't '(next n)' indefinitely create cons nodes with a car of n + 2? Yet when I return 'even', it is a cons of (0 . # < Closure>). Could someone be so kind as to explain why this is? Thanks!
Everytime (lambda ...) is evaluated it becomes a closure. What it means is that f is free and available for both procedures next and for the anonymous procedure it creates. m, which is a bound variable in next is also captured as a free variable in the anonymous procedure. If the language were dynamically bound none of them would exist if you called the resulting procedure in the cdr since the bindings would no longer exist, but since we have closures the variable exists even after the procedures that created them ended.
The pair returned by the stream procedure has references to the closure created when (lambda (n) (+ n 2)) was evaluated though the name f even though the call is finished. Thus if you do:
((cdr even)) ; ==>
(#<closure>) ; ==>
(cons 2 #<new-closure>) ; ==> Here
It's important to know that the evaluation of next becomes a pair with a new closure that has a new free variable m that is 2 this time. For each time you call the cdr it creates a new pair with a new closure. If it was the same each time you wouldn't have different result each iteration.
A lambda on it's own doesn't run the code in it's body. Thus instead of infinite recursion you only get one step and the result (cons 2 #<new-closure>). You need to call the cdr of this again ni order to get one more step. etc. Likewise if I did this:
(define (test a)
(define (helper b)
(+ a b))
helper) ; return the helper that has a as closure variable
Since we actually don't use the name one could just have anonymous lambda there instead of the define + the resulting variable. Anyway, you get something that gives you partially application:
((test 5) 2) ; ==> 7
(define ten-adder (test 10))
(ten-adder 2) ; ==> 12
(ten-adder 5) ; ==> 15
Related
The code below, under dynamic scope assumption, would return error.
(let ((f (lambda (g)
(lambda (n)
(if (zero? n)
1
(* n ((g g) (- n 1))))))))
((f f) 5))
My answer was 0, because:
n*(n-1)*(n-2)*(n-3)*(n-3)*(n-4)*1;; since the call with n=0, n bound to 0
0*0*0*0*1
What am I missing here?
(define test
(let ((x 10))
(lambda () x)))
Here we return lambda function from the scope where x is a local variable. Under lexical scope an environment gets attached to the created lambda function. This environment consists of the bound variables on top of the free variables that were available when the lambda function was being created -- here, x, bound to 10. Thus when this returned lambda function is called, its x can only be 10.
In dynamic scope the let is dead code. The lambda function that is created does not store its lexical environment and thus when it will be called, x will be looked up fresh, at the actual time of the call. The variable that was called x with value 10 will no longer exist by then. The x looked up by the lambda will be whatever you have x bound to, at the call time:
(let ((x 20))
(test))
; ==> 20
And of course:
(test); == ERROR: Unbound variable x
So to your code it's the same problem. Whatever g is when (lambda (n) ...) is evaluated, creating the lambda function, goes out of scope when that lambda function is returned, and thus when that returned lambda function is called, g will be looked up fresh, and will be whatever g is bound to at the time of calling, as before. In order for this to work in a dynamic scope you could do this:
(let ((f (lambda (g n)
(if (zero? n)
1
(* n (g g (- n 1)))))))
(f f 5))
The difference here is that g never goes out of scope. This works in both dynamic and lexical scope. You can simplify it for dynamic scope like this:
(let ((f (lambda (n) ; ((lambda (f) (f 5))
(if (zero? n) ; (lambda (n)
1 ; (if (zero? n)
(* n (f (- n 1))))))) ; 1
(f 5)) ; (* n (f (- n 1))))))
In lexical scope the f inside (lambda (n) ...) is unbound variable, but in a dynamic scope f is first established, and after the call (f 5) it remains available for all the nested calls, (f 4), (f 3) etc., until the evaluation of (f 5) inside (lambda (f) (f 5)) is finished; only then that f is disestablished, destroyed, when that lambda is exited returning the result of (f 5).
In Paul Grahams nice wrap-up of McCarthys original lisp paper he mentions that there was a bug in the paper. The very first higher order function, maplist, had x as the name for the list argument. In the demonstration diff he passes a function to maplist that has x as a parameter. These two collide after the first pair and thus it does not work because of dynamic scope. Dynamic scope is extremely error prone and in Common Lisp where all globals are dynamic, the *earmuffs* naming convention is a necessity to avoid countless hours finding the global that changed the function to do something completely different than expected.
Using dynamic scope, g will be undefined because there is no variable named g on line 6.
I'm trying to understand the scheme code of make-counter procedure. It's a higher order procedure (a procedure outputs another procedure) and I'm stuck with it.
(define make-counter
(lambda (n)
(lambda ()
(set! n (+ n 1))
n)))
(define ca (make-counter 0))
(ca)
(ca)
This outputs 1 and 2 respectively as expected. Why do we need 2 nested procedures here? What are their functions individually?
I'd be appreciated if someone explains in details. Thanks from now on.
Indented properly, this is:
(define make-counter
(lambda (n)
(lambda ()
(set! n (+ n 1))
n)))
By the way, you can use a different syntax:
(define (make-counter n)
(lambda ()
(set! n (+ n 1))
n))
make-counter is a function that accepts a number n and returns an object called closure, which acts like a function but contains a state. Different invocations of make-counter will produce different closures, even when given the same n in argument. A closure can be called using the function-call syntax, as you experimented.
When you call the closure, the code that is contained within is executed. In your example, the closure accepts zero arguments, and mutates the variable named n. Again, the binding from n to a value is local to the closure and different for all instances of counters. But inside a particular counter, n always refer to the same memory location.
A call to the set! function changes what n evaluates to, and replaces the previous value with (+ n 1), incrementing the local counter variable.
I know this is maybe an oddball idea, but I thought might as well give it a try to ask here.
I was experimenting in Racket about state representation without local variables.
The idea was defining a function that prints it's parameter value and if called again gives me another value. Since pure functions called with the same parameter always produce the same result, my workaround-idea got me the following.
(define (counter n)
(displayln n)
(λ () (counter (add1 n)))) ; unapplied lambda so it doesn't go in a loop
Then I devised a function to call counter and its resulting lambdas a certain number of times.
(define (call proc n)
(unless (zero? n)
(let ([x (proc)])
(call x (sub1 n)))))
Which results in this:
> (call (counter 0) 5)
0
1
2
3
4
5
What is the name for the concept applied here? Propably it's something trivial what you need in real applications all the time, but since I have no experience in that respect yet so I can't pinpoint a name for it. Or maybe I just complicated something very simple, but nonetheless I would appreciate an answer so I can look further into it.
Sorry if my question is not clear enough, but english is not my first language and to ask about things I have no name for makes me feel kinda uncertain.
You're using closures to save state: a lambda form stores the environment in which it was defined, and you keep redefining the procedure (called x in your code), so each time it "remembers" a new value for n.
Another way to do the same would be to let the procedure itself keep track of the value - in other words, counter should remember the current n value between invocations. This is what I mean:
(define (counter initial)
(let ((n (sub1 initial)))
(lambda ()
(set! n (add1 n))
n)))
In the above code, the first invocation of counter returns a new lambda that closes over n, and each invocation of that lambda modifies n and returns its new value. Equivalently, we could use Racket-specific syntax for currying and the begin0 special form to achieve the same effect:
(define ((counter n))
(begin0
n
(set! n (add1 n))))
Either way, notice how the procedure "remembers" its previous value:
(define proc (counter 0))
(proc)
=> 0
(proc)
=> 1
And we would call it like this:
(define (call proc n)
(unless (zero? n)
(displayln (proc))
(call proc (sub1 n))))
(call (counter 0) 5)
=> 0
1
2
3
4
Also notice that the above fixes an off-by-one error originally in your code - the procedure was being called six times (from 0 to 5) and not five times as intended, that happened because call invokes counter five times, but you called counter one more time outside, when evaluating (counter 0).
In an effort to find a simple example of CPS which doesn't give me a headache , I came across this Scheme code (Hand typed, so parens may not match) :
(define fact-cps
(lambda(n k)
(cond
((zero? n) (k 1))
(else
(fact-cps (- n 1)
(lambda(v)
(k (* v n))))))))
(define fact
(lambda(n)
(fact-cps n (lambda(v)v)))) ;; (for giggles try (lambda(v)(* v 2)))
(fact 5) => 120
Great, but Scheme isn't Common Lisp, so I took a shot at it:
(defun not-factorial-cps(n k v)
(declare (notinline not-factorial-cps)) ;; needed in clisp to show the trace
(cond
((zerop n) (k v))
((not-factorial-cps (1- n) ((lambda()(setq v (k (* v n))))) v))))
;; so not that simple...
(defun factorial(n)
(not-factorial-cps n (lambda(v)v) 1))
(setf (symbol-function 'k) (lambda(v)v))
(factorial 5) => 120
As you can see, I'm having some problems, so although this works, this has to be wrong. I think all I've accomplished is a convoluted way to do accumulator passing style. So other than going back to the drawing board with this, I had some questions: Where exactly in the Scheme example is the initial value for v coming from? Is it required that lambda expressions only be used? Wouldn't a named function accomplish more since you could maintain the state of each continuation in a data structure which can be manipulated as needed? Is there in particular style/way of continuation passing style in Common Lisp with or without all the macros? Thanks.
The problem with your code is that you call the anonymous function when recurring instead of passing the continuation like in the Scheme example. The Scheme code can easily be made into Common Lisp:
(defun fact-cps (n &optional (k #'values))
(if (zerop n)
(funcall k 1)
(fact-cps (- n 1)
(lambda (v)
(funcall k (* v n))))))
(fact-cps 10) ; ==> 3628800
Since the code didn't use several terms or the implicit progn i switched to if since I think it's slightly more readable. Other than that and the use of funcall because of the LISP-2 nature of Common Lisp it's the identical code to your Scheme version.
Here's an example of something you cannot do tail recursively without either mutation or CPS:
(defun fmapcar (fun lst &optional (k #'values))
(if (not lst)
(funcall k lst)
(let ((r (funcall fun (car lst))))
(fmapcar fun
(cdr lst)
(lambda (x)
(funcall k (cons r x)))))))
(fmapcar #'fact-cps '(0 1 2 3 4 5)) ; ==> (1 1 2 6 24 120)
EDIT
Where exactly in the Scheme example is the initial value for v coming
from?
For every recursion the function makes a function that calls the previous continuation with the value from this iteration with the value from the next iteration, which comes as an argument v. In my fmapcar if you do (fmapcar #'list '(1 2 3)) it turns into
;; base case calls the stacked lambdas with NIL as argument
((lambda (x) ; third iteration
((lambda (x) ; second iteration
((lambda (x) ; first iteration
(values (cons (list 1) x)))
(cons (list 2) x)))
(cons (list 3) x))
NIL)
Now, in the first iteration the continuation is values and we wrap that in a lambda together with consing the first element with the tail that is not computed yet. The next iteration we make another lambda where we call the previous continuation with this iterations consing with the tail that is not computed yet.. At the end we call this function with the empty list and it calls all the nested functions from end to the beginning making the resulting list in the correct order even though the iterations were in oposite order from how you cons a list together.
Is it required that lambda expressions only be used? Wouldn't a named
function accomplish more since you could maintain the state of each
continuation in a data structure which can be manipulated as needed?
I use a named function (values) to start it off, however every iteration of fact-cps has it's own free variable n and k which is unique for that iteration. That is the data structure used and for it to be a named function you'd need to use flet or labels in the very same scope as the anonymous lambda functions are made. Since you are applying previous continuation in your new closure you need to build a new one every time.
Is there in particular style/way of continuation passing style in
Common Lisp with or without all the macros?
It's the same except for the dual namespace. You need to either funcall or apply. Other than that you do it as in any other language.
The following example involves jumping into continuation and exiting out. Can somebody explain the flow of the function. I am moving in a circle around continuation, and do not know the entry and exit points of the function.
(define (prod-iterator lst)
(letrec ((return-result empty)
(resume-visit (lambda (dummy) (process-list lst 1)))
(process-list
(lambda (lst p)
(if (empty? lst)
(begin
(set! resume-visit (lambda (dummy) 0))
(return-result p))
(if (= 0 (first lst))
(begin
(call/cc ; Want to continue here after delivering result
(lambda (k)
(set! resume-visit k)
(return-result p)))
(process-list (rest lst) 1))
(process-list (rest lst) (* p (first lst))))))))
(lambda ()
(call/cc
(lambda (k)
(set! return-result k)
(resume-visit 'dummy))))))
(define iter (prod-iterator '(1 2 3 0 4 5 6 0 7 0 0 8 9)))
(iter) ; 6
(iter) ; 120
(iter) ; 7
(iter) ; 1
(iter) ; 72
(iter) ; 0
(iter) ; 0
Thanks.
The procedure iterates over a list, multiplying non-zero members and returning a result each time a zero is found. Resume-visit stores the continuation for processing the rest of the list, and return-result has the continuation of the call-site of the iterator. In the beginning, resume-visit is defined to process the entire list. Each time a zero is found, a continuation is captured, which when invoked executes (process-list (rest lst) 1) for whatever value lst had at the time. When the list is exhausted, resume-visit is set to a dummy procedure. Moreover, every time the program calls iter, it executes the following:
(call/cc
(lambda (k)
(set! return-result k)
(resume-visit 'dummy)))
That is, it captures the continuation of the caller, invoking it returns a value to the caller. The continuation is stored and the program jumps to process the rest of the list.
When the procedure calls resume-visit, the loop is entered, when return-result is called, the loop is exited.
If we want to examine process-list in more detail, let's assume the list is non-empty. Tho procedure employs basic recursion, accumulating a result until a zero is found. At that point, p is the accumulated value and lst is the list containing the zero. When we have a construction like (begin (call/cc (lambda (k) first)) rest), we first execute first expressions with k bound to a continuation. It is a procedure that when invoked, executes rest expressions. In this case, that continuation is stored and another continuation is invoked, which returns the accumulated result p to the caller of iter. That continuation will be invoked the next time iter is called, then the loop continues with the rest of the list. That is the point with the continuations, everything else is basic recursion.
What you need to keep in mind is that, a call to (call/cc f) will apply the function f passed as argument to call/cc to the current continuation. If that continuation is called with some argument a inside the function f, the execution will go to the corresponding call to call/cc, and the argument a will be returned as the return value of that call/cc.
Your program stores the continuation of "calling call/cc in iter" in the variable return-result, and begins processing the list. It multiplies the first 3 non-zero elements of the list before encountering the first 0. When it sees the 0, the continuation "processing the list element 0" is stored in resume-visit, and the value p is returned to the continuation return-result by calling (return-result p). This call will make the execution go back to the call/cc in iter, and that call/cc returns the passed value of p. So you see the first output 6.
The rest calls to iter are similar and will make the execution go back and forth between such two continuations. Manual analysis may be a little brain-twisting, you have to know what the execution context is when a continuation is restored.
You could achieve the same this way:
(define (prod-iter lst) (fold * 1 (remove zero? lst)))
... even though it could perform better by traversing only once.
For continuations, recall (pun intended) that all call/cc does is wait for "k" to be applied this way:
(call/cc (lambda (k) (k 'return-value)))
=> return-value
The trick here is that you can let call/cc return its own continuation so that it can be applied elsewhere after call/cc has returned like this:
;; returns twice; once to get bound to k, the other to return blah
(let ([k (call/cc (lambda (k) k))]) ;; k gets bound to a continuation
(k 'blah)) ;; k returns here
=> blah
This lets a continuation return more than once by saving it in a variable. Continuations simply return the value they are applied to.
Closures are functions that carry their environment variables along with them before arguments get bounded to them. They are ordinary lambdas.
Continuation-passing style is a way to pass closures as arguments to be applied later. We say that these closure arguments are continuations. Here's half of the current code from my sudoku generator/solver as an example demonstrating how continuation-passing style can simplify your algorithms:
#| the grid is internally represented as a vector of 81 numbers
example: (make-vector 81 0)
this builds a list of indexes |#
(define (cell n) (list (+ (* (car 9) (cadr n))))
(define (row n) (iota 9 (* n 9)))
(define (column n) (iota 9 n 9))
(define (region n)
(let* ([end (+ (* (floor-quotient n 3) 27)
(* (remainder n 3) 3))]
[i (+ end 21)])
(do ([i i
(- i (if (zero? (remainder i 3)) 7 1))]
[ls '() (cons (vector-ref *grid* i) ls)])
((= i end) ls))))
#| f is the continuation
usage examples:
(grid-ref *grid* row 0)
(grid-set! *grid* region 7) |#
(define (grid-ref g f n)
(map (lambda (i) (vector-ref g i)) (f n)))
(define (grid-set! g f n ls)
(for-each (lambda (i x) (vector-set! g i x))
(f n) ls))