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.