[Top][All Lists]

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

`use-syntax' and module transformers

From: Ludovic Courtès
Subject: `use-syntax' and module transformers
Date: Mon, 31 Jul 2006 11:30:37 +0200
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/21.4 (gnu/linux)


Currently, `use-syntax' and the same-named option of `define-module' are
defined as follows:

  -- syntax: use-syntax module-name
      Load the module `module-name' and use its system transformer as
      the system transformer for the currently defined module, as well
      as installing it as the current system transformer.

(I believe "system" should read "syntax" here.)  The notion of "module
transformer" is not defined, making it look like an obscure feature.

Unlike what one might think, `use-syntax' and `export-syntax' are not
symmetric: they have nothing to do with each other.  The naive user who
thought that both are related will experience funny things.  When using
the `:use-syntax' option of `define-module', one will be able to use
pretty much any module, without any problem.  However, sometimes, the
same module will fail to load when using the `use-syntax' macro (more on
that below):

  guile> (use-syntax (srfi srfi-9))

  In standard input:
     1: 0* (use-syntax (srfi srfi-9))
     1: 1  (eval-case (# # # *unspecified*) (else #))
     1: 2  (begin (process-use-modules #) (set-module-transformer! # srfi-9) 
  In unknown file:
     ?: 3* [set-module-transformer! #<directory (guile-user) 3008c8d0> ...

  <unnamed port>: While evaluating arguments to set-module-transformer! in 
expression (set-module-transformer! (current-module) srfi-9):
  <unnamed port>: Unbound variable: srfi-9
  ABORT: (unbound-variable)

(This difference in behavior is due to a difference in the way
`use-syntax' and `define-module' look for a module transformer.  In the
above example, `use-syntax' looks for a variable named `srfi-9' in the
_current_ module and raises an error if it is not found;
`process-define-module', OTOH, looks for a variable named `srfi-9' in
the public interface of the used module but does not complain if it
doesn't find it.  So there are actually two differences.)

In some cases, using `use-syntax' instead of `use-modules' will yield a
strange behavior:

  guile> (use-syntax (ice-9 match))
  guile> (+ 2 3)
  ERROR: In procedure apply:
  ERROR: Wrong type argument in position 1: #<macro! match>
  ABORT: (wrong-type-arg)

Ok, this only demonstrates a lack of documentation, and perhaps a
confusing naming.  Now, what about the idea of module transformers

The idea of a module transformer is similar to that of a macro, except
that the module transformer gets applied unconditionally to all the
S-exps that get read while the module it is attached to is current.  The
semantics are, well, quite complicated (likewise, I believe that this is
one of the reason Neil rejected the idea of a per-module reader which I
proposed initially).

Currently, the only module (I think) in core Guile that uses this
feature is `(ice-9 syncase)'.  I don't understand that code, but I
suspect that it could live without it, especially now that we have
`current-reader'.  I saw another use of module transformers in Guile-VM
where the module transformer is used to replace `foo.field' by
`(slot-ref foo field)'.  This also could be implemented as a specific
reader checking for symbols that contain a dot.

Why did I worry about `use-syntax' in the first place?  In order to
support compilation of macros, we need a way to differentiate between
compile-time dependencies (i.e., modules that are used because they
provide macros or procedures or data used by other macros) and run-time
dependencies.  I thought that `use-syntax' had been invented for this
purpose, but that most people had resorted to using `use-modules'
instead just because it doesn't make any difference.  I was the naive
user I mentioned above, and I was wrong.  ;-)

In summary, I consider `use-syntax' to be currently obscure and I
question the usefulness of module transformers.  What do you think?

If we agree that their usefulness is questionable, then we could re-use
the name `use-syntax' for another purpose, namely to express
compile-time dependencies.  Otherwise, maybe we could introduce yet
another form to express that.


reply via email to

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