On 8/19/2017 6:16 AM, Zelphir Kaltstahl wrote:
I looked at the code for a while again and think I now begin to understand it a 
bit more:

I did not know `(let/ec` so I had to read about it. It says, that it is equivalent to 
`(call/ec proc` or something, which is equivalent to `(call-with-escape-continuation 
...`. Uff … I don't know much about continuations, except from a vague idea of when they 
are called. The idea gets mingled with structures in other programming languages which 
are "catching exceptions" and such stuff. I don't know this stuff, so I guess 
`(call-with-escape-continuation` works like catching an exception, which is not really an 
exception, but just a signal, that code is returning. Then instead of simply returning, 
the escape continuation is called. This is done implicitly without specifying a named 
exception for returning and without defining some conditional structure on the side where 
it would return to.

This could all be wrong ...

It's at least a misconception. Continuations are _not_ exceptions - they are a much lower level construct. Exception handling is built on top of continuations.

There is nothing magic or mysterious about a continuation. In Scheme, continuations are the moral equivalent of GOTO with arguments [yes, you can pass arguments to continuations]. In actual fact they can be used to write code that jumps around arbitrarily ... but the standard uses are more structured.

When you say, (let/ec foo ... ) , all that's happening is the compiler defines a pseudo-function named 'foo' that when called will exit from the block of code in the scope of the let. (call/cc foo ...) does the same, but assumes you will be immediately calling a function instead of executing inline code. Invoking foo anywhere in the function (or its descendants) will jump back out of the call chain. Scheme makes invoking the continuation look like a function call even though it really is a jump that won't return.

You do need to learn about continuations because they are the underlying basis of many programming techniques: exceptions, co-routines, threads, etc. ... all of which can be implemented directly in Scheme without dipping into assembler.

Dan Friedman's paper is great, but is too technical and too Scheme-centric for beginners. The Wikipedia article on continuations (https://en.wikipedia.org/wiki/Continuation) is simpler to understand. Be sure to look through the "further reading" and links at the end. But the way to really get a handle on what continuations are is to read a book on compilers - at which point you'll realize that they really are little more than a branch target.

However, with this kind of idea about escape continuations in mind, I think I get the idea behind 
using `(let/ec` in the code. When a place wants to exit, it is stopped from doing so, giving it 
more work, as if to say: "Hey wait! You can escape, but only if you do THIS! (escape 
continuation)" Then the place, desperately wanting to escape thinks: "Damn, OK, I'll do 
just that little bit of code more.", not realizing, that it is stuck in a loop. How mean.

I wonder however, if there is no simpler way of doing this.

I mean, if `(place-channel-get ...)` blocks, could I simply put stuff into an 
endless loop without escape continuation and only break the loop, if a certain 
symbol is received on the channel?

How are you going to "break out" of the loop? In Scheme there are only 3 ways to jump over or out of a block of code: return from a function, invoke a continuation, or raise an exception. The loop I wrote was in the middle of the function where returning was not an option and there was no reason to raise an exception. Delimited (aka "escape") continuations are a structured way to jump out of a loop.

A 'do' loop is a macro that hides continuations inside. You might as well learn to use them directly.

Since `(place-channel-get ...)` is blocking, it should not generate any CPU 
load, when there is no message on the channel (right?).

Why do I need to introduce something as complex as `(let/ec ...)`?

Because you need to exit from of the - otherwise infinite - loop.

I appreciate the code shared here. I just hesitate to use it, when I don't even 
understand it myself or when I am super unsure about understanding it (escape 
continuations). I am also thinking about how I can replace all the exclamation 
mark procedures, before adding it to my other code, which does not deal with 
assignments so far.

Don't get too hung up on style points ... the goal is to write code that is easy to read and that you [and others] will understand without needing days of intensive study. If avoiding assignments makes your code longer and more convoluted, then doing it was a bad thing.

Is there some easy to understand introduction to continuations in Racket? (not 
a super clever and scientific Friedman paper, which I'd probably need 1 year to 
actually understand :D)

A book on compiler construction is your best bet.

Scheme - and thus Racket which is based on it - exposes continuations in ways that most other language don't. You will need to learn the ways that Scheme defines and invoke continuations to use them effectively ... but there's really no magic going on.

George



--
You received this message because you are subscribed to the Google Groups "Racket 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to