[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Continuation examples (was Re: So, what the heck is a continuation anyway?)
Guy Steele - Sun Microsystems Labs <gls@labean.East.Sun.COM> writes:
> Okay, just for fun, I upgraded the toy "FOO interpreter" of my
> previous messages:
Hello Guy, nice program :-)
> ((eq (first exp) 'LETREC)
> (let ((newenv (pairlis (mapcar #'first (second exp))
> (make-list (length (second exp)))
> env)))
> (@evletrec (second exp) newenv (third exp) newenv cont)))
[...]
> (defun @evletrec (bindings slots body env cont)
> (cond ((null bindings) (@eval body env cont))
> (t (@eval (second (first bindings)) env
> #'(lambda (fn)
> (rplacd (first slots) fn) ;the side effect that "ties the knot"
> (@evletrec (rest bindings) (rest slots) body env cont))))))
There's a bug here: evletrec assumes `slots' will be in the same order
as `bindings', but `pairlis' can muck that up. On my computer with
CLISP, the slots get reversed and the "evil" program becomes
_diabolical_ (`last' is invoked first).
Can be fixed by changing the `pairlis' in @eval to `pairlis-forward':
(defun pairlis-forward (keys values alist)
(append (mapcar #'cons keys values) alist))
> The lessons here are:
> (1) LETREC is not that difficult to add.
> (2) Even toy, throwaway interpreters are vulnerable to feature creep.
(3) Even toy, throwaway interpreters have to be ported.
Cheers,
Luke