Re: issue with internal define and define-values

7 views
Skip to first unread message

John Cowan

unread,
Nov 21, 2018, 10:42:22 AM11/21/18
to scheme-re...@googlegroups.com, Marc Nieper-Wißkirchen, Marc Feeley
Nobody speaks for WG1 nowadays, but your message is duly forwarded.  As for giving R5RS semantics to the identifiers defined in the (scheme r5rs) library, nobody does it, but it's not exactly wrong. Presumably people use that library (if at all) to run R5RS programs.  Hopefully few of their programs will depend on incompatible subtleties such as this.

---------- Forwarded message ---------
From: Marc Nieper-Wißkirchen <ma...@nieper-wisskirchen.de>
Date: Wed, Nov 21, 2018 at 4:03 AM
Subject: Fwd: issue with internal define and define-values
To: Marc Feeley <fee...@iro.umontreal.ca>
Cc: John Cowan <co...@ccil.org>


Dear Marc,

just saw your issue about internal `define' and `define-values' on the WG1 mailing list by chance. I'm not a member of WG1 so I cannot post on that list and cannot speak for WG1.

It appears to me that the issue you raised is actually a non-issue because the example code is not conformant to the R7RS: Section 5.3.2 says that an expanded body containing internal definitions can be converted into a completely equivalent `letrec*' expression. Now Section 4.2.2 of the R7RS says that it is an error to invoke the continuation of an initalizer of ` fletrec'' more than once. (This restriction, which makes some R5RS programs non-conforming, exists since R6RS; see the Introduction of https://www.cs.indiana.edu/~dyb/pubs/letrec-reloaded.pdf for a discussion.) Ergo, it is an error to invoke the continuation of the right-hand side of an internal `define' or `define-values' more than once, which is what is happening in your code, which I copy here for convenience:

(define (p x)
  (write x)
  (newline))

(define (f x)
  (call-with-current-
continuation
   (lambda (k)
     (k (* x x) k))))

(define closures '())

(define (go)
  (define-values (n again)
    (f 2))
  (set! closures (cons (lambda () n) closures))
  (p n)
  (let ((next (- n 1)))
    (set! n (+ n 1000))
    (if (>= next 0)
        (again next again))))

(go)

(p ((list-ref closures 0)))
(p ((list-ref closures 1)))
(p ((list-ref closures 2)))
(p ((list-ref closures 3)))
(p ((list-ref closures 4)))

Regards,

Marc
Reply all
Reply to author
Forward
0 new messages