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


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))
  > (let* ((c (make-cell))
           (d c))
      ((c 'set) 1)
      ((d 'set) 2)
      (d 'get))

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

Haskell mailing list

Reply via email to