From: Karol Skocik
Subject: bese continuations
Date: 
Message-ID: <1131737202.050118.237570@g44g2000cwa.googlegroups.com>
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

From: Bill Atkins
Subject: Re: bese continuations
Date: 
Message-ID: <1131754902.078642.54180@g14g2000cwa.googlegroups.com>
Further:

  http://bc.tech.coop/blog/050731.html

http://common-lisp.net/project/bese/docs/arnesi/html/Automatically_Converting_a_Subset_of_Common_Lisp_to_CPS.html
From: Karol Skocik
Subject: Re: bese continuations
Date: 
Message-ID: <1131784179.181553.80070@z14g2000cwz.googlegroups.com>
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
From: John Thingstad
Subject: Re: bese continuations
Date: 
Message-ID: <op.sz3jbvj3pqzri1@mjolner.upc.no>
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/
From: Bill Atkins
Subject: Re: bese continuations
Date: 
Message-ID: <1131751477.244422.29100@f14g2000cwb.googlegroups.com>
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.
From: John Thingstad
Subject: Re: bese continuations
Date: 
Message-ID: <op.sz3o8qazpqzri1@mjolner.upc.no>
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/
From: Alan Crowe
Subject: Re: bese continuations
Date: 
Message-ID: <867jbdpr0v.fsf@cawtech.freeserve.co.uk>
"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
From: Karol Skocik
Subject: Re: bese continuations
Date: 
Message-ID: <1131894326.321419.126890@g43g2000cwa.googlegroups.com>
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