Hi Julian, On Mon 26 Jan 2009 01:27, Julian Graham <jool...@gmail.com> writes:
> Maybe some more advanced Schemers than I can shed some light on the > following: Well, that's not me, but I'll join you in fumbling for a solution :-) > The levels system is simply a numerical way of encapsulating this > information, but the proper order of evaluation can also be inferred > by inspecting the import- and export-specs of the libraries being > loaded I think you're right, yes. I think that the approach that you describe has been called "Implicit phasing" by Ghuloum and Dybvig. They have a paper about it, "Implicit phasing in R6RS libraries" -- but I haven't been able to find it freely on the web. ACM fail. > * R6RS says that a library's imports need to be visited/instantiated > at the time the bindings they export are "referenced." Why? As > above, why can't they be visited/instantiated at the time the imports > for the importing library are processed? I could not find the quote that you referred to here -- I think what I can tell (from 7.2): If any of a library’s definitions are referenced at phase 0 in the expanded form of a program, then an instance of the referenced library is created for phase 0 before the program’s definitions and expressions are evaluated. This rule applies transitively: if the expanded form of one library references at phase 0 an identifier from another library, then before the referencing library is instantiated at phase n, the referenced library must be instantiated at phase n. When an identifier is referenced at any phase n greater than 0, in contrast, then the defining library is instantiated at phase n at some unspecified time before the reference is evaluated. Similarly, when a macro keyword is referenced at phase n during the expansion of a library, then the defining library is visited at phase n at some unspecified time before the reference is evaluated. So what this says to me is that: (1) At phase 0, libraries that you need to run a /program/ are instantiated before the program is run. (2) At phase n > 0, we do not specify when libraries are imported. > Is there any noticeable difference to the user? Dunno, to me it sounds like a concession, that side effects from loading libraries occur before side effects from running a program; but that for meta-levels things are left unspecified. > Or do you guys read R6RS 7.2 to mean that the side-effects of > top-level expressions absolutely need to happen at a time determined > by the import level? No. So, for some of your other questions here's section 7.5 of the rationale: 7.5. Instantiation and initialization Opinions vary on how libraries should be instantiated and initialized during the expansion and execution of library bodies, whether library instances should be distinguished across phases, and whether levels should be declared so that they constrain identifier uses to particular phases. As I read this, it means that at least PLT wanted the separate instantiation model, and Chez wanted single-instantiation, implicit phasing. This report therefore leaves considerable latitude to implementations, while attempting to provide enough guarantees to make portable libraries feasible. So from 7.2 of R6RS itself: An implementation may distinguish instances/visits of a library for different phases or to use an instance/visit at any phase as an instance/visit at any other phase. Which is to say, "we allow single instantiation" -- as Guile modules are. An implementation may further expand each library form with distinct visits of libraries in any phase and/or instances of libraries in phases above 0. Which is to say, "we also allow the PLT model, explicitly." An implementation may create instances/visits of more libraries at more phases than required to satisfy references. This is an odd one. I suppose what it means is that if you need a macro from library A to expand library B, but you don't need library A at runtime, the spec allows library A to be /instantiated/ at runtime. When an identifier appears as an expression in a phase that is inconsistent with the identifier’s level, then an implementation may raise an exception either at expand time or run time, or it may allow the reference. So, furthermore, it seems that not only may library A be instantiated at runtime, /it may be in library B's "import list" as well/. This is what happens with Guile's current module semantics. Thus, a library whose meaning depends on whether the instances of a library are distinguished or shared across phases or library expansions may be unportable. Indeed, indeed. > I understand that the authors of the reference implementation > re-created a lot of machinery out of whole cloth since they were > avoiding assumptions about features of their target Scheme platforms, > but, man, both van Tonder and Dybvig-Ghuloum look like overkill for > Guile. Am I missing a major piece of understanding here? I don't think you're missing anything big, no. I hadn't fully poked into these implementations -- if it is easier just to build something on top of Guile's modules than to retrofit guile's modules into one of their implementations, then that's all the better, right? Cheers, Andy -- http://wingolog.org/