[gambit-list] Help With Memory

David Rush kumoyuki at gmail.com
Sat Sep 27 07:27:38 EDT 2008


On Sat, Sep 27, 2008 at 2:56 AM, Joel J. Adamson <adamsonj at email.unc.edu> <
adamsonj at email.unc.edu> wrote:

> >>>>> "DR" == David Rush <kumoyuki at gmail.com> writes:
>
>    DR> Don't get me wrong - I am a big fan of call/cc. But it is a
>    DR> *big* gun and it is silly to use it for relatively simple things
>    DR> when a trivial code rearrangement will also produce code that is
>    DR> more sound, easier to reason about, and potentially faster.
>
> So can you give a non-trivial example?


Well I already did earlier in this thread. For a larger example, I'd have to
point you to a rather larger program than would fit in the margin of this
email :)

Some years ago I did quite a bit of (very unscientific) benchmarking w/rt
different Scheme implementations and discovered the important of
type-coherence to the performance of compiled code. The poster child for
this is, of course, Stalin, but *every* Scheme compiler has a 'unsafe' mode
(which disables type-checking to some degree), and using explicit CPS makes
it easier to keep your code correct under those conditions.


>  As I said, I used it because my
> problem was the sort of thing that intro textbooks (e.g., The Scheme
> Programming Language) say to use it for.


Well, that's because it's an easy way to demonstrate the power of the
construct. It is however poor software engineering as the use of call/cc
frequently gets you involved in the law of unintended consequences. One
correspondent actually pointed out to me that call/cc is closely akin to
set! as a side-effecting operation. It certainly can have global
consequences as it is a run-time implementation of a global compile-time
transformation.

Which is all different from what I am suggesting. call/cc is - just like
macros - something where most of the time there is a cleaner and more
elegant way to achieve the same effect. Those few times where you do need
it, there is literally no other other way.

For example, one place where I did use call/cc heavily was in transforming a
yacc (well a scheme equivalent) generated parser from using a model where it
controlled all the IO into one where it was event-driven. I needed a
large-scale, global transformation of code I did not control and call/cc fit
the bill perfectly. I also paid for it heavily with a program that ran
rather slower and allocated way more heavily than it needed too - as I
discovered when I rewrote the parser from scratch as an event-driven system.

My point is simply this - any tail-call is a continuation invocation. The
fact that we can pass anonymous functions around with ease in Scheme means
that we can create whatever continuation we need to be executed and pass it
directly to the tail-call where it should be invoked. And the really great
thing is that we need *not* invoke full call/cc when we do this. We get all
this for free because of the requirement for full tail-call optimization.
You just need to remain aware of when you are making tail-calls - and you
should be doing that anyway.

david
-- 
GPG Public key at http://cyber-rush.org/drr/gpg-public-key.txt
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.iro.umontreal.ca/pipermail/gambit-list/attachments/20080927/b22c830c/attachment.htm>


More information about the Gambit-list mailing list