This is the mail archive of the
guile@sources.redhat.com
mailing list for the Guile project.
Re: How often are continuations created?
Mikael Djurfeldt <mdj@mdj.nada.kth.se> writes:
> Keisuke Nishida <kxn30@po.cwru.edu> writes:
>
> > Oh, should it? But Guile does restart it from 0:
> >
> > guile> (define some-cont #f)
> > guile> (define magic-computation
> > (let ((capture #t))
> > (lambda (x)
> > (if capture
> > (begin
> > (set! capture #f)
> > (set! some-cont (call-with-current-continuation id)))))))
> > guile> (do ((v (make-vector 5 #f))
> > (i 0 (1+ i)))
> > ((= i 5))
> > (vector-set! v i (magic-computation i))
> > (display i))
> > 01234guile> (some-cont #f)
> > 01234guile>
> >
> > Which one is the correct behavior?
>
> Miroslav is right.
> Guile is wrong.
>
> This is a Guile bug.
Here's the Guile do code:
case SCM_BIT8(SCM_IM_DO):
x = SCM_CDR (x);
proc = SCM_CAR (SCM_CDR (x)); /* inits */
t.arg1 = SCM_EOL; /* values */
while (SCM_NIMP (proc))
{
t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
proc = SCM_CDR (proc);
}
env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
x = SCM_CDR (SCM_CDR (x));
while (proc = SCM_CAR (x), SCM_FALSEP (EVALCAR (proc, env)))
{
for (proc = SCM_CADR (x); SCM_NIMP (proc); proc = SCM_CDR (proc))
{
t.arg1 = SCM_CAR (proc); /* body */
SIDEVAL (t.arg1, env);
}
for (t.arg1 = SCM_EOL, proc = SCM_CDDR (x);
SCM_NIMP (proc);
proc = SCM_CDR (proc))
t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1); /* steps */
env = EXTEND_ENV (SCM_CAR (SCM_CAR (env)), t.arg1, SCM_CDR (env));
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The problem is here: Guile creates a *new* frame instead of mutating
the old, so call/cc will look at the fresh version of the first frame
instead of the *mutated* version of the fresh form.
}
x = SCM_CDR (proc);
if (SCM_NULLP (x))
RETURN (SCM_UNSPECIFIED);
PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
goto begin;
This can be fixed by mutating the frame when updating it.