Hi Oleg, Thanks again for your comments, I've replied inline below. On Mon, Feb 20, 2012 at 12:04 AM, <oleg@okmij.org> wrote: > > I'd like to draw attention to one part of R5RS that was in need of > clarifications or revisions -- call/cc. It is one of the most > confusing features of Scheme, for a good reason: it is a wrong > abstraction. > > The new features of R7RS, exceptions and parameters -- > make clarifications or revisions more urgent. The interactions of > call/cc with exceptions and dynamic binding are highly non-trivial and > confusing, leading to unexpected consequences such as memory leaks, > exceptions handled with unexpected handlers or the files that should > be closed remaining open. "Confusing" is rather subjective. Exceptions and parameters are defined in terms of call/cc and dynamic-wind, so the semantics are at least unambiguous - parameters are in fact strictly a library feature. I think the problem here is that the interaction of call/cc and dynamic-wind itself can be confusing, and it is for this reason that call/cc is not considered an every day tool but a basis for defining simpler control operators. > At the very least, I would like to see the > Report warning about the problems caused by call/cc and advising > against its use unless strictly necessary. Ideally, I'd like to see > call/cc relegated to optional features, with opening a discussion for > better abstractions. (I have a few in mind.) The WG2 has already decided to include some form of delimited continuation in the "Large" language, and is in fact looking for new volunteers for that effort. We'd be thrilled to have whatever help you can contribute there. For the R7RS "Small" language report, making call/cc optional is a very big step, and we would need a better abstraction already available and widely used. I think as a standard the correct path would be to make the best alternative possible available in R7RS "Large", encourage its use, and then consider making call/cc optional in R8RS. > The primitive call/cc has been added to Scheme when little has been > known about expressiveness of undelimited and delimited > continuations. [I'm generous: a good alternative -- generators -- and > their efficient implementations have been known before Scheme was > invented.] Now we know that capturing undelimited continuations gives > us, per se, little power. We cannot even implement exceptions -- let > alone more interesting effects such as state or non-determinism -- > without using other features such as mutation. And yet Scheme has mutation. I don't think it's fair to consider features in isolation, but to view Scheme as a complete language, and consider the interaction of all features provided. With mutation, call/cc can implement delimited continuations. The inverse is not so - delimited continuations can't implement call/cc nor many uses of it such as amb. Thus call/cc makes Scheme strictly more expressive than delimited continuations. Since it can be used to implement delimited continuations as a library, it is preferable from a theoretical standpoint. From a practical standpoint implementations are free to implement the delimited conts more efficiently (and in fact use the same infrastructure to implement call/cc by wrapping a delimiter around the whole program). So in the long term I think it makes the most sense to provide both, treat call/cc as more fundamental, yet encourage use of delimited conts wherever possible. > Using call/cc has many practical drawbacks -- for example, huge > resource leak. Capturing the whole continuation (where only a prefix > is really needed) prevents objects referenced from the unneeded suffix > of the continuations from being garbage collected. I understand how this can be an issue in theory, but are there real-world applications where this has been a problem? It seems to me that when using call/cc for delimited cont type control flow, the suffix will remain constant and will be needed eventually anyway. When using call/cc for undelimited control flow, this is something that would not have been possible otherwise anyway, and is in a sense a pay-as-you-go feature. > All the uses of call/cc in practical programs that I'm aware of are > better served by more appropriate operations. For example, it has > been frequently observed that in most all the cases a captured > continuation is invoked at most once. As shown by Dybvig et al and > Feeley, one-shot continuations are much more efficient to implement. Yes, I think one-shot continuations should also be included in the large language, following the same arguments as delimited continuations - they should be used wherever possible, although in some implementations they may simply be implemented in terms of call/cc. > Ironically, the illustrating examples of call/cc in R7RS [p49 of the > draft 6] are better implemented with now provided exceptions. The > draft retains the phrase [p49, middle of the first column] > from R5RS that ``A common use of > call-with-current-continuation is for structured, non-local exits from > loops or procedure bodies''. I'd like to propose to add the phrase > ``Non-local exists are so common that R7RS provides better tools for > that -- exceptions.'' There are those who would disagree on general style principals, that exceptions should never be used for non-exceptional situations. call/cc with a cont named "return" is a common idiom, and more obvious to me than (guard (exn (else exn)) ... (raise <result>)) although of course call/ec can be more efficient. > My second suggestion is to modify the phrase > ``The call-with-current-continuation procedure allows Scheme > programmers to do that by creating a procedure that acts just like the > current continuation.'' [p 49, middle of the first column] > to say that the procedure that acts like a current continuation is, > like the error or raise procedures, is special in that it never > returns and so cannot be meaningfully composed. I think that's reasonable, we can add this and consider additional warnings about using call/cc as you suggest (I've created ticket 352 for this). > I would like the discussion of call/cc to mention non-trivial > interactions of call/cc with exception handlers and dynamic binding > (parameters) and the danger of memory leak. We can and should provide examples where this interaction is surprising. I think we'd need more data on memory leaks to mention them in the standard. -- Alex _______________________________________________ Scheme-reports mailing list Scheme-reports@scheme-reports.org http://lists.scheme-reports.org/cgi-bin/mailman/listinfo/scheme-reports