

Python's "yield" - In Scheme (Using Continuations) - PieSquared
http://blog.bytefreeze.com/past/2010/6/22/pythons_yield_in_scheme/

======
philh
This doesn't require call/cc - you can do it with just closures (I've done it
in perl, for example). It's also not as powerful as yield, in that it requires
the list of return values to be precomputed.

However, call/cc could be used to implement something of equivalent power to
yield.

~~~
lmkg
> it requires the list of return values to be precomputed.

I thought Scheme's semantics were allowed to be lazy to some extent, but I'm
unaware of the finer points of it. Would a conforming implementation allow
being lazy in this instance?

I definitely agree that this seems like a strange place to pull out
continuations. I get the impression that the author started from wanting an
example of continuations, rather than an implementation of yield. As other
people have pointed out, continuations and closures are equivalently powerful
given CPS, but continuations seem simply gratuitous for this example.

Just to make my point, here's my Common Lisp implementation:

    
    
      (defun generator (list last-val)
        (lambda ()
          (if list (pop list) last-val)))
    

Scheme would have to roll its own Pop macro, but I don't see how that would
require a raw continuation primitive.

~~~
PieSquared
I'm the one who wrote the post, and in retrospect I can see why people would
be a bit confused at this example.

I started out wanting to explain my actual implementation of a 'yield'
command. As I wrote the post, though, it grew overcomplicated and filled with
explanations of Scheme's syntax macros, which was not at all my intention.

I guess in simplifying the implementation I also lost a bit of the idea behind
it. You _do_ need continuations to implement a general-case yield; if you just
want generators for a list, you can use closers (and be more efficient, too).

Thanks to you (and to parent) for pointing that out; if you don't mind, I'll
add mention of what you said to the blog post?

~~~
lmkg
By all means, go ahead =).

I'm actually a fan of continuations, I just didn't see what the purpose was in
the example that you gave. What would be helpful is an explanation of why a
yield with continuations is more powerful than one with closures. That will
probably require an explanation of what you mean by a "general-case yield"
(I'm not that familiar with Python).

------
dododo
call/cc was introduced, as i understand it, as a means of formalising goto in
this paper:

Denotational semantics of goto: An exit formulation and its relation to
continuations. Cliff B. Jones.
<http://www.springerlink.com/content/f340274565373810/>

this implementation of yield in scheme reminds me of the procedure linkage
table in ELF executables, roughly in C: goto *current_entry_point then update
current_entry_point on return (in the ELF PLT this is a one shot update).

~~~
carterschonwald
actually it goes back even farther!

ftp://ftp.cs.cmu.edu/user/jcr/histcont.pdf has a history written by John
Reynolds, probably the world's most senior (and baller in the sense of doing
amazing work) among currently active programming language theoreticians.

Quote from pages 2-3 of the linked pdf:

Apparently, the earliest description of a use of continuations was given by
Adriaan van Wijngaarden (Director of the Mathematisch Centrum in Amsterdam) in
September 1964, at an IFIP Working Conference on For- mal Language Description
Languages held in Baden bei Wien, Austria. A written version of this talk,
along with a transcript of the discussion that followed, appears in the
conference proceedings [45].

Van Wijngaarden’s goal was to formulate a preprocessor that would translate
Algol 60 into a more restricted sublanguage. The final stage of the
preprocessing was (what we would now call) a transformation of proper
procedures into continuation-passing style (CPS) [41], with an at- tendant
elimination of labels and goto statements. (An earlier stage of the
preprocessing replaced function procedures by proper procedures.) As van
Wijngaarden described the transformation:

Provide each procedure declaration with an extra formal param- eter —
specified label — and insert at the end of its body a goto statement leading
to that formal parameter. Correspond- ingly, label the statement following a
procedure statement, if not labeled already, and provide that label as the
correspond- ing extra actual parameter. [45]

~~~
dododo
oops. you're right. i provided a bad reference. sorry!

