I have been playing around with continuations in scheme (specifically guile) over the last couple of days and am a little puzzled by the results that some of the functions have and was wondering if anyone could explain exactly what is going on here.
There is a function called (get-token) that will retrieve the next found token in a given file. For example, if the next 3 tokens were "a", "b", and "c", calling (get-token) would return "a" the first time it is called, "b" the second time it is called, and "c" the third time it is called.
What I would like to do is have a function (peek-token) that will call (get-token), return the token, and then return to a state before the (get-token) function was called. I have attempted a number of different methods to achieve this result, and the one I currently have is:
;; make things a little easier to write
(define-syntax bind/cc
(syntax-rules ()
((bind/cc var . body)
(call/cc (lambda (var) . body)))))
;; function should return next token and then
;; revert to previous state
(define (peek-token)
(bind/cc return
(let ((token (get-token)))
(return token))))
How I understand it right now, the bind/cc will save a continuation at the first return and then execute the following block of code. Then when return is hit again, the program jumps back to where the continuation was bound and the token value is given as a result.
However, when I run the above function the results are exactly the same as the original (get-token) function.
I would be very grateful if anyone could explain where I am going wrong, or express a better way to get the same result (I know some people hate going the way of call/cc).
To hack a Mark Twain misquote to pieces: The reports of call/cc's capabilities are greatly exaggerated.
More specifically, call/cc captures call state, not program state. That means that it captures information about where the flow of code goes when the continuation is invoked. It does not capture information on variables, and in particular, if your get-token saves its iteration state by set!ting a variable, that is not going to be restored when you invoke your continuation.
In fact, your expression of (call/cc (lambda (k) (let ((token (get-token))) (k token)))) should behave identically to simply (get-token); there should not be any observable differences between the two expressions.
Related
The parameter of call/cc is a procedure taking as its argument a continuation. Is the procedure written in CPS?
No.
CPS-styled functions expect other normal functions as their argument(s), and may call them in tail position. These functions are confusingly called "continuations" in Scheme vernacular. I prefer "contingencies", to disambiguate.
The argument function to call/cc expects an actual undelimited continuation as its argument. That actual continuation is not a function. Calling it with a value returns that value into that continuation's return context which is thus saved along with the continuation -- a feat unheard of w.r.t. simple functions.
A tail-called function returns its result into its calling function's caller's context.
A continuation which is called returns the supplied value to its creating call/cc call's context. It is thus not a function. Thus a function using it is not written in CPS.
Firstly, what is CPS? Continuation-Passing Style is a way of compiling a program which relies on continuations (i.e. uses the call/cc operator) into a target language which doesn't support continuation, but does support lexical closures and tail calls (or some facsimile of tail calls, like the ability to roll back the stack when it gets too deep with actual call frames).
A program transformed with CPS is itself not written in the continuation-passing style. It doesn't have to be; it has a call/cc operator provided by the CPS translator, which gives it access to the current continuation wherever it is needed.
Because CPS is mostly a source-to-source transformation, it is illustrated and taught using hand-written, explicit CPS. Quite often, the Scheme language is used for this. The Scheme language already has call/cc, but when experimenting with explicit, hand-written CPS, we have to pretend that call/cc doesn't exist. Under the CPS paradigm, we can, of course, provide an operator called my-call/cc which is built on our CPS, and has nothing to do with the underlying Scheme's call/cc.
In a CPS-compiled language implementation, every procedure has a continuation argument (with the necessary exception of procedures in the host language's library). The functional argument of call/cc, the function which receives the continuation, is no exception. Being a procedure in a CPS-world, it has to have continuation parameter, so that it is compatible with procedure calls, which pass that argument.
The argument procedure of call/cc can in fact use that continuation argument, and the very first example of the Wikipedia demonstrates this. Here is a copy of that example, in which I renamed the return parameter to c, to reduce confusion:
(define (f c) ;; function used for capturing continuation
(c 2) ;; invoke continuation
3) ;; if continuation returns, return 3.
(display (f (lambda (x) x))) ; displays 3
(display (call/cc f)) ; displays 2
The procedure f's c argument doesn't have to be a continuation; in the first call it's just the dummy function (lambda (x) x). f calls it, and that function returns, and so then control falls through to the 3.
Under CPS, f has a hidden argument, which we can reveal with hand-written CPS:
(define (f c k)
(c 2 k)
(k 3 k))
When 3 is being returned, it's because the hidden continuation is invoked. Since the program can do that, f has to have one.
Note that c and k are different continuations! Maybe that's where the confusion comes in. The c continuation is the caller's current one that is passed by call/cc, and is part of the explicit semantics of call/cc. The k is the hidden one added by the CPS transformer. It's f's own continuation. Every function has one in the CPS-transformed world. Under the CPS paradigm, if f wishes to return, it calls k (which is why I renamed return to c). If f wishes to continue the suspended call/cc, it calls c.
By the way, under automatic CPS, k is not going to be literally called k, because that wouldn't be hygienic: programs can freely bind the k symbol. It will have to be a machine-generated symbol (gensym), or receive some other form of hygienic treatment.
The only function that have to be treated specially under CPS so that they don't have continuation arguments are library functions in the host language/VM that are to be available to the CPS-translated language. When the CPS-translated language calls (display obj) to print an object, that display function either has to be a renamed wrapper that can take the continuation argument (and then ignore it and call the real display function without it), or else the call to display has to be specially handled by the CPS translator to omit the continuation argument.
Lastly, why can CPS implement continuations in a language/VM that doesn't natively provide them? The reason is that all function calls in CPS-transformed programs are tail calls, and so never return. The tricky part in implementing continuations is capturing the entire call stack so that when a continuation is resumed, it can return. Such a feature can only be added at the language implementation level. In the 1970's, InterLisp used "spaghetti stacks" to implement this: stack frames are garbage collected heap objects, pointing to parent frames. But what if functions don't do such a thing as returning? Then the need to add a spaghetti stack to the implementation goes away. Note that the spaghetti stack has not exactly gone away: we have something equivalent under CPS, namely chains of captured lexical environments. A continuation is a lambda, which captures the surrounding procedure's k parameter, which is itself a lambda that has captured its parent's k parameter, ... and so on: it's a chain of environments, similar to stack frames, in which the hidden k parameters are frame pointers. But the host language already gave us lexically capturing lambdas; we have just leveraged these lambdas to de facto represent the continuation spaghetti stack, and so we didn't have to go down to the implementation level to do anything.
Is there a way in Chicken Scheme to determine at run-time if a variable is currently defined?
(let ((var 1))
(print (is-defined? var)) ; #t
(print (is-defined? var)) ; #f
EDIT: XY problem.
I'm writing a macro that generates code. This generated code must call the macro in mutual recursion - having the macro simply call itself won't work. When the macro is recursively called, I need it to behave differently than when it is called initially. I would use a nested function, but uh....it's a macro.
Rough example:
(defmacro m (nested)
(if nested
BACKQUOTE(print "is nested")
BACKQUOTE(m #t)
(yes, I know scheme doesn't use defmacro, but I'm coming from Common Lisp. Also I can't seem to put backquotes in here without it all going to hell.)
I don't want the INITIAL call of the macro to take an extra argument that only has meaning when called recursively. I want it to know by some other means.
Can I get the generated code to call a macro that is nested within the first macro and doesn't exist at the call site, maybe? For example, generating code that calls (,other-macro) instead of (macro)?
But that shouldn't work, because a macro isn't a first-class object like a function is...
When you write recursive macros I get the impression that you have an macro expansion (m a b ...) that turns into a (m-helper a (b ...)) that might turn into (let (a ...) (m b ...)). That is not directly recursive since you are turning code into code that just happens to contain a macro.
With destructuring-bind you really only need to keep track of two variables. One for car and one for cdr and with an implicit renaming macro the stuff not coming from the form is renamed and thus hygenic:
(define-syntax destructuring-bind
(ir-macro-transformer
(lambda (form inject compare?)
(define (parse-structure structure expression optional? body)
;;actual magic happens here. Returns list structure with a mix of parts from structure as well as introduced variables and globals
)
(match form
[(structure expression) . body ]
`(let ((tmp ,expression))
,(parse-structure structure 'tmp #f body))))))
To check if something from input is the same symbol you use the supplied compare? procedure. eg. (compare? expression '&optional).
There's no way to do that in general, because Scheme is lexically scoped. It doesn't make much sense to ask if a variable is defined if an referencing an undefined variable is an error.
For toplevel/global variables, you can use the symbol-utils egg but it is probably not going to work as you expect, considering that global variables inside modules are also rewritten to be something else.
Perhaps if you can say what you're really trying to do, I can help you with an alternate solution.
(Though this is indeed simple question, I find sometimes it is common mistakes that I made when writing Scheme program as a beginner.)
I encountered some confusion about the define special form. A situation is like below:
(define num1
2)
(define (num2)
2)
I find it occurs quite often that I call num2 without the parentheses and program fails. I usually end up spending hours to find the cause.
By reading the r5rs, I realized that definition without parenthesis, e.g. num1, is a variable; while definition with parenthesis, e.g. num2, is a function without formal parameters.
However, I am still blurred about the difference between a "variable" and "function".
From a emacs lisp background, I can only relate above difference to similar idea as in emacs lisp:
In Emacs Lisp, a symbol can have a value attached to it just as it can
have a function definition attached to it.
[here]
Question: Is this a correct way of understanding the difference between enclosed and non-enclosed definitions in scheme?
There is no difference between a value and a function in Scheme. A function is just a value that can be used in a particular way - it can be called (as opposed to other kinds of value, such as numbers, which cannot be called, but can be e.g. added, which a function cannot).
The parentheses are just a syntactic shortcut - they're a faster, more readable (to experts) way of writing out the definition of the name as a variable containing a function:
(define (num)
2)
;is exactly the same as
(define num
(lambda () 2) )
The second of these should make it more visually obvious that the value being assigned to num is not a number.
If you wanted the function to take arguments, they would either go within the parentheses (after num, e.g. (num x y) in the first form, or within lambda's parentheses (e.g. (lambda (x y)... in the second.
Most tutorials for the total beginner actually don't introduce the first form for several exercises, in order to drive home the point that it isn't separate and doesn't really provide any true functionality on its own. It's just a shorthand to reduce the amount of repetition in your program's text.
In Scheme, all functions are values; variables hold any one value.
In Scheme, unlike Common Lisp and Emacs Lisp, there are no different namespaces for functions and other values. So the statement you quoted is not true for Scheme. In Scheme a symbol is associated with at most one value and that value may or may not be a function.
As to the difference between a non-function value and a nullary function returning that value: In your example the only difference is that, as you know, num2 must be applied to get the numeric value and num1 does not have to be and in fact can't be applied.
In general the difference between (define foo bar) and (define (foo) bar) is that the former evaluated bar right now and foo then refers to the value that bar has been evaluated to, whereas in the latter case bar is evaluated each time that (foo) is used. So if the expression foo is costly to calculate, that cost is paid when (and each time) you call the function, not at the definition. And, perhaps more importantly, if the expression has side effects (like, for example, printing something) those effects happen each time the function is called. Side effects are the primary reason you'd define a function without parameters.
Even though #sepp2k has answered the question, I will make it more clearer with example:
1 ]=> (define foo1 (display 23))
23
;Value: foo1
1 ]=> foo1
;Unspecified return value
Notice in the first one, foo1 is evaluated on the spot (hence it prints) and evaluated value is assigned to name foo1. It doesn't evaluate again and again
1 ]=> (define (foo2) (display 23))
;Value: foo2
1 ]=> foo2
;Value 11: #[compound-procedure 11 foo2]
1 ]=> (foo2)
23
;Unspecified return value
Just foo2 will return another procedure (which is (display 23)). Doing (foo2) actually evaluates it. And each time on being called, it re-evaluates again
1 ]=> (foo1)
;The object #!unspecific is not applicable.
foo1 is a name that refers a value. So Applying foo1 doesn't make sense as in this case that value is not a procedure.
So I hope things are clearer. In short, in your former case it is a name that refers to value returned by evaluating expression. In latter case, each time it is evaluated.
I am reading DrRacket document http://docs.racket-lang.org/guide/binding.html
There is a function
(define f
(lambda (append)
(define cons (append "ugly" "confusing"))
(let ([append 'this-was])
(list append cons))))
> (f list)
'(this-was ("ugly" "confusing"))
I see that we define function f, inside we define lambda that takes (append), why ?
Procedure (body) for lambda is another function called cons, that appends two strings.
I don't understand this function at all.
Thanks !
The section that you're referring to demonstrates lexical scope in Racket. As in other Scheme implementations, the main point is that you can "shadow" every binding in the language. Unlike most "mainstream" languages, there are no real keywords that are "sacred" in the sense that they can never be shadowed by a local binding.
Note that a really good tool to visualize what is bound where is DrRacket's "check syntax" button: click it, and you'll see your code with highlights that shows which parts are bindings, which are special forms -- and if you hover the mouse over a specific name, you'll see an arrow that tells you where it came from.
Scheme takes some getting used to :)
f is assigned the function returned by the lambda.
lambda defines the function that takes a parameter (called append).
(define cons (append "ugly" "confusing")) is not a function per se, but calls append with the two strings as parameter and assigns the result to cons.
inside the let block, append is re-assigned a different value, the symbol this-was.
the let block creates a list of append (which now contains 'this-was) and cons (which contains '("ugly" "confusing") from 3 above
since 5 is the last statement that value is returned by the whole function which is called f
f is called with the parameter list (the list function). which gets passed as the parameter append. And this is why 3 above creates a list '("ugly" "confusing") which gets assigned to cons.
Hope that cleared up things a bit.
Cheers!
This is related to What is call/cc?, but I didn't want to hijack this question for my own purposes, and some of its arguments like the analogy to setjmp/longjmp evade me.
I think I have a sufficient idea about what a continuation is, I think of it as a snapshot of the current call stack. I don't want to go into the discussion why this might be interesting or what you can do with continuations. My question is more specifically, why do I have to provide a function argument to call/cc? Why doesn't call/cc just return the current continuation, so I could do whatever I please with it (store it, call it, you name it)? In a link from this other question (http://community.schemewiki.org/?call-with-current-continuation-for-C-programmers), it talks about "Essentially it's just a clean way to get the continuation to you and keep out of the way of subsequent jumps back to the saved point.", but I'm not getting it. It seems unnecessarily complicated.
If you use a construct like Jay shows, then you can grab the continuation, but in a way, the value that is grabbed is already spoiled because you're already inside that continuation. In contrast, call/cc can be used to grab the continuation that is still pending outside of the current expression. For example, one of the simplest uses of continuations is to implement a kind of an abort:
(call/cc (lambda (abort)
(+ 1 2 (abort 9))))
You cannot do that with the operation you describe. If you try it:
(define (get-cc) (call/cc values))
(let ([abort (get-cc)]) (+ 1 2 (abort 9)))
then you get an error about applying 9 as a procedure. This happens because abort jumps back to the let with the new value of 9 -- which means that you're now doing a second round of the same addition expression, except that now abort is bound to 9...
Two additional related notes:
For a nice an practical introduction to continuations, see PLAI.
call/cc is a little complex in that it takes in a function -- a conceptually easier to use construct is let/cc which you can find in some implementations like PLT Scheme. The above example becomes (let/cc abort (+ 1 2 (abort 9))).
That would be less versatile. If you want that behavior, you can just do:
(call/cc (lambda (x) x))
You could take a look at the example usages of continuations in "Darrell Ferguson and Dwight Deugo. "Call with Current Continuation Patterns". 8th Conference on Pattern Languages of Programs. September 2001." (http://library.readscheme.org/page6.html) and try to rewrite them using a call/cc-return, defined as above.
I suggest starting by asking yourself: what does it mean to be a first-class continuation?
The continuation of an expression essentially consists of two pieces of data: first, the closure (i.e., environment) of that expression; and second, a representation of what should be done with the result of the expression. A language with first-class continuations, then, is one which has data structures encapsulating these parts, and which treats these data structures just as it would any other.
call/cc is a particularly elegant way to realise this idea: the current continuation is packaged up as a procedure which encapsulates what-is-to-be-done-with-the-expression as what the procedure does when applied to the expression; to represent the continuation this way simply means that the closure of this procedure contains the environment at the site it was invoked.
You could imagine realising the idea of first-class continuations in other ways. They wouldn't be call/cc, and it's hard for me to imagine how such a representation could be simpler.
On a parting note, consider the implementation of let/cc that Eli mentioned, which I prefer to call bind/cc:
(define-syntax bind/cc
(syntax-rules ()
((bind/cc var . body)
(call/cc (lambda (var) . body)))))
And as an exercise, how would you implement call/cc based on bind/cc?
Against common SO netiquette I'm answering my own question, but more as the editor than the provider of the answer.
After a while I started a similar question over at LtU. After all, these are the guys that ponder language design all day long, aren't they, and one of the answers finally kicked in with me. Now things mentioned here, e.g. by Eli or in the original question, make much more sense to me. It's all about what gets included in the continuation, and where the applied continuation sets in.
One of the posters at LtU wrote:
"You can see exactly how call/cc allows you to "keep out of the way." With em or get/cc you need to do some kind of test to determine if you have a back-jump or just the initial call. Basically, call/cc keeps the use of the continuation out of the continuation, whereas with get/cc or em, the continuation contains its use and so (usually) you need to add a test to the beginning of the continuation (i.e. immediately following get/cc / em) to separate the "using the continuation parts" from the "rest of the continuation" parts."
That drove it home for me.
Thank you guys anyway!