Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

At long last, first release of Lexicon code

11 views
Skip to first unread message

Ron Garret

unread,
Jun 8, 2006, 2:30:25 AM6/8/06
to
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

Thomas F. Burdick

unread,
Jun 8, 2006, 4:58:26 AM6/8/06
to
Ron Garret <rNOS...@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?

Ron Garret

unread,
Jun 8, 2006, 1:30:31 PM6/8/06
to
In article <xcvejy0...@conquest.OCF.Berkeley.EDU>,

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

0 new messages