guile-devel
[Top][All Lists]
Advanced

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

Re: r6rs libraries, round two


From: Neil Jerram
Subject: Re: r6rs libraries, round two
Date: Sun, 28 Jun 2009 14:28:55 +0100
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux)

Julian Graham <address@hidden> writes:

> Hi Guilers,
>
> With the 1.9 series launched, I wanted to start thinking about R6RS
> libraries again, since it would be awesome to have some semblance of
> an implementation ready by October.

Indeed, yes.

I assume the objective here is to allow a Guile program or module to
use a portable R6RS library; i.e., specifically, allowing
`(use-modules ...)' or `#:use-module (...)' to resolve to an R6RS
library.  Is that correct?

(In addition, I guess we could support `import' directly in contexts
other than R6RS library code, i.e. in a top level program or Guile
module.  But it's not clear to me if that would provide any extra
benefit.)

>> I think such issues should lead us to have a `:version' option that does
>> just what's needed for R6RS, and does not try to do anything smart
>> (which could seem to be non-deterministic).  We could even go as far as
>> discouraging its use in the manual.

(I'm assuming this means a :version option to use-modules or
#:use-module.)

> Alright -- so, to summarize what (I think) has been decided:
>
> 1. Having more than one version of a module loaded at a time in a
> single Guile process / VM is not going to be supported.

Yes, at least as far as R6RS library modules are concerned.  I've
reviewed the relevant discussions on this now and am happy that
there's no desire to support multiple live versions of R6RS libraries.

I'd prefer not to rule this out, though, for any future versioning
that we might add to (define-module ...).  Is that feasible?

> 2. Mixing load calls that specify version with load calls that do not
> should produce deterministic behavior independent of the set of
> already-loaded modules.  (As described here: [1].)

I think that's only possible if we impose some restrictions on how
R6RS libraries can be imported...

> R6RS says that the mechanism by which implementations match
> version-less library references is implementation-dependent, but, in
> order to avoid breaking rule number two, I think there's really only
> one way to do it:
>
> The expander has to recursively examine all of the imports, starting
> with the top-level program, and keep track of the version specifiers
> it finds.

That sounds like it requires us to `read' all of the program code, and
all imported modules and libraries, before deciding which versions to
use.  Possible problems with that would be (i) reader macros that have
non-trivial side effects; (ii) different possible versions of a
library that themselves import different versions of another library,
and so on.

But on the other hand:

- Once we're into R6RS library code, we're OK, because the R6RS layout
  requires all of the imports to be declared upfront; so we don't need
  to read the rest of the library code.

- In a Guile module, we could specify that versioned imports can only
  be done by #:use-module expressions as part of the (define-module
  ...) form, and not support versioned imports by (use-modules ...).
  Then we'd only have to read the (define-module ...) form.

- That just leaves the main program.  For that we could invent a new
  form, like define-module but for the main program, and say that it
  has to cover all versioned imports.

Hmm.. it seems this boils down to saying that we would partially
deprecate `(use-modules ...)'.

>  In order for a program to be consistent with regard to
> version, all of the version specifiers for a particular library name
> must be prefixes of the most fully-specified version of that library.
> If this is true, then once the most fully-specified version is
> resolved, wildcard version specifiers can be resolved to that version.
>
> Unfortunately, depending on the order in which imports are processed,
> this mechanism might need to examine the headers of several versions
> of a particular library.  So it's the most correct, but it may be
> non-optimal.
>
> A lazier but potentially less load-thrashy alternative would be to
> have wildcard versions match the latest available version of a library
> OR an already-loaded version of that library if present.

I can imagine a less clever approach, in which each import is
considered as we come to it, and

- if there's already a live module with that name

  - if it's version is compatible with the new import, it's used

  - if it's version isn't compatible, error

- else load a live module as indicated by the new import (somehow -
  e.g. Andy's symlink approach).

Now obviously this could render some programs unstartable.  But that
could be OK, so long as there was an easy fix for the program author,
such as adding

(use-modules ((the troublesome module) #:version (the right version)))

near the top of the main program.  It would be even more OK if we
could provide a tool to help work out (the right version).

But even with that tool, this less clever approach is a lot less nice
than something that Just Works - which is what your suggestion above
is.  So I'd prefer your suggestion if we can make it work.

Regards,
        Neil




reply via email to

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