[r6rs-discuss] [Formal] eliminate library export immutability loophole

From: R. Kent Dybvig <dyb>
Date: Sun Mar 11 23:47:59 2007

I'm responding as a user/implementor, not speaking for the editors.

> Assuming this comes to pass, do you have a precise semantics in mind

Yes. Instead of expanding a library body into the equivalent of:

  (letrec* ((var rhs-expr) ...) body-expr ... (unspecified))

we would expand it instead into the equivalent of:

  (letrec* ((var (once-only rhs-expr)) ...) body-expr ... (unspecified))

where (once-only e) raises an exception if e returns more than once.
once-only might be defined as follows:

  (define-syntax once-only
    (syntax-rules ()
      [(_ e)
       (let ([done #f])
         (let ([t e])
           (when done
             (error #f "library definition RHS expr returned twice"))
           (set! done #t)
           t))]))

> (perhaps with some illustrative examples)?

Okay, here's one example:

  (library (L1)
    (export y get-y set-y!)
    (import (r6rs))
    (define x (call/cc (lambda (k) (list 0 k values))))
    (define y (car x))
    (define z ((caddr x)))
    (define get-y (lambda () y))
    (define set-y!
      (lambda (v)
        (call/cc (lambda (k) ((cadr x) (list v (cadr x) k)))))))

By my reading of the current library description, the program:

  (import (r6rs) (L1))
  (write (list y (get-y))) (newline)
  (set-y! 3)
  (write (list y (get-y))) (newline)

prints

  (0 0)
  (0 3)

With the proposed semantics, it would print

  (0 0)

then raise an exception (if we decide it "must" or if an implementation
does what it "should"). If the exception were caught and the program
subsequently referenced y or called (get-y), the values of those
expressions would be 0.

Now that I've demonstrated how the loophole can be exploited on a public
mailing list, we have an even more urgent need to close it. ;-)

Kent
Received on Sun Mar 11 2007 - 23:47:53 UTC

This archive was generated by hypermail 2.3.0 : Wed Oct 23 2024 - 09:15:01 UTC