Hi, On Sunday, February 20, 2022 11:48:01 AM EST Liliana Marie Prikler wrote: > Am Sonntag, dem 20.02.2022 um 09:09 -0500 schrieb Philip McGrath: > > Hi, > > > > On Sunday, February 20, 2022 4:03:26 AM EST Liliana Marie Prikler > > > > wrote: > > > So here's my suggestion: > > > > > > Inside chez-and-racket-bootstrap, define (make-) functions > > > for > > > the following: > > > - chez-bootstrap-bootfiles, chez-for-racket-bootstrap-bootfiles: > > > Taking version and origin. > > > - racket-vm-cgc: Taking version and origin. > > > - racket-vm-bc: Taking racket-vm-cgc. > > > - racket-vm-cs: Taking racket-vm-bc. > > > > > > Inside chez, define chez-scheme, as well as non-bootstrapped > > > versions of stex et al. Also define make-chez-scheme-for-racket, > > > taking version and origin as parameter. Finally, define chez- > > > scheme-for-system, which uses (resolve-interface '(gnu packages > > > racket)) to get racket's version and > > > origin. > > > > > > Inside racket, define %racket-version, %racket-origin, racket- > > > minimal > > > and racket. It'd also be good if you made local definitions > > > (define racket-vm-cgc (make-racket-vm-cgc %racket-version %racket- > > > origin)) > > > (define racket-vm-bc (make-racket-vm-bc racket-vm-cgc)) > > > ... > > > in this file. > > > > My understanding—which is not very good!—is that this would have the > > same problem we do currently. It would be analogous to my example > > > from : > Well, for one this claim is both verifiable and falsifiable by way of > implementation. For another, I don't really see the issue however. > Since those bindings would be local to racket.scm and not used anywhere > else, I don't think there is a cycle to be found anywhere. > While working on v4, I did try using `racket-vm-for-system` at what Ludo’ called "the top level of a module", and I encountered the same error. > > > But Ludo’'s examples show that's wrong: those uses of `chez > > > scheme` are in what the "expansion contexts" model would call > > > "expression contexts". > > > > > > Instead, I think rule № 2 prohibits any reference to a variable > > > imported from another (gnu packages ...) module that will be > > > evaluated when the (gnu packages ...) modules are—visited? > > > instantiated? [2][3]—IDK when exactly, but, for practical purposes, > > > any variable reference that is not underneath a lambda abstraction. > > > > > > If that's right, IIUC, it would mean that: > > > > > > (define chez-scheme-for-racket > > > (make-chez-scheme-for-racket ...)) > > > > > > would also be prohibited. > > > > > > On the other hand, uses of `(racket-vm-for-system)` and `(chez- > > > scheme-for-system)` in an `imports` field should still be fine, > > > thanks to the implicit thunks. > > > > The reference to `make-chez-scheme-for-racket` or `make-racket-vm-cs` > > or any such procedure defined in "chez-and-racket-bootstrap.scm" > > would be evaluated when "racket.scm" is instantiated—or whenever > > precisely it is that causes the problem. > > I don't think that'd be a problem since make-chez-scheme-for-racket is > itself a function. If it still is, one pair of brackets makes it not > so. This is a well-explored technique of resolving chains, used for > example in our build system code. chez-and-racket-bootstrap.scm should > imo not be imported anywhere but chez.scm and racket.scm, so it by > itself can not form a cycle. Only chez.scm and racket.scm can, but > there are ways of making those well-formed. AFAICT the error is not from applying the function bound to the variable `racket-vm-for-system` (or `make-racket-vm-bc`, or whatever), but from evaluating the reference to a variable imported from a sibling `(gnu packages ...)` module, regardless of the value to which the variable is bound. My current best guess at Guile's semantics for mutually-recursive modules is that it's something like the `letrec` restriction, e.g. the difference between these two examples (given an implementation that fully enforces `letrec` semantics, as opposed to `letrec*`): --8<---------------cut here---------------start------------->8--- $ scheme Chez Scheme Version 9.5.6 Copyright 1984-2021 Cisco Systems, Inc. > (letrec ((a (lambda () 1)) (b a)) 2) Exception: attempt to reference undefined variable a Type (debug) to enter the debugger. > (letrec ((a (lambda () 1)) (b (lambda () (a)))) (b)) 1 --8<---------------cut here---------------end--------------->8--- > > See (standard-packages) in guix/build-system/gnu.scm pointing to (gnu > packages commencement) or (default-python) in guix/build- > system/python.scm for pointers. Given Ludo’'s explanation, I think the difference (or at least an important difference) is that those functions are defined in `(guix ...)` modules, as opposed to `(gnu packages ...)` modules. But I wish I knew with any degree of certainty *why* this would be true, if indeed it is. Maybe Maxime knows? -Philip