From: Vassil Nikolov
Subject: How to ensure lexical binding? (DECLARE (NOTSPECIAL ...))?
Date: 
Message-ID: <72614.vnikolov@math.acad.bg>
Dear readers,

I have been thinking about a way to ensure that a binding
in a LET form is lexical.  Imagine programming in an
environment where modules written by others are used.
It is possible, at least in theory, that the name
chosen for a local variable will be the same as the
name of a variable that has been proclaimed special.
Then the binding will be a special one even in the
absence of a special declaration; in the best case
that would lead to inefficiency, in the worst case
bugs will be introduced.

I know that this is usually prevented from happening
by using packages and by placing asterisks around
the names of globally special variables, but I was
wondering how to _guarantee_ a lexical binding
independent on using different name spaces.

One trivial way to ensure that a local variable
is lexically bound is ugly: instead of
  (let ((foo (bar baz)))
    (quux foo))
to say
  (let ((#1=#:foo (bar baz)))
    (quux #1#))
This can be improved, of course, by defining a macro,
say, LEXICAL-LET, which expands into a combination of
the above with SYMBOL-MACROLET to hide the gensyms.

I was wondering, however, if we might consider adding
to the language a NOTSPECIAL declaration:
  (let ((foo (bar baz)))
    (declare (notspecial foo))
    (quux foo))
would mean: even in the presence of a special proclamation
for FOO, forget about it and make FOO a lexical variable.
It seems to me this would be easy to implement since
what is being added is just a simple mechanism of notifying
the compiler to do what it already knows how to do, i.e.
lexical binding.  Existing programs would not be affected
(unless some implementation has already introduced this
declaration with a different meaning).  The language would
become more symmetrical.

I may be indulging in fantasies, but I think that one day
Common Lisp, or perhaps another Lisp dialect, may acquire
a sophisticated (sub)language for defining declarations.
This means that there would be a set of primitive declarations
and ways to combine them; in other words, a programmable
compiler.  (Compilers... the final frontier!  Users can
define new operations, new types, new classes... why not
new declarations?)

You may tell me that the above is just nonsense, and you may
well be right.  But have you never wanted to tell the compiler
certain things about a program and thus to provide it with
the information that would allow some optimisation,
even if it does not actually do the optimisation?

Best regards,
Vassil.

Vassil Nikolov         <········@math.acad.bg>       (+359-2) 713-3813
Department of Information Research                       also 713-3818
Institute of Mathematics and Informatics        fax: (+359-2) 9713649
Acad. G. Bonchev, block 8, Sofia 1113, Bulgaria

From: Kent M Pitman
Subject: Re: How to ensure lexical binding? (DECLARE (NOTSPECIAL ...))?
Date: 
Message-ID: <sfwk9fdijcr.fsf@world.std.com>
········@math.acad.bg (Vassil Nikolov) writes:

> I have been thinking about a way to ensure that a binding
> in a LET form is lexical.

There is a way to do this: get your own package.

If you don't trust someone else to use your programming 
conventions, you have no business programming in the same
package as them.

The solutions you enumerate seem like they place enormous
burden on "good guy" programmers just to protect the right
of other programmers to be "bad guys".  This is exactly
backward from what I consider a good expenditure of resources.

In the past, there was an UNSPECIAL declaration, but it led
to complex patterns turning on and off of specialness of 
variables that never had any business being special in the 
first place.  The idea of having no way to get back is to
encourage people not to do it in the first place.

The right way to think about the language is that all variables
with *'s around them MUST be special and all variables with
no special markers around them MUST NOT be special.  (And we
can quibble about whether +foo+ should be a special or a constant
or whatever since it's in a gray area.)  We were going to define
*'s to always be special but it would have broken many 
historically important programs like Macsyma which had huge
numbers of special variables so we allowed the feature, but it's
really for backward compatibility, not for new design.  You
simply should not ever make non-*'d variables special and you
should tell anyone you see doing it that Kent says it's bad. :-)

> I may be indulging in fantasies, but I think that one day
> Common Lisp, or perhaps another Lisp dialect, may acquire
> a sophisticated (sub)language for defining declarations.

The idea of "declaration macros" expanding into more primitive
declarations has been discussed but mostly other things always
have higher priority.  (And some people resent the idea of 
"yet another namespace".)  Still, what you are talking about
is not even implementable with declaration macros; it requires
a new primitive declaration.  In general, the ability to add
user-defined primitive declarations is likely never to come
in the Common Lisp family because it violates a portability
principle of CL--defining it at the user level would require
knowledge of the interpreter and compiler, which would require
making interpreters and compilers similar enough that it would
inhibit many useful optimizations.  So it's unlikely to happen.

Maybe in a reflective lisp (such as originally proposed by
Brian Smith and later discussed by numerous others in the
theoretical literature) it might make sense.  

> Compilers... the final frontier!  Users can
> define new operations, new types, new classes... why not
> new declarations?

They cannot however define new special forms, new primitive
type specifiers, new primitive classes (built-in-class).
Unfortunately, new layered declarations might be possible
(and CLTL2 had some support we were contemplating but it turned
out too complex and we backed out of it for the ANSI standard)
but new primitive declarations... well, don't hold your breath.

> You may tell me that the above is just nonsense, 

It's never nonsense to try to articulate things you want.
If anything, people are too quick to assume that things that are
hard should not be tried.  In many ways, Lisp is an exercise in
designing a language around the idea of "what people want"
rather than (as with most languages) "what implementors think
they can give you".  Lisp puts pressure on implementors to find
ways to do things that people are determined to do anyway.

But this is a case where the underlying thing you want 
(lexical variables) is already there.  What is (apparently)
standing between you and what you want is someone's bad judgment.
In that case, I think the resources of the community are better
spent teaching the person with bad judgment to code better.

Just my opinion, though.  Not the official position of any of
the organizations with which I am affiliated.
From: Matthias Hoelzl (tc)
Subject: Re: How to ensure lexical binding? (DECLARE (NOTSPECIAL ...))?
Date: 
Message-ID: <8767qxzaoj.fsf@gauss.muc.de>
········@math.acad.bg (Vassil Nikolov) writes:

> I may be indulging in fantasies, but I think that one day
> Common Lisp, or perhaps another Lisp dialect, may acquire
> a sophisticated (sub)language for defining declarations.
> This means that there would be a set of primitive declarations
> and ways to combine them; in other words, a programmable
> compiler.  (Compilers... the final frontier!  Users can
> define new operations, new types, new classes... why not
> new declarations?)
> 
> You may tell me that the above is just nonsense, and you may
> well be right.  But have you never wanted to tell the compiler
> certain things about a program and thus to provide it with
> the information that would allow some optimisation,
> even if it does not actually do the optimisation?

You might want to look at Gregor Kiczales' research about
aspect-oriented programming which deals with these topics.  Personally
I think that the above is far from being nonsense, in my opinion
combining reflexion, aspects and meta-object-protocols is one of the
most interesting directions in current programming language design.

  Matthias
From: Kelly Murray
Subject: Re: How to ensure lexical binding? (DECLARE (NOTSPECIAL ...))?
Date: 
Message-ID: <627tpu$b0u$1@news2.franz.com>
> > I have been thinking about a way to ensure that a binding
> > in a LET form is lexical.

I believe a better (but incompatible) change to CL would be to have
ALL variables as lexically bound, and then introduce a different special 
form to bind special variables.   This means special bindings would not
be possible in lambda's and functions.

This would greatly simplify the compiler.
More importantly, it would make someone think twice before using special bindings.
This is good because they are very different mechanisms,
and have vastly different implications for a language that supports
multiprocessing.  

-Kelly Murray  ···@franz.com 



  
From: Kent M Pitman
Subject: Re: How to ensure lexical binding? (DECLARE (NOTSPECIAL ...))?
Date: 
Message-ID: <sfwsots5wxr.fsf@world.std.com>
···@math.ufl.edu (Kelly Murray) writes:

> I believe a better (but incompatible) change to CL would be to have
> ALL variables as lexically bound, and then introduce a different special 
> form to bind special variables.   This means special bindings would not
> be possible in lambda's and functions.

Yeah, you're not the only one to suggest this.  There's been pressure from
the EuLisp community to do it this way.  I'm making a note to open this
for reconsideration if/when we do a full-scale reconsideration of CL 
features.  There were reasons for not doing it this way before, when a lot
of the community was nervous about lexicals and wanted to support old
code easily and also wanted to be able to move back and forth easily, but
those arguments may not apply next time around.