From: Ron Garret
Subject: At long last, first release of Lexicon code
Date: 
Message-ID: <rNOSPAMon-ED4ADC.23302407062006@news.gha.chartermi.net>
I know you've all been waiting with baited breath for this.  After 
exploring a zillion possibilities and learning more about macro 
expansion than I ever wanted to know, I finally figured out a portable 
way to get my ^FOO syntax working well enough to get my new macro system 
working.  In the end I was able to do it with no reader hacks at all, 
though I had to change my original design a bit to get it to work.  The 
resulting system works differently than I had originally envisioned it, 
but I think it might be better the way it turned out.

So I am at long last publicly releasing a preliminary version of my code 
for first-class lexical environments a.k.a. lexicons f.k.a. locales.  
The code has been tested cursorily on MCL, OpenMCL, CLisp and SBCL.  I 
have not leaned very hard on it.  There is no documentation (except for 
the original locales paper, which is now badly out of date), but there 
is an illustrative example at the end.  Also, the code is pretty simple 
and should not be hard to follow.  You can find it at:

http://www.flownet.com/ron/lisp/lexicon.lisp

You will also need:

http://www.flownet.com/ron/lisp/utilities.lisp

GPL applies.  Comments welcome.

rg

From: Thomas F. Burdick
Subject: Re: At long last, first release of Lexicon code
Date: 
Message-ID: <xcvejy09g7h.fsf@conquest.OCF.Berkeley.EDU>
Ron Garret <·········@flownet.com> writes:

> I know you've all been waiting with baited breath for this.  After 
> exploring a zillion possibilities and learning more about macro 
> expansion than I ever wanted to know, I finally figured out a portable 
> way to get my ^FOO syntax working well enough to get my new macro system 
> working.  In the end I was able to do it with no reader hacks at all, 
> though I had to change my original design a bit to get it to work.  The 
> resulting system works differently than I had originally envisioned it, 
> but I think it might be better the way it turned out.

Care to summarize what you were trying to do with ^FOO, for those of
us who stopped reading that long, long thread?
From: Ron Garret
Subject: Re: At long last, first release of Lexicon code
Date: 
Message-ID: <rNOSPAMon-AC566C.10303108062006@news.gha.chartermi.net>
In article <···············@conquest.OCF.Berkeley.EDU>,
 ···@conquest.OCF.Berkeley.EDU (Thomas F. Burdick) wrote:

> Ron Garret <·········@flownet.com> writes:
> 
> > I know you've all been waiting with baited breath for this.  After 
> > exploring a zillion possibilities and learning more about macro 
> > expansion than I ever wanted to know, I finally figured out a portable 
> > way to get my ^FOO syntax working well enough to get my new macro system 
> > working.  In the end I was able to do it with no reader hacks at all, 
> > though I had to change my original design a bit to get it to work.  The 
> > resulting system works differently than I had originally envisioned it, 
> > but I think it might be better the way it turned out.
> 
> Care to summarize what you were trying to do with ^FOO, for those of
> us who stopped reading that long, long thread?

The original design was for ^foo to reference the top-level lexical 
binding of foo in the current (at macroexpansion time) lexicon 
regardless of any other lexical bindings that may be then in effect.

What I actually ended up with was that ^foo has this behavior only in 
the function call position.  In an argument position ^foo may be 
shadowed by lexical bindings of ^foo.  In other words, variables 
preceded by a caret act like lisp-2 variables (except that the two 
namespaces are not function/value but toplevel/local) while all other 
variables are Lisp-1 variables.

The upshot of all this is that when you program with lexicons you are 
programming in a Lisp-1 (in the current implementation -- it is easy to 
make Lisp-N lexicons) but you can write macros using caret variables in 
function call position in order to avoid name capture problems.  The net 
results is a Lisp-1 without hygienic macros but with an operational 
equivalent to Lisp-2 macros.

The example at the end of the code is probably more illuminating:

? (def lst #'list)   ; LST is now a Lisp-1 version of the LIST function
LST

? (lst lst lst)
(#<Compiled-function LIST #x21EC04E> #<Compiled-function LIST #x21EC04E>)

? (let ((lst #'cons)) (lst lst lst))
(#<Compiled-function CONS #x2378EAE> . #<Compiled-function CONS 
#x2378EAE>)

? (let ((lst #'cons)) (^lst ^lst lst))
(#<Compiled-function LIST #x21EC04E> #<Compiled-function CONS #x2378EAE>)

? (let ((^lst #'cons)) (^lst ^lst lst))
(#<Compiled-function CONS #x2378EAE> #<Compiled-function LIST #x21EC04E>)

; DEFM defines a Lisp1 macro
? (defm (m1 arg)
  `(values (lst ',arg ',arg) (^lst ',arg ',arg) (^lst ^lst lst)))
M1

? (let ((lst #'cons) (^lst #'vector)) (m1 foo))
(FOO . FOO)
(FOO FOO)
(#<Compiled-function VECTOR #x217D6AE> #<Compiled-function CONS 
#x2378EAE>)

NOTE: There are two "bugs" that you will notice as you play with it.  
First, only symbols that have been referred to in the body of a DEF work 
properly.  That is because the lexicon code heavily munges the behavior 
of symbols using macros and symbol macros.  Lexicon variables and CL 
variables can coexist, but they do not interoperate well.  The results 
can be quite confusing if you're not prepared.

Second, macros are not yet fully first class even though they may appear 
to be.  You can do this:

(let ((x m1)) (x 1))

but the result is not what you would expect.  There is no macrolet or 
compile-time let (list Pascal's SLET) though it is my intention to add 
these.  I don't expect it to be too hard.  Probably only take me a year 
this time :-)

rg