guile-devel
[Top][All Lists]
Advanced

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

Re: Syntax checks


From: Marius Vollmer
Subject: Re: Syntax checks
Date: 14 Apr 2002 19:52:54 +0200
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Lynn Winebarger <address@hidden> writes:

>         Are you actively working on the module system/first class 
> environments?

No, not actively.

>  The TODO list currently only lists 1.6 and "Eventually" as target
> times.  I am interested in this particular task, but am still poking
> around the source.  It's not entirely clear what the exact
> difference between environments and modules is (or should be).

The environments are intended to provide the run-time data structures
that implement the module system.

I myself am not entirely sure how to use the environments, and if we
need their--although elegant--richness.  When developing the semantics
of the module system, we should not try to move it into such a
direction that it fits perfectly with the existing environments
interfaces.  If it does fit, so much the better, but that should not
be the main goal.

> Well, there's import/export and syntax readers.  I did go back and
> read a lot of discussion from late 2000/early 2001, but I'm not sure
> how much has sunk in yet.  Also, while I'm aware modules should act
> orthogonally to objects in terms of introducing namespaces, it seems
> to me the module system should allow constructs similar to the
> imperative object-oriented languages.

Can you elaborate?  Are you talking about data hiding, inheritance,
etc?

> Before I go on, though, I'd like to find out if there's any point to
> doing so.

Hmm, I can't really follow you here.  What questions do you need
answered precisely to find out?  I'm not sure what you would like to
"go on" with.

>          The real question (lingering from at least late 2000) seems
> to be whether lambda abstractions should delay expansion as well as
> evaluation.  My first impulse is to say it shouldn't, that macros
> are "evaluated" at read time.

Yep.  I think we should be careful about defining our 'times'.  'Read
time' would be during the call to 'read', but that's not related to
macros yet.  'read' is also used for reading general data structures
in the sexp language.  'Read time' is concerned with evaluating the
"#." construct, etc, but not with Scheme macros.

I think that following the 'read time' (of a Scheme program), we
should always have a 'compile time' (even when we are going to execute
the program right away).  During this compile time, Scheme macros are
expanded.  Then might follow 'execute time'.

>  Among other effects of using lambda to delay expansion, you have
> introduced a definite evaluation ordering of applications.  I'm guessing one
> of the appeals of this behaviour is that in
> (define (foo x) (bar x))
> (define (bar x) (+ x 5))
> (define-syntax bar (syntax-rules () ((_ x) (+ x 5))))
> 
>     the 2 definitions of bar work "the same".  However, IMO, the second
> definition should yield an  error in  (foo 4)  because it's evaluation time 
> and bar evaluates to a macro,

Yes, and a block compiler might warn about this in advance.  (Both
about redefining bar and about using bar as a function and later
defining it as a macro.)

Hmm, I wouldn't say "bar evaluates to a macro".  This makes sense
right now because of the way our evaluator works, but I think it wrong
to say that 'bar' is evaluated, at all.  It is recognized by the
compiler (or memoizer) as a macro.

> and 5 is not "syntax".

I don't understand, could'ya explain?

>     Mainly, however, I see this as a kind of lexical scoping - if
> you re-evaluated macros whenever they changed, you have a kind of
> dynamic scope.  I know this was characterized by Marius in the
> opposite way in the earlier (late 2000) discussion.  I.e. that
> because macro expanding at read time captures whatever value of the
> syntax binding was lying around rather than the binding itself (to
> be used over and over), it is "dynamic".

Hmm, if I remember the discussion right, we were talking about two
kinds of consistencies of a system, not about scoping disciplines.
Consider the following simple model of interactive development of a
'system': you start with a set of files and load them into a freshly
started Guile process.  You then make changes to the files and load
them again.  Do this a couple of times.  At the end, you have a new
set of files, and Guile process in a certain state.  You then start a
second, fresh Guile process and load the new set of files.

When the two Guile processes must be in the same state, we would have
"static consistency".  The state of the system is only determined by
what is in the files that describes it.  When the two Guile processes
are allowed to differ in their states, we would have "dynamic
consistency".  The state of the system is determined by the operations
performed on the Guile process (in our simple model, the only
operation was loading a file).


Now I argue that static consistency is _very_ hard to achieve in full
generality, and if so only with great costs, and maybe wouldn't even
be desirable from a user point of view.  Re-expanding macros when
their definition changes is one example.  You need to keep extensive
data structures around (but maybe not in core) to realize it, it would
take significant time to do it, and it would probably make it
needlessly difficult to steer your system thru some 'illegal'
configurations when needing to make coordinated changes to a multitude
of places.

I think it will be better to not try to achieve static consistency
automatically.  Dynamic consistency, of course, is trivial to have
(basically, you can't avoid it).

For example, instead of magically reexpanding all uses of a redefined
macro, we should simply require the user to reload or recompile all
affected files, if he so desires.  The system can help by providing a
list of affected files, and doing the whole reloading/recompiling upon
a simple command.

Also, I think we should extend this to bindings in modules: when the
list of exported bindings of a module changes (say), the current
proposal is to automatically correct all existing uses of the affected
bindings.  I now think it will be better to fix the list of imported
bindings when executing a 'define-module' or 'use-modules' (if it
survives) statement.  This is Dirk's signatures idea, and I now
finally got it, I think.  When you want a changed export list to take
effect, you need to reload/recompile the files that are affected by
it.



reply via email to

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