Is the environment not part of a continuation in scheme?
I have tested this with Chicken, Gauche, Racket and Gambit, and they all behave similarly:
(define kont #f)
(let ((a 1)
(b 2))
(call-with-current-continuation
(lambda (k)
(set! kont k)
(display 'mutating)
(newline)
(set! a -1)
(set! b -2)))
(display (+ a b))
(newline))
I would expect -3 when the LET is evaluated, but +3 in the calls to kont (since I thought the program would remember the bindings of a and b before mutation):
(let ... ) ; <-- evaluating the LET above
; prints "mutating"
=> -3
(kont 100)
=> -3
(kont 100)
=> -3
So the continuation only affects control, and not the environment? In this case, why is it said that one of the ways to implement continuations is to "copy the stack" (are bindings are not on the stack?)
The continuation captures the bindings. However, as you surmise, these bindings are mutable.
You've been somewhat misled, here, by the "copies the stack" slogan. While this is a reasonable way to think about call/cc, it's not the whole story. For one thing, you really really wouldn't want a language feature that exposed whether or not local bindings were stack-allocated or not.
Instead, call/cc is defined using the notion of "program contexts". For a nice treatment of this, you might want to take a look at Shriram Krishnamurthi's (free, online) textbook PLAI, or at the (not-free, much more in-depth) book "Semantics Engineering with PLT Redex".
As an aside; your program doesn't really check what you wanted it to check, because you never invoked the captured continuation. I think you wanted to write something like this:
#lang racket
(define kont #f)
(let ([a 3])
(let/cc k
(set! kont k)
(set! a 4))
(printf "~s\n" a))
(kont)
... which shows pretty much the same behavior that you mention above.
You change the values of a and b in the environment with set!. So a and b is -1 and -2 in the continuation environment. You can not unroll side effects. There are no differences between a, b and kont in your continuation.
Related
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.
I have an experiment for my project, basically, I need to embedded some s-expression into the code and make it run, like this,
(define (test lst)
(define num 1)
(define l (list))
`#lst) ; oh, this is not the right way to go.
(define lst
`( (define num2 (add1 num))
(displayln num2)))
I want the test function be like after test(lst) in racket code:
(define (test lst)
(define num 1)
(define l (list))
(define num2 (add1 num)
(displayln num2))
How can I do this in racket?
Update
The reason I would like to use eval or the previous questions is that I am using Z3 racket binding, I need to generate formulas (which uses racket binding APIs), and then I will fire the query at some point, that's when I need to evaluate those code.
I have not figured out other ways to go in my case...
One super simple example is, imagine
(let ([arr (array-alloc 10)])
(array-set! arr 3 4))
I have some model to analyze the constructs (so I am not using racketZ3 directly), during each analyzing point, I will map the data types in the program into the Z3 types, and made some assertions,
I will generate something like:
At allocation site, I will need to make the following formula:
(smt:declare-fun arr_z3 () IntList)
(define len (make-length 10))
Then at the array set site, I will have the following assertions and to check whether the 3 is less then the length
(smt:assert (</s 3 (len arr_z3)))
(smt:check-sat)
Then finally, I will gather the formulas generated as above, and wrap them in the form which is able to fire Z3 binding to run the following gathered information as code:
(smt:with-context
(smt:new-context)
(define len (make-length 10))
(smt:assert (</s 3 (len arr_z3)))
(smt:check-sat))
This is the super simple example I can think of... making sense?
side note. Z3 Racket binding will crash for some reason on version 5.3.1, but it mostly can work on version 5.2.1
Honestly, I don’t understand what exactly you would like to achieve. To quote N. Holm, Sketchy Scheme, 4.5th edition, p. 108: »The major purpose of quasiquotation is the construction of fixed list structures that contain only a few variable parts«. I don’t think that quasiquotation would be used in a context like you are aiming at.
For a typical context of quasiquotation consider the following example:
(define (square x)
(* x x))
(define sentence
'(The square of))
(define (quasiquotes-unquotes-splicing x)
`(,#sentence ,x is ,(square x)))
(quasiquotes-unquotes-splicing 2)
===> (The square of 2 is 4)
Warning: if you're not familiar with how functions work in Scheme, ignore the answer! Macros are an advanced technique, and you need to understand functions first.
It sounds like you're asking about macros. Here's some code that defines test to be a function that prints 2:
(define-syntax-rule (show-one-more-than num)
(begin
(define num2 (add1 num))
(displayln num2)))
(define (test)
(define num1 1)
(show-one-more-than num1))
Now, I could (and should!) have written show-one-more-than as a function instead of a macro (the code will still work if you change define-syntax-rule to define), but macros do in fact operate by producing code at their call sites. So the above code expands to:
(define (test)
(define num1 1)
(begin
(define num2 (add1 num1))
(displayln num2)))
Without knowing the problem better, it's hard to say what the correct approach to this problem is. A brute force approach, such as the following:
#lang racket
(define (make-test-body lst)
(define source `(define (test)
(define num 1)
(define l (list))
,#lst))
source)
(define lst
`((define num2 (add1 num))
(displayln num2)))
(define test-source
(make-test-body lst))
(define test
(parameterize ([current-namespace (make-base-namespace)])
(eval `(let ()
,test-source
test))))
(test)
may be what you want, but probably not.
I have to define a variadic function in Scheme that takes the following form:
(define (n-loop procedure [a list of pairs (x,y)]) where the list of pairs can be any length.
Each pair specifies a lower and upper bound. That is, the following function call: (n-loop (lambda (x y) (inspect (list x y))) (0 2) (0 3)) produces:
(list x y) is (0 0)
(list x y) is (0 1)
(list x y) is (0 2)
(list x y) is (1 0)
(list x y) is (1 1)
(list x y) is (1 2)
Obviously, car and cdr are going to have to be involved in my solution. But the stipulation that makes this difficult is the following. There are to be no assignment statements or iterative loops (while and for) used at all.
I could handle it using while and for to index through the list of pairs, but it appears I have to use recursion. I don't want any code solutions, unless you feel it is necessary for explanation, but does anyone have a suggestion as to how this might be attacked?
The standard way to do looping in Scheme is to use tail recursion. In fact, let's say you have this loop:
(do ((a 0 b)
(b 1 (+ a b))
(i 0 (+ i 1)))
((>= i 10) a)
(eprintf "(fib ~a) = ~a~%" i a))
This actually get macro-expanded into something like the following:
(let loop ((a 0)
(b 1)
(i 0))
(cond ((>= i 10) a)
(else (eprintf "(fib ~a) = ~a~%" i a)
(loop b (+ a b) (+ i 1)))))
Which, further, gets macro-expanded into this (I won't macro-expand the cond, since that's irrelevant to my point):
(letrec ((loop (lambda (a b i)
(cond ((>= i 10) a)
(else (eprintf "(fib ~a) = ~a~%" i a)
(loop b (+ a b) (+ i 1)))))))
(loop 0 1 0))
You should be seeing the letrec here and thinking, "aha! I see recursion!". Indeed you do (specifically in this case, tail recursion, though letrec can be used for non-tail recursions too).
Any iterative loop in Scheme can be rewritten as that (the named let version is how loops are idiomatically written in Scheme, but if your assignment won't let you use named let, expand one step further and use the letrec). The macro-expansions I've described above are straightforward and mechanical, and you should be able to see how one gets translated to the other.
Since your question asked how about variadic functions, you can write a variadic function this way:
(define (sum x . xs)
(if (null? xs) x
(apply sum (+ x (car xs)) (cdr xs))))
(This is, BTW, a horribly inefficient way to write a sum function; I am just using it to demonstrate how you would send (using apply) and receive (using an improper lambda list) arbitrary numbers of arguments.)
Update
Okay, so here is some general advice: you will need two loops:
an outer loop, that goes through the range levels (that's your variadic stuff)
an inner loop, that loops through the numbers in each range level
In each of these loops, think carefully about:
what the starting condition is
what the ending condition is
what you want to do at each iteration
whether there is any state you need to keep between iterations
In particular, think carefully about the last point, as that is how you will nest your loops, given an arbitrary number of nesting levels. (In my sample solution below, that's what the cur variable is.)
After you have decided on all these things, you can then frame the general structure of your solution. I will post the basic structure of my solution below, but you should have a good think about how you want to go about solving the problem, before you look at my code, because it will give you a good grasp of what differences there are between your solution approach and mine, and it will help you understand my code better.
Also, don't be afraid to write it using an imperative-style loop first (like do), then transforming it to the equivalent named let when it's all working. Just reread the first section to see how to do that transformation.
All that said, here is my solution (with the specifics stripped out):
(define (n-loop proc . ranges)
(let outer ((cur ???)
(ranges ranges))
(cond ((null? ranges) ???)
(else (do ((i (caar ranges) (+ i 1)))
((>= i (cadar ranges)))
(outer ??? ???))))))
Remember, once you get this working, you will still need to transform the do loop into one based on named let. (Or, you may have to go even further and transform both the outer and inner loops into their letrec forms.)
Consider the following code:
(call-with-values
(lambda ()
(call/cc (lambda (k)
(k k k))))
(lambda (x y)
(procedure-arity y)))
It's pretty obvious here that the continuation at the point of the call/cc call is the lambda on the right-hand side, so its arity should be 2. However, the return value of the above (in Racket) is (arity-at-least 0) instead.
Indeed, running similar code in Guile (substituting procedure-minimum-arity for procedure-arity) shows that the continuation also supposedly allows any number of arguments, even though it's pretty clearly not the case.
So, why is that? As far as I understand (correct me if my understanding is wrong), the arity of a continuation is pretty straightforward: it's 1 except in the context of call-with-values, in which case it's whatever the arity of the right-hand-side lambda is. (Which, granted, can be complicated if it's a case-lambda or the like, but no more complicated than if you were calling (procedure-arity (case-lambda ...)) directly.)
A simpler way to see the same is:
(call-with-values
(lambda () (error 'arity "~v" (procedure-arity (call/cc (λ (k) k)))))
(lambda (x y) (procedure-arity y)))
and even simpler:
(procedure-arity (call/cc (λ (x) x)))
And for your question -- it's clear in the first case that the continuation expects two inputs, but cases like that are not too common. Eg, they're usually such examples, whereas "real code" would use define-values or have some unknown continuation, where the continuations that call/cc creates can have different arities depending on the context that they were created at. This means that there's not much point in trying to figure out these rare cases where the continuation's arity is known.
Footnote:
;; nonsensical, but shows the point
(define (foo) (call/cc (λ (x) x)))
(define x (foo))
(define-values [y z] (foo))
rt.
I want to redefine a function at run time so that i can change the behavior of the system at run time.
thanks.
(define (foo x) ...stuff...)
(set! foo (lambda (x) ...different stuff...))
It might be advisable to use let to do this locally, this can also apply to keywords in this sense:
(let ((define +))
(define 2 3)) ; ===> 5
Or even redefine them to constants, remember, Scheme is a lisp-1:
(let ((define 2) (+ 4))
(- define +)) ; ===> -2
Or even:
(let ((quote /))
'3) ===> 1/3
Doing it only locally preserves the functional style.
Assuming you want to overload a function you defined earlier, simply define it again. This also works for redefining functions such as car and cdr, e.g. to make car into cdr:
(define (car x) (cdr x))
However, I think you won't be able to affect other already defined functions with such a redefinition, so a system function which uses car will still use the original system car and not yours:
(define (test x) (car x))
(define (car x) (cdr x))
(test '(1 2 3))
1
I guess the reason for this is that internally the symbols disappear once a function gets read or evaluated and the symbols are replaced by what they're bound to; in this case, the actual code of the function. So rebinding a symbol to a different function won't affect the rest of your already defined code. This is usually a good thing because it helps uphold referential transparency.
If you want to redefine scheme keywords such as lambda or cond, use let-syntax (see http://community.schemewiki.org/?scheme-faq-language)