Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

A call/cc gimmick

3 views
Skip to first unread message

Lauri Alanko

unread,
Jan 23, 2004, 2:10:14 PM1/23/04
to
Here's a function I threw together the other day:

(lambda ()
((call/cc
(lambda (c)
(lambda ()
(lambda (f)
(call/cc
(lambda (d)
(c (lambda () (d (f))))))))))))

A puzzle for starters: what's this good for?

Then some genuine questions: is there a better way do it? And is
something like this included in any common library? This _seems_ to me
like a very fundamental operation. And finally, what's a good name for
this?

Comments welcome.


Lauri Alanko
l...@iki.fi

Taylor Campbell

unread,
Jan 23, 2004, 11:58:38 PM1/23/04
to
Lauri Alanko <l...@iki.fi> wrote in message news:<burrim$17m$1...@la.iki.fi>...

> Here's a function I threw together the other day:
>
> (lambda ()
> ((call/cc
> (lambda (c)
> (lambda ()
> (lambda (f)
> (call/cc
> (lambda (d)
> (c (lambda () (d (f))))))))))))
>
> A puzzle for starters: what's this good for?

This is good for controlling what dynamic context you can evaluate code
in. First, let me rewrite it a bit to give it a better name and better
name its continuations:

(define (current-dynamic-context)
((call-with-current-continuation
(lambda (with-original-context)
(lambda ()
(lambda (thunk)
(call-with-current-continuation
(lambda (return-to-caller)
(with-original-context
(lambda ()
(call-with-values ; Let THUNK return more than one
thunk ; value.
return-to-caller)))))))))))

It is typically complemented with WITH-DYNAMIC-CONTEXT

(define (with-dynamic-context context thunk)
(context thunk))

if only for clarity.

Here's an example of manipulating the dynamic context as with SRFI 39's
parameter objects, voluminously documenting the flow of the continually
changing of dynamic context:

(define p (make-parameter 'outer))
(define write-p
(let ((count 0))
(lambda ()
(display "p ") (write count)
(display ": ") (write (p))
(newline)
(set! count (+ count 1)))))
(write-p)
(let ((outer-context (current-dynamic-context)))
(write-p)
(let ((inner-context
(parameterize ((p 'inner))
(write-p)
(with-dynamic-context outer-context write-p)
(write-p)
(let ((inner-context (current-dynamic-context)))
(write-p)
(with-dynamic-context outer-context
(lambda ()
(write-p)
(with-dynamic-context inner-context write-p)
(write-p)))
(write-p)
(with-dynamic-context inner-context
(lambda ()
(write-p)
(with-dynamic-context outer-context write-p)
(write-p)))
(write-p)
inner-context))))
(write-p)
(with-dynamic-context inner-context write-p)
(write-p)
(with-dynamic-context outer-context write-p)
(write-p))
(write-p))
(write-p)

It's left as an exercise to the reader to figure out the output of this
program, should he consider it a challenge.

> Then some genuine questions: is there a better way do it?

I've seen this implemented in one other way, in an old draft of SRFI 34
(no longer available, as far as I know, except in CVS archives):

(define (current-dynamic-context)
(let ((p (call-with-current-continuation
(lambda (k) (cons #f k)))))
(if (car p)
(call-with-values (car p) (cdr p))
(cdr p))))

(define (with-dynamic-context context thunk)
(call-with-current-continuation
(lambda (k)
(context (cons thunk k)))))

However, this version is _far_ more obfuscated and perplexing to digest
than your version, and there's not much difference otherwise.

> And is
> something like this included in any common library? This _seems_ to me
> like a very fundamental operation.

I can't say I remember seeing this in any libraries, but yes, certainly
it is a very useful operation.

> And finally, what's a good name for
> this?

A good name is what it encapsulates: the dynamic context of the site in
which it was called. This dynamic context includes the current dynamic
environment, wind points, and perhaps more.

Marc Feeley

unread,
Jan 24, 2004, 11:37:34 AM1/24/04
to
> Here's a function I threw together the other day:
>
> (lambda ()
> ((call/cc
> (lambda (c)
> (lambda ()
> (lambda (f)
> (call/cc
> (lambda (d)
> (c (lambda () (d (f))))))))))))
>
> A puzzle for starters: what's this good for?

Check my Scheme workshop 2001 paper:

http://kaolin.unice.fr/Scheme2001/article/feeley.ps

Marc

Lauri Alanko

unread,
Jan 24, 2004, 12:11:18 PM1/24/04
to
Marc Feeley <fee...@IRO.UMontreal.CA> virkkoi:

> Check my Scheme workshop 2001 paper:
>
> http://kaolin.unice.fr/Scheme2001/article/feeley.ps

Neat! This is funny: that context-capture function of mine was motivated
by a practical need that arose in a program I was designing: I needed a
way to store and restore a dynamic environment. But at the same time,
and completely unrelated (I thought), I'm writing a little bit about
reflection, and right at the moment I was about to mention that although
Scheme's call/cc reifies a computational structure, it's not
"reflection" proper, since the continuations are opaque and cannot be
analyzed (or constructed). And your paper is directly related to that.

So, thanks. It's rare to find a relevant reference handed on a silver
plate when you've only just decided that you maybe ought to nose around
a bit... :)


Lauri Alanko
l...@iki.fi

0 new messages