Hello!
Trying to learn scheme, I've made this small test file and tried it in gambit-c and plt-scheme.
(define (call/ccc x) (call-with-current-continuation x))
(define coco 1)
(begin (display "begin") (newline) (call/ccc (lambda (c) (set! coco c))) (display "again") (newline) (display "end") (newline) )
(coco 13)
The result was: - plt-scheme printed: begin again end 13
- gambit-c printed: begin again end again end again end ...
My question: which one is the intended behavior ?
Thank you!
________ Information from NOD32 ________ This message was checked by NOD32 Antivirus System for Linux Mail Servers. part000.txt - is OK http://www.eset.com
Afficher les réponses par date
How did you enter the code for evaluation? Did you type it in to PLT's REPL and loaded it from a file in Gambit?
The behaviour of Gambit's "load" is to treat the content of the file as a complete sequence of commands/expressions. It is as though the sequence was wrapped in a "begin" form. Equivalently, in this case, it is as though the whole code was in the body of a toplevel procedure definition which is called once, as in:
----------------------------------------------------------------- (define (the-whole-file)
(define (call/ccc x) (call-with-current-continuation x))
(define coco 1)
(begin (display "begin") (newline) (call/ccc (lambda (c) (set! coco c))) (display "again") (newline) (display "end") (newline) )
(coco 13))
(the-whole-file) -----------------------------------------------------------------
It should be clear now why you have an endless loop. The continuation stored in coco is in essence:
(lambda (result) (display "again") (newline) (display "end") (newline) (coco 13))
So the call (coco 13) will loop forever.
I'm actually surprised that PLT does not do the same. Most probably PLT's "load" is modeled on the REPL (i.e. it is a read-eval-print loop which simply takes its input from a file). So the continuation stored in coco is really:
(lambda (result) (display "again") (newline) (display "end") (newline) (next-iteration-of-the-load-repl))
But when (next-iteration-of-the-load-repl) is called, it will read end- of-file and thus exit load's read-eval-print loop.
I think Gambit's model is cleaner, as it allows to have the same semantics for load whether the file being loaded is source code or compiled code.
Marc
On 11-Jun-08, at 4:53 AM, Cristian Baboi wrote:
Hello!
Trying to learn scheme, I've made this small test file and tried it in gambit-c and plt-scheme.
(define (call/ccc x) (call-with-current-continuation x))
(define coco 1)
(begin (display "begin") (newline) (call/ccc (lambda (c) (set! coco c))) (display "again") (newline) (display "end") (newline) )
(coco 13)
The result was:
plt-scheme printed: begin again end 13
gambit-c printed: begin again end again end again end ...
My question: which one is the intended behavior ?
Thank you!
________ Information from NOD32 ________ This message was checked by NOD32 Antivirus System for Linux Mail Servers. part000.txt - is OK http://www.eset.com _______________________________________________ Gambit-list mailing list Gambit-list@iro.umontreal.ca https://webmail.iro.umontreal.ca/mailman/listinfo/gambit-list
On Wed, 11 Jun 2008 15:06:24 +0300, Marc Feeley feeley@iro.umontreal.ca wrote:
How did you enter the code for evaluation? Did you type it in to PLT's REPL and loaded it from a file in Gambit?
No. I typed it in notepad, then loaded it from the file in both cases.
The behaviour of Gambit's "load" is to treat the content of the file as a complete sequence of commands/expressions. It is as though the sequence was wrapped in a "begin" form. Equivalently, in this case, it is as though the whole code was in the body of a toplevel procedure definition which is called once, as in:
I understand why. I was just surprised by the difference in behavior.
I'm actually surprised that PLT does not do the same. Most probably PLT's "load" is modeled on the REPL (i.e. it is a read-eval-print loop which simply takes its input from a file).
The thing is that in PLT, at the top level, (coco 13) will return 13
I think Gambit's model is cleaner, as it allows to have the same semantics for load whether the file being loaded is source code or compiled code.
I asked because it is not clear to me if there is some standard that prescribe how the top level should behave and I was surprised by the different results. In both cases I've run the file by calling (load "test.scm").
Thank you.
________ Information from NOD32 ________ This message was checked by NOD32 Antivirus System for Linux Mail Servers. part000.txt - is OK http://www.eset.com
I'm actually surprised that PLT does not do the same. Most probably PLT's "load" is modeled on the REPL (i.e. it is a read-eval-print loop which simply takes its input from a file).
I changed the example to:
(module test mzscheme
(define (call/ccc x) (call-with-current-continuation x))
(define coco 1)
(begin (display "begin") (newline) (call/ccc (lambda (c) (set! coco c))) (display "again") (newline) (display "end") (newline) )
(coco 13) )
and loaded it with require. This time the result was the same as gambit-c.
________ Information from NOD32 ________ This message was checked by NOD32 Antivirus System for Linux Mail Servers. part000.txt - is OK http://www.eset.com
At Wed, 11 Jun 2008 08:06:24 -0400, Marc Feeley wrote:
I'm actually surprised that PLT does not do the same. Most probably PLT's "load" is modeled on the REPL (i.e. it is a read-eval-print loop which simply takes its input from a file). So the continuation stored in coco is really:
(lambda (result) (display "again") (newline) (display "end") (newline) (next-iteration-of-the-load-repl))
But when (next-iteration-of-the-load-repl) is called, it will read end- of-file and thus exit load's read-eval-print loop.
I think Gambit's model is cleaner, as it allows to have the same semantics for load whether the file being loaded is source code or compiled code.
For what it's worth, here's what PLT Scheme actually does:
* Every top-level form is wrapped with a prompt.
* `begin' at the top level splices. Consequently, each sub-form within a top-level `begin' is also wrapped with a prompt.
That's why `(coco 13)' after the `load' produces 13, instead of an error about a closed file.
[ If anyone wonders what I mean by "prompt", see http://www.cs.utah.edu/plt/publications/icfp07-fyff.pdf ]
It's true that `load' in PLT Scheme reads and evaluates forms from a file one-by-one, but still with prompts. That can be consistent with compiling the forms one-by-one to produce a file whose compiled fragments are evaluated one-by-one. In particular, the prompts around sub-forms in a top-level `begin' help keep everything consistent (without having say, for example, that `begin' only sort of "splices" into the top level). Concretely, try compiling Cristian's example with `mzc --zo' and `load' the resulting ".zo" file.
Of course, `load' in neither Gambit nor PLT Scheme really makes evaluation from source consistent with evaluation of compiled code --- not when macros get involved. Given how the Scheme top-level is hopeless in this respect, PLT Scheme leaves most problems of compiled-vs-source consistency to the module system, and we see `load' as a tool similar to REPL evaluation. From that perspective, prompts play a role in making `load' and REPL evaluation more consistent with each other.
Matthew
Matthew Flatt mflatt@cs.utah.edu writes:
At Wed, 11 Jun 2008 08:06:24 -0400, Marc Feeley wrote:
[...]
I think Gambit's model is cleaner, as it allows to have the same semantics for load whether the file being loaded is source code or compiled code.
For what it's worth, here's what PLT Scheme actually does:
I'm glad you watch this list, professor! I feel like I understand PLT Scheme better than when I used it ;)
Joel