Mutation
Antonio Leitao
aml@gia.ist.utl.pt
15 May 1997 16:40:11 +0100
>>>>> "Scott" =3D=3D Scott L Burson <gyro@zeta-soft.com> writes:
From> hbaker@netcom.com (Henry G. Baker)
Date> Wed, 14 May 1997 07:11:29 -0700 (PDT)
Baker> One of the most important kinds of functional arrays are functio=
nal
Baker> character strings. In particular, character strings used as 'pn=
ames'
Baker> ('print-names'). One of the biggest performance problems with C=
L is
Baker> that some 'interrogation functions' -- i.e., 'symbol-name' (I th=
ink
Baker> that that is the name of the function!) -- are forced to _always=
_ copy
Baker> the string, because they can't guarantee that the requestor won'=
t
Baker> mutate it. With an immutable character string, however, symbol-=
name
Baker> can simply and efficiently return the actual character string, s=
afe in
Baker> the knowledge that it can't be hacked.
Scott> I kinda thought `symbol-name' would have to copy the string as you =
suggest,
Scott> but one day just a few weeks ago I typed the following at Allegro/U=
nix:
Scott> (eq (symbol-name 'foo) (symbol-name 'foo))
Scott> and got back T. "Odd", sez I, "what happens if I modify the string=
?" Well,
Scott> to make a long story short, it eventually became clear that Allegro=
has some
Scott> way of detecting modifications of strings that have been returned f=
rom
Scott> `symbol-name', and what it does when it detects one is to make a ne=
w copy of
Scott> the symbol's name. Thus:
>> (setq *str* (symbol-name 'foo))
Scott> "FOO"
>> (setf (char *str* 0) #\G)
Scott> #\G
>> *str*
Scott> "GOO"
>> (symbol-name 'foo)
Scott> "FOO"
>> (eq * *str*)
Scott> NIL
Scott> I'm not arguing against the introduction of immutable things, but I=
thought
Scott> this was a cute hack.
Scott> -- Scott
But a dangerouse one, also.
First, according to CLTL2, "it is an error to modify a string being
used as the print name of a symbol". As a matter of fact, even CLTL
says that "it is an extremely bad idea to modify a string being used
as the print name of a symbol".
If this is true, we aren't allowed to modify the result of
symbol-name. Period. If you violate the rule, the consequences are up
to you. I don't understand why symbol-name is forced to _always_ copy
the string. It should never copy because it doesn't need to do that.
Finally, your example is dangerouse because it can misleade you to
think that symbol-name provides some hidden trick that allows you to
change the string while avoiding performance penalties. But
look at a slightly modified example:
USER(46): (setf *str1* (symbol-name 'foo))
"FOO"
USER(47): (setf *str2* (symbol-name 'foo))
"FOO"
USER(48): (eq *str2* (symbol-name 'foo))
T
USER(49): (setf (char *str1* 0) #\G)
#\G
USER(50): (eq *str2* (symbol-name 'foo))
NIL
USER(51): (symbol-name 'foo)
"FOO"
USER(52): *str2*
"GOO"
Ant=F3nio Leit=E3o.