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

contractual programming

   Date: Wed, 21 Oct 92 18:40:29 BST
   From: Jeff Dalton <jeff@uk.ac.ed.aiai>
   Sender: info-dylan-request <info-dylan-request%com.apple.cambridge@com.apple.cambridge.brazil>


   Some of the recent Scheme solutions look fairly reasonable, though
   I still feel I need more experience with them before I can say whether
   they do what I want.  

I seem to have heard you say that a few times in the past!

   What is it that's wrong with "macros that work", by the way?

I think the difficulty stems from them working in a single context and
"all at once".

   Do they break down in more cases than the Common Lisp approach?

CL never breaks down, it's just rather messy but at least you how it's
going to screw you.  Macros work in CL because it is symbol based (I
need a phrase here---please don't waste time flaming about the
accuracy of the term) and each symbol is tagged with where it comes
from by virtue of the packages.  Shadowing issues must be dealt with
explicitly by gensym.

In a module based system there is a stronger orientation towards
bindings and the difficulty is distinguishing between identifiers and
symbols---since at the abstract syntax level they seem the same.
Furthermore, because of quote a symbol which is data at one stage of
expansion can become an identifier at the next.  This is why some
special form like syntax-quote seems unavoidable...supporters of the
Wirth school of programming might argue that it is good documentation
to use a special operator.  In addition, there is no information
attached to a symbol/identifier to tell you which module it came from.

That aside, the main feature of the scheme we have been does go back
to Kohlbecker's '86 paper---at least, the way I read it---in that we
paint the identifiers resulting from the expansion of an expression
with the module in which the expander was defined.  This gives us
inter-module hygiene, but not local hygiene.  This model also fails
for macro-defining macros.  A hybrid of the labelling by depth of
expansion with labelling by modules might resolve intr-module hygiene.

Our aim is that an expander should be a black box in the same way as
any other exported function, so that the user need not be aware of the
modules on which the expansion result depends.  Put another way, you
should not have to import a module because it is part of the run-time
of the expanded expression, since that breaks the macro abstraction.
Because an expansion can, quite reasonably, refer to bindings visible
in its expander's defining module and these may either not be visible
or would create a name conflict in the use module we have to
circumvent the language defined module interface in a way similar to
the use of :: in CL packages.

This raises another important issue: what is the class of the result
of macro expansion?  Is it an s-expression or implementation-defined?
Is it re-readable?  If so, then we have an external representation to
break the module abstraction and poke around anywhere.  I do not want
this freedom, since it prevents a compiler taking any advantage of the
existence of modules, so although I want to be able to inspect the
result of an expansion I don't think I want to pay the price of being
able to key it in.