Does anyone out there have experience using Paul Graham's macros
from chapter 20 of the book titled "On Lisp"
Those six macros allow *most* of the functionality of Scheme
"continuations" to be ported to Common Lisp.
I want to do opportunistic backtracking in CL, without going through
all the hassle that would occur if I did not have access to continuations.
Speed of execution is not a consideration, because I plan to convert
all the continuations to their faster running counterparts, once the
continuation version is up and running.
I feel if someone could show me how to use Paul's macros
to convert the Scheme code below to its CL version, then I should
be able to do subsequent conversions on my own.
The code below is similar to CL's 'dotimes' loop - - I have no
interest in it other than learning how to use the macros in order
to convert it to CL.
For the life of me, I can't convert it, no matter how much I re-read
the books.
; Scheme code - - load into MacGambit or MacScheme
;*******************************************
(define first (lambda (n) (car n)))
(define second (lambda (n) (cadr n)))
(define call/cc call-with-current-continuation)
(define print (lambda (arg) (display arg) (newline)))
(define attempt
(lambda (n)
(print "Likewise this message")
(let ((receiver (lambda (proc) (list n proc) )))
(call/cc receiver) )))
(define countdown
(lambda (n)
(newline)
(print "This message only appears once")
(let ((pair (attempt n)))
(let ( (v (first pair))
(returner (second pair)))
(print v)
(if (positive? v)
(returner (list (- v 1) returner))
(print "Blastoff"))
(newline)
(newline)) )))
;*******************************************
; End of code
Running countdown on MacGambit Scheme (free) produces this printout
: (countdown 3)
This message only appears once
Likewise this message
3
2
1
0
Blastoff
#f
:
The colon character is the prompt in the MacGambit version of Scheme.
The last #f is just the returned value of the program.
The first four functions are not really necessary, they just improve the readability of the program for those of us who are used to Common Lisp.
Gerald
In article <············@mhafc.production.compuserve.com> Gerald Smith
<··········@CompuServe.COM> writes:
[...]
I feel if someone could show me how to use Paul's macros
to convert the Scheme code below to its CL version, then I should
be able to do subsequent conversions on my own.
[...]
My first reply apparently didn't come through, so I'll try for a
second time.
First & explanatory step: translate your Scheme example by passing
continuations explicitely.
(defun attempt* (k n)
(print "Likewise this message")
(funcall k n k))
(defun countdown* (n)
(format t "~%This message only appears once~%")
(let ((k #'(lambda (n k)
(print n)
(if (plusp n)
(funcall k (- n 1) k)
(format t "~%Blast off~%~%")))))
(attempt* k n)))
Try (COUNTDOWN* 3) -- it works (I do hope it does :).
Second step: rewrite this using Paul Graham's macros.
(=defun attempt (n)
(print "Likewise this message")
(=values n (=funcall #'(lambda (cc) cc))))
(=defun countdown (n)
(terpri)
(print "This message only appears once")
(=bind (n k) (attempt n)
(print n)
(if (plusp n)
(funcall k (- n 1) k)
(format t "~%Blast off~%~%"))))
I believe that this is an application of the cp macros somewhat beyond
the intentions of the author, but it works anyway (tested in CLISP).
rthappe
PS: as for the intentions of the author. If (in `On Lisp') you examine
the implementation of threads (chapter 21), then you'll notice that,
as far as the examples go (BARBARIANS), you could remove all the
=s (e.g. =DEFUN --> DEFUN) without changing the behaviour of
the program (that's obvious since there is no =BIND in the whole
program, which means that all the time it's simply #'IDENTITY which
is passed around as continuation).