Hi,
can anybody write me a small example how they work? I have tried hard
to google some example, but while there is a lot of stuff written about
them, I just can't figure out THAT one small clear example.
I would like to have a example which does something like this :
(dotimes (i 10)
;; save continuation to some *variable*
;; return i)
so that when I do something like (funcall *variable*) it continues in
the loop.
Thanks for any ideas!
Karol
OK,
I know about these. I think I will subscribe to bese list, to get the
answer. however, I don't think that the example should be complicated,
that's why I wanted to check that here first.
Cheers,
Karol
On Fri, 11 Nov 2005 20:26:42 +0100, Karol Skocik <············@gmail.com>
wrote:
> Hi,
> can anybody write me a small example how they work? I have tried hard
> to google some example, but while there is a lot of stuff written about
> them, I just can't figure out THAT one small clear example.
> I would like to have a example which does something like this :
>
> (dotimes (i 10)
> ;; save continuation to some *variable*
> ;; return i)
>
> so that when I do something like (funcall *variable*) it continues in
> the loop.
>
> Thanks for any ideas!
> Karol
>
Paul Grayhams book "On lisp".
http://www.paulgraham.com/onlisptext.html
Chapter 20 Continuations
Contains a implementation in CL + examples
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
http://lisp.tech.coop/Web%2FContinuation
The above is a link to a tutorial on UCW continuations (and on
continuations in general).
John Thingstad: The OP was asking for help with Bese continuations,
referring to the specific continuation system used by Marco Barringer
in the Uncommon Web framework. Your link isn't necessarily helpful.
On Sat, 12 Nov 2005 00:24:37 +0100, Bill Atkins <·········@gmail.com>
wrote:
> http://lisp.tech.coop/Web%2FContinuation
>
> The above is a link to a tutorial on UCW continuations (and on
> continuations in general).
>
> John Thingstad: The OP was asking for help with Bese continuations,
> referring to the specific continuation system used by Marco Barringer
> in the Uncommon Web framework. Your link isn't necessarily helpful.
>
Yes, I notied that a bit to late.
Bese continuations are different from scheme ontinuations so the examples
ther won't work directly. (I read up)
A web seach showed that there is a bese news group which
might provide better help also.
--
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
"Karol Skocik" <············@gmail.com> writes:
> Hi,
> can anybody write me a small example how they work? I have tried hard
> to google some example, but while there is a lot of stuff written about
> them, I just can't figure out THAT one small clear example.
> I would like to have a example which does something like this :
>
> (dotimes (i 10)
> ;; save continuation to some *variable*
> ;; return i)
>
> so that when I do something like (funcall *variable*) it continues in
> the loop.
Well continuations have been bugging me for ages and I still
don't understand them, unless I've made a break through this
afternoon, but maybe I have :-) Here goes:
First some limbering up exercises, compute the length of a
list. I've called it beads, like counting the beads on a
string.
The ordinary way
(deftun beads (list)
'(((a b c)) 3
((0 1 2 3 4)) 5)
(if list
(+ 1 (beads (cdr list)))
0))
Continuation passing style
(deftun beads/c (list c)
`(((a b c) identity) 3
((0 1 2 3 4) identity) 5)
(if list
(beads/c (cdr list)
(lambda(result)
(funcall c
(+ 1 result))))
(funcall c 0)))
I've been talking about test-first coding, now I'm actually
doing it with deftun, which is like defun but with a list of
test cases before the body of the code. You can get a copy
of the macro from
http://www.cawtech.demon.co.uk/lisp/first-try.lisp
Whoops, the file name gives away the quality to be expected
of the code.
Next exercise, crappy quadratic list reverse
(deftun rev (list)
`(((a b c)) (c b a)
((0 1 2 3 4)) (4 3 2 1 0))
(if list
(append (rev (cdr list))
(list (car list)))
'()))
(deftun rev/c (list cont)
'(((one two three) identity) (three two one))
(if list
(rev/c (cdr list)
(lambda(result)
(funcall cont
(append result
(list (car list))))))
(funcall cont '())))
I haven't tried an accumulation variable yet. I'll attempt
the linear time list reverse. I call it slinky because the
way the items cascade from one list to the other reminds me
of the childrens toy
(defun slinky (a b)
(if a
(slinky (cdr a)
(cons (car a)
b))
b))
(defun slinky/c (a b cont)
(if a
(slinky/c (cdr a)
(cons (car a) b)
cont)
(funcall cont b)))
It is intriguing that this is easier. Where C would have
return you funcall the continuation with the value you wish
to return. It the recursive call is a tail call you can just
make it, with the continuation that got passed in. If the
recursive call is not a tail call, put it in tail call
position and make up a continuation that does the work you've
left out so far.
Hmm, how does this work for a tree recursion
(deftun fib(n)
'((0) 1
(1) 1
(2) 2
(3) 3
(4) 5
(5) 8)
(if (< n 2)
1
(+ (fib (- n 1))
(fib (- n 2)))))
(deftun fib/c (n cont)
'((0 identity) 1
(5 identity) 8)
(if (< n 2)
(funcall cont 1)
(fib/c (- n 1)
(lambda(result-one)
(fib/c (- n 2)
(lambda (result-two)
(funcall cont (+ result-one
result-two))))))))
I'm gathering up the results of successive recursive calls
as arguments to my continuation so that they are available
when I finally return my answer to the continuation that was
passed in.
I'll assume that (dotimes (i 10)(this and that and i)) gets
converted to
(repeater/c 10 (lambda(i)(this and that and i)) continuation)
where
(defun repeater/c (count function cont)
(if (zerop count)
(funcall cont nil)
(funcall function
count
(lambda(result)
(declare (ignore result))
(repeater/c (- count 1)
function
cont)))))
and my demo function snarfs the fifth continuation
(defvar a)
(defun demo (count cont)
(if (= count 5)
(setf a cont))
(funcall cont (print count)))
CL-USER> (repeater/c 10 #'demo #'identity)
10
9
8
7
6
5
4
3
2
1
NIL
CL-USER> (funcall a 'foo)
4
3
2
1
NIL
That looks quite promising.
I hope I've got the hang of continuation and am not
misleading the original poster. Oh well, if I've got this
wrong the savages of comp.lang.lisp will be quick to tear me
limb from limb ;-}
Alan Crowe
Edinburgh
Scotland
Thanks for explanation. I think I have understood that to some basic
level.
If somebody is interested, here is your updated slinky/c function :
GI> (defun slinky/c (a b cont)
(if a
(lambda ()
(slinky/c (cdr a)
(cons (car a) b)
cont))
(funcall cont b)))
SLINKY/C
GI> (slinky/c '(1 2 3) '(a) #'identity)
#<Interpreted Function "LAMBDA (A B CONT)" {586DA131}>
GI> (funcall *)
#<Interpreted Function "LAMBDA (A B CONT)" {586DE5E9}>
GI> (funcall *)
#<Interpreted Function "LAMBDA (A B CONT)" {586E4989}>
GI> (funcall *)
(3 2 1 A)
HA!! Gotcha! :))
The bese continuation of my original question looks like this (Marco
Baringer's code) :
ARNESI> (defvar *k* nil)
*K*
ARNESI> (with-call/cc
(dotimes (i 3)
(let/cc k
(setf *k* k)
i)))
0
ARNESI> (kall *k*)
1
ARNESI> (kall *k*)
2
ARNESI> (kall *k*)
NIL
ARNESI> (kall *k*)
4
Nice stuff :)
Thanks to all,
Karol