This is the mail archive of the
guile@sources.redhat.com
mailing list for the Guile project.
Re: CTAX revisited
- To: Ian Bicking <ianb at colorstudy dot com>
- Subject: Re: CTAX revisited
- From: Mikael Djurfeldt <mdj at mdj dot nada dot kth dot se>
- Date: 23 Jul 2000 23:48:25 +0200
- Cc: djurfeldt at nada dot kth dot se, guile at sourceware dot cygnus dot com
- Cc: djurfeldt at nada dot kth dot se
- References: <20000723131320.F285@lothlorien> <xy7hf9gisbl.fsf@mdj.nada.kth.se><20000723144721.H285@lothlorien>
- Reply-To: djurfeldt at nada dot kth dot se
Ian Bicking <ianb@colorstudy.com> writes:
> On Sun, Jul 23, 2000 at 09:01:50PM +0200, Mikael Djurfeldt wrote:
> > A primitive way to solve it is by using `catch' which is more
> > light-weight than continuations:
>
> I had thought about this -- it fit with Tcl semantics -- but it isn't
> quite the same semantics in C (-like languages). It would work fine
> with Correct programs, which perhaps should be enough. The only
> problem is that subroutine could potentially throw a break or continue
> and not throw an error as a result. As in:
>
> while (x) {
> subroutine();
> }
>
> function subroutine() {
> break;
> }
>
> And subroutine() would break out of the while
This is handled best at translation time: break should not be allowed
in the above context.
> > An approach which might lead to more efficient code is to transform
> > the code into continuation passing style. Then return, break and
> > continue can be given simple definitions.
>
> I'm not totally clear about how this would work. How would you
> translate:
>
> while (x) {
> foo();
> if (y)
> break;
> bar();
> }
Given the continuation c, the while loop translates into the
following expression:
(letrec ((c1 (lambda () ; while
(if x
(foo (lambda ()
(if y
(c) ; break
(bar c1))))))))
(c1))
(Note two simplifications relative other forms of CPS:
1. I don't pass variables at each stage, but use the lexical
environment to transfer values.
2. I've omitted the dummy argument when a continuation isn't using
the result of previous computation.)
After translating to CPS, one can translate back again to yield
efficient code:
(letrec ((c1 (lambda ()
(if x
(begin
(foo)
(if y
*unspecified*
(begin
(bar)
(c1))))))))
(c1))