Here's something you can do with lexicons that you can't do with
packages:
? (in-lexicon "BOB")
#<lexicon BOB>
? (ldefvar foo 'bob-foo)
FOO
? (in-lexicon "JACK")
#<lexicon JACK>
? (ldefun foo () 'jack-foo)
FOO
? (in-lexicon "MYLEX")
#<lexicon MYLEX>
? (*import (find-lexicon "BOB") (current-lexicon) 'foo :namespaces
'(value))
T
? (*import (find-lexicon "JACK") (current-lexicon) 'foo :namespaces
'(function))
T
? foo
BOB-FOO
? (foo)
JACK-FOO
?
With packages, when you import a symbol you get everything associated
with that symbol whether you want it or not. With lexicons you have
much more fine-grained control. Here's another example:
? (make-lexicon "LISP1")
#<lexicon LISP1>
? (convert-lexicon-to-lisp1-semantics (find-lexicon "LISP1"))
#<lexicon LISP1>
? (in-lexicon "LISP1")
#<lexicon LISP1>
? (ldefvar foo (lambda () 'lisp1-foo))
FOO
? foo
#<Anonymous Function #x300041AF8BBF>
? (foo)
LISP1-FOO
?
Here's the code for convert-lexicon-to-lisp1-semantics, in its entirety:
(defun convert-lexicon-to-lisp1-semantics (lexicon)
(setf (ref (lexicon-namespaces lexicon) 'function)
(ref (lexicon-namespaces lexicon) 'value))
lexicon)
rg
On Feb 22, 5:10 pm, Ron Garret <·········@flownet.com> wrote:
> Here's something you can do with lexicons that you can't do with
> packages:
>
> ? (in-lexicon "BOB")
> #<lexicon BOB>
> ? (ldefvar foo 'bob-foo)
> FOO
> ? (in-lexicon "JACK")
> #<lexicon JACK>
> ? (ldefun foo () 'jack-foo)
> FOO
> ? (in-lexicon "MYLEX")
> #<lexicon MYLEX>
> ? (*import (find-lexicon "BOB") (current-lexicon) 'foo :namespaces
> '(value))
> T
> ? (*import (find-lexicon "JACK") (current-lexicon) 'foo :namespaces
> '(function))
> T
> ? foo
> BOB-FOO
> ? (foo)
> JACK-FOO
> ?
>
> With packages, when you import a symbol you get everything associated
> with that symbol whether you want it or not.
Well, that's because you're actually getting THAT symbol. The symbol
you selected to import is EQ to the one that gets imported, i.e. to
itself.
So of course, X and Y cannot have any different properties whatsoever
if they are in fact the same object.
So whatever you think your lexicons are doing, they aren't doing what
is understood as importing a /symbol/. The symbols are interpreted in
the context of a lexicon, and the importing operation clearly has to
replicate context. When it replicates all of the context (or what is
considered ``all'' for some purpose) then it looks like a package
import, because the effect is that you can now use the symbol in the
target package and it denotes the same stuff.
But the importing isn't really about the symbol, but about what the
symbol denotes. By bringing X from there to here, you are simply
making X denote here that which X denotes there. And in so doing you
can choose not to carry some of the denotations, or you can carry over
all of them.
The beauty of packages is that they are completely separated from this
entire business of denotation. Conflating symbols with their
denotation is exactly what is wrong with the module or package systems
of other programming languages.
So for instance in C++, if you have two classes a and b, and you have
a::bar and b::bar, then the symbol bar is really the same symbol. It
just denotes different things in different class scopes. Proof: if b
were to be derived from a, then b::bar would shadow a::bar for the
purposes of name lookup through b. Yet, a::bar and b::bar do name
different things, and they are accessible through scope resolution.
Your import is a lot like the using directive. In C++ if you write
``using foo::x'', you're also just making x denote in the present
scope that what it denotes in namespace foo. It has nothing to do with
the symbol x itself; all x's everywhere in the C++ codebase are
already the same name, they just denote different things in different
scopes (as does the symbol X in Lisp, of course).
Here is another example. Suppose you have a class A and derived B.
There is an A::x function, and B has two functions both called B::x.
Those two functions shadow A::x. With the using A::x directive in B,
you can bring A::x to the same level, so all three x functions
accessible as B::x. It's not the symbol x being imported; x clearly
already denotes things in both scopes. It's just a denotation being
carried over. There are restrictions. Since you can't have a data
member x and a function x in the same class scope, you can't violate
that. The only reason B::x can denote A::x is because of the
inheritance relationship: a B is really a kind of A, and so it has
that x.
Imagine if in C++ the name x could actually be declared in multiple
ways to have multiple simultaneous bindings of different kinds in the
same namespace. Setting aside the problems of syntactic ambiguities,
suppose you could have a function int x(); a variable int x; and a
type or class x, all in the same scope. Then the using directive, like
your lexicon import, could also be hacked to be able to express the
request ``import x, but only the variable x, not the function or type
of the same name''.
Somehow I can't get excited about C++-like namespaces in Lisp; I mean,
thank goodness we don't have that kind of convoluted cruft, right?
But, at the same time, it's like infix syntax. When people grumble, we
can say we have it and cite a URL.
So good job, I guess?
Maybe you can implement class scopes as lexicons, and make sure that
multiple inheritance causes the base class lexicons to merge: that is
to say, lookups through the derived class lexicon have visibility into
all of the base class lexicons. Oh oh, but say, unlike in C++ where
you end up with diagnosable ambiguities, just make clashes silently
resolve in favor of the rightmost base.
I've been living without multiple inheritance symbol clashes long
enough in CL; it's time for some bug-for-bug compatibility with real
OO.
In article
<····································@28g2000hsw.googlegroups.com>,
Kaz Kylheku <········@gmail.com> wrote:
> So whatever you think your lexicons are doing, they aren't doing what
> is understood as importing a /symbol/.
Well, duh. That would be the whole point.
> But the importing isn't really about the symbol, but about what the
> symbol denotes. By bringing X from there to here, you are simply
> making X denote here that which X denotes there. And in so doing you
> can choose not to carry some of the denotations, or you can carry over
> all of them.
Yes, exactly.
> The beauty of packages is that they are completely separated from this
> entire business of denotation.
Sometimes that is beauty, sometimes it can be an annoyance. It depends
on the situation.
> Conflating symbols with their
> denotation is exactly what is wrong with the module or package systems
> of other programming languages.
But Common Lisp *does* conflate symbols with their denotations. The
package system doesn't change that. All the package system does is give
you a one-to-many mapping from *names* to symbols. (Actually, it's
many-to-many, and it's context-sensitive, but we'll leave that aside for
now.)
> Somehow I can't get excited about C++-like namespaces in Lisp;
I guess you're not my target audience then.
> So good job, I guess?
Thank you?
> Maybe you can implement class scopes as lexicons, and make sure that
> multiple inheritance causes the base class lexicons to merge: that is
> to say, lookups through the derived class lexicon have visibility into
> all of the base class lexicons. Oh oh, but say, unlike in C++ where
> you end up with diagnosable ambiguities, just make clashes silently
> resolve in favor of the rightmost base.
>
> I've been living without multiple inheritance symbol clashes long
> enough in CL; it's time for some bug-for-bug compatibility with real
> OO.
The multiple-inheritance problem is a particularly thorny issue. My
position on that is that any time you do multiple inheritance
successfully it's only because the classes you inherit from conform to
some protocol that makes the multiple inheritance work. Part of that
protocol might be to always have the two classes "live" in different
packages, but it might be something else, like making sure that their
slot names don't conflict, or making sure that if they do conflict it
doesn't matter. But you have to do *something*. The CL package system
does not allow you to take two arbitrary classes, fram them together and
expect the result to be useful.
The fact of the matter is that most programmers do not seem to find the
functionality provided by packages to be essential. (If they did,
they'd all be using CL, since CL is the only programming language that
has them.) By contrast, many programmers do seem to find the
functionality provided by lexically scoped modules to be useful, since
many languages offer this functionality and it is widely used. (CL is
one of the few languages that *doesn't* have this functionality
built-in.) So even though it may not be your cup of tea, some people
may find it useful. You really don't need to be quite so disparaging
about it.
rg
On 2008-02-23 03:20:41 -0500, Ron Garret <·········@flownet.com> said:
> In article
> <····································@28g2000hsw.googlegroups.com>,
> Kaz Kylheku <········@gmail.com> wrote:
>
>
>> Somehow I can't get excited about C++-like namespaces in Lisp;
>
> I guess you're not my target audience then.
FWIW, I am your target audience and I'm looking forward to your release
announcement. I've run into the precise annoyance you illustrate
elsewhere more times than I can count, so the ability to defer lexical
bindings alone would make them useful to me. The ability to
independently import function and value cells is nice too.
regards,
Ralph
In article
<····································@pasdespamsilvousplaitmaccom>,
Raffael Cavallaro
<················@pas-d'espam-s'il-vous-plait-mac.com> wrote:
> On 2008-02-23 03:20:41 -0500, Ron Garret <·········@flownet.com> said:
>
> > In article
> > <····································@28g2000hsw.googlegroups.com>,
> > Kaz Kylheku <········@gmail.com> wrote:
> >
> >
> >> Somehow I can't get excited about C++-like namespaces in Lisp;
> >
> > I guess you're not my target audience then.
>
> FWIW, I am your target audience and I'm looking forward to your release
> announcement. I've run into the precise annoyance you illustrate
> elsewhere more times than I can count, so the ability to defer lexical
> bindings alone would make them useful to me. The ability to
> independently import function and value cells is nice too.
Good to know. Thanks!
rg
On Feb 23, 6:20 pm, Raffael Cavallaro <················@pas-d'espam-
s'il-vous-plait-mac.com> wrote:
> On 2008-02-23 03:20:41 -0500, Ron Garret <·········@flownet.com> said:
>
> > In article
> > <····································@28g2000hsw.googlegroups.com>,
> > Kaz Kylheku <········@gmail.com> wrote:
>
> >> Somehow I can't get excited about C++-like namespaces in Lisp;
>
> > I guess you're not my target audience then.
>
> FWIW, I am your target audience and I'm looking forward to your release
> announcement. I've run into the precise annoyance you illustrate
> elsewhere more times than I can count, so the ability to defer lexical
> bindings alone would make them useful to me. The ability to
> independently import function and value cells is nice too.
>
> regards,
>
> Ralph
I am wondering whether I am your target audience. This is what I am
looking for:
I would like to define a package that defines values of physics
constants. I would than import some of these constants into my
working package. But I would like to rename the constants.
For example, suppose I have a constant defined as *speed-of-light* in
the :physics-constants package. But that is long and overly
descriptive, and in my working package I would like to use "c".
Now I guess I could write a macro wrapper to use-package when it comes
to importing variables from my physics-constants package. (Or maybe
package is overkill for my purpose. I could use some kind of hash and
rename on the fly.)
Does your lexicon package give this functionality?
Thank you,
Mirko
FYI, My question comes from my recent experience with Fortran 95 (yep,
my programming career has been going backwards lately). Fortran 95
has the "use module" command that allows the user to import variable
declarations and procedure definitions. The use command allows the
user to use different name of the imported variables. For example:
use module_foo, only: new_name => old_name
In this example, we use the declaration of the variable old_name
defined in module_foo, but we use it under the new_name
(I'm not quite sure of the syntax -- could be old_name => new_name --
as my references are at work).
<·············@gmail.com> wrote:
+---------------
| I would like to define a package that defines values of physics
| constants. I would than import some of these constants into my
| working package. But I would like to rename the constants.
|
| For example, suppose I have a constant defined as *speed-of-light* in
| the :physics-constants package. But that is long and overly
| descriptive, and in my working package I would like to use "c".
|
| Now I guess I could write a macro wrapper to use-package when it comes
| to importing variables from my physics-constants package. (Or maybe
| package is overkill for my purpose. I could use some kind of hash and
| rename on the fly.)
+---------------
Ouch! That sounds way too heavyweight for simple renaming of a few
constants. What about just using DEFINE-SYMBOL-MACRO? E.g.:
(define-symbol-macro +c+ physics-constants:+speed-of-light+)
Note: Just as *...* is conventionally used for special variables
(DEFVAR/DEFPARAMETER), +...+ is the CL convention for constants
(DEFCONSTANT). Though calling it simply "C" probably isn't an issue
in this case, since names defined with DEFINE-SYMBOL-MACRO *can* be
lexically rebound with LET or SYMBOL-MACROLET. [Names defined with
DEFCONSTANT can't.]
-Rob
-----
Rob Warnock <····@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607
In article <································@speakeasy.net>,
····@rpw3.org (Rob Warnock) wrote:
> <·············@gmail.com> wrote:
> +---------------
> | I would like to define a package that defines values of physics
> | constants. I would than import some of these constants into my
> | working package. But I would like to rename the constants.
> |
> | For example, suppose I have a constant defined as *speed-of-light* in
> | the :physics-constants package. But that is long and overly
> | descriptive, and in my working package I would like to use "c".
> |
> | Now I guess I could write a macro wrapper to use-package when it comes
> | to importing variables from my physics-constants package. (Or maybe
> | package is overkill for my purpose. I could use some kind of hash and
> | rename on the fly.)
> +---------------
>
> Ouch! That sounds way too heavyweight for simple renaming of a few
> constants. What about just using DEFINE-SYMBOL-MACRO? E.g.:
>
> (define-symbol-macro +c+ physics-constants:+speed-of-light+)
>
> Note: Just as *...* is conventionally used for special variables
> (DEFVAR/DEFPARAMETER), +...+ is the CL convention for constants
> (DEFCONSTANT). Though calling it simply "C" probably isn't an issue
> in this case, since names defined with DEFINE-SYMBOL-MACRO *can* be
> lexically rebound with LET or SYMBOL-MACROLET. [Names defined with
> DEFCONSTANT can't.]
Yes, I would second this recommendation. The whole point of lexicons is
to manage namespaces automatically, so if you actually *want* to rename
things manually then you're probably better off just using packages.
rg
On Feb 24, 12:34 am, ····@rpw3.org (Rob Warnock) wrote:
> <·············@gmail.com> wrote:
>
> +---------------
> | I would like to define a package that defines values of physics
> | constants. I would than import some of these constants into my
> | working package. But I would like to rename the constants.
> |
> | For example, suppose I have a constant defined as *speed-of-light* in
> | the :physics-constants package. But that is long and overly
> | descriptive, and in my working package I would like to use "c".
> |
> | Now I guess I could write a macro wrapper to use-package when it comes
> | to importing variables from my physics-constants package. (Or maybe
> | package is overkill for my purpose. I could use some kind of hash and
> | rename on the fly.)
> +---------------
>
> Ouch! That sounds way too heavyweight for simple renaming of a few
> constants. What about just using DEFINE-SYMBOL-MACRO? E.g.:
>
> (define-symbol-macro +c+ physics-constants:+speed-of-light+)
>
> Note: Just as *...* is conventionally used for special variables
> (DEFVAR/DEFPARAMETER), +...+ is the CL convention for constants
> (DEFCONSTANT). Though calling it simply "C" probably isn't an issue
> in this case, since names defined with DEFINE-SYMBOL-MACRO *can* be
> lexically rebound with LET or SYMBOL-MACROLET. [Names defined with
> DEFCONSTANT can't.]
>
> -Rob
>
> -----
> Rob Warnock <····@rpw3.org>
> 627 26th Avenue <URL:http://rpw3.org/>
> San Mateo, CA 94403 (650)572-2607
Thanks. That looks sensible enough.
Mirko