[Top][All Lists]

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

Re: Two questions about the guile module system

From: Marius Vollmer
Subject: Re: Two questions about the guile module system
Date: 05 Apr 2003 19:00:38 +0200
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3

Joris van der Hoeven <address@hidden> writes:

> In guile 1.3.4, I could put the following in my main initialization file:
>   (use-modules (boot-stuff)) ; defines export-from
>   (use-modules (std-lib-1) ... (std-lib-n))
>   (export-from (std-lib-1) ... (std-lib-n))
>   ...
>   (use-modules (appl-mod-1) ... (appl-mod-k))
>   ...
> When doing this, I can use all variables exported by
> the standard libraries std-lib-1, ..., std-lib-n
> inside appl-mod-1, ..., appl-mod-k.
> Unfortunately, this mechanism breaks in guile-1.6.3.
> The point is that, during the importation of
> appl-mod-1, ..., appl-mod-k, the outer context is lost.

The relevant difference between guile 1.3.4 and 1.6 is that in version
1.6, you are initially in the (guile-user) module, while in 1.3.4 you
are probably in the (guile) module.  What module you are in is of
course the module that you are exporting from with 'export-from'.

Now, the (guile) module is special in that its bindings are
automatically visible in all normal modules.  The ones from
(guile-user) are not automatically visible.

So when you export-from the (guile) module, the exported bindings
become visible in all other modules, including in the (appl-mod-...)

To access bindings exported from (guile-user), you must explicitely
'use' it, just like any other module.

I think it is best to change your code to

   (define-module (std-libs))

   (use-modules (boot-stuff)) ; defines export-from
   (use-modules (std-lib-1) ... (std-lib-n))
   (export-from (std-lib-1) ... (std-lib-n))
   (use-modules (appl-mod-1) ... (appl-mod-k))

and add a (use-modules (std-libs)) to any module that needs it.
(Probably all (appl-mod-...) modules and maybe also the (std-lib-...)

> It seems that only a very minimal context is visible
> inside the application modules.

A module starts out with all bindings from the (guile) module visible.
What you did in Guile 1.3.4 was to 'accidentally' add bindings to the
(guile) module, which of course made them automatically visible

> > (Btw, there is also module-map which might be more natural to use in
> > place of module-for-each.)
> What does that routine do?

It is to module-for-each what map is to for-each: it returns a list of
the results of applying the proc to each symbol/variable pair.  You
can use it like:

    (define-macro (re-export-from . which-list)
      (define (module-exports which)
        (let* ((m (resolve-module which #f))
               (m-public (module-ref m '%module-public-interface #f)))
          (module-map (lambda (sym var) sym) m-public)))
      (let ((l (apply append (map module-exports which-list))))
        `(re-export ,@l)))

> > > This makes it impossible to enhance the root environment
> > > with even a single macro like 'define-my-module'.
> >
> > I find this not to be true, but it is indeed tricky to reason about
> > the context in which modules are loaded.
> So how can I make things such that whenever I declare a new module,
> then all symbols which are visible in the initial context
> are available by default?

You will need to put those enhancements into the (guile) module.  I'm
not sure whether that is unconditionally a good idea since you are
changing the nevironment for all code, not just for your own.

So, a better alternative is maybe to make a new 'use-modules' variant
that makes sure that modules are loaded in a controlled environment.

> This important, since I also noticed that even the C++ routines
> which I glued to Guile are not available inside my modules!

They are probably in the (guile-user) module as well.

GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3  331E FAF8 226A D5D4 E405

reply via email to

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