Mentioned on c.l.py: http://cseng.aw.com/book/related/0,3833,0805311912+20,00.html This is the full text of "Advanced Programming Language Design", available online a chapter at a time in PDF format. Chapter 2 (Control Structures) has a nice intro to coroutines in Simula and iterators in CLU, including a funky implementation of the latter via C macros that assumes you can get away with longjmp()'ing "up the stack" (i.e., jumping back into a routine that has already been longjmp()'ed out of). Also an intro to continuations in Io: CLU iterators are truly elegant. They are clear and expressive. They provide a single, uniform way to program all loops. They can be implemented efficiently on a single stack. ... Io continuations provide a lot of food for thought. They spring from an attempt to gain utter simplicity in a programming language. They seem to be quite expressive, but they suffer from a lack of clarity. No matter how often I have stared at the examples of Io programming, I have always had to resort to traces to figure out what is happening. I think they are just too obscure to ever be valuable. Of course in the handful of other languages that support them, continuations are a wizard-level implementation hook for building nicer abstractions. In Io you can't even write a loop without manipulating continuations explicitly. takes-all-kinds-ly y'rs - tim
On Sun, Feb 11, 2001 at 07:08:37PM -0500, Tim Peters wrote:
are a wizard-level implementation hook for building nicer abstractions. In Io you can't even write a loop without manipulating continuations explicitly.
Note that, as Finkel mentions somewhere near the end of the book, Io was never actually implemented. (The linked list example is certainly head-exploding, I must say...) --amk
Tim Peters wrote:
Mentioned on c.l.py:
http://cseng.aw.com/book/related/0,3833,0805311912+20,00.html
This is the full text of "Advanced Programming Language Design", available online a chapter at a time in PDF format.
Chapter 2 (Control Structures) has a nice intro to coroutines in Simula and iterators in CLU, including a funky implementation of the latter via C macros that assumes you can get away with longjmp()'ing "up the stack" (i.e., jumping back into a routine that has already been longjmp()'ed out of). Also an intro to continuations in Io:
CLU iterators are truly elegant. They are clear and expressive. They provide a single, uniform way to program all loops. They can be implemented efficiently on a single stack. ... Io continuations provide a lot of food for thought. They spring from an attempt to gain utter simplicity in a programming language. They seem to be quite expressive, but they suffer from a lack of clarity. No matter how often I have stared at the examples of Io programming, I have always had to resort to traces to figure out what is happening. I think they are just too obscure to ever be valuable.
Yes, this is a nice and readable text. But, the latter paragraph shows that the author is able to spell continuations without understanding them. Well, probably he does understand them, but his readers don't. At least this paragraph shows that he has an idea: """ Given that continuations are very powerful, why are they not a part of ev-ery language? Why do they not replace the conventional mechanisms of con-trol structure? First, continuations are extremely confusing. The examples given in this section are almost impossible to understand without tracing, and even then, the general flow of control is lost in the details of procedure calls and parameter passing. With experience, programmers might become comfortable with them; however, continuations are so similar to gotos (with the added complexity of parameters) that they make it difficult to structure programs. """ I could understand the examples without tracing, and they were by no means confusing, but very clear. I believe the above message coming from a stack-educated brain (as we almost are) which is about to get the point, but still is not there.
Of course in the handful of other languages that support them, continuations are a wizard-level implementation hook for building nicer abstractions. In Io you can't even write a loop without manipulating continuations explicitly.
What is your message? Do you want me to react? Well, here the expected reaction, nothing new. I already have given up pushing continuations for Python; not because continuations are wrong, but too powerful for most needs and too simple (read "obscure") for most programmers. I will provide native implementations of coroutines & co in one or two months (sponsored work), and continuation support will be conditionally compiled into Stackless. I still regard them useful for education (Raphael Finkel would argue differently after playing with Python continuations), but their support should not go into the Python standard. I'm currently splitting the compromizes in ceval.c by being continuation related or not. My claim that this makes up 10 percent of the code or less seems to hold. chewing-on-the-red-herring-ly y'rs - chris -- Christian Tismer :^) <mailto:tismer@tismer.com> Mission Impossible 5oftware : Have a break! Take a ride on Python's Kaunstr. 26 : *Starship* http://starship.python.net 14163 Berlin : PGP key -> http://wwwkeys.pgp.net PGP Fingerprint E182 71C7 1A9D 66E9 9D15 D3CC D4D7 93E2 1FAE F6DF where do you want to jump today? http://www.stackless.com
[Christian Tismer]
... What is your message? Do you want me to react?
I had no msg other than to share a cool link I thought people here would find interesting. While Greg Wilson, e.g., complained about the C macro implementation of CLU iterators in his review, that's exactly the kind of thing that should be *interesting* to Python-Dev'ers: a long and gentle explanation of an actual implementation. I expect that most people here still have no clear idea how generators (let alone continuations) can be implemented, or why they'd be useful. Here's a function to compute the number of distinct unlabelled binary trees with n nodes (these are the so-called Catalan numbers -- the book didn't mention that): cache = {0: 1} def count(n): val = cache.get(n, 0) if val: return val for leftsize in range(n): val += count(leftsize) * count(n-1 - leftsize) cache[n] = val return val Here's one to generate all the distinct unlabelled binary trees with n nodes: def genbin(n): if n == 0: return [()] result = [] for leftsize in range(n): for left in genbin(leftsize): for right in genbin(n-1 - leftsize): result.append((left, right)) return result For even rather small values of n, genbin(n) builds lists of impractical size. Trying to build a return-one-at-a-time iterator form of genbin() today is surprisingly difficult. In CLU or Icon, you just throw away the "result = []" and "return result" lines, and replace result.append with "suspend" (Icon) or "yield" (CLU). Exactly the same kind of algorithm is needed to generate all ways of parenthesizing an n-term expression. I did that in ABC once, in a successful attempt to prove via exhaustion that raise-complex-to-integer-power in the presence of signed zeroes is ill-defined under IEEE-754 arithmetic rules. While nobody here cares about that, the 754 committee took it seriously indeed. For me, I'm still just trying to get Python to address all the things I found unbearable in ABC <0.7 wink>. so-if-there's-a-msg-here-it's-unique-to-me-ly y'rs - tim
participants (3)
-
Andrew Kuchling
-
Christian Tismer
-
Tim Peters