On Tue, 30 Dec 2003, Kevin S. Millikin wrote:
On Tuesday, December 30, 2003 12:39 PM, Ben Rudiak-Gould wrote:
With letrec and unrestricted call/cc you can implement ML-style refs:
With an *implementation of letrec that uses mutation* and unrestricted call/cc, you can implement ML-style ref cells:
[...]
(define c (make-cell)) ((c 'set) 3) (c 'get) 3 ((c 'set) 7) done (c 'get) 3
Interesting. This still violates referential transparency, though. (c 'get) returns a value or errors out depending on whether (c 'set) has been called yet. Here's a more obvious violation:
(let* ((c (make-cell)) (d (make-cell))) ((c 'set) 1) ((d 'set) 2) (d 'get)) 2 (let* ((c (make-cell)) (d c)) ((c 'set) 1) ((d 'set) 2) (d 'get)) 1
And take a look at this!
(define c (make-cell)) (define d c) ((d 'set) 9) (d 'get)
Error in car: #<procedure> is not a pair. Type (debug) to enter the debugger. Something very nasty is going on here. I'm not sure exactly what it is, but I think at least one of the define statements is getting executed at least twice. I still think there's a deep antagonism between unrestricted call/cc and referential transparency, and changing letrec's semantics can't fix it. -- Ben