This is the mail archive of the guile@sources.redhat.com mailing list for the Guile project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]