[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Paul Graham <paulgraham@yahoo.com>] Re: What is alightweight language
Title: Re: [Paul Graham <paulgraham@yahoo.com>] Re:
What is a
At 12:14 PM -0500 12/13/01, jmarshall@mak.com wrote:
Matthias Felleisen
<matthias@ccs.neu.edu> writes:
> Paul writes:
>
> As in many uses of continuations, you don't actually
need
> call/cc-- you can fake continuations using carefully
constructed
> closures-- but having call/cc makes it cleaner and
easier.
>
> It's not just cleaner and easier, it maintains invariants
automatically. If
> your programmer abuses your patterns just a bit, all kind of
things can
> happen and you don't even know.
I'm not sure I understand what you mean here. I thought that
Paul was
suggesting using CPS in lieu of call-with-current-continuation.
I
don't see CPS as being any `dirtier' that
call-with-current-continuation.
It's "dirtier" because programming in a CPS discipline
requires that the whole program (libraries, etc.) obey the CPS
invariants. So, suppose I want to write a short-cutting 'andmap'
that accepts a function and a list (uh, in scheme):
; andmap : ('a -> boolean) (listof boolean) ->
boolean
(define (andmap fn lst)
(call/cc
(lambda (escape)
(letrec ([loop
(lambda (remaining)
(cond [(null? remaining)
#t]
[(fn (car remaining)) (loop (cdr remaining))]
[else (escape #f)]))])
(loop lst)))))
; test expression
(and
(andmap (lambda (x) (= x 9)) '(9 9 9))
(not (andmap (lambda (x) (= x 9)) '(9 4 a))))
; CPS'ed version:
; andmap: ('a (boolean ->) -> ) (listof boolean) (boolean
-> ) ->
(define (andmap-cps fn lst escape-k)
(letrec ([loop
(lambda (remaining k)
(if (null? remaining)
(k
#t)
(fn
(car remaining)
(lambda (fn-result)
(if fn-result
(loop (cdr
remaining) k)
(escape-k
#f))))))])
(loop lst escape-k)))
; test expression
(and
(andmap-cps (lambda (x k) (k (= x 9))) '(9 9 9) (lambda (x)
x))
(not (andmap-cps (lambda (x k) (k (= x 9))) '(9 4 a)
(lambda (x) x))))
In the second (CPS'ed) case:
1) reading it is horrible, and
2) writing it is horrible, even though
3) I didn't have the energy to push the CPS through the
primitives, but most of all
4) as Matthias points out, if andmap is called with a procedure
that does not obey the CPS invariants, the whole computation falls off
the back of the dump truck.
... unless you were just talking about using a CPS-ing compiler
to implement call/cc.
john clements