(defun quote-all (lst)
(if (not (null lst))
(cons (string (car lst))(quote-all (cdr lst)))))
--
do...@sierratel.com
---
Garbage In, Gospel Out
Dowe> Hello, I am a lisp newbie with a slight problem, the following code works
Dowe> fine except that it smashes case when it converts from symbols to strings
Dowe> (I hope my jargon is correct). How do I keep the case information intact?
Dowe> (defun quote-all (lst)
Dowe> (if (not (null lst))
Dowe> (cons (string (car lst))(quote-all (cdr lst)))))
Your problem is that string, given a symbol, returns it's name which
is normally uppercase. You can change the case using e.g.
....
(write-to-string (car lst) :case :downcase) ...
Incidentally your code can be expressed more succinctly by the
equivalent:
(defun quote-all (lst)
(mapcar #'string lst))
--
class struggle SDI Rule Psix CIA Noriega assassination Clinton $400
million in gold bullion kibo genetic Saddam Hussein FSF explosion
supercomputer ammunition
> Hello, I am a lisp newbie with a slight problem, the following code
> works fine except that it smashes case when it converts from symbols
> to strings (I hope my jargon is correct). How do I keep the case
> information intact?
>
> (defun quote-all (lst)
> (if (not (null lst))
> (cons (string (car lst))(quote-all (cdr lst)))))
If I understand you, you mean this effect:
> (quote-all '(foo bar baz))
("FOO" "BAR" "BAZ")
That's not a bug in your code. Symbols in Lisp are case-insensitive,
look:
> 'foo
FOO
How that came to be and if it's a good idea still is being debated by
people much more experienced than me. Just some things you could
explore, depending on what you want to do:
- If you want to process textual information, use strings, not
symbols. A symbol is much more than just some characters (it can have
a value, a function value and a property list, to begin with).
- If you want to use lowercase symbols, you can quote them like this:
> '|fOo|
|fOo|
> (string '|fOo|)
"fOo"
- If you are feeling adventurous, you can make the lisp reader case
sensitive. Read all about it in the HyperSpec:
http://www.xanalys.com/software_tools/reference/HyperSpec/Body/acc_readtable-case.html
The operative word is "adventurous" here. Avoid clobbering the
standard readtable or be surprised at the amount of breakage that
occurs -- including having to type everything in UPPER CASE. Instead,
use something like:
(let ((*readtable (copy-readtable nil)))
(setf (readtable-case *readtable*) :preserve)
(do-something))
And while you're exploring, take a look at the mapping functions.
Your example function could be written as
(defun quote-all (lst)
(mapcar #'string lst))
Have fun,
Rudi
> ... How do I keep the case information intact?
> (defun quote-all (lst)
> (if (not (null lst))
> (cons (string (car lst))(quote-all (cdr lst)))))
How about
(defun quote-all (lst)
(if lst
(cons (symbol-name (first lst))(quote-all (rest lst)))
nil))
(quote-all '(|Common| |Lisp| |is| |a| |big| |language|))
or
(defun quote-all (lst)
(mapcar #'symbol-name lst))
-wb
> do...@krikkit.localdomain (Dowe Keller) writes:
>
> > Hello, I am a lisp newbie with a slight problem, the following code
> > works fine except that it smashes case when it converts from symbols
> > to strings (I hope my jargon is correct). How do I keep the case
> > information intact?
> >
> > (defun quote-all (lst)
> > (if (not (null lst))
> > (cons (string (car lst))(quote-all (cdr lst)))))
>
> If I understand you, you mean this effect:
>
> > (quote-all '(foo bar baz))
> ("FOO" "BAR" "BAZ")
>
> That's not a bug in your code. Symbols in Lisp are case-insensitive,
> look:
>
> > 'foo
> FOO
Errr... this needs a bit of expansion. Symbols in Common LISP are
case-insensitive. Common LISP is the most prevelent LISP in use these
days, but that doesn't make it the only one. Symbols in InterLISP and
Portable Standard LISP, for example, are case sensitive.
> How that came to be and if it's a good idea still is being debated by
> people much more experienced than me.
Allegedly[1], part of the US DoD requirement was that Common LISP
should be usable with a type of terminal which had no shift key, and
could display only upper case. The DoD was very influential in the
beginnings of the Common LISP project.
Like the separation of function and value cells, it's a feature of
Common LISP we're stuck with now, but which I don't think anyone any
longer seriously defends.
[1] Several people have given me this story independently. I can't at
this moment find a reference for it.
--
si...@jasmine.org.uk (Simon Brooke) http://www.jasmine.org.uk/~simon/
'Victories are not solutions.'
;; John Hume, Northern Irish politician, on Radio Scotland 1/2/95
;; Nobel Peace Prize laureate 1998; few have deserved it so much
Actually, several do. Just look at the last few month's postings on this
newsgroup. Every so often a Schemer tries to make the point that Scheme's
"Lisp-1" approach is better than Common Lisp's "Lisp-2" approach and gets
shouted down. As for myself, I've come to like the fact that I can name a
function parameter "list" without having the system go into a tizzy, even
though I am still somewhat dismayed each time I need to use a "funcall".
But, all-in-all, it's just another choice in language design that can be
easily defended either way.
faa
> Errr... this needs a bit of expansion. Symbols in Common LISP are
> case-insensitive. Common LISP is the most prevelent LISP in use these
> days, but that doesn't make it the only one. Symbols in InterLISP and
> Portable Standard LISP, for example, are case sensitive.
Common Lisp symbols *are* case sensitive:
USER(1): (eq 'foo '|foo|)
NIL
However, the CommonLisp reader may canonicalize the case of an
unescaped symbol before interning it. (And the printer may
canonicalize the case before printing it, as well.)
> Like the separation of function and value cells, it's a feature of
> Common LISP we're stuck with now, but which I don't think anyone any
> longer seriously defends.
There are certainly numerous vehement defenders of this.
> Errr... this needs a bit of expansion. Symbols in Common LISP are
> case-insensitive. Common LISP is the most prevelent LISP in use these
> days, but that doesn't make it the only one. Symbols in InterLISP and
> Portable Standard LISP, for example, are case sensitive.
> [ ... ]
> Like the separation of function and value cells, it's a feature of
> Common LISP we're stuck with now, but which I don't think anyone any
> longer seriously defends.
Assuming I haven't misunderstood, I'll defend:
I think case-sensitivity is one of the worst mis-features of a language.
From a human cognitive standpoint, there is no semantic difference between
House, house, HOUSE ... so to design a language that allows tokens with
different capitalization to have differnet semantics is, imho, insanity.
One of the 327 things I love about CL is that it *is* case-insensitive.
I also like the fact that variable names don't collide with function names.
Given that (foo foo) is (ignoreing special-forms and macros) semantically
clear, the first foo is a function and the second foo is a value, it seems
to me that forbiding a symbol from being used for both is a waste of
legalese.
> [ ... ]
maybe we need a new news group: comp.lang.common-lisp
Wrong.
| - If you are feeling adventurous, you can make the lisp reader case
| sensitive.
Correct, the Lisp reader is doing the case manipulation.
#:Erik
--
If this is not what you expected, please alter your expectations.
Is there a semantic difference between color and colour ? Should
the lisp reader stop the current insane behavior (behaviour) and make
them the same symbol?
If your answer is 'no' then what have you learned about the
responsibility of a language lexer vis-a-vis the semantics of a human
language?
Wrong. Stop confusing the reader with the symbol!
| Like the separation of function and value cells, it's a feature of
| Common LISP we're stuck with now, but which I don't think anyone any
| longer seriously defends.
What!? Are you saying that YOU THINK the existence of function and
value cells in symbols is as stupid as upper-case symbol names? If
so, are you insane, trolling, stupid, or another Scheme bigot?
comp.lang.lisp.other is probably better.
> Rudolf Schlatte <rsch...@ist.tu-graz.ac.at> writes:
>
> > do...@krikkit.localdomain (Dowe Keller) writes:
> >
> > > Hello, I am a lisp newbie with a slight problem, the following code
> > > works fine except that it smashes case when it converts from symbols
> > > to strings (I hope my jargon is correct). How do I keep the case
> > > information intact?
> > >
> > > (defun quote-all (lst)
> > > (if (not (null lst))
> > > (cons (string (car lst))(quote-all (cdr lst)))))
> >
> > If I understand you, you mean this effect:
> >
> > > (quote-all '(foo bar baz))
> > ("FOO" "BAR" "BAZ")
> >
> > That's not a bug in your code. Symbols in Lisp are case-insensitive,
> > look:
> >
> > > 'foo
> > FOO
>
> Errr... this needs a bit of expansion. Symbols in Common LISP are
> case-insensitive. Common LISP is the most prevelent LISP in use these
> days, but that doesn't make it the only one. Symbols in InterLISP and
> Portable Standard LISP, for example, are case sensitive.
Actually, I would quibble with this. Symbols in Common Lisp are, in
fact, case sensitive. It is just that the default reader will upcase
all (non-escaped) symbol names before interning the symbol.
That is why (eq 'foo 'FOO) => T
and (eq '|foo| '|FOO|) => NIL
The symbols must be case sensitive for the latter to return NIL. The
fact that the reader is doing the case conversion for you makes it
appear that lisp is case insensitive when in fact it isn't.
The "problem" that the newbie described was occurring during the reading
in of the symbols, so that means that nothing that could be done in the
function QUOTE-ALL could fix it. That is because information was lost
during the reading process.
Now it turns out that you can set the Lisp reader to behave
differently. If you set the readtable case to :preserve, then you tell
the reader not to do the case conversions. One could do this to the
global readtable by
(setf (readtable-case *readtable*) :preserve)
but I would be reluctant to do this for fear of breaking other code that
doesn't expect this. For example, after doing this, the following would
fail:
(defun quote-all (lst)
(if (not (null lst))
(cons (string (car lst))
(quote-all (cdr lst)))))
because the symbol |defun| isn't defined (among others). You would have
to write all of the built-in lisp functions in uppercase:
(DEFUN quote-all (lst)
(IF (NOT (NULL lst))
(CONS (STRING (CAR lst))
(quote-all (CDR lst)))))
Generally when I want to preserve the case, I create a new readtable and
then bind the global readtable around the forms that need to have the
reading done case sensitively. Usually I end up doing something like:
(defvar *case-sensitive-readtable* (copy-readtable nil))
(setf (readtable-case *case-sensitive-readtable*) :preserve)
and then using it in a form like:
(let ((*readtable* *case-sensitive-readtable*))
(read ...)
(read-from-string ....)
...)
For the example in question, one could do:
(let ((*readtable* *case-sensitive-readtable*))
(quote-all (read-from-string "(foo bar baz))))
=> ("foo" "bar" "baz")
Finally, one can ask why symbols are being used instead of strings in
this particular application at all.
--
Thomas A. Russ, USC/Information Sciences Institute t...@isi.edu
> Finally, one can ask why symbols are being used instead of strings in
> this particular application at all.
it seems to be a lisp tradition to do so. many lisp texts do this,
e.g., peter norvigs PAIP (look at the eliza program).
you make the symbol-name be your string and let the lisp reader
tokenize. you can also hang stuff off the symbol on the value,
function or property-list slots.
the reader case-smash makes sense for symbols used as code, but less
so for symbols used as a kind of ersatz string.
the symbol as string idea doesn't sit well with me either, but perhaps
i am missing something important. if i were doing it, i'd use strings
(or a structure or class containing the string and whatever hangers-on
it needed) and write a string-tokenizer instead of (ab)using the
reader.
can someone with more experience provide some insights?
--
johan kullstam l72t00052
> * Simon Brooke <si...@jasmine.org.uk>
> | Like the separation of function and value cells, it's a feature of
> | Common LISP we're stuck with now, but which I don't think anyone any
> | longer seriously defends.
>
> What!? Are you saying that YOU THINK the existence of function and
> value cells in symbols is as stupid as upper-case symbol names? If
> so, are you insane, trolling, stupid, or another Scheme bigot?
I'm far from being a Scheme bigot; I don't like (and don't often use)
the language. I'm not trolling either. Whether I am insane is a matter
for the psychiatric profession; whether I am stupid is for you to
judge.
I do think that treating functions as different from other data is
'stupid', yes; it leads to all sorts of hacks and kludges and results
in no benefits that I am aware of. It is, in my opinion, historical
baggage left over from implementation details in LISP
1.5. Furthermore, it's clear that many of the most influential people
in the design of Common LISP are now of the same opinion; for example,
Richard Gabriel's 1988 paper in _LISP & Symbolic Computation_ on just
this issue, or some of Scott Fahlman's posts on LISP2 and the design
of Dylan on this very group in February and March of 1995.
However, if you have a different opinion, please feel free to argue
it. What benefit is there, beyond having to invoke baroque syntax to
use a lambda expression, and having to do two operations instead of
one at every step in a structure walker?
--
si...@jasmine.org.uk (Simon Brooke) http://www.jasmine.org.uk/~simon/
"The result is a language that... not even its mother could
love. Like the camel, Common Lisp is a horse designed by
committee. Camels do have their uses."
;; Scott Fahlman, 7 March 1995
> the symbol as string idea doesn't sit well with me either, but perhaps
> i am missing something important. if i were doing it, i'd use strings
> (or a structure or class containing the string and whatever hangers-on
> it needed) and write a string-tokenizer instead of (ab)using the
> reader.
>
> can someone with more experience provide some insights?
You can "INTERN" symbols. Interning symbols means that
you put them in a package. Reading FOO and later
reading FOO will give you the same symbol (an object).
Reading "FOO" and later reading "FOO" will give you
two string objects.
--
Rainer Joswig, BU Partner,
ISION Internet AG, Steinhöft 9, 20459 Hamburg, Germany
Tel: +49 40 3070 2950, Fax: +49 40 3070 2999
Email: mailto:rainer...@ision.net WWW: http://www.ision.net/
> Simon Brooke <si...@jasmine.org.uk> writes:
>
> > Errr... this needs a bit of expansion. Symbols in Common LISP are
> > case-insensitive. Common LISP is the most prevelent LISP in use these
> > days, but that doesn't make it the only one. Symbols in InterLISP and
> > Portable Standard LISP, for example, are case sensitive.
>
> Common Lisp symbols *are* case sensitive:
>
> USER(1): (eq 'foo '|foo|)
> NIL
>
> However, the CommonLisp reader may canonicalize the case of an
> unescaped symbol before interning it. (And the printer may
> canonicalize the case before printing it, as well.)
Well, what also happens is that these symbols are INTERNed
in a package. Depending on what INTERNing does you can have
the same symbol or not. The behaviour of Common Lisp's
interning of symbols can be found in the standard docs.
> I do think that treating functions as different from other data is
> 'stupid', yes; it leads to all sorts of hacks and kludges and results
> in no benefits that I am aware of. It is, in my opinion, historical
Functions are not treated any differently from other data in Common
Lisp. Period. There exist different namespaces in Common Lisp for
different constructs, among them are namespaces for types, classes, go
tags, restarts, ..., and finally for the operator position of compound
forms and another one for symbol-macros and variables.
While there have been long ranging and often violent discussions on
the merits and demerits of separating the last two namespaces, I
have as yet not seen the same amount of effort expended on the
unification of the other namespaces. Why are we not seeing enraged
calls for the unification of say the class namespace with the s-m&v
namespace? Why is no one raging about the ugliness of having to use
(find-class 'my-class-name) to get the class object for my-class-name?
Why doesn't my-class-name evaluate to the class object? What about
restarts?
It seems to me that many instantly recognize the utility of different
namespaces in those cases, and implicitly agree that the trade-off
involved isn't very burdensome. Yet when it comes to operator names
and s-m&v names, suddenly we enter holy teritory, and no amount of
utility can ever weigh up the cardinal sin of separating those
namespaces. I find this rather remarkable, from a meta-viewpoint...
I won't argue in depth why I find the separation both of high utility
and little downside _in the context of CL_, because I find that others
have done this far more eloquently than I could have done. Take a
look at postings and papers by Kent M. Pitman in this newsgroup and
elsewhere[1].
Regs, Pierre.
Footnotes:
[1] Among others the following message-ids should provide food for
thought:
<sfwwwnf...@world.std.com>
<sfwafcp...@world.std.com>
<sfwiupa...@world.std.com>
--
Pierre Mai <pm...@acm.org> PGP and GPG keys at your nearest Keyserver
"One smaller motivation which, in part, stems from altruism is Microsoft-
bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]
are they? what about x\yz or |aBcD| ? unless i am grossly mistaken,
those symbols retain case sensitivity, and i also think that the
conversion to upper case is done in the reader.
> days, but that doesn't make it the only one. Symbols in InterLISP and
> Portable Standard LISP, for example, are case sensitive.
>
>> How that came to be and if it's a good idea still is being debated by
>> people much more experienced than me.
>
> Allegedly[1], part of the US DoD requirement was that Common LISP
> should be usable with a type of terminal which had no shift key, and
> could display only upper case. The DoD was very influential in the
> beginnings of the Common LISP project.
available hardware at the time of development is one reason. another
cause that influences the decision about case sensitivity seems to be
the question whether program text should be talked about or whether it
should only be viewed.
> ...
--
Hartmann Schaffer
> > However, the CommonLisp reader may canonicalize the case of an
> > unescaped symbol before interning it. (And the printer may
> > canonicalize the case before printing it, as well.)
>
> Well, what also happens is that these symbols are INTERNed
> in a package. Depending on what INTERNing does you can have
> the same symbol or not. The behaviour of Common Lisp's
> interning of symbols can be found in the standard docs.
In know Rainer knows better, but he has expressed something
sloppily in a way that may someday confuse someone.
INTERN (and FIND-SYMBOL) operate on SYMBOL-NAMEs, which are
STRINGs. INTERN and FIND-SYMBOL never manipulate the case
of characters in these names. Conceptually, they compare
string names as if by EQUAL and are therefore case sensitive
and case preserving.
The reader does indeed call INTERN, and the reader does do
various things with case, but all that is the business of the
reader, not INTERN.
The reader normally shifts all lower-case characters in a symbol
name to upper case. There is a settable mode in a READTABLE
which can change this to DOWNCASE, PRESERVE, or INVERT. The
standard reader syntax allows any character (e.g. whitespace
and lower-case) to be escaped so that it loses any special
syntactic meaning and is not case shifted. See backslash and
vertical bar.
The printer normally preserves case on output, although if
*PRINT-ESCAPE* or other controls are true, it may add escapes
necessary so that the printed output could be read back
the same. The actual case behavior of the printer is controlled
by a combination of READTABLE-CASE and the *PRINT-CASE* according
to a set of rules that is far to complex to be worth learning,
much less remembering. You can see them in ANS 22.1.3.3.2.
A point often missed by beginners (because it only _very_ rarely
has any effect) is that SYMBOL-NAMEs are not used when Lisp
executes. In particular, comparison of symbols by EQ, EQL,
EQUAL, and EQUALP do not look at the SYMBOL-NAMEs or the
SYMBOL-PACKAGEs of the argument SYMBOLs. SYMBOLs are first-class
objects for which all four equality predicates operate as by EQ.
It is rare CL code that ever calls INTERN or FIND-SYMBOL, and the
only important parts of the implementation that call them are
the reader and printer. SYMBOL-NAMES are not referenced at all
during the execution of random Lisp code, unless that code explicitly
calls INTERN, FIND-SYMBOL, various package functions, or invokes
the reader or printer on SYMBOLs. Informally, all the messy case
manipulations of CL happen at read and print time.
Bill Ackerman told me the following more than 30 years ago:
Lisp would be the perfect computing language if only it didn't
have I/O.
this seems to be largely a question of your background. i
mathematics, e.g., it is quite common to use differences in fonts and
capitalization as significant. some people seem to be more visual
oriented, in which case font, capitalization etc are meaningful
distinctions, while other people seem to be more vebally oriented, in
which case case sensitivity is very difficult to grasp.
> ...
--
Hartmann Schaffer
> > Well, what also happens is that these symbols are INTERNed
> > in a package. Depending on what INTERNing does you can have
> > the same symbol or not. The behaviour of Common Lisp's
> > interning of symbols can be found in the standard docs.
>
> In know Rainer knows better, but he has expressed something
> sloppily in a way that may someday confuse someone.
>
> INTERN (and FIND-SYMBOL) operate on SYMBOL-NAMEs, which are
> STRINGs. INTERN and FIND-SYMBOL never manipulate the case
> of characters in these names. Conceptually, they compare
> string names as if by EQUAL and are therefore case sensitive
> and case preserving.
>
> The reader does indeed call INTERN,
Unless you create non-interned symbols. ;-)
? (eq ':foo ':foo)
T
? (eq '#:foo '#:foo)
NIL
> and the reader does do
> various things with case, but all that is the business of the
> reader, not INTERN.
Yes. Thus was my hint of reading the docs to see what
INTERN is doing.
But if you lean back and look at it more abstractly you
intern some object into a data structure. Later
you may want to retrieve the object based on some
input. You also may want to iterate in some order
over this datastructure. Removing objects may also
be nice.
In this case we have for packages:
- data structure: package
- interning in packages: INTERN
- retrieving from packages: FIND-SYMBOL
- iterating: DO-SYMBOLS, ...
- removing: UNINTERN
- ...
So in some Lisp system it might be possible
to think of an INTERN operation that uses
a different mechanism and/or a different
datastructure. In Symbolics Genera INTERN
also is sensitive for styles in the strings,
for example. So when you are interning
"FOO" and "FOO" you won't get the same symbol,
given that there are different styles in the string. Yes,
this is ancient and only in Symbolics Genera.
Btw., in CL-HTTP you often find these mechanisms.
An example for URLs:
- data structure: EQUAL hashtable
- interning of URLs: URL:INTERN-URL
- retrieving URLs: URL:INTERN-URL :if-does-not-exist :SOFT
- iterating: URL:MAP-URL-TABLE
- removing: URL:UNINTERN-URL
Hey, even more confusion.
And just _how_ does Common Lisp do this? Having two different value
slots for a symbol is not at all what you describe as stupid. If
you are thinking about the need to use the `function' special form
where (presumably) you would have been happier with regular variable
access, that is _so_ not the issue. You can bind a variable to a
function object any day and funcall it. Try, you may be shocked.
If this is the old "I hate funcall" whine, please say so right away
so I can ignore you completely.
| it leads to all sorts of hacks and kludges and results in no
| benefits that I am aware of.
Really? Assuming that we still talk about symbol-function and
symbol-value, the hysterical need for "hygienic" macros in Scheme is
_not_ caused by their conflated namespaces? Come on, now. Why
exaggerate your case when there is at lest one _obvious_ benefit
(and one obvious drawback to the conflating namespaces, namely the
Scheme experiment).
The main human benefits are that you don't have to worry about name
collisions when you define a lexical variable and that you don't
have to look for all sorts of bindings when reading code. The main
compiler benefit is that if you maintain control over what you stuff
into the symbol-function slot, you don't have to test it for a
function object every time you use it.
| It is, in my opinion, historical baggage left over from
| implementation details in LISP 1.5.
And which "implementation details" are you referring to?
| Furthermore, it's clear that many of the most influential people
| in the design of Common LISP are now of the same opinion; for example,
| Richard Gabriel's 1988 paper in _LISP & Symbolic Computation_ on just
| this issue, or some of Scott Fahlman's posts on LISP2 and the design
| of Dylan on this very group in February and March of 1995.
Yeah, _sure_ I'll trust a _Dylan_ designer to have useful comments
about Common Lisp. "I hate this, let's go make our _own_ language"
people are so full of agendas both hidden and overt that you can't
take anything they say about the old language seriously.
| However, if you have a different opinion, please feel free to argue
| it. What benefit is there, beyond having to invoke baroque syntax
| to use a lambda expression, and having to do two operations instead
| of one at every step in a structure walker?
And what the fuck does lambda expressions have to do with symbol and
value cells in symbols?
All of trolling, stupid, and insane, that's my conclusion.
| "The result is a language that... not even its mother could
| love. Like the camel, Common Lisp is a horse designed by
| committee. Camels do have their uses."
| ;; Scott Fahlman, 7 March 1995
If you don't like Common Lisp, Simon, you don't have to suffer it.
There are plenty of other languages out there you can use. Those
who have hated parts of the language have gone elsewhere. Those who
remain actually _like_ the language, even if this is unfathomable to
you. It it also my firm opinion that computer professionals who use
tools they dislike or hate _are_ insane at best. (Worse would be
slavery, criminal incompetence, extremely low self-esteem and other
results of prostitution, or extreme poverty, all of which remove
one's ability to choose rationally among the _generally_ available
options.) One simply does not choose to use something one hates for
whatever reasons. That's why Scott Fahlman went to Dylan, I guess,
but I know that's why I dropped working with SGML, C++, and Perl.
Where I come from case matters. "ls" is a command, "LS" is an error.
I happen not to see any similarity in those two strings (`a' and `A'
are different letters damn-it ;-).
BTW: Even if the language is case insensitive it shouldn't smash case.
BTW version 2: Thanks to everyone for their thoughtful and insightful
answers.
--
do...@sierratel.com
---
This is the theory that Jack built.
This is the flaw that lay in the theory that Jack built.
This is the palpable verbal haze that hid the flaw that lay in...
So complete the list of functions by adding make-symbol. Furrfu.
Now that you bring it up, here's a (style?) question I've been wanting
to ask (still being somewhat only a casual user of CL):
Other than reducing possible confusion while debugging with "macroexpand",
is there any real reason to prefer (gensym "foo") over (make-symbol "foo")
when defining macros that need non-capturing local variables? Both produce
fresh uninterned symbols which can't conflict with (capture) any other symbol.
So in what circumstances is one preferred over the other, or vice-versa?
-Rob
p.s. I think I know why one doesn't use literal uninterned symbols for
such things, e.g.:
(defmacro foo (arg1 arg2 &body body)
(let ((tmp '#:tmp)) ; BUG!
...stuff that uses ,tmp ...))
You only get *one* uninterned symbol when the macro is defined, which
gets used for all possible instances of the macro. So if you had nested
occurrences, in the expansion an inner occurrence of #:tmp could shadow
an outer one. But that can't happen with:
(defmacro foo (arg1 arg2 &body body)
(let ((tmp (make-symbol "tmp")))
...stuff that uses ,tmp ...))
because "make-symbol" gets called for each occurrence.
-----
Rob Warnock, 41L-955 rp...@sgi.com
Applied Networking http://reality.sgi.com/rpw3/
Silicon Graphics, Inc. Phone: 650-933-1673
1600 Amphitheatre Pkwy. PP-ASEL-IA
Mountain View, CA 94043
> Really? Assuming that we still talk about symbol-function and
> symbol-value, the hysterical need for "hygienic" macros in Scheme is
> _not_ caused by their conflated namespaces?
Please explain what you mean with that. Common Lisp has its separate
namespaces, and even there macros commonly use gensym so as not to
accidentally use variables of their callers. How does this differ
from Scheme's hygienic macros?
(Did you mean that Scheme macros are _forced_ to be hygienic?)
Do you see the same issue with the class namespace, the package
namespace, or any of the other n namespaces that CL has?
--tim
| Common Lisp has its separate namespaces, and even there macros
| commonly use gensym so as not to accidentally use variables of their
| callers. How does this differ from Scheme's hygienic macros? (Did
| you mean that Scheme macros are _forced_ to be hygienic?)
Yes, Scheme has a "high-level" macro mechanism in which hygiene is
enforced. This is the only standardized macro mechanism in Scheme.
Schemers have also realized that it is sometimes necessary to break
hygiene intentionally, so there are various proposals to accomplish
that. It's been too long since I kept track of the Scheme world;
maybe one of these proposals is emerging as standard, or maybe not.
Scheme's hygienic macros are really easy to use, and ought to
eliminate a whole host of bugs, at least in the hands of inexperienced
programmers. I see no reason why they cannot be implemented in CL --
not replacing CL macros of course, but as a supplement. Does anybody
know if this has been tried? Of course, if there is some deeper
reasons why this cannot or should not be done, I'd be thrilled to hear
about them.
--
* Harald Hanche-Olsen <URL:http://www.math.ntnu.no/~hanche/>
- "There arises from a bad and unapt formation of words
a wonderful obstruction to the mind." - Francis Bacon
Well, I use make-symbol exclusively and see no reason for gensym or
gentemp at all. I tend to set *print-circle* to t, anyway.
Interesting.
That means that rather than macro-expanding into something that the
system provides, you generate whatever symbol name you want, right?
--
cbbr...@hex.net - <http://www.hex.net/~cbbrowne/>
Rules of the Evil Overlord #157. "Whenever plans are drawn up that
include a time-table, I'll post-date the completion 3 days after it's
actually scheduled to occur and not worry too much if they get
stolen." <http://www.eviloverlord.com/>