242 lines
18 KiB
HTML
242 lines
18 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 DECLARE-MACROS 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/iss094_w.htm">
|
|
<LINK REL=UP HREF="../Issues/iss095.htm">
|
|
<LINK REL=NEXT HREF="../Issues/iss096_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/iss094_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss095.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss096_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
|
|
|
|
<HR>
|
|
|
|
|
|
|
|
<H2>Issue DECLARE-MACROS Writeup</H2>
|
|
|
|
<PRE><B>Issue:</B> <A HREF="iss095.htm">DECLARE-MACROS</A> <P>
|
|
<B>References:</B> Declaration Syntax (p154)<P>
|
|
<B>Category:</B> CHANGE<P>
|
|
<B>Edit history:</B> 22-Oct-87, Version 1 by Pitman<P>
|
|
9-Nov-87, Version 2 by Masinter<P>
|
|
5-Feb-88, Version 3 by Pitman<P>
|
|
<P>
|
|
<B>Problem Description:<P>
|
|
</B><P>
|
|
It is permissible for a macro call to expand into a declaration and be<P>
|
|
recognized as such. This linguistic feature provides some useful<P>
|
|
flexibility, but has a number of disadvantages:<P>
|
|
<P>
|
|
* Operations on the executable portion of a body of code inside a <P>
|
|
binding form (such as inserting an additional form) is a complicated<P>
|
|
operation. This is because one or more trial macro expansions must be<P>
|
|
done in order to pass over any declarations or documentation string<P>
|
|
and find the beginning of the body.<P>
|
|
<P>
|
|
* In order to find the end of the declarations, <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>MACROEXPAND</B></A> must be<P>
|
|
called until a non-macro form is seen or until a macro does not expand<P>
|
|
into a macro. In some interpreters which do macro expansion on the fly,<P>
|
|
this may cause inefficiency because macro expansion of the first form<P>
|
|
in a body must be done twice. In implementations where this is <P>
|
|
optimized, the implementor may resent the fact that an optimization is<P>
|
|
needed in the first place.<P>
|
|
<P>
|
|
* Various code analysis tools have been shown to have been significantly<P>
|
|
slowed down by the need to expand macros in order to determine whether<P>
|
|
a binding is <A REL=DEFINITION HREF="../Body/d_specia.htm#special"><B>SPECIAL</B></A> when analyzing a variable binding form. This is<P>
|
|
particularly serious when macro invocations are deeply nested; the<P>
|
|
number of macro expansions can be exponential in the depth of nesting<P>
|
|
unless a macro-expansion caching mechanism is added. <P>
|
|
<P>
|
|
* User macros must be very careful about finding declarations in a body<P>
|
|
of code by doing proper macro expansion. Often, however, naive users<P>
|
|
don't realize this and so unknowingly write buggy code. This problem can<P>
|
|
be (and is) defined away as simply a programmer error, but this is a<P>
|
|
place where we could fairly straightforwardly redefine the language to<P>
|
|
better accommodate what has been shown to be a common expectation of the<P>
|
|
naive user.<P>
|
|
<P>
|
|
<B>Proposal (DECLARE-MACROS:FLUSH):<P>
|
|
</B><P>
|
|
Under this proposal, it would not be "permissible for a macro call to<P>
|
|
expand into a declaration and be recognized as such, provided that the<P>
|
|
macro call appears where a declaration may legitimately appear." (CLtL<P>
|
|
p. 154). Macros could not legitimately expand into declarations; the only<P>
|
|
valid declarations would be a list whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> is the symbol <A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A>.<P>
|
|
<P>
|
|
It would still be possible for a macro call to expand into a <A REL=DEFINITION HREF="../Body/f_procla.htm#proclaim"><B>PROCLAIM</B></A><P>
|
|
form, however.<P>
|
|
<P>
|
|
<B>Rationale:<P>
|
|
</B><P>
|
|
The ability to have a macro form expand into a declaration has been shown<P>
|
|
to be useful in some situations. More often, however, the presence of<P>
|
|
this feature has been seen to cause problems elsewhere in the language.<P>
|
|
Ultimately, its benefits have not outweighed its costs.<P>
|
|
<P>
|
|
<B>Current Practice:<P>
|
|
</B><P>
|
|
Most or all implementations support the old behavior even though few<P>
|
|
user programs probably need it.<P>
|
|
<P>
|
|
Some user macros are careful about finding declarations in a body of code<P>
|
|
by doing proper macro expansion, but some probably cheat and look just<P>
|
|
for explicit uses of <A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A>. The cheat probably works most of the time.<P>
|
|
<P>
|
|
<B>Cost to implementors:<P>
|
|
</B><P>
|
|
The nature of this change is such that implementations which did not<P>
|
|
choose to change would simply be supporting an implementation-dependent<P>
|
|
extension (except for some `minor' worry about destructive modification<P>
|
|
due to macro expanding while <A REL=DEFINITION HREF="../Body/v_mexp_h.htm#STmacroexpand-hookST"><B>*MACROEXPAND-HOOK*</B></A> is set to something<P>
|
|
which implemented displacing macros).<P>
|
|
<P>
|
|
In any case, there might be several places in which the interpreter,<P>
|
|
compiler, and system macros had knowledge about doing macro expansion<P>
|
|
before declaration processing. The change is not trivial, but most of<P>
|
|
its complexity is likely to be in finding the places which need change<P>
|
|
and not in making the actual change.<P>
|
|
<P>
|
|
<B>Cost to users:<P>
|
|
</B><P>
|
|
Most users probably do not write macros which expand into <A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> forms<P>
|
|
so most users are probably not affected.<P>
|
|
<P>
|
|
Users who do exploit this feature probably know that they do. In any<P>
|
|
case, compilers could be made to detect cases where this feature is<P>
|
|
being exploited and warn about it.<P>
|
|
<P>
|
|
Franz and Gold Hill are notable exceptions to the claim that users may<P>
|
|
not want this. Both claim to make a reasonable amount of use of macros<P>
|
|
which expand into different <A REL=DEFINITION HREF="../Body/d_optimi.htm#speed"><B>SPEED</B></A> and <A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> declarations, usually<P>
|
|
dependent on a global switch.<P>
|
|
<P>
|
|
Rewrites must be devised on a case-by-case basis. A common sort of<P>
|
|
rewrite would take the form:<P>
|
|
<P>
|
|
Old code: (<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> SPEEDY ()<P>
|
|
`(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#speed"><B>SPEED</B></A> 3) (<A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> 0))))<P>
|
|
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> (..bindings..) (SPEEDY) ..body..)<P>
|
|
<P>
|
|
New code: (<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> SPEEDY-LET (BVL <A REL=DEFINITION HREF="../Body/03_dd.htm#AMbody"><B>&BODY</B></A> FORMS)<P>
|
|
`(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ,BVL<P>
|
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#speed"><B>SPEED</B></A> 3) (<A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> 0)))<P>
|
|
,@FORMS))<P>
|
|
(SPEEDY-LET (..bindings..) ..body..)<P>
|
|
<P>
|
|
Another tactic would be:<P>
|
|
<P>
|
|
Old code: (<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A>)<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_defpar.htm#defvar"><B>DEFVAR</B></A> *SPEEDY* <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>))<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> USE-STANDARD-SPEED-AND-SAFETY ()<P>
|
|
(<A REL=DEFINITION HREF="../Body/s_if.htm#if"><B>IF</B></A> *SPEEDY*<P>
|
|
`(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#speed"><B>SPEED</B></A> 3) (<A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> 0)))<P>
|
|
`(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#speed"><B>SPEED</B></A> 0) (<A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> 3)))))<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> FOO ()<P>
|
|
(USE-STANDARD-SPEED-AND-SAFETY)<P>
|
|
...)<P>
|
|
New code: (<A REL=DEFINITION HREF="../Body/s_eval_w.htm#eval-when"><B>EVAL-WHEN</B></A> (<A REL=DEFINITION HREF="../Body/f_eval.htm#eval"><B>EVAL</B></A> <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> <A REL=DEFINITION HREF="../Body/f_load.htm#load"><B>LOAD</B></A>)<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_defpar.htm#defvar"><B>DEFVAR</B></A> *STANDARD-SPEED-AND-SAFETY* '((<A REL=DEFINITION HREF="../Body/d_optimi.htm#speed"><B>SPEED</B></A> 0) (<A REL=DEFINITION HREF="../Body/d_optimi.htm#safety"><B>SAFETY</B></A> 3))))<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> FOO ()<P>
|
|
(<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A> (<A REL=DEFINITION HREF="../Body/d_optimi.htm#optimize"><B>OPTIMIZE</B></A> #.*STANDARD-SPEED-AND-SAFETY*))<P>
|
|
...)<P>
|
|
<P>
|
|
Still a third tactic would be to actually shadow <A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A>, <A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A>, etc. with<P>
|
|
variants that process macro expansions and then to build code in a<P>
|
|
package that used the revised <A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A>, <A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A>, etc. eg,<P>
|
|
<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> PARSE-BODY (BODY ENV)<P>
|
|
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((DECLS '())<P>
|
|
(DOC '()))<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_do_do.htm#do"><B>DO</B></A> () ((<A REL=DEFINITION HREF="../Body/a_null.htm#null"><B>NULL</B></A> (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>CDR</B></A> BODY)))<P>
|
|
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((<A REL=DEFINITION HREF="../Body/f_exp_e.htm#exp"><B>EXP</B></A> (<A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>MACROEXPAND</B></A> (<A REL=DEFINITION HREF="../Body/m_pop.htm#pop"><B>POP</B></A> BODY) ENV)))<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_cond.htm#cond"><B>COND</B></A> ((<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A> (<A REL=DEFINITION HREF="../Body/f_stgp.htm#stringp"><B>STRINGP</B></A> <A REL=DEFINITION HREF="../Body/f_exp_e.htm#exp"><B>EXP</B></A>) BODY)<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_when_.htm#unless"><B>UNLESS</B></A> (<A REL=DEFINITION HREF="../Body/a_null.htm#null"><B>NULL</B></A> DOC)<P>
|
|
(<A REL=DEFINITION HREF="../Body/f_warn.htm#warn"><B>WARN</B></A> "More than one <A REL=DEFINITION HREF="../Body/f_docume.htm#documentation"><B>documentation</B></A> <A REL=DEFINITION HREF="../Body/a_string.htm#string"><B>string</B></A> was seen."))<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_push.htm#push"><B>PUSH</B></A> <A REL=DEFINITION HREF="../Body/f_exp_e.htm#exp"><B>EXP</B></A> DOC))<P>
|
|
((<A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>AND</B></A> (<A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>NOT</B></A> (<A REL=DEFINITION HREF="../Body/a_atom.htm#atom"><B>ATOM</B></A> <A REL=DEFINITION HREF="../Body/f_exp_e.htm#exp"><B>EXP</B></A>)) (<A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>EQ</B></A> (<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>CAR</B></A> <A REL=DEFINITION HREF="../Body/f_exp_e.htm#exp"><B>EXP</B></A>) '<A REL=DEFINITION HREF="../Body/s_declar.htm#declare"><B>DECLARE</B></A>))<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_push.htm#push"><B>PUSH</B></A> <A REL=DEFINITION HREF="../Body/f_exp_e.htm#exp"><B>EXP</B></A> DECLS))<P>
|
|
(T<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_push.htm#push"><B>PUSH</B></A> <A REL=DEFINITION HREF="../Body/f_exp_e.htm#exp"><B>EXP</B></A> BODY)<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_return.htm#return"><B>RETURN</B></A> <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>NIL</B></A>)))))<P>
|
|
(<A REL=DEFINITION HREF="../Body/a_values.htm#values"><B>VALUES</B></A> BODY (<A REL=DEFINITION HREF="../Body/f_revers.htm#nreverse"><B>NREVERSE</B></A> DECLS) (<A REL=DEFINITION HREF="../Body/f_revers.htm#nreverse"><B>NREVERSE</B></A> DOC))))<P>
|
|
<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> MY:DEFUN (NAME LAMBDA-LIST <A REL=DEFINITION HREF="../Body/03_dd.htm#AMbody"><B>&BODY</B></A> DECLS-DOC-AND-FORMS<P>
|
|
<A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&ENVIRONMENT</B></A> ENV)<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_multip.htm#multiple-value-bind"><B>MULTIPLE-VALUE-BIND</B></A> (FORMS DECLS DOC-STRINGS)<P>
|
|
(PARSE-BODY DECLS-DOC-AND-FORMS ENV)<P>
|
|
`(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> ,NAME ,BVL ,@DECLS ,@DOC-STRINGS ,@FORMS)))<P>
|
|
<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> MY:LET (BINDINGS <A REL=DEFINITION HREF="../Body/03_dd.htm#AMbody"><B>&BODY</B></A> DECLS-DOC-AND-FORMS<P>
|
|
<A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&ENVIRONMENT</B></A> ENV)<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_multip.htm#multiple-value-bind"><B>MULTIPLE-VALUE-BIND</B></A> (FORMS DECLS DOC-STRINGS)<P>
|
|
(PARSE-BODY DECLS-DOC-AND-FORMS ENV)<P>
|
|
`(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ,BINDINGS ,@FORMS)))<P>
|
|
<P>
|
|
...etc.<P>
|
|
<P>
|
|
<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> cannot be done this way, of course, since it is not a macro (or<P>
|
|
even a special form). Support for expanding declarations in a <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A><P>
|
|
would have to be provided either by using implementation-specific support<P>
|
|
(such as Zetalisp's ``<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> macros'') or by a workaround such as a<P>
|
|
macro like:<P>
|
|
<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> (LAMBDA-LIST <A REL=DEFINITION HREF="../Body/03_dd.htm#AMbody"><B>&BODY</B></A> DECLS-DOC-AND-FORMS<P>
|
|
<A REL=DEFINITION HREF="../Body/03_dd.htm#AMenvironment"><B>&ENVIRONMENT</B></A> ENV)<P>
|
|
(<A REL=DEFINITION HREF="../Body/m_multip.htm#multiple-value-bind"><B>MULTIPLE-VALUE-BIND</B></A> (FORMS DECLS DOC-STRINGS)<P>
|
|
(PARSE-BODY DECLS-DOC-AND-FORMS ENV)<P>
|
|
`#'(<A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> ,BINDINGS ,@FORMS)))<P>
|
|
<P>
|
|
Note that unlike the other examples, <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> need not be (and in fact,<P>
|
|
may not be) in the "MY" package in order for this to work since the<P>
|
|
<A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> special form will generally only recognize LISP:LAMBDA.<P>
|
|
<P>
|
|
<B>Benefits:<P>
|
|
</B><P>
|
|
The efficiency of some tools may be improved.<P>
|
|
User macros which must do minor surgery on bodies of code will be<P>
|
|
easier to write.<P>
|
|
<P>
|
|
<B>Aesthetics:<P>
|
|
</B><P>
|
|
This change simplifies the semantics of the language slightly and<P>
|
|
probably tends to better support the assumptions of naive programmers<P>
|
|
writing macros.<P>
|
|
<P>
|
|
In some cases involving complicated extensions to declarations, it<P>
|
|
may be slightly harder to express such extensions in a modular way.<P>
|
|
Experience thus far has shown such cases to be rare, however.<P>
|
|
<P>
|
|
<B>Discussion:<P>
|
|
</B><P>
|
|
Symbolics took an in-house poll of people who take advantage of the<P>
|
|
feature and it was generally agreed that in most cases where this<P>
|
|
feature is used at all, that it would be just as easy to work around<P>
|
|
using the sample rewrite techniques cited above.<P>
|
|
<P>
|
|
Moon `credits' Pitman for (against some opposition) pushing this<P>
|
|
`feature' down everyone's throats in the original CL design process.<P>
|
|
Pitman admits this was an expensive mistake. Moon and Pitman support<P>
|
|
this change as an important simplification to the language.<P>
|
|
<P>
|
|
The cleanup committee unanimously endorsed this proposal.<P>
|
|
<P>
|
|
In discussion at the Nov-87 X3J13 meeting, Franz and Gold Hill<P>
|
|
mentioned that they use this feature a lot and were not entirely<P>
|
|
happy about its going away.<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>
|