guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: r6rs libraries


From: Andy Wingo
Subject: Re: r6rs libraries
Date: Tue, 27 Jan 2009 11:51:54 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux)

Hi Julian,

On Mon 26 Jan 2009 01:27, Julian Graham <address@hidden> 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/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]