1
0
Fork 0
cl-sites/HyperSpec-7-0/HyperSpec/Issues/iss182_w.htm
2024-04-01 10:24:07 +02:00

149 lines
10 KiB
HTML

<!-- Common Lisp HyperSpec (TM), version 7.0 generated by Kent M. Pitman on Mon, 11-Apr-2005 2:31am EDT -->
<HTML>
<HEAD>
<TITLE>CLHS: Issue GENSYM-NAME-STICKINESS Writeup</TITLE>
<LINK HREF="../Data/clhs.css" REL="stylesheet" TYPE="text/css" />
<META HTTP-EQUIV="Author" CONTENT="Kent M. Pitman">
<META HTTP-EQUIV="Organization" CONTENT="LispWorks Ltd.">
<LINK REL=TOP HREF="../Front/index.htm">
<LINK REL=COPYRIGHT HREF="../Front/Help.htm#Legal">
<LINK REL=DISCLAIMER HREF="../Front/Help.htm#Disclaimer">
<LINK REL=PREV HREF="../Issues/iss181_w.htm">
<LINK REL=UP HREF="../Issues/iss182.htm">
<LINK REL=NEXT HREF="../Issues/iss183_w.htm">
</HEAD>
<BODY>
<H1><A REV=MADE HREF="http://www.lispworks.com/"><IMG WIDTH=80 HEIGHT=65 ALT="[LISPWORKS]" SRC="../Graphics/LWSmall.gif" ALIGN=Bottom></A><A REL=TOP HREF="../Front/index.htm"><IMG WIDTH=237 HEIGHT=65 ALT="[Common Lisp HyperSpec (TM)]" SRC="../Graphics/CLHS_Sm.gif" ALIGN=Bottom></A> <A REL=PREV HREF="../Issues/iss181_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss182.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss183_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
<HR>
<H2>Issue GENSYM-NAME-STICKINESS Writeup</H2>
<PRE><B>Issue:</B> <A HREF="iss182.htm">GENSYM-NAME-STICKINESS</A><P>
<B>Forum:</B> Cleanup<P>
<B>References:</B> <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> (p169)<P>
<B>Category:</B> CHANGE<P>
<B>Edit history:</B> 14-Feb-89, Version 1 by Pitman<P>
15-Mar-89, Version 2 by Steele (add GENSYM-COUNTER function)<P>
20-Mar-89, Version 3 by Pitman (make it a variable)<P>
<P>
<B>Problem Description:<P>
</B><P>
Many people avoid use of the argument to <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> because the argument<P>
is `sticky' and such stickiness can lead to confusion. The problem is<P>
that if any application (usually a macro) uses the <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>gensym</B></A> argument at<P>
all, then all applications are forced to. If they do not, they risk<P>
finding that the `helpful' argument supplied in some previous call will<P>
be harmful to them.<P>
<P>
Proposal (<A HREF="iss182.htm">GENSYM-NAME-STICKINESS:LIKE-TEFLON</A>)<P>
<P>
Define that if an optional argument [either a string or a number] is<P>
given to <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A>, it does <A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>NOT</B></A> have a side-effect on <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A>'s internal state.<P>
<P>
Introduce a new variable, <A REL=DEFINITION HREF="../Body/v_gensym.htm#STgensym-counterST"><B>*GENSYM-COUNTER*</B></A>, which holds the state of<P>
the <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>gensym</B></A> counter. That is, the next symbol generated by <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> will<P>
be number n. The initial value of this variable is not defined, but<P>
must always be a non-negative integer. This variable may be either <P>
assigned or bound by users at any time, but always to a non-negative<P>
integer.<P>
<P>
Deprecate the use of a numeric argument to <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A>.<P>
<P>
<B>Rationale:<P>
</B><P>
Conscientious programmers are forced now to write their own <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A><P>
lookalikes because they know the system's <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> has an invasive<P>
effect. This defeats the primary intended function of <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A>, which<P>
is to satisfy the most common idiomatic use of <A REL=DEFINITION HREF="../Body/f_mk_sym.htm#make-symbol"><B>MAKE-SYMBOL</B></A>.<P>
<P>
The stickiness of the <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> prefix was an attempt to be gratuitously<P>
compatible with Maclisp, at the expense of good programming pratice.<P>
<P>
Users who need the old behavior of <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> can trivially implement<P>
that behavior using <A REL=DEFINITION HREF="../Body/f_mk_sym.htm#make-symbol"><B>MAKE-SYMBOL</B></A>.<P>
<P>
Occasionally you want to reset the <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> counter so that, for example,<P>
you can get the compiler to generate the same symbol names again<P>
(good for comparing results to see what really changed).<P>
<P>
<B>Test Case:<P>
</B><P>
;; #1: Test stickiness of name part.<P>
(<A REL=DEFINITION HREF="../Body/f_chareq.htm#char-equal"><B>CHAR-EQUAL</B></A> (<A REL=DEFINITION HREF="../Body/f_char_.htm#char"><B>CHAR</B></A> (<A REL=DEFINITION HREF="../Body/f_symb_2.htm#symbol-name"><B>SYMBOL-NAME</B></A> (<A REL=DEFINITION HREF="../Body/f_firstc.htm#second"><B>SECOND</B></A> (<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>LIST</B></A> (<A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> &quot;A&quot;) (<A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A>)))) 0)<P>
#\G)<P>
=&gt; <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> ;under CLtL<P>
=&gt; T ;under this proposal<P>
<P>
;; #2: Test stickiness of number part.<P>
(= (<A REL=DEFINITION HREF="../Body/f_parse_.htm#parse-integer"><B>PARSE-INTEGER</B></A> (<A REL=DEFINITION HREF="../Body/s_progn.htm#progn"><B>PROGN</B></A> (<A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> 6789) (<A REL=DEFINITION HREF="../Body/a_string.htm#string"><B>STRING</B></A> (<A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> &quot;G&quot;))) :START 1)<P>
6790)<P>
=&gt; T ;under CLtL<P>
=&gt; <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A> ;under this proposal (except when *gensym-counter* happens to align)<P>
<P>
;; #3: Illustrate use of new variable.<P>
(<A REL=DEFINITION HREF="../Body/f_stgeq_.htm#stringEQ"><B>STRING=</B></A> (<A REL=DEFINITION HREF="../Body/f_symb_2.htm#symbol-name"><B>SYMBOL-NAME</B></A> (<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((<A REL=DEFINITION HREF="../Body/v_gensym.htm#STgensym-counterST"><B>*GENSYM-COUNTER*</B></A> 43)) (<A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> &quot;FOO&quot;)))<P>
&quot;FOO43&quot;)<P>
=&gt; T ;under this proposal (not meaningful previously)<P>
<P>
<B>Current Practice:<P>
</B><P>
Symbolics Cloe and Genera are compatible with CLtL, so this would be an<P>
incompatible change.<P>
<P>
<B>Cost to Implementors:<P>
</B><P>
Very small.<P>
<P>
If any implementations currently use a more compact representation for<P>
the internal state of <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> than a variable holding a string and a<P>
separate variable holding an integer, they might be forced to change.<P>
Even then, the change would proabably still be quite small.<P>
<P>
<B>Cost to Users:<P>
</B><P>
Most uses of <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> do not depend on the stickiness of the name, so the<P>
change would be compatible. In some cases, the change would be an<P>
improvement. Even in the worst case where someone depends on stickiness,<P>
it's extremely straightforward to write the couple of lines of code to<P>
produce an application based on <A REL=DEFINITION HREF="../Body/f_mk_sym.htm#make-symbol"><B>MAKE-SYMBOL</B></A> that is at least as flexible<P>
as <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A>, and often moreso.<P>
<P>
<B>Cost of Non-Adoption:<P>
</B><P>
Good programmers would avoid using the argument to <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> (or using <P>
<A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> altogether) in many situations where they ought not have to.<P>
<P>
<B>Benefits:<P>
</B><P>
Gensyms which appear to convey information through their name would not<P>
accidentally pop out and cause confusion in places where they oughtn't.<P>
<P>
Making the <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>gensym</B></A> counter visible as a variable means that people will<P>
be able to bind the <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>gensym</B></A> counter locally when they don't want to affect<P>
the global counter.<P>
<P>
<B>Aesthetics:<P>
</B><P>
Unnecessary global state changes are hard to reason about. This would <P>
be a small simplification.<P>
<P>
<B>Discussion:<P>
</B><P>
Pitman claims to have written a non-sticky <A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>GENSYM</B></A> function for nearly<P>
every one of the dozen or so large systems that he's written or worked<P>
on in the last decade in order to get around the stated problem.<P>
Others have suggested similar experience.<P>
<P>
Pitman and Steele support LIKE-TEFLON.<P>
<P>
</PRE>
<HR>
<A REL=NAVIGATOR HREF="../Front/StartPts.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Starting Points]" SRC="../Graphics/StartPts.gif" ALIGN=Bottom></A><A REL=TOC HREF="../Front/Contents.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Contents]" SRC="../Graphics/Contents.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Master.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Index]" SRC="../Graphics/Index.gif" ALIGN=Bottom></A><A REL=INDEX HREF="../Front/X_Symbol.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Symbols]" SRC="../Graphics/Symbols.gif" ALIGN=Bottom></A><A REL=GLOSSARY HREF="../Body/26_a.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Glossary]" SRC="../Graphics/Glossary.gif" ALIGN=Bottom></A><A HREF="../Front/X3J13Iss.htm"><IMG WIDTH=80 HEIGHT=40 ALT="[Issues]" SRC="../Graphics/Issues.gif" ALIGN=Bottom></A><BR>
<A REL=COPYRIGHT HREF="../Front/Help.htm#Legal"><I>Copyright 1996-2005, LispWorks Ltd. All rights reserved.</I></A><P>
</BODY>
</HTML>