Gareth McCaughan <gareth.mccaughan@pobox.com> wrote:
+---------------
| Marco Baringer <mb@bese.it> writes:
| > ...
|
| I think what you want is, with the definition of RUN-TRAMPOLINED above,
| (defun func1 () #'func2)
| (defun func2 () #'func1)
| or, if you need to be able to pass arguments around,
| (defun run-trampolined (func args)
| (catch 'done
| (loop ... )))
+---------------
Actually, you don't even need the THROW to pass arguments around:
just use closures over the args:
> (defun work (who)
(princ who)
(princ " ")
(force-output)
(sleep 1))
WORK
> (defun func1 ()
(work 1)
(let ((n (random 100)))
(if (> n 50)
(lambda () (func3 1 n))
#'func2)))
FUNC1
> (defun func2 ()
(work 2)
(let ((n (random 100)))
(if (> n 50)
(lambda () (func3 2 n))
#'func1)))
FUNC2
> (defun func3 (who what)
(format t "3: func~a said '~a'~%" who what)
(cond
((> what 95) nil)
((= who 1) #'func2)
(t #'func1)))
FUNC3
> (defun run-trampolined (func)
(loop for f = func then (funcall f) while f))
RUN-TRAMPOLINED
> (run-trampolined (lambda () (func3 0 0))) ; fake "func0"
3: func0 said '0'
2 1 2 3: func2 said '86'
1 2 3: func2 said '61'
1 2 3: func2 said '83'
1 3: func1 said '74'
2 1 3: func1 said '76'
2 3: func2 said '62'
1 3: func1 said '54'
2 3: func2 said '51'
1 2 1 2 1 2 3: func2 said '88'
1 3: func1 said '97'
NIL
>
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607