New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Larceny can invoke libraries more than once #655

Closed
larceny-trac-import opened this Issue Jul 28, 2013 · 3 comments

Comments

Projects
None yet
3 participants
@larceny-trac-import

larceny-trac-import commented Jul 28, 2013

Reported by: will on Sat Sep 19 13:58:43 2009
Larceny is supposed to invoke libraries only once, but that guarantee
apparently fails when the libraries are in the same file as an R6RS
top-level program. For example:

;;; From: "David Van Horn" <dvanhorn@ccs.neu.edu>
;;; To: larceny-users@lists.ccs.neu.edu
;;; Sent: Saturday, September 19, 2009 10:00:03 AM GMT -05:00 US/Canada Eastern
;;; Subject: [Larceny-users] quote-like form
;;;
;;; Suppose I define a cons-like structure and I want to provide a form that
;;; is like quote, but produces my cons-like things when it quotes syntactic
;;; pairs.  In particular, I need the form to respect the eq?-ness
;;; requirements on quoted pairs, so that:
;;;
;;;     (define (f) '(x))
;;;     (eq? (f) (f))     => #t
;;;
;;; I wonder if someone could sketch how to do this in Larceny?
;;;
;;; Thanks,
;;; David

;;; The following code would not work in implementations that
;;; invoke libraries multiple times.
;;;
;;; Larceny is supposed to invoke libraries only once.
;;;
;;; In Larceny v0.97, however, a bug causes the libraries to be
;;; invoked twice if they're in the same file with the top-level
;;; program.  The following code appears to work in Larceny v0.97
;;; so long as the top-level program is not in the same file as
;;; the libraries.

(library (mycons auxiliary)

  (export mycons mycar mycdr                   ; used by clients of (mycons)
          new-label-for fetch-labelled-thing)  ; used only by myquote

  (import (rnrs base)
          (rnrs hashtables))

  (define label-counter 0)                     ; largest label in use

  (define label-table                          ; maps labels to things
    (make-hashtable (lambda (x) x) =))

  (define (new-label-for y)
    (set! label-counter (+ 1 label-counter))
    (hashtable-set! label-table label-counter (make-thing y))
    label-counter)

  (define (fetch-labelled-thing label)
    (hashtable-ref label-table label 'this-never-matters))

  ; For this example, the things are just vectors.

  (define (make-thing y)
    (list->vector y))

  (define (mycons x y)
    (list->vector (cons x (vector->list y))))

  (define (mycar x)
    (vector-ref x 0))

  (define (mycdr x)
    (list->vector (cdr (vector->list x))))

) ; end of (mycons auxiliary)

(library (mycons)

  (export myquote mycons mycar mycdr)

  (import (for (rnrs base) run expand)
          (for (rnrs syntax-case) expand)
          (for (mycons auxiliary) run expand))

  (define-syntax myquote
    (lambda (x0)
      (syntax-case x0 ()
       ((_ x)
        (let* ((y (syntax->datum #'x))
           (label (new-label-for y)))
          #`(fetch-labelled-thing #,label))))))

) ; end of (mycons)

;;; For Larceny v0.97, this top-level program has to be
;;; in a separate file.  That's a bug.

(import (rnrs base)
        (rnrs io simple)
    (mycons))

(define (f) (myquote (a b c)))

(define thing0 (myquote ()))

(define thing1 (myquote (a b c)))

(define thing2 (f))

(define thing3 (f))

(write (list thing0 thing1 thing2 thing3))
(newline)

(write (list (mycar thing1) (mycdr thing1)))
(newline)

(write (list (eq? thing1 thing1)
             (eq? thing1 thing2)
             (eq? thing1 thing3)
             (eq? thing2 thing2)
             (eq? thing2 thing3)
             (eq? thing3 thing3)))
(newline)

@WillClinger WillClinger added this to the Larceny 0.99 milestone Jan 30, 2015

@WillClinger WillClinger modified the milestones: Larceny 1.3, Larceny 0.99 May 6, 2016

@WillClinger WillClinger added P: minor and removed P: major labels May 6, 2016

@WillClinger

This comment has been minimized.

Show comment
Hide comment
@WillClinger

WillClinger May 6, 2016

Member

This is surprisingly hard to fix because of the way our library/macro expander is written.

On the other hand, neither R6RS nor R7RS require implementations to allow libraries to be defined within the same file as a top-level program, and many implementations don't. Placing the top-level program in a separate file is a viable workaround.

So I'm downgrading the priority and changing the milestone.

Member

WillClinger commented May 6, 2016

This is surprisingly hard to fix because of the way our library/macro expander is written.

On the other hand, neither R6RS nor R7RS require implementations to allow libraries to be defined within the same file as a top-level program, and many implementations don't. Placing the top-level program in a separate file is a viable workaround.

So I'm downgrading the priority and changing the milestone.

@WillClinger

This comment has been minimized.

Show comment
Hide comment
@WillClinger

WillClinger Jul 3, 2016

Member

It looks as though R7RS allows libraries to be invoked more than once, so this is an issue only when files that contain libraries together with a top-level program are run in R6RS mode. So far as I know, Larceny is the only implementation of R6RS that is capable of executing such files, so the easiest way to close this issue would be to disallow mixing of libraries and top-level programs in R6RS mode.

Those files could still be executed in R7RS mode, where invoking libraries twice is okay.

Member

WillClinger commented Jul 3, 2016

It looks as though R7RS allows libraries to be invoked more than once, so this is an issue only when files that contain libraries together with a top-level program are run in R6RS mode. So far as I know, Larceny is the only implementation of R6RS that is capable of executing such files, so the easiest way to close this issue would be to disallow mixing of libraries and top-level programs in R6RS mode.

Those files could still be executed in R7RS mode, where invoking libraries twice is okay.

@WillClinger

This comment has been minimized.

Show comment
Hide comment
@WillClinger

WillClinger Jul 3, 2017

Member

Fixed by changeset 8309025

Member

WillClinger commented Jul 3, 2017

Fixed by changeset 8309025

@WillClinger WillClinger closed this Jul 3, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment