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

basic package question

24 views
Skip to first unread message

Quinn Dunkan

unread,
Apr 19, 2002, 8:15:01 PM4/19/02
to
I'm not too clear on how the CL package system works, and probably how
symbol->value resolution works in general.

% cat foo.lisp
(defpackage foo
(:export x))
(in-package :foo) ; cmucl likes a keyword here for some reason
(setf x 10)
% clisp
[1]> (load "foo.lisp")
;; Loading file foo.lisp ...
;; Loading of file foo.lisp is finished.
T
[2]> (use-package :foo)
... error: X is already interned in COMMON-LISP-USER

Of course, (import 'foo:x) gives the same error, which also happens on cmucl.
(find-symbol "X") claims that it is internal to USER, but X is neither bound
nor fbound in USER (foo:x works as I expect). I suppose (based on my vague
understanding of how symbols work), there's no need for a symbol to have a
value, function, plist, or whatever to be interned, it merely needs to be
mentioned. This sort of thing seems like it would easily create spurious
name clashes (when you import a symbol you previously mentioned in a QUOTE), so
maybe that's not how it works. Anyway, it still doesn't explain where the
USER package is getting those symbols.

In addition, import and use-package seem work as I expect when COMMON-LISP-USER
is not involved.

Coby Beck

unread,
Apr 19, 2002, 9:00:07 PM4/19/02
to

"Quinn Dunkan" <qu...@hurl.ugcs.caltech.edu> wrote in message
news:slrnac1co4...@hurl.ugcs.caltech.edu...

> I'm not too clear on how the CL package system works, and probably how
> symbol->value resolution works in general.
>
> % cat foo.lisp
> (defpackage foo
> (:export x))
> (in-package :foo) ; cmucl likes a keyword here for some reason
> (setf x 10)
> % clisp
> [1]> (load "foo.lisp")
> ;; Loading file foo.lisp ...
> ;; Loading of file foo.lisp is finished.
> T
> [2]> (use-package :foo)
> ... error: X is already interned in COMMON-LISP-USER
>

Try:
(defvar x 10)
in foo.lisp. I don't know that that is the problem but it seems likely.
Because you are setf'ing a previously unmentioned variable, x, the
consequences are undefined.

--
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")

Kent M Pitman

unread,
Apr 19, 2002, 9:01:27 PM4/19/02
to
qu...@hurl.ugcs.caltech.edu (Quinn Dunkan) writes:

> I'm not too clear on how the CL package system works, and probably how
> symbol->value resolution works in general.
>
> % cat foo.lisp
> (defpackage foo
> (:export x))

The :EXPORT clause takes an argument which is a string. It can't take
the symbol to export since the symbol to export doesn't exist yet at the
time the DEFPACKAGE form is read. But by specifying a symbol, you have
created that symbol. You might as well have typed

(cl:defpackage cl-user::foo
(:export cl-user::x))

This will be interpreted as

(CL:DEFPACKAGE "FOO"
(:export "X"))

but as a side-effect, you have created CL-USER::FOO and CL-USER::X.

> (in-package :foo) ; cmucl likes a keyword here for some reason

Package names are strings, not symbols.

The defpackage defines a package named "FOO".

IN-PACKAGE does not evaluate its argument. It used to.
Some implementations get worried if you say (in-package foo) that
you are trying to name a variable; using a self-evaluating expression
like "FOO" or :FOO or :foo works best.

> (setf x 10)
> % clisp
> [1]> (load "foo.lisp")
> ;; Loading file foo.lisp ...
> ;; Loading of file foo.lisp is finished.
> T
> [2]> (use-package :foo)
> ... error: X is already interned in COMMON-LISP-USER

It's a bad idea to just use free uses of USE-PACKAGE.

In doing this USE-PACKAGE, you are trying to make CL-USER inherit FOO:X
but there is already a CL-USER::X (see above). That conflict has to be
dealt with.

Solution?

Use

(defpackage "FOO"
(:export "X"))

Don't be making symbols you don't mean to use.

> Of course, (import 'foo:x) gives the same error, which also happens
> on cmucl. (find-symbol "X") claims that it is internal to USER, but
> X is neither bound nor fbound in USER (foo:x works as I expect). I
> suppose (based on my vague understanding of how symbols work),
> there's no need for a symbol to have a value, function, plist, or
> whatever to be interned, it merely needs to be mentioned. This sort
> of thing seems like it would easily create spurious name clashes
> (when you import a symbol you previously mentioned in a QUOTE), so
> maybe that's not how it works. Anyway, it still doesn't explain
> where the USER package is getting those symbols.

You're making them!



> In addition, import and use-package seem work as I expect when
> COMMON-LISP-USER is not involved.

Right. Because you're probably using them in packages that you haven't
polluted. ;)

Paul F. Dietz

unread,
Apr 19, 2002, 9:26:48 PM4/19/02
to
Kent M Pitman wrote:

> The :EXPORT clause takes an argument which is a string.

Actually, a sequence of string designators.

> Use
>
> (defpackage "FOO"
> (:export "X"))
>
> Don't be making symbols you don't mean to use.

But this does the wrong thing if your lisp doesn't
by default read symbols as being in upper case.

I prefer something like this:

(defpackage :foo
(:export #:x))

There was a long, drawn out thread about this last
year, wasn't there?

Paul

Kent M Pitman

unread,
Apr 19, 2002, 10:46:37 PM4/19/02
to
"Paul F. Dietz" <di...@interaccess.com> writes:

> Kent M Pitman wrote:
>
> > The :EXPORT clause takes an argument which is a string.
>
> Actually, a sequence of string designators.
>
> > Use
> >
> > (defpackage "FOO"
> > (:export "X"))
> >
> > Don't be making symbols you don't mean to use.
>
> But this does the wrong thing if your lisp doesn't
> by default read symbols as being in upper case.

I don't understand what you mean. All Common Lisp symbols are
canonically in uppercase. If you want to make them be in lowercase,
you want "foo" and "x". But I don't see why you would want to leave
it to chance.

I have a suspicion you're actually confused on this, but I can't tell
for sure by the way you're expressing yourself. The example below
suggests a confusion.

> I prefer something like this:
>
> (defpackage :foo
> (:export #:x))
>
> There was a long, drawn out thread about this last
> year, wasn't there?

There may have been.

You're welcome to suggest whatever weird style you want.
I just abhor this particular style.

Making extra gensyms to throw away seems silly.

Making extra symbols in the keyword package seems equally confusing
and pointless to me.

As far as I know, this style was developed by people who want to stick
their head in the standa nd not acknowledge that the normal internal
case is, in fact, uppercase. I don't think the issue is that it might
not be uppercase--it's that they _wish_ it might not be.

I think that only encourages confusion.

Quinn Dunkan

unread,
Apr 20, 2002, 4:34:34 AM4/20/02
to
On Sat, 20 Apr 2002 01:01:27 GMT, Kent M Pitman <pit...@world.std.com> wrote:
>qu...@hurl.ugcs.caltech.edu (Quinn Dunkan) writes:
>
>> I'm not too clear on how the CL package system works, and probably how
>> symbol->value resolution works in general.
>>
>> % cat foo.lisp
>> (defpackage foo
>> (:export x))
>
>The :EXPORT clause takes an argument which is a string. It can't take
>the symbol to export since the symbol to export doesn't exist yet at the
>time the DEFPACKAGE form is read. But by specifying a symbol, you have
>created that symbol. You might as well have typed
>
> (cl:defpackage cl-user::foo
> (:export cl-user::x))

Ah! I hadn't made the connection that you aren't in the package until you
say in-package. Which is obvious in retrospect, I guess.

>> (in-package :foo) ; cmucl likes a keyword here for some reason
>
>Package names are strings, not symbols.

Ok, that makes sense now. Come to think of it, CLHS says a package designator
is a string or a package---symbols are not included.

Which also makes me wonder why symbols work at all. CLOCC code uses:

(in-package :cllib)

Even given that a symbol is accepted as a package designator, I still don't
understand why a keyword would also designate the same package, since :X and
X are different symbols.

>It's a bad idea to just use free uses of USE-PACKAGE.

Do you mean that as in "you should use (:uses ...) in defpackage instead" or
"you shouldn't clog up your namespace with lots of symbol inheriting"?
In this case, I'm testing my packages from the REPL, so I can't put (:uses ...)
in USER's defpackage, and I'm not too concerned with namespace pollution since
it's temporary, and I can unuse if I make a mess. At least that's the idea.

Is there any reason to prefer:

(defpackage "FOO"
(:export "A" "B" "C"))

over:

(defpackage "FOO")
(in-package :foo) ; or "FOO"?
(export '(a b c))

anyway, thanks for the clue!

Paul F. Dietz

unread,
Apr 20, 2002, 7:04:14 AM4/20/02
to
Kent M Pitman wrote:

> > But this does the wrong thing if your lisp doesn't
> > by default read symbols as being in upper case.
>
> I don't understand what you mean. All Common Lisp symbols are
> canonically in uppercase. If you want to make them be in lowercase,
> you want "foo" and "x". But I don't see why you would want to leave
> it to chance.
>
> I have a suspicion you're actually confused on this, but I can't tell
> for sure by the way you're expressing yourself. The example below
> suggests a confusion.

The default readtable has readtable-case of :upcase, but you might
want to change that -- or have it changed out from under you in the
future by some vendor -- and the code I described would work regardless.


> As far as I know, this style was developed by people who want to stick

> their head in the [sand and] not acknowledge that the normal internal

> case is, in fact, uppercase.

Yes, I remember which side of that long thread you were on. :)

As a user, I do something protective like that just so I'm not
potentially screwed if for some reason it does change. This doesn't
indicate I want it to change, but if some vendor has made noises
that suggest it may want to do that I am going to be careful.
The cost is minimal.

Paul

Erik Naggum

unread,
Apr 20, 2002, 7:06:35 AM4/20/02
to
* "Paul F. Dietz" <di...@interaccess.com>

| But this does the wrong thing if your lisp doesn't by default read
| symbols as being in upper case.

Then you are not using ANSI Common Lisp, but some other Lisp.

| I prefer something like this:
|
| (defpackage :foo
| (:export #:x))
|
| There was a long, drawn out thread about this last year, wasn't there?

I have tried long and hard to understand the position that (1) ANSI
Common Lisp mandates upper-case symbol names, (2) someone does not like
that, so (3) violating ANSI Common Lisp requirements is the only
solution. It most definitely is not the _only_ solution.

If you are a good citizen of the Common Lisp community, you realize that
it does not matter at all what the internal case of the symbols are. If
you want to see and type lower-case symbol names, that has no bearing on
what the internal symbol names must be. Thinking it does indicates a
massive failure to grasp how the whole string-to-symbol operation works.

I am probably no more than a few days away from a fully working solution
that would make Allegro CL, which has introduced this problem to our
community, work equally well with _both_ upper-case and lower-case symbol
names in the code it reads and its programmers are exposed to. Today,
you are required to make a decision whether you want your code to see
upper-case _or_ lower-case symbol names. This has been a source of some
very serious annoyances and even "wars" here, but it has at its root a
personal dislike of the arbitrary choice of upper-case symbol names and a
lack of professionalism by those who hold this personal grudge against
the standard. I believe I have found an easy, modular, and predictable
way to make the programmer choose, so the implementor does not have to.

///
--
In a fight against something, the fight has value, victory has none.
In a fight for something, the fight is a loss, victory merely relief.

Post with compassion: http://home.chello.no/~xyzzy/kitten.jpg

Erik Naggum

unread,
Apr 20, 2002, 7:56:27 AM4/20/02
to
* "Paul F. Dietz" <di...@interaccess.com>
| The default readtable has readtable-case of :upcase, but you might want
| to change that -- or have it changed out from under you in the future by
| some vendor -- and the code I described would work regardless.

Paul, you have solved the wrong problem and have just created another,
much more serious one: fear of trusting the standard. This is a very
contagious fear and once started, can cause you to become paranoid in the
extreme about trusting a language standard. Bugs in implementations are
no longer bugs, they _may_ be intentional violations that you have to
take into account in much more serious ways than bugs -- they are likely
to last. Some vendors want you to live in this fear all the time, but
the primary such fear-monger is fortunately not interested in Common
Lisp. In my view, it is not a good sign at all when a vendor works
against the community standards, and almost even worse when they give you
a choice of departing from the standard with them or not, especially when
you sort of have to depart with them to get their new features. I am not
at all impressed with these tactics and their effect on people, which is
why I have spent a huge amount of time trying to find alternative
solutions that do not cause people to live in fear and engage in counter-
measures to prevent painful brushes with vendor-initiated violations.

| Yes, I remember which side of that long thread you were on. :)

The "side" Kent and I are on is: as a vendor, DO NOT VIOLATE THE STANDARD
just because you have a personal opinion or grudge against the committee
decision to use upper-case symbol names. It is essentially arbitrary,
and if you need a different solutions, make it coexist with the standard.

| As a user, I do something protective like that just so I'm not
| potentially screwed if for some reason it does change.

You mean, if your vendor is not particularly interested in letting you
continue to work with ANSI Common Lisp?

| This doesn't indicate I want it to change, but if some vendor has made
| noises that suggest it may want to do that I am going to be careful. The
| cost is minimal.

The cost should be zero. If your vendor makes fully conforming code stop
working, they have transferred the cost of their decision to you. If
they do this to you, you have to weigh that cost against the cost of
using a different vendor.

I believe I have found a way to make the cost exactly zero to programmers.
It does require some investment by the vendors, however, but this is how
responsible people generally do language development. What has taken me
so long is figuring out how to make this investment small enough and the
obvious benefits large enough that people will want to make make it.

My _personal_ opinion is _also_ that lower-case symbol names look far
more "modern" than upper-case symbol names, but I actually value my own
professionalism towards specifications much higher than my personal
opinion, so I have to accept that the symbol-names are upper-case until I
can convince people that the specification should be changed, and when it
is changed, that no previously conforming program would break. To make
this even more palatable to users of other implementations than those I
have the ability to influence, a solution has to be made available that
all users can load into their Common Lisp systems and expect to work. I
care enough about this issue to have spent a few months on this rather
than just go ahead and violate the standard by flipping the case of all
the characters of all the symbol names in the Common Lisp image and ask
the rest of the world to deal with it.

Kent M Pitman

unread,
Apr 20, 2002, 8:55:41 AM4/20/02
to
Erik Naggum <er...@naggum.net> writes:

> * "Paul F. Dietz" <di...@interaccess.com>
> | But this does the wrong thing if your lisp doesn't by default read
> | symbols as being in upper case.
>
> Then you are not using ANSI Common Lisp, but some other Lisp.

This goes back to the question Erann Gat was implicitly raising of how easy
it is to make another whole language. The answer? This easy.

Fortunately, Franz seems so far to like the plan I proposed for how to
resolve this in a CL-compatible way in their products, and there is
some hope that in the future this will be resolved. (Unless as they
try to implement my suggestion they run into a snag that none of us
has seen yet.)

Things don't get fixed overnight, but it's nice that they're
interested in resolving this nagging and vexxing problem.

Erik Naggum

unread,
Apr 20, 2002, 9:13:28 AM4/20/02
to
* Kent M Pitman

| Fortunately, Franz seems so far to like the plan I proposed for how to
| resolve this in a CL-compatible way in their products, and there is some
| hope that in the future this will be resolved. (Unless as they try to
| implement my suggestion they run into a snag that none of us has seen
| yet.)

There are serious snags in this area. I believe I have worked them out.

Duane Rettig

unread,
Apr 20, 2002, 12:00:01 PM4/20/02
to
Kent M Pitman <pit...@world.std.com> writes:

> "Paul F. Dietz" <di...@interaccess.com> writes:
>
> > Kent M Pitman wrote:
> >
> > > The :EXPORT clause takes an argument which is a string.
> >
> > Actually, a sequence of string designators.
> >
> > > Use
> > >
> > > (defpackage "FOO"
> > > (:export "X"))
> > >
> > > Don't be making symbols you don't mean to use.
> >
> > But this does the wrong thing if your lisp doesn't
> > by default read symbols as being in upper case.
>
> I don't understand what you mean. All Common Lisp symbols are
> canonically in uppercase. If you want to make them be in lowercase,
> you want "foo" and "x". But I don't see why you would want to leave
> it to chance.

Careful about your use of the word "All". Remember, Common Lisp is
not a case-insensitive language; only its reader is, and even that
can be inhibited:

CL-USER(1): (symbol-name '|aBc|)
"aBc"
CL-USER(2):

> I have a suspicion you're actually confused on this, but I can't tell
> for sure by the way you're expressing yourself. The example below
> suggests a confusion.
>
> > I prefer something like this:
> >
> > (defpackage :foo
> > (:export #:x))
> >
> > There was a long, drawn out thread about this last
> > year, wasn't there?
>
> There may have been.
>
> You're welcome to suggest whatever weird style you want.
> I just abhor this particular style.

I assume that your reasoning below says why you abhor this style.
However, I am going to ask the question anyway: Why?
In fact, it would seem to me that if you are not the type of
person who would type this way:

(DEFUN FOO (X)
(BAR X))

but instead type your program in this way:

(defun foo (x)
(bar x))

that you might then use the same reasoning to type your defpackage
form in lowercase and have it come out right:

(:export #:x)

instead of

(:export #:X)

or

(:export "X")

> Making extra gensyms to throw away seems silly.

No more silly than making strings to throw away. A good defpackage
implementation will optimize this out anyway.

> Making extra symbols in the keyword package seems equally confusing
> and pointless to me.

Agreed. Both of these forms:

(:export x)

and

(:export :x)

are wasteful.

> As far as I know, this style was developed by people who want to stick
> their head in the standa nd not acknowledge that the normal internal
> case is, in fact, uppercase. I don't think the issue is that it might
> not be uppercase--it's that they _wish_ it might not be.

Again, the internal representation of Common Lisp is not uppercase.
It is only the reader that performs the case folding, and that can
be turned off by quoting the characters.

> I think that only encourages confusion.

Perhaps, but I think the confusion is where the case
sensitivity/insensitivity really occurs in Common Lisp.

--
Duane Rettig Franz Inc. http://www.franz.com/ (www)
1995 University Ave Suite 275 Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253 du...@Franz.COM (internet)

Duane Rettig

unread,
Apr 20, 2002, 12:00:01 PM4/20/02
to
Erik Naggum <er...@naggum.net> writes:

> * Kent M Pitman
> | Fortunately, Franz seems so far to like the plan I proposed for how to
> | resolve this in a CL-compatible way in their products, and there is some
> | hope that in the future this will be resolved. (Unless as they try to
> | implement my suggestion they run into a snag that none of us has seen
> | yet.)
>
> There are serious snags in this area. I believe I have worked them out.

I'd be interested in seeing your solution. I have not had a chance to
work on this (and have told Kent as much) because I am deep into buttoning
up our 6.2 version, which has been essentially feature-frozen after beta
release. But I am of course interested in seeing a solution for the
future (it would also be nice if it were patchable).

Thomas F. Burdick

unread,
Apr 20, 2002, 12:43:09 PM4/20/02
to
qu...@schilling.ugcs.caltech.edu (Quinn Dunkan) writes:

> On Sat, 20 Apr 2002 01:01:27 GMT, Kent M Pitman <pit...@world.std.com> wrote:

> > qu...@hurl.ugcs.caltech.edu (Quinn Dunkan) writes:

> > > (in-package :foo) ; cmucl likes a keyword here for some reason
> >
> > Package names are strings, not symbols.
>
> Ok, that makes sense now. Come to think of it, CLHS says a package designator
> is a string or a package---symbols are not included.
>
> Which also makes me wonder why symbols work at all.

The spec actually says a string *designator* or a package. "string
designator" is also a defined term:

string designator n. a designator for a string; that is, an object
that denotes a string and that is one of: a character (denoting a
singleton string that has the character as its only element), a
symbol (denoting the string that is its name), or a string (denoting
itself). The intent is that this term be consistent with the
behavior of string; implementations that extend string must extend
the meaning of this term in a compatible way.

I'm very glad this piece of terminology is in there, because "string
designator" is a useful concept.

> CLOCC code uses:
>
> (in-package :cllib)
>
> Even given that a symbol is accepted as a package designator, I still don't
> understand why a keyword would also designate the same package, since :X and
> X are different symbols.

Well, it's only being used for its SYMBOL-NAME.

--
/|_ .-----------------------.
,' .\ / | No to Imperialist war |
,--' _,' | Wage class war! |
/ / `-----------------------'
( -. |
| ) |
(`-. '--.)
`. )----'

Erik Naggum

unread,
Apr 20, 2002, 2:15:47 PM4/20/02
to
* Duane Rettig <du...@franz.com>

| I'd be interested in seeing your solution.

I have some wrinkles to iron out and some real life testing to do, so the
timing of Paul F. Dietz' comments were slightly infavorable. Franz Inc
will be the first to know how about this, as you probably will be the
only ones to seriously put it to the test, too. :)

| I have not had a chance to work on this (and have told Kent as much)
| because I am deep into buttoning up our 6.2 version, which has been
| essentially feature-frozen after beta release. But I am of course
| interested in seeing a solution for the future (it would also be nice if
| it were patchable).

It should be patchable for either image, but my primary goal has been to
give you a very good reason not to distribute two different images, as it
causes people to choose the lower-case image when all they want is some
of the features that some of your programmers only think will "work" with
in lower-case, and offer some fairly ridiculous arguments to the effect
that it is "necessary". My goal has been to make it as easy to choose
whether you see upper- or lower-case symbols as to set the readtable-case
or the *print-case* variable.

Kent M Pitman

unread,
Apr 20, 2002, 4:02:58 PM4/20/02
to
t...@famine.OCF.Berkeley.EDU (Thomas F. Burdick) writes:

...


> The spec actually says a string *designator* or a package. "string
> designator" is also a defined term:
>
> string designator n. a designator for a string; that is, an object
> that denotes a string and that is one of: a character (denoting a
> singleton string that has the character as its only element), a
> symbol (denoting the string that is its name), or a string (denoting
> itself). The intent is that this term be consistent with the
> behavior of string; implementations that extend string must extend
> the meaning of this term in a compatible way.
>
> I'm very glad this piece of terminology is in there, because "string
> designator" is a useful concept.

Heh. You should have seen the kind of junk that I was able to throw
away due to the addition of this term. Phrases like

"a symbol or a string or a list of symbols or a list of strings"

were both more wordy AND incorrect (because they often omitted "a list of
mixed symbols and strings") than the resulting:

"a designator for a list of string designators"

But the other important aspect of the change is that any phrase as
textually compact as "a symbol or a string" still has an "or" in it, and
that means any use of "or" to conjoin phrases or clauses in the sentence
is arbitrarily harder to make work because you have to use ", or" or "; or"
or you have to just give up and go to multiple sentences.

I almost couldn't NOT have introduced this terminology. I'm amazed Steele
survived without it.

Marco Antoniotti

unread,
Apr 21, 2002, 4:38:50 PM4/21/02
to

CASE FIGHT!!!!!!!!

"Paul F. Dietz" <di...@interaccess.com> writes:

> Kent M Pitman wrote:
>
> > The :EXPORT clause takes an argument which is a string.
>
> Actually, a sequence of string designators.
>
> > Use
> >
> > (defpackage "FOO"
> > (:export "X"))
> >
> > Don't be making symbols you don't mean to use.
>
> But this does the wrong thing if your lisp doesn't
> by default read symbols as being in upper case.

Which happens to be the non standard way of doing things.
ANSI requires that to be the default. If that is not the case, then
you are consciously using a tweak of the reader.

> I prefer something like this:
>
> (defpackage :foo
> (:export #:x))
>
> There was a long, drawn out thread about this last
> year, wasn't there?

Yes. It was the CASE WARS thread. The problem is that the solution
devised by Franz to fix the not-so-good (with the power of hindsight)
decision to make CL case insensitive uppercasing, is not backward
compatible.

Now. A backward compatible solution can be specified (shameless
plug), but it requires agreement by the implementors to provide it.

The above style placates Franz case sensitive images, but it is
arguably unpleasant and it is guaranteed to work well only in ACL. It
does work in any CL, but, e.g. you do not have any guarantees that the
uninterned symbols get collected.

Cheers

--
Marco Antoniotti ========================================================
NYU Courant Bioinformatics Group tel. +1 - 212 - 998 3488
719 Broadway 12th Floor fax +1 - 212 - 995 4122
New York, NY 10003, USA http://bioinformatics.cat.nyu.edu
"Hello New York! We'll do what we can!"
Bill Murray in `Ghostbusters'.

Duane Rettig

unread,
Apr 22, 2002, 12:00:02 AM4/22/02
to
Marco Antoniotti <mar...@cs.nyu.edu> writes:

> CASE FIGHT!!!!!!!!

Not at all.

> The above style placates Franz case sensitive images, but it is
> arguably unpleasant and it is guaranteed to work well only in ACL. It
> does work in any CL, but, e.g. you do not have any guarantees that the
> uninterned symbols get collected.

I would hope that this would not be the situation. Uninterned symbols
are not pointed to by any package, and thus tend to have similar
characteristics as strings, wrt the number of references _to_ them.
I.e. interned symbols will have an extra reference to them, from
their home package, and it is usually this reference which keeps the
symbol from being gc'd. However, uninterned symbols have no such
reference to keep them from being gc'd.

So whatever the implementation, the form

(:export #:x)

would have similar nature wrt gc to

(:export "X")

since if the defpackage form does not let go of the #:x it would also
not let go of the "X". Now, of course there is the possibility that
the symbol x has not yet been created, and so "X" in the export list
might be used for the symbol-name during the subsequent intern of x
before its export. However, the possibility exists to use
(symbol-name '#:x) in the same way. So the gc characteristics
of the two specifications are the same, with the exception that the
temporary allocation of #:x is larger than "X", if not optimized.

So in conclusion, I would hope that any defpackage implementation
would allow its entries to be gc'd (modulo the interning usage I
cited) whether it is an uninterned symbol or a string.

james anderson

unread,
Apr 25, 2002, 5:47:51 AM4/25/02
to

i have, quite coincidentally, recently received a note from a lisp user
who was confounded in his effort to use an application by problems with
symbol name case. it was most amusing that, in keeping with the
respective lisp vendor's documents on the subject, the enquiry was
phrased in term of what one should do to make the application code
'portable'." i had always presumed that "portable" would be confined to
runtime behaviour which itself conforms to "the standard".

the initial issue concerned symbol name case in code. i see some value
to the "mixed case" style of capitalization, which can cause problems
with some modes of case sensitivity. the lisp in question can be
configured to accommodate mixed case style, so that is a minor issue.

beyond that, there are some cases where the upcased and literal cased
symbols in the same package are assigned distinct meanings. this
applies, for example, with function and/or class definitions generated
from external, non-lisp definitions. in order for this to work, intern,
defpackage, and read/print should all have readily predictable effects
as to the internal and external representations of objects which they
manipulate. i would have been less likely to use that method if it were
not trivially possible to predict the internal symbol name case in a
conforming lisp.

aside from my general curiosity about the possible advantages of
permitting the programmer to predict the effects of thirty-six possible
combinations of symbol case, readtable case, and print case, i am
concerned whether everything which can be expressed in any given mode
can also be expressed "portably". in particular, can everything which
can be expressed in the mode which conforms to ansi behaviour also be
expressed portably.

has there been any discussion on that question?


Duane Rettig wrote:
>
> ...

Kent M Pitman

unread,
Apr 25, 2002, 11:30:15 AM4/25/02
to
james anderson <james.a...@setf.de> writes:

> beyond that, there are some cases where the upcased and literal
> cased symbols in the same package are assigned distinct
> meanings. this applies, for example, with function and/or class
> definitions generated from external, non-lisp definitions. in order
> for this to work, intern, defpackage, and read/print should all have
> readily predictable effects as to the internal and external
> representations of objects which they manipulate. i would have been
> less likely to use that method if it were not trivially possible to
> predict the internal symbol name case in a conforming lisp.

As far as I know, there is no situation involving Common Lisp in which
the internal symbol name case is not predictable. So I don't know
what this means.



> aside from my general curiosity about the possible advantages of
> permitting the programmer to predict the effects of thirty-six
> possible combinations of symbol case, readtable case, and print
> case,

There is no question that some of these combinations are more and less
useful than others; but as far as I know, the utility of any given
combination does not vary according to vendor platform. The language
spec leaves vendors latitude about, for example, whether to quote a
symbol name like \a\b or |ab| but not about whether to apply quoting
at all. The language spec leaves no discretion about whether any
given notation results in any given symbol name.

> i am concerned whether everything which can be expressed in any
> given mode can also be expressed "portably".

If you set the printer/reader variables and readtable options the
same, all should work the same in any _conforming_ implementation. If
an implementation doesn't conform, you will get a problem.

> in particular, can everything which can be expressed in the mode
> which conforms to ansi behaviour also be expressed portably.

The ANSI behavior is portable among vendors that conform to the ANSI
spec. Your statement here supposes some other kind of portable.



> has there been any discussion on that question?

There has been a lot of frenzy about the fact that Franz offers two
implementations: one attempts to be ANSI compliant and one
(unfortunately badly named "modern") is apparently not trying to be
ANSI compliant. (At some point in the future, there's some hope these
will be unified, but for now not.) If you program in their non-ANSI
version (or _anyone's_), your code will not be portable; that's what
it means to be non-compliant--there is no promise that the standard
will apply. If you stick to ANSI-compliant code and ANSI-compliant
processors (i.e., implementations), your code should be portable,
barring bugs in implementations. That's the whole point of a
standard--it tells the user and vendor each must do in order that when
the two come together, programs will work.

Note that if this is not about Franz Allegro, it's news to me, and you
should say more. I don't know of another vendor that has elected this
kind of deviation.

james anderson

unread,
Apr 25, 2002, 4:01:58 PM4/25/02
to

Kent M Pitman wrote:
>
> james anderson <james.a...@setf.de> writes:
>
> > beyond that, there are some cases where the upcased and literal
> > cased symbols in the same package are assigned distinct
> > meanings. this applies, for example, with function and/or class
> > definitions generated from external, non-lisp definitions. in order
> > for this to work, intern, defpackage, and read/print should all have
> > readily predictable effects as to the internal and external
> > representations of objects which they manipulate. i would have been
> > less likely to use that method if it were not trivially possible to
> > predict the internal symbol name case in a conforming lisp.
>
> As far as I know, there is no situation involving Common Lisp in which
> the internal symbol name case is not predictable. So I don't know
> what this means.

i should have written that last clause as

"... less likely to use that method were it not trivially possible to


predict the internal symbol name case in a conforming lisp."

with the addition of case modes, prediction is still possible, but it is
no longer trivial.
this aside from issues of conformance.

>
> ...


>
> > i am concerned whether everything which can be expressed in any
> > given mode can also be expressed "portably".
>
> If you set the printer/reader variables and readtable options the
> same, all should work the same in any _conforming_ implementation. If
> an implementation doesn't conform, you will get a problem.
>
> > in particular, can everything which can be expressed in the mode
> > which conforms to ansi behaviour also be expressed portably.
>
> The ANSI behavior is portable among vendors that conform to the ANSI
> spec. Your statement here supposes some other kind of portable.
>

the ' " 's was were intended to indicate vendor terminology.

> > has there been any discussion on that question?
>
> There has been a lot of frenzy about the fact that Franz offers two
> implementations: one attempts to be ANSI compliant and one
> (unfortunately badly named "modern") is apparently not trying to be
> ANSI compliant. (At some point in the future, there's some hope these
> will be unified, but for now not.) If you program in their non-ANSI
> version (or _anyone's_), your code will not be portable;

where the vendor's documentation addresses the problem, it describes
several idioms for simple symbol manipulation which can serve to ensure
that portable code (in the ansi sense) is also "portable" in the case
mode sense. with little effort made to distinguish "case mode portable"
from portable. which led to my question, as to whether there is always a
"case mode portable" formulation for any given operation which is also
portable in the ansi sense.

> that's what
> it means to be non-compliant--there is no promise that the standard
> will apply. If you stick to ANSI-compliant code and ANSI-compliant
> processors (i.e., implementations), your code should be portable,
> barring bugs in implementations. That's the whole point of a
> standard--it tells the user and vendor each must do in order that when
> the two come together, programs will work.
>

after reading their documentation, i came to the conclusion that coding
"case mode portable" code portably would entail either a greater
dependance on the reader than i would have wanted, or would require that
one implement alternative symbol management routines which were
sensitive to the non-conformant case modes when they were present. for
the moment, i responded to the original party who was having problems,
that some things would require a conformant lisp.

i was just wondering if there's more behind this.

> Note that if this is not about Franz Allegro, it's news to me, and you
> should say more. I don't know of another vendor that has elected this
> kind of deviation.

...

Kent M Pitman

unread,
Apr 25, 2002, 4:28:59 PM4/25/02
to
james anderson <james.a...@setf.de> writes:

> where the vendor's documentation addresses the problem, it describes
> several idioms for simple symbol manipulation which can serve to ensure
> that portable code (in the ansi sense) is also "portable" in the case
> mode sense. with little effort made to distinguish "case mode portable"
> from portable. which led to my question, as to whether there is always a
> "case mode portable" formulation for any given operation which is also
> portable in the ansi sense.

I have no idea. You don't say which vendor. You are working outside of
the spec. As far as I'm concerned, you're on your own. You are asking
for trouble, as far as I can see, and you have been given what you've asked
for. This is not the intended programming style. There are good reasons
the stnadard doesn't provide the functionality you want, and they are that
it would lead to all kinds of portability problems that sound very similar
to what you've gotten here. That is pretty much the end of the story as
far as I'm concerned.

> > that's what
> > it means to be non-compliant--there is no promise that the standard
> > will apply. If you stick to ANSI-compliant code and ANSI-compliant
> > processors (i.e., implementations), your code should be portable,
> > barring bugs in implementations. That's the whole point of a
> > standard--it tells the user and vendor each must do in order that when
> > the two come together, programs will work.
> >
>
> after reading their documentation, i came to the conclusion that coding
> "case mode portable" code portably would entail either a greater
> dependance on the reader than i would have wanted, or would require that
> one implement alternative symbol management routines which were
> sensitive to the non-conformant case modes when they were present. for
> the moment, i responded to the original party who was having problems,
> that some things would require a conformant lisp.
>
> i was just wondering if there's more behind this.

Yes, the "more" is that if you use a vendor product that does not follow
the standard, then all bets are off as to what is compatible with what.
That's why we have standards.

I can't personally feel any great sympathy for anyone who takes the bait
and uses the vendor-specific option that says "I will make your life
difficult if you use any vendor other than me" and then you find later
that your life is difficult.

This is just not a difficult problem.
SUGGESTION: JUST DON'T USE NON-PORTABLE STUFF.

There is simply no good programming need for non-portable naming.
It is a contrived problem. If you use naming that doesn't interlock
correctly with other programs, you may find that things don't interlock with
other programs. Is this a surprise?

> > Note that if this is not about Franz Allegro, it's news to me, and you
> > should say more. I don't know of another vendor that has elected this
> > kind of deviation.
>
> ...

Was that "..." an answer?

Duane Rettig

unread,
Apr 25, 2002, 5:00:01 PM4/25/02
to
james anderson <james.a...@setf.de> writes:

> i have, quite coincidentally, recently received a note from a lisp user
> who was confounded in his effort to use an application by problems with
> symbol name case. it was most amusing that, in keeping with the
> respective lisp vendor's documents on the subject, the enquiry was
> phrased in term of what one should do to make the application code
> 'portable'." i had always presumed that "portable" would be confined to
> runtime behaviour which itself conforms to "the standard".

I am not sure what document you mean, nor what usage of the word "portable"
you are using. There is an Ansi CL definition of portable, which in
essence means "conforming", but there is also a more generic Computer
Science definition of the word portable, and an even more generic
dictionary definition of the term. My own World Book dictionary defines
it as "capable of being carried or moved; easily carried".

I beleive that Franz's documentation tries to distinguish either by
phrasology or by context whether we are talking about portability in
the ANSI CL sense, or in the more generic sense. Where we talk about
case portability, for example, we do not generate a link to the CL
definition of portability. And we try to be specific about what kind
of portability we are describing. For example, in

http://www.franz.com/support/documentation/6.0/doc/case.htm#portability-1

we say "If portability of your code between the various case modes is
important, here are some things you should do"...

But also, we talk of portability for compatibility packages, like the
older defforeign interface working with the newer def-foreign-call
interface, or portability between Windows and Unix despite the different
line-ending techniques they use.

None of the usages of the term are necesssarily mutually exclusive, and
one can write a case-portable program which is also portable in the ANSI
sense that it conforms to ANSI specs.

Duane Rettig

unread,
Apr 25, 2002, 5:00:01 PM4/25/02
to
Kent M Pitman <pit...@world.std.com> writes:

> There has been a lot of frenzy about the fact that Franz offers two

> implementations: [...]

> If you program in their non-ANSI
> version (or _anyone's_), your code will not be portable;

While I agreed with most of what you said, this statement is definitely
not true. It is absolutely possible to write ANSI conforming programs
in case-sensitive style which also happens to be case-portable (i.e.
it works in both implementations). In such a case (pun intended :-)
the program can be written to be both portable in the ANSI sense, and
also portable in the case-sensitivity sense.

Of course, I am not arguing that it is impossible to write a case-sensitive
program that is not ANSI compliant (e.g. with usage of the same words which
vary only in case), but such a program is by definition not case-portable
(i.e. it won't work in both case-sensitive-lower lisps and ANSI lisps).
The documents we write about such case-portability are designed to show
a programmer how to write in a style that will work in both implementations.

> Note that if this is not about Franz Allegro, it's news to me, and you
> should say more. I don't know of another vendor that has elected this
> kind of deviation.

I also made the assumption that the previous poster was talking about
us.

Duane Rettig

unread,
Apr 25, 2002, 6:00:06 PM4/25/02
to
Kent M Pitman <pit...@world.std.com> writes:

> james anderson <james.a...@setf.de> writes:
>
> > where the vendor's documentation addresses the problem, it describes
> > several idioms for simple symbol manipulation which can serve to ensure
> > that portable code (in the ansi sense) is also "portable" in the case
> > mode sense. with little effort made to distinguish "case mode portable"
> > from portable. which led to my question, as to whether there is always a
> > "case mode portable" formulation for any given operation which is also
> > portable in the ansi sense.
>
> I have no idea. You don't say which vendor.

I agree with this. Although we both assume that it is Franz.

> You are working outside of the spec.

You can't be sure of this. Mr. Anderson might not even be able to be sure
of this, because he is posting on behalf of another, who should be contacting
the vendor for support.

> As far as I'm concerned, you're on your own.

This is not true. Mr. Anderson (or his "original party") should contact
the vendor for which they are having any problems.

Erik Naggum

unread,
Apr 25, 2002, 7:32:47 PM4/25/02
to
* james anderson

| i have, quite coincidentally, recently received a note from a lisp user
| who was confounded in his effort to use an application by problems with
| symbol name case. it was most amusing that, in keeping with the
| respective lisp vendor's documents on the subject, the enquiry was
| phrased in term of what one should do to make the application code
| 'portable'." i had always presumed that "portable" would be confined to
| runtime behaviour which itself conforms to "the standard".

Well, I for one intensely dislike the hijacking of "portably" to mean
"compatible with both the standard and our violation of the standard".

If anyone wants a deviation from the standard, it should be made very,
very explicit. I am working on a defsyntax form that takes care of many
aspects of the reader and printer, and among them symbol case. You
identify the source file with an in-syntax form and choose a syntax
dynamically with with-syntax, all by name. These forms clearly require a
previous in-package, too, so as to make a file without either still use
standard syntax, and to be self-identifying for deviating syntaxes.

My goal has been to ensure that all conforming code would work the same,
but I am stuck with macros that define symbols. Suppose you have the
form (defstruct EvilName ...). As long as you use monocase symbol names,
this works just fine when the macro definition captures the syntax in
which it was defined, but you would have to get MAKE-EvilName if you used
the string "MAKE-", although you would get make-good-name as expected,
With the aid of hindsight from CLOS, macros that generate symbol names
are bad karma. That programmers do not use them without understanding
how they work is virtually the only hope. I remain somewhat uncertain
whether this pathological case is worth solving, but there is a snag here
in that it matters whether you do early or late symbol-name extraction
when you use that string to form other symbols. (This is why Franz Inc
suggests that late symbol-name extraction is preferable. I am not sure I
agree, but it would be a much better proposal with interned-string-style
keywords as the name of symbols, even though that would not help against
mixing conventions.)

Generally, I think the need to support conventions like FooBarZot should
be supported with automatic conversion to and from foo-bar-zot. I find
the FooBarZot conventions so horribly disgusting that it has been a very
serious detractor from solving the case-sensitive lower-case Common Lisp
problem. I have even made Emacs help me not see that crap in Java.

| in order for this to work, intern, defpackage, and read/print should all
| have readily predictable effects as to the internal and external
| representations of objects which they manipulate. i would have been less
| likely to use that method if it were not trivially possible to predict
| the internal symbol name case in a conforming lisp.

The solution to the whole problem is to make the readtable hold a slot
for intern, find-symbol, and symbol-name so the readtable determines
whether (symbol-name 'car) returns "CAR" or "car". Switch to another
readtable and you get what you expect. Good Common Lisp style mandates
that you do not make dependencies on user-settable reader and printer
control variables. (Franz Inc unfortunately does a shoddy job in this
area, and this, I believe, is because the case-sensitive lower-case
"solution" is there for them to point users at, which is another reason
why this form of deviation is so very harmful and causes much unfair
distrust in the standard.)

| aside from my general curiosity about the possible advantages of
| permitting the programmer to predict the effects of thirty-six possible
| combinations of symbol case, readtable case, and print case, i am
| concerned whether everything which can be expressed in any given mode
| can also be expressed "portably".

Unless "portably" here is the hijacked Franz meaning, the solution is
quite simple, wrap your printing and reading in with-standard-io-syntax.

| has there been any discussion on that question?

As far as I can tell, the Franz Inc stance on lower-case symbol names is
highly irrational and is based in personal animosity towards people, not
any longer in anything actually technical -- if it were, they would have
researched this and done something far better than they have -- and far
less destructive. I mean, when they wanted to support CORBA, they did it
amazingly well. When they wanted to support Java, they did it amazingly
well. When they wanted to support Unicode, they did it amazingly well.
Botching something so central is clearly not from incompetence, which in
my eyes makes it much more than a nuisance.

That said, I also think the internal symbol-names in Common Lisp should
have been lower-case, the case of the symbol when interned should have
been stored, and possibly even that matches that differ in case should
produce a warning if the user so desired. But that was not the way it
went, and if we want to change anything, it is vital that the decision
that was made is respected and honored, or any new decision will not be,
either. In order to make a transition actually work, we must be just as
careful as when Internet mail went from 7-bit to 8-bit characters. MIME
is the result of a clearly erroneous decision _not_ to support 8-bit in
Internet mail dating back to the 7-bit-only characters on the computers
that were on the ARPAnet in 1973. MIME is horribly ugly because of this
ancient 7-bit restriction, but we can now send 8-bit text with ESMTP,
which itself depends on MIME for the appropriate character set, but all
the same, we still allow only 7-bit characters in the headers, leading to
one of the most god-awful syntactic inventions since Perl. This is the
kind of thing that happens when an old decision is crippling the future.
However, this should have been invisible to users of reasonable-quality
mail software. When it does not, when people are actually shown this
crap instead of the information it represents, they object vociferously.
Back in the early days, there were a lot of people who argued that we
should "just send eight bits", causing massive grief around the world
even though it sort of worked most of the time -- but only within a group
of people who used the same 8-bit character set. Venture outside that
group, and you lose big time with the "just send eight bits"-line. In
order to make sure that people of different value systems or concrete
values can work together, more elaborate systems need to be set up than
those that work for a single person or homogeneous group. Respect for
this more complicated system and the procedures necessary to arrive at
them is at odds with the desire to "do it my way" and be satisfied with
"it works for me". Actually achieving an improved standard or a workable
change as a first step that satisfies all sides is very hard work.

Erik Naggum

unread,
Apr 25, 2002, 7:58:48 PM4/25/02
to
* Kent M Pitman

| This is just not a difficult problem.
| SUGGESTION: JUST DON'T USE NON-PORTABLE STUFF.

This is the wrong response to the situation. It is often necessary to
use non-portable stuff to get the job done. It is not even sufficient to
say "non-standard", because many interesting things are not standardized.
To make this as precise as possible, I think the most _accurate_ term
should be "anti-standard" or "counter-standard". If the standard
mandates something, do it that way. If no standard mandates something,
do it any way you want.

| There is simply no good programming need for non-portable naming. It is
| a contrived problem.

I actually disagree on this. The problem is very real: When you set up a
case sensitive reader, and that _is_ an option in the standard, the only
way to type lower-case symbol names and get the standard symbols is to
use :invert, which only inverts monocase symbol names. This means that
(symbol-name <whatever>) may be exactly what you want, or the inverted
version of what you want if it happened to be monocase. The only option
is to use some other function than symbol-name to retrieve the name of
the symbol, and then you need some other function than intern to make a
new symbol, which effectively inverts it before calling the regular
intern. This is an annyoing waste. As a user-code programmer, the only
solution is to make your own abstraction for symbols, which leads to
messy interaction with other systems. As a systems-code programmer, you
should instead provide the necessary features and facilities to choose a
lower-case _view_ of the standard symbols and their names. This is what
I have been working with. In any case, the _actual_ internal symbol name
is immaterial as long as cl:intern and ecl:symbol-name both work with
upper-case symbol names for the common-lisp-package. What it _actually_
is underneath should not concern anyone: that is _not_ what the standard
mandates.

Erik Naggum

unread,
Apr 25, 2002, 8:40:44 PM4/25/02
to
* Duane Rettig

| The documents we write about such case-portability are designed to show
| a programmer how to write in a style that will work in both implementations.

But standard, conforming code no longer works when you use the standard
symbol-names in strings that are used to name symbols. Code that does a
fraction of what the reader does, but which upcases the string in order
to conform to the standard, will fail miserably. Protocols that specify
uppercase names and use that directly to map to symbols will not work if
the symbols are used in the program. This is wrong. This is bad. This
has nothing to do with how you represent or deal with the symbol-names of
symbols internal to the program. It has everything to do with how you
treat _external_ input. Not being able to implement your _own_ reader
because the implementation uses stealth case switching is fantastically
hostile and exposes a decision that should be tacit and invisible to full
view and discussion, like we have here periodically.

Put slightly differently, you force every programmer to be _aware_ of the
case issue when they should instead just _know_ what to do and expect.
This is not unlike how you train soldiers to march. If you always start
on one foot, you never have a problem -- they just get it right whether
they are confused about left or right or not, but if you have an option
to start on either foot, you have to communicate "left" or "right" at
some point, and lots of people confuse them, so you get an inevitable
mess out of just _creating_ the option, even if you think you solve
something by offering a choice because you believe that the particular
choice is no good. The whole key is to _accept_ that an arbitrary
decision has to be made, make it, and move on with it as a declared
constant, not keep it a variable as if you could undo the decision.

Now, I sympathize with the problems that do occur when you want to use
the symbol-name for something else, but a readtable-case of :invert and
an additional inverter in, say, the FFI code, _does_ take care of it.

However, I believe that programmers should also have a choice, but a
_visible_ one that they cannot escape noticing. A source or object file
does not know which Allegro CL image is used to load it amd it should not
have to know, either, but if the source file _actually_ and _explicitly_
requests a particular readtable, it knows. This is the same argument
that the SGML community had with respect to the SGML declaration. I
helped make it possible to use named declarations instead of omitting it,
which everybody did, because the whole declaration had to be inline.

To this end, Allegro CL's support for named readtables is _very_ nice.
Concomitant support for the in-syntax macro that Kent Pitman once offered
would have been most welcome.

Kent M Pitman

unread,
Apr 26, 2002, 5:34:56 AM4/26/02
to
Duane Rettig <du...@franz.com> writes:

> > You are working outside of the spec.
>
> You can't be sure of this. Mr. Anderson might not even be able to
> be sure of this, because he is posting on behalf of another, who
> should be contacting the vendor for support.

I didn't mean to be suggesting otherwise. Although not explicit, I guess
I meant in fact that this was his main and best option.

> > As far as I'm concerned, you're on your own.
>
> This is not true. Mr. Anderson (or his "original party") should contact
> the vendor for which they are having any problems.

My remark wasn't intended to be in conflict with yours, though I guess I
was vague on this.

I just mean _I_ wasn't going to volunteer on this. (And probably that
I wasn't alone.) But that's not to say no one would volunteer, especially
since indeed some vendors have support.

james anderson

unread,
Apr 26, 2002, 9:27:20 AM4/26/02
to

the responses have convinced me that matters of symbol name case are not
trivial and that i should presume as little as possible about internal
symbol representation.

the problematic program generates marshalling functions and macros from
document type definitions and schema. these functions include numerous
pairs, one a macro and one a generic function, which produce an encoded
markup stream. they differ primarily in that the macro version makes
more decions at compile time about what and how to encode things. i had
been generating the respective symbols in the same package, inverting
the case of one or the other of them in accord with readtable case. i
believe that method is portable. despite that, it is not as robust as it
could be.

it would be better to allow one to specify destination packages and
cases for the respective symbols when the marshalling functions are
generated from the definitions. the default settings would be carried
over from readtable case, but it would be possible to accommodate other approaches.

...

Erik Naggum

unread,
Apr 26, 2002, 8:22:20 PM4/26/02
to
* james anderson <james.a...@setf.de>

| the responses have convinced me that matters of symbol name case are not
| trivial and that i should presume as little as possible about internal
| symbol representation.

Well, while this is a valid conclusion, I think you should just know that
unless you work _very_ hard to make it otherwise, the standard mandates
upper-case internal symbol names, and you should _never_ expect to find a
symbol in all lower-case in the package named "COMMON-LISP".

We have no mechanism that could support symbol forwarding in Common Lisp,
although it could have been a good thing to have, such that you could
rename symbols upon import to a new package. Such a feature could have
been used to make lower-case "clones" of symbols. (One _could_ hack the
package hashtables to fake this effort.)

| the problematic program generates marshalling functions and macros from
| document type definitions and schema. these functions include numerous
| pairs, one a macro and one a generic function, which produce an encoded
| markup stream. they differ primarily in that the macro version makes
| more decions at compile time about what and how to encode things. i had
| been generating the respective symbols in the same package, inverting the
| case of one or the other of them in accord with readtable case. i
| believe that method is portable. despite that, it is not as robust as it
| could be.

Well, it is. The readtable case is not where you want to look at this.

| it would be better to allow one to specify destination packages and cases
| for the respective symbols when the marshalling functions are generated
| from the definitions. the default settings would be carried over from
| readtable case, but it would be possible to accommodate other approaches.

"Destination packages"? Hm. This weird expression _may_ indicate a lack
of understanding of the package system. I hope you are aware that the
way to control the package into which the reader will intern symbols when
they have no package qualification is controlled by the value of the
special variable *package*. If you are not using the reader to read
Common Lisp code with symbols that (may) live in the common-lisp package,
you may use any case you want for your own symbols and adjust the
readtable-case so it fits your needs. There is nothing in Common Lisp
that requires your own symbols to be in upper-case, it is just massively
convenient when also working with symbols in the common-lisp package.

james anderson

unread,
Apr 27, 2002, 8:29:52 AM4/27/02
to

Erik Naggum wrote:
>
> * james anderson <james.a...@setf.de>
> | the responses have convinced me that matters of symbol name case are not
> | trivial and that i should presume as little as possible about internal
> | symbol representation.
>
> Well, while this is a valid conclusion, I think you should just know that
> unless you work _very_ hard to make it otherwise, the standard mandates
> upper-case internal symbol names, and you should _never_ expect to find a
> symbol in all lower-case in the package named "COMMON-LISP".

i am not concerned directly with symbols in the "COMMON-LISP" package.
i am concerned that, when a program generation utility creates symbols
in other packages, it do so in a way which accommodates a similar
expectation with respect to symbols in user packages, but does not fail
if the expectation is not met.

>
> We have no mechanism that could support symbol forwarding in Common Lisp,
> although it could have been a good thing to have, such that you could
> rename symbols upon import to a new package. Such a feature could have
> been used to make lower-case "clones" of symbols. (One _could_ hack the
> package hashtables to fake this effort.)
>
> | the problematic program generates marshalling functions and macros from
> | document type definitions and schema. these functions include numerous
> | pairs, one a macro and one a generic function, which produce an encoded
> | markup stream. they differ primarily in that the macro version makes
> | more decions at compile time about what and how to encode things. i had
> | been generating the respective symbols in the same package, inverting the
> | case of one or the other of them in accord with readtable case. i
> | believe that method is portable. despite that, it is not as robust as it
> | could be.
>
> Well, it is.

was "it" intended to mean "portable", "as robust as it could be", or
"not as robust as it could be"?

> The readtable case is not where you want to look at this.

why not? (please see below.)

>
> | it would be better to allow one to specify destination packages and cases
> | for the respective symbols when the marshalling functions are generated
> | from the definitions. the default settings would be carried over from
> | readtable case, but it would be possible to accommodate other approaches.
>
> "Destination packages"? Hm. This weird expression _may_ indicate a lack
> of understanding of the package system.

the program in question has until now taken things like this

<!ELEMENT html (head, body) >
<!ATTLIST html
xmlns CDATA #FIXED 'http://www.w3.org/1999/xhtml'
id ID #IMPLIED
dir (ltr|rtl) #IMPLIED
xml:lang NMTOKEN #IMPLIED
lang NMTOKEN #IMPLIED >

and generated code which included things roughly like this

(DEFPACKAGE "http://www.w3.org/1999/xhtml" (:use) (:nicknames "xhtml"))

(DEFMACRO |http://www.w3.org/1999/xhtml|:|html|
((&KEY (XMLNS "http://www.w3.org/1999/xhtml") ID DIR |xml|::LANG LANG)
&REST BODY)
(LIST* 'XML
(CONS '{xhtml}html
(REMOVE NIL
(LIST (WHEN XMLNS (LIST '{xmlns}|| XMLNS))
(WHEN ID (LIST '{}id ID))
(WHEN DIR (LIST '{}dir DIR))
(WHEN |xml|::LANG (LIST '{xml}lang |xml|::LANG))
(WHEN LANG (LIST '{}lang LANG)))))
BODY))

(DEFGENERIC |http://www.w3.org/1999/xhtml|::HTML
(DATUM &KEY XMLNS ID DIR |xml|::LANG LANG)
(:METHOD ((GENERATOR FUNCTION) &KEY (XMLNS *XHTML-NAMESPACE-NAME*) ID
DIR |xml|::LANG LANG)
(|xhtml|:|html| (:XMLNS XMLNS :ID ID :DIR DIR :|xml|::LANG
|xml|::LANG :LANG LANG)
(FUNCALL GENERATOR)))
(:METHOD ((DATUM T) &REST ARGS) (DECLARE (DYNAMIC-EXTENT ARGS))
(APPLY #'|http://www.w3.org/1999/xhtml|::HTML #'(LAMBDA NIL
(ENCODE-NODE DATUM)) ARGS)))

where XML is a macro which performs primitive element encoding.

the symbols for function, macro, and parameter bindings were generated
from document names as follows

first, select a so-called "destination" package:
if the name specified a namespace, use a package with the same name;
if an attribute name specified no namespace, then use the package bound
to *package*;
if an element name specified no namespace, then use the name of the
default namespace or, if no default namespace had been specified, then
use the package bound to *package*.

second, select a case for the symbol name:
an attribute name is transformed or preserved in manner consistent with
readtable case
a function name is also transformed or preserved in a manner consistent
with readtable case
a macro name is transformed so as to be the opposite case of the
function name.

transform the name case as specified and intern the result in the
destination package.

(that this fails where the document definition includes mixed case name
is another problem.)


> I hope you are aware that the
> way to control the package into which the reader will intern symbols when
> they have no package qualification is controlled by the value of the
> special variable *package*.

i did not want to use the reader. i suppose, since the names are
produced by parsing a document definition and should be fairly safe,
that concern may be unwarranted.

If you are not using the reader to read
> Common Lisp code with symbols that (may) live in the common-lisp package,
> you may use any case you want for your own symbols and adjust the
> readtable-case so it fits your needs. There is nothing in Common Lisp
> that requires your own symbols to be in upper-case, it is just massively
> convenient when also working with symbols in the common-lisp package.
>

there is nothing in common lisp, but it would be good if the symbol
names followed the expection which you mentioned above. i am trying it
out now with independant options for destination packages for macro and
function names and for the respective case transformation. the latter
options use the readtable case as a default, but may be specified either
as one of the readtable case keywords or as a function. at the moment, i
upcase the names, since that's my readtable case setting, and intern the
macro and function names in distinct packages, for example "_xhtml" and "xhtml".

? why would it be ill advised to use readtable case as the default?

...

Erik Naggum

unread,
Apr 27, 2002, 2:21:44 PM4/27/02
to
* james anderson <james.a...@setf.de>

| i am not concerned directly with symbols in the "COMMON-LISP" package. i
| am concerned that, when a program generation utility creates symbols in
| other packages, it do so in a way which accommodates a similar
| expectation with respect to symbols in user packages, but does not fail
| if the expectation is not met.

I need to sort out a few things to make sure I understand what you are
talking about. (1) The expectations you want met are not simply that
symbols in the common-lisp package are all upper-case and that the reader
and printer may produce other cases. If it were, I would conclude that
you would have no problem at all since you control the reader and
printer. But you give contradicting information to this position, i.e.,
you continue to have problems. (2) If the expectation is not met, the
only way that could happen as I see your situation is precisely if the
symbols in the common-lisp package were not all upper-case. You appear
to claim that this is not the problem. (3) I sense a confusion in how
you believe the reader and printer control variables affect the reading
and printing of symbols. This sense is strongly reinforced by the fact
that you neglect to tell us what your settings are.

| and generated code which included things roughly like this

Is this output from something? The reason I ask is that it appears more
than unlikely that either of {xmlns}||, {}id, {}dir, {xml}lang, or {}lang
would survive a printer that would both need to write |html| and also be
happy with :use and :nicknames.

| second, select a case for the symbol name:
| an attribute name is transformed or preserved in manner consistent with
| readtable case

Why? The readtable-case is completely irrelevant to you. It concerns
the mapping from input string to symbol name, but if this is SGML, you
already know that the names are case-insensitive and you can canonicalize
any way _you_ want, or if this is XML, you already know that the names
are case-sensitive, so you should perform no transformations at all.

| a function name is also transformed or preserved in a manner consistent
| with readtable case
| a macro name is transformed so as to be the opposite case of the
| function name.

This part is _really_ weird. The macro appears to be a completely
useless massive complication of the whole node creation process. Would
you call it on its own? Why a macro in the first place? Why make a new
macro for each element when one can do for all? The whole point of the
macro seems to be to convert an argument property list to an association
list where all properties with a nil (= #IMPLIED?) value are removed
while converting from a keyword to some weird internal symbol. This
appears to me to be an excellent case for data-driven programming, not
code-driven.

| (that this fails where the document definition includes mixed case name
| is another problem.)

Well, it is a pretty strong indicator that you screwed up the design.

| i did not want to use the reader. i suppose, since the names are
| produced by parsing a document definition and should be fairly safe,
| that concern may be unwarranted.

If this is so, where does the reader come in at all?

0 new messages