560 lines
44 KiB
HTML
560 lines
44 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 FUNCTION-NAME 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/iss173_w.htm">
|
||
|
<LINK REL=UP HREF="../Issues/iss174.htm">
|
||
|
<LINK REL=NEXT HREF="../Issues/iss176_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/iss173_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Previous]" SRC="../Graphics/Prev.gif" ALIGN=Bottom></A><A REL=UP HREF="../Issues/iss174.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Up]" SRC="../Graphics/Up.gif" ALIGN=Bottom></A><A REL=NEXT HREF="../Issues/iss176_w.htm"><IMG WIDTH=40 HEIGHT=40 ALT="[Next]" SRC="../Graphics/Next.gif" ALIGN=Bottom></A></H1>
|
||
|
|
||
|
<HR>
|
||
|
|
||
|
|
||
|
|
||
|
<H2>Issue FUNCTION-NAME Writeup</H2>
|
||
|
|
||
|
<PRE><B>Status:</B> Proposal LARGE, with sections 7, 8, 9 removed, passed Mar 89 X3J13<P>
|
||
|
<P>
|
||
|
<B>Issue:</B> <A HREF="iss174.htm">FUNCTION-NAME</A><P>
|
||
|
<P>
|
||
|
<B>References:</B> <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> rules for what -place- can be (pp.94-7)<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_fbound.htm#fboundp"><B>FBOUNDP</B></A> function (p.90)<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_fmakun.htm#fmakunbound"><B>FMAKUNBOUND</B></A> function (p.92)<P>
|
||
|
<A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> special form (p.87)<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A> and <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> of <A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>symbol-function</B></A> (p.90)<P>
|
||
|
88-002R pages 1-21, 2-21, 2-26, 2-39, 2-44, 2-46, 2-51, and 2-55<P>
|
||
|
(There are additional references for <A REL=DEFINITION HREF="../Body/s_the.htm#the"><B>the</B></A> MEDIUM <A REL=DEFINITION HREF="../Body/a_and.htm#and"><B>and</B></A> LARGE<P>
|
||
|
proposals, but they are <A REL=DEFINITION HREF="../Body/a_not.htm#not"><B>not</B></A> listed here. They're obvious.)<P>
|
||
|
<P>
|
||
|
Related issues: SETF-FUNCTION-VS-MACRO, SETF-PLACES (both subsumed by this)<P>
|
||
|
<P>
|
||
|
<B>Category:</B> ADDITION<P>
|
||
|
<P>
|
||
|
<B>Edit history:</B> Version 1, 23-Jan-89, by Moon <P>
|
||
|
(based on discussion at Jan X3J13 meeting)<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
<B>Problem description:<P>
|
||
|
</B><P>
|
||
|
The Common Lisp Object System needs a well-defined way to relate the name<P>
|
||
|
and arguments of a writer function to those of a reader function, because<P>
|
||
|
both functions can be generic and can have user-defined methods. The way<P>
|
||
|
that was adopted into Common Lisp when X3J13 voted to accept document<P>
|
||
|
88-002R was to use a list (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> reader) as the name of the writer function.<P>
|
||
|
<P>
|
||
|
Some changes to the non-object-oriented portion of Common Lisp are required<P>
|
||
|
in order to support this.<P>
|
||
|
<P>
|
||
|
This issue has three proposals.<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
<B>Proposal (FUNCTION-NAME:SMALL):<P>
|
||
|
</B> <P>
|
||
|
Add a new concept "function-name" (called "function-specifier" in<P>
|
||
|
88-002R). A <A HREF="iss174.htm">function-name</A> is either a symbol or a 2-element list whose<P>
|
||
|
first element is the symbol <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> and whose second element is a symbol.<P>
|
||
|
Implementations are free to extend the syntax of function-names to<P>
|
||
|
include lists beginning with additional symbols other than <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A>.<P>
|
||
|
<P>
|
||
|
Add a new function (<A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> <A HREF="iss174.htm">function-name</A>), which returns the<P>
|
||
|
current global function definition named by <A HREF="iss174.htm">function-name</A>, or signals<P>
|
||
|
an error if there is no global function definition. This follows all<P>
|
||
|
the same rules listed for <A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A> in CLtL p.90.<P>
|
||
|
<P>
|
||
|
Add <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> of <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> to change the current global function definition<P>
|
||
|
named by a <A HREF="iss174.htm">function-name</A>. This follows all the same rules listed for<P>
|
||
|
<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> of <A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A> in CLtL p.90.<P>
|
||
|
<P>
|
||
|
Change the <A REL=DEFINITION HREF="../Body/f_fbound.htm#fboundp"><B>FBOUNDP</B></A> and <A REL=DEFINITION HREF="../Body/f_fmakun.htm#fmakunbound"><B>FMAKUNBOUND</B></A> functions, and the <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> special<P>
|
||
|
form, to accept function-names in place of symbols. Implementation<P>
|
||
|
defined extensions to the syntax of function-names cannot use the<P>
|
||
|
symbol <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A>, since <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> already uses that symbol.<P>
|
||
|
<P>
|
||
|
Change the rules for <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> places (CLtL pp.94-7) by adding the following<P>
|
||
|
clause after all the existing clauses:<P>
|
||
|
<P>
|
||
|
- Any other list whose first element is a symbol, call it reader.<P>
|
||
|
In this case, <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> expands into a call to the function named by the<P>
|
||
|
list (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> reader). The first argument is the new value and the<P>
|
||
|
remaining arguments are the values of the remaining elements of<P>
|
||
|
-place-. This expansion occurs regardless of whether reader or<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> reader) is defined as a function locally, globally, or not at<P>
|
||
|
all. For example,<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> (reader arg1 arg2...) new-value)<P>
|
||
|
expands into a form with the same effect and value as<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>LET</B></A> ((#:temp-1 arg1) ;force correct order of evaluation<P>
|
||
|
(#:temp-2 arg2)<P>
|
||
|
...<P>
|
||
|
(#:temp-0 new-value))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> (<A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> reader)) #:temp-0 #:temp-1 #:temp-2...)).<P>
|
||
|
<P>
|
||
|
Change the functions GET-SETF-METHOD and GET-SETF-METHOD-MULTIPLE-VALUE<P>
|
||
|
to implement the above change to the rules.<P>
|
||
|
<P>
|
||
|
Document that a function named (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> reader) should return its first<P>
|
||
|
argument as its only value, in order to preserve the semantics of <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A>.<P>
|
||
|
<P>
|
||
|
Change the macro <A REL=DEFINITION HREF="../Body/m_defgen.htm#defgeneric"><B>DEFGENERIC</B></A> and the function <A REL=DEFINITION HREF="../Body/f_ensure.htm#ensure-generic-function"><B>ENSURE-GENERIC-FUNCTION</B></A> to<P>
|
||
|
refer to the function <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> where they now refer to the function<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_symb_1.htm#symbol-function"><B>SYMBOL-FUNCTION</B></A>.<P>
|
||
|
<P>
|
||
|
Change the macros <A REL=DEFINITION HREF="../Body/m_defcla.htm#defclass"><B>DEFCLASS</B></A>, <A REL=DEFINITION HREF="../Body/m_defgen.htm#defgeneric"><B>DEFGENERIC</B></A>, and <A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>DEFMETHOD</B></A>, the special forms<P>
|
||
|
GENERIC-FLET and GENERIC-LABELS, and the functions <A REL=DEFINITION HREF="../Body/f_docume.htm#documentation"><B>DOCUMENTATION</B></A> and<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_ensure.htm#ensure-generic-function"><B>ENSURE-GENERIC-FUNCTION</B></A> to use the term "function-name" where they now<P>
|
||
|
use the term "function-specifier" or "function specifier".<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
<B>Rationale for FUNCTION-NAME:SMALL:<P>
|
||
|
</B><P>
|
||
|
This is the minimum change to Common Lisp needed to do what 88-002R says<P>
|
||
|
about (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> reader). Giving implementations freedom to extend the syntax<P>
|
||
|
of function-names allows for current practice. Changing the name from<P>
|
||
|
"function-specifier" to "function-name" avoids confusion and improves<P>
|
||
|
consistency with the rest of the language, at the cost of a few small<P>
|
||
|
changes to 88-002R.<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
<B>Proposal (FUNCTION-NAME:MEDIUM):<P>
|
||
|
</B><P>
|
||
|
Everything in FUNCTION-NAME:SMALL, and in addition:<P>
|
||
|
<P>
|
||
|
Change the <A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> macro to accept a <A HREF="iss174.htm">function-name</A> for its name argument,<P>
|
||
|
instead of only accepting a symbol. If <A HREF="iss174.htm">function-name</A> is (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> sym),<P>
|
||
|
the body is surrounded by an implicit block named sym.<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
<B>Rationale for FUNCTION-NAME:MEDIUM:<P>
|
||
|
</B><P>
|
||
|
Keeping <A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> consistent with <A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>DEFMETHOD</B></A> is a good idea. Also 88-002R<P>
|
||
|
says "The name of a generic function, like the name of an ordinary<P>
|
||
|
function, can be either a symbol or a two-element list whose...", which<P>
|
||
|
implies this change to <A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A>.<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
<B>Proposal (FUNCTION-NAME:LARGE):<P>
|
||
|
</B><P>
|
||
|
Everything in FUNCTION-NAME:MEDIUM, and in addition the following<P>
|
||
|
numbered points, each of which could be adopted independently,<P>
|
||
|
except where explicitly noted:<P>
|
||
|
<P>
|
||
|
1. Change the function <A REL=DEFINITION HREF="../Body/f_cmp.htm#compile"><B>COMPILE</B></A> to accept a <A HREF="iss174.htm">function-name</A> as its name<P>
|
||
|
argument.<P>
|
||
|
<P>
|
||
|
2. Change the function <A REL=DEFINITION HREF="../Body/f_disass.htm#disassemble"><B>DISASSEMBLE</B></A> to accept a <A HREF="iss174.htm">function-name</A> as its name<P>
|
||
|
argument.<P>
|
||
|
<P>
|
||
|
3. Change the <A REL=DEFINITION HREF="../Body/d_ftype.htm#ftype"><B>FTYPE</B></A>, <A REL=DEFINITION HREF="../Body/d_inline.htm#inline"><B>INLINE</B></A>, and <A REL=DEFINITION HREF="../Body/d_inline.htm#notinline"><B>NOTINLINE</B></A> declarations and proclamations<P>
|
||
|
to accept function-names, not just symbols, as function names.<P>
|
||
|
<P>
|
||
|
4. Change the <A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A> and <A REL=DEFINITION HREF="../Body/s_flet_.htm#labels"><B>LABELS</B></A> special forms to accept a <A HREF="iss174.htm">function-name</A> in<P>
|
||
|
the name position, not just a symbol.<P>
|
||
|
<P>
|
||
|
5. Change the <A REL=DEFINITION HREF="../Body/m_tracec.htm#trace"><B>TRACE</B></A> and <A REL=DEFINITION HREF="../Body/m_tracec.htm#untrace"><B>UNTRACE</B></A> macros to accept function-names, not just<P>
|
||
|
symbols, in the function name positions.<P>
|
||
|
<P>
|
||
|
6. Change the <A REL=DEFINITION HREF="../Body/f_ed.htm#ed"><B>ED</B></A> function to accept (<A REL=DEFINITION HREF="../Body/f_ed.htm#ed"><B>ED</B></A> <A HREF="iss174.htm">function-name</A>) in place of<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_ed.htm#ed"><B>ED</B></A> symbol).<P>
|
||
|
<P>
|
||
|
7. Change the syntax of a function call to allow a <A HREF="iss174.htm">function-name</A> as the<P>
|
||
|
first element of the list, rather than allowing only a symbol.<P>
|
||
|
<P>
|
||
|
8. Change the <A REL=DEFINITION HREF="../Body/m_defmac.htm#defmacro"><B>DEFMACRO</B></A> macro and the <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A> special form to accept a<P>
|
||
|
<A HREF="iss174.htm">function-name</A> in the name position, not just a symbol. Change the<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_macro_.htm#macro-function"><B>MACRO-FUNCTION</B></A> function to accept function-names, not just symbols.<P>
|
||
|
Change the last rule for <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> places to use<P>
|
||
|
((<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> reader) #:temp-0 #:temp-1 #:temp-2...)<P>
|
||
|
in place of<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> (<A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> reader)) #:temp-0 #:temp-1 #:temp-2...)<P>
|
||
|
so that (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> reader) can be defined as a macro. This depends on item<P>
|
||
|
7. If item 4 is rejected, <A REL=DEFINITION HREF="../Body/s_flet_.htm#macrolet"><B>MACROLET</B></A> should be stricken from this item.<P>
|
||
|
<P>
|
||
|
9. Add an optional environment argument to <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A>, <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> of<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A>, <A REL=DEFINITION HREF="../Body/f_fbound.htm#fboundp"><B>FBOUNDP</B></A>, and <A REL=DEFINITION HREF="../Body/f_fmakun.htm#fmakunbound"><B>FMAKUNBOUND</B></A>. This is the same as the<P>
|
||
|
&environment argument to a macroexpander. This argument can be used to<P>
|
||
|
access local function definitions, to access function definitions in the<P>
|
||
|
compile-time remote environment, and to modify function definitions in<P>
|
||
|
the compile-time remote environment.<P>
|
||
|
<P>
|
||
|
10. Change the second, third, fourth, fifth, seventh, and ninth rules for<P>
|
||
|
<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> places so that they only apply when the <A HREF="iss174.htm">function-name</A> refers to the<P>
|
||
|
global function definition, rather than a locally defined function or<P>
|
||
|
macro. (The ninth rule is the one that refers to <A REL=DEFINITION HREF="../Body/m_defset.htm#defsetf"><B>DEFSETF</B></A> and<P>
|
||
|
DEFINE-SETF-METHOD; the other rules listed are the ones that list<P>
|
||
|
specific built-in functions). The effect of this change is that <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A><P>
|
||
|
methods defined for global functions are ignored when there is a local<P>
|
||
|
function binding; instead, the function named (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> reader), which may<P>
|
||
|
have a local function binding, is called. This change is most useful<P>
|
||
|
in connection with item 4, but does not actually depend on it.<P>
|
||
|
<P>
|
||
|
11. Clarify that the eighth rule for <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> places (the one for macros)<P>
|
||
|
uses <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand-1"><B>MACROEXPAND-1</B></A>, not <A REL=DEFINITION HREF="../Body/f_mexp_.htm#macroexpand"><B>MACROEXPAND</B></A>.<P>
|
||
|
<P>
|
||
|
<B>Rationale for FUNCTION-NAME:LARGE:<P>
|
||
|
</B><P>
|
||
|
This extends the new feature throughout the language, in order to make<P>
|
||
|
things generally more consistent and powerful. Point by point:<P>
|
||
|
<P>
|
||
|
1,2,3 - one should be able to compile, examine, and make declarations<P>
|
||
|
about functions regardless of whether they are named with symbols or<P>
|
||
|
with lists.<P>
|
||
|
<P>
|
||
|
4 - locally defined non-generic <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> functions are a logical companion<P>
|
||
|
to locally defined generic <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> functions, which can be defined with<P>
|
||
|
GENERIC-FLET or GENERIC-LABELS. They make sense on their own, since one<P>
|
||
|
might define a local reader function and want a local writer function<P>
|
||
|
to go with it.<P>
|
||
|
<P>
|
||
|
5,6 - one should be able to apply development tools to functions<P>
|
||
|
regardless of how they are named. The function <A REL=DEFINITION HREF="../Body/f_docume.htm#documentation"><B>DOCUMENTATION</B></A> was already<P>
|
||
|
updated to work for function-names by 88-002R. There might be some<P>
|
||
|
difficulty with implementation-dependent syntax extensions to <A REL=DEFINITION HREF="../Body/m_tracec.htm#trace"><B>TRACE</B></A> and<P>
|
||
|
<A REL=DEFINITION HREF="../Body/m_tracec.htm#untrace"><B>UNTRACE</B></A> conflicting with this new syntax.<P>
|
||
|
<P>
|
||
|
7 - this restores consistency between the <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> special form and the<P>
|
||
|
first element of a function call form.<P>
|
||
|
<P>
|
||
|
8 - it seems more consistent to allow macros to be named the same way<P>
|
||
|
that ordinary functions are named. However, this might be considered<P>
|
||
|
redundant with <A REL=DEFINITION HREF="../Body/m_defset.htm#defsetf"><B>DEFSETF</B></A>.<P>
|
||
|
<P>
|
||
|
9 - this is not needed by the "chapter 1 and 2" level of CLOS, but might<P>
|
||
|
be used by the metaobject based implementation of <A REL=DEFINITION HREF="../Body/f_ensure.htm#ensure-generic-function"><B>ENSURE-GENERIC-FUNCTION</B></A>.<P>
|
||
|
<P>
|
||
|
10 - this change was in SETF-FUNCTION-VS-MACRO and makes item 4 more useful.<P>
|
||
|
<P>
|
||
|
11 - this change was in SETF-FUNCTION-VS-MACRO and is a good idea, but<P>
|
||
|
actually is independent of everything else being proposed here.<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
<B>Examples:<P>
|
||
|
</B><P>
|
||
|
;This is an example of the sort of syntax 88-002R allows<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>defmethod</B></A> (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> child) (new-value (parent some-class))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_slt_va.htm#slot-value"><B>slot-value</B></A> 'child parent) new-value)<P>
|
||
|
(update-dependencies parent)<P>
|
||
|
new-value)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (child foo) bar)<P>
|
||
|
<P>
|
||
|
;If <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> of <A REL=DEFINITION HREF="../Body/f_subseq.htm#subseq"><B>SUBSEQ</B></A> was not already built into Common Lisp,<P>
|
||
|
;it could have been defined like this, if the MEDIUM or LARGE<P>
|
||
|
;proposal is adopted.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> <A REL=DEFINITION HREF="../Body/f_subseq.htm#subseq"><B>subseq</B></A>) (new-value <A REL=DEFINITION HREF="../Body/t_seq.htm#sequence"><B>sequence</B></A> start <A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&optional</B></A> end)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_when_.htm#unless"><B>unless</B></A> end (<A REL=DEFINITION HREF="../Body/s_setq.htm#setq"><B>setq</B></A> end (<A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>length</B></A> <A REL=DEFINITION HREF="../Body/t_seq.htm#sequence"><B>sequence</B></A>)))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_setq.htm#setq"><B>setq</B></A> end (<A REL=DEFINITION HREF="../Body/f_max_m.htm#min"><B>min</B></A> end (+ start (<A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>length</B></A> new-value))))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_do_do.htm#do"><B>do</B></A> ((i start (<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A> i))<P>
|
||
|
(j 0 (<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A> j)))<P>
|
||
|
((= i end) new-value)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_elt.htm#elt"><B>elt</B></A> <A REL=DEFINITION HREF="../Body/t_seq.htm#sequence"><B>sequence</B></A> i) (<A REL=DEFINITION HREF="../Body/f_elt.htm#elt"><B>elt</B></A> new-value j))))<P>
|
||
|
<P>
|
||
|
;The preceding example would have to be defined like this<P>
|
||
|
;if only the SMALL proposal is adopted. This is a <A REL=DEFINITION HREF="../Body/t_method.htm#method"><B>method</B></A><P>
|
||
|
;all of whose parameter specializer names are T.<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defmet.htm#defmethod"><B>defmethod</B></A> (<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> <A REL=DEFINITION HREF="../Body/f_subseq.htm#subseq"><B>subseq</B></A>) (new-value <A REL=DEFINITION HREF="../Body/t_seq.htm#sequence"><B>sequence</B></A> start <A REL=DEFINITION HREF="../Body/03_da.htm#AMoptional"><B>&optional</B></A> end)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_when_.htm#unless"><B>unless</B></A> end (<A REL=DEFINITION HREF="../Body/s_setq.htm#setq"><B>setq</B></A> end (<A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>length</B></A> <A REL=DEFINITION HREF="../Body/t_seq.htm#sequence"><B>sequence</B></A>)))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_setq.htm#setq"><B>setq</B></A> end (<A REL=DEFINITION HREF="../Body/f_max_m.htm#min"><B>min</B></A> end (+ start (<A REL=DEFINITION HREF="../Body/f_length.htm#length"><B>length</B></A> new-value))))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_do_do.htm#do"><B>do</B></A> ((i start (<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A> i))<P>
|
||
|
(j 0 (<A REL=DEFINITION HREF="../Body/f_1pl_1_.htm#1PL"><B>1+</B></A> j)))<P>
|
||
|
((= i end) new-value)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_elt.htm#elt"><B>elt</B></A> <A REL=DEFINITION HREF="../Body/t_seq.htm#sequence"><B>sequence</B></A> i) (<A REL=DEFINITION HREF="../Body/f_elt.htm#elt"><B>elt</B></A> new-value j))))<P>
|
||
|
<P>
|
||
|
;Another example, showing a locally defined <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> function<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> frobulate (mumble)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>let</B></A> ((table (mumble-table mumble)))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>flet</B></A> ((foo (x)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_gethas.htm#gethash"><B>gethash</B></A> x table))<P>
|
||
|
((<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> foo) (new x)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (<A REL=DEFINITION HREF="../Body/f_gethas.htm#gethash"><B>gethash</B></A> x table) new)))<P>
|
||
|
..<P>
|
||
|
(foo a)<P>
|
||
|
..<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> (foo a) b))))<P>
|
||
|
<P>
|
||
|
;get-setf-method could implement <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> functions by calling<P>
|
||
|
;this function when the earlier rules do not apply<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>defun</B></A> get-setf-method-for-setf-function (form)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/s_let_l.htm#let"><B>let</B></A> ((new-value (<A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>gensym</B></A>))<P>
|
||
|
(temp-vars (<A REL=DEFINITION HREF="../Body/m_do_do.htm#do"><B>do</B></A> ((a (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>cdr</B></A> form) (<A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>cdr</B></A> a))<P>
|
||
|
(v <A REL=DEFINITION HREF="../Body/a_nil.htm#nil"><B>nil</B></A> (<A REL=DEFINITION HREF="../Body/a_cons.htm#cons"><B>cons</B></A> (<A REL=DEFINITION HREF="../Body/f_gensym.htm#gensym"><B>gensym</B></A>) v)))<P>
|
||
|
((<A REL=DEFINITION HREF="../Body/a_null.htm#null"><B>null</B></A> a) v))))<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_values.htm#values"><B>values</B></A> temp-vars<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>cdr</B></A> form)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/a_list.htm#list"><B>list</B></A> new-value)<P>
|
||
|
`(<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>funcall</B></A> #'(<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> ,(<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> form)) ,new-value ,@temp-vars)<P>
|
||
|
`(,(<A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> form) ,@temp-vars))))<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
<B>Current practice:<P>
|
||
|
</B><P>
|
||
|
No implementation supports exactly what is proposed. Symbolics Genera<P>
|
||
|
and the TI Explorer support something close to the MEDIUM proposal, but<P>
|
||
|
differing in a number of details. Symbolics Genera supports items 1, 2,<P>
|
||
|
3, 6, and 11, and modified forms of items 5 and 8, of the LARGE proposal.<P>
|
||
|
Moon considers this proposal's variations from Symbolics current practice<P>
|
||
|
to be an improvement, although incompatible in some cases.<P>
|
||
|
<P>
|
||
|
Many implementations currently support only symbols as function names.<P>
|
||
|
<P>
|
||
|
Symbolics Genera and the TI Explorer have some additional <A HREF="iss174.htm">function-name</A><P>
|
||
|
syntaxes.<P>
|
||
|
<P>
|
||
|
<B>Cost to Implementors:<P>
|
||
|
</B><P>
|
||
|
The SMALL and MEDIUM proposals are estimated to be no more than 50 lines<P>
|
||
|
of code and <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> no changes to the "guts" of the interpreter and<P>
|
||
|
compiler. Most of the code for this can be written portably and was<P>
|
||
|
shown on two slides at the X3J13 meeting.<P>
|
||
|
<P>
|
||
|
Some of the changes in the LARGE proposal are trivial, some <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A><P>
|
||
|
the compiler to use <A REL=DEFINITION HREF="../Body/f_equal.htm#equal"><B>EQUAL</B></A> instead of <A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>EQ</B></A> to compare function names, and<P>
|
||
|
items 4, 7, and 8 might <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> a more substantial implementation<P>
|
||
|
effort. Even that effort is estimated to be negligible compared to<P>
|
||
|
the effort required to implement CLOS.<P>
|
||
|
<P>
|
||
|
<B>Cost to Users:<P>
|
||
|
</B><P>
|
||
|
No cost to users, other than program-understanding programs, since this<P>
|
||
|
is an upward compatible addition.<P>
|
||
|
<P>
|
||
|
As with any language extension, some program-understanding programs may<P>
|
||
|
need to be enhanced. A particular issue here is programs that assume<P>
|
||
|
that all function names are symbols. They may use <A REL=DEFINITION HREF="../Body/f_get.htm#get"><B>GET</B></A> to access<P>
|
||
|
properties of a function name or use <A REL=DEFINITION HREF="../Body/f_eq.htm#eq"><B>EQ</B></A> or <A REL=DEFINITION HREF="../Body/a_eql.htm#eql"><B>EQL</B></A> (perhaps via <A REL=DEFINITION HREF="../Body/a_member.htm#member"><B>MEMBER</B></A> or<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_assocc.htm#assoc"><B>ASSOC</B></A>) to compare function names for equality. Such programs will need<P>
|
||
|
improvement before they can understand programs that use the new feature,<P>
|
||
|
but otherwise they will still work.<P>
|
||
|
<P>
|
||
|
<B>Cost of non-adoption:<P>
|
||
|
</B><P>
|
||
|
We would have to make some other language change since the language<P>
|
||
|
became inconsistent when 88-002R was adopted.<P>
|
||
|
<P>
|
||
|
<B>Performance impact:<P>
|
||
|
</B><P>
|
||
|
This has no effect on performance of compiled code. It might slow<P>
|
||
|
down the compiler and interpreter but not by very much.<P>
|
||
|
<P>
|
||
|
<B>Benefits:<P>
|
||
|
</B><P>
|
||
|
CLOS will work as designed.<P>
|
||
|
<P>
|
||
|
<B>Esthetics:<P>
|
||
|
</B><P>
|
||
|
Some people dislike using anything but symbols to name functions.<P>
|
||
|
Other people would prefer that if the change is to be made at all,<P>
|
||
|
the LARGE proposal be adopted so that the language is uniform in its<P>
|
||
|
treatment of the new extended function names. Other proposals for<P>
|
||
|
how to deal with <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> in CLOS were considerably less esthetic,<P>
|
||
|
especially when package problems are taken into account.<P>
|
||
|
<P>
|
||
|
<A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> would be more esthetic, but less powerful, if it had only the<P>
|
||
|
proposed <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> functions and did not have <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> macros. Such a major<P>
|
||
|
incompatible change is of course out of the question; however, if <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A><P>
|
||
|
functions are stressed over <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A> macros, <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> will be much easier to<P>
|
||
|
teach.<P>
|
||
|
<P>
|
||
|
<B>Discussion:<P>
|
||
|
</B><P>
|
||
|
Moon supports at least FUNCTION-NAME:MEDIUM. He does not necessarily<P>
|
||
|
approve of all parts of <A HREF="iss174.htm">FUNCTION-NAME:LARGE</A>.<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
!<P>
|
||
|
Additional Comments:<P>
|
||
|
<P>
|
||
|
On the whole, I like this presentation much better than either of the<P>
|
||
|
other two writeups that were circulated previously. I suspect that it<P>
|
||
|
might be necessary to vote on each of the items in the LARGE proposal<P>
|
||
|
individually, though. I think I would support items 1, 2, and 11, and<P>
|
||
|
don't have any particular objections to 3, 5, and 6. For item 4, if<P>
|
||
|
consistency with GENERIC-FLET and GENERIC-LABELS is an object, another<P>
|
||
|
alternative is to change those two special forms to be like ordinary<P>
|
||
|
<A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A> and <A REL=DEFINITION HREF="../Body/s_flet_.htm#labels"><B>LABELS</B></A>, instead of vice versa.<P>
|
||
|
<P>
|
||
|
- - - - - - -<P>
|
||
|
I support FUNCTION-NAME:MEDIUM and may support LARGE once I think about<P>
|
||
|
it some more.<P>
|
||
|
<P>
|
||
|
As I explained in Hawaii, support for either of these is based on the<P>
|
||
|
:conc-name bugs being removed from the condition system. Of course, I<P>
|
||
|
believe the best way to do that is to CLOSify it.<P>
|
||
|
- - - - - - - - <P>
|
||
|
I'm still thinking about this, but while I am I wanted point out that<P>
|
||
|
MEDIUM is unacceptable to me because I don't think <A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A> and <A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A> should<P>
|
||
|
disagree on what they permit as defined names. If <A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A> were added to<P>
|
||
|
MEDIUM, I suspect I'd think it was an internally consistent position.<P>
|
||
|
<P>
|
||
|
LARGE has an appeal to me in general, but I'm still mulling over <P>
|
||
|
the specifics.<P>
|
||
|
- - - - - - - - - -<P>
|
||
|
I favor the <A HREF="iss174.htm">FUNCTION-NAME:LARGE</A> proposal, because it defines a single,<P>
|
||
|
useful notion of what a function name is. The other proposals have<P>
|
||
|
the flaw that there are two kinds of function names: symbols, and<P>
|
||
|
extended names, with only some of the Lisp primitives accepting the<P>
|
||
|
latter. This may be convenient for some implementations, for the<P>
|
||
|
short term, but it fragments the language.<P>
|
||
|
<P>
|
||
|
I have two other comments on the proposal.<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
A. Reducing the Cost to Implementors<P>
|
||
|
<P>
|
||
|
One observation you could put in the Cost To Implementors section is<P>
|
||
|
that none of the SMALL, MEDIUM, or LARGE proposals <A REL=DEFINITION HREF="../Body/f_provid.htm#require"><B>require</B></A> changes to<P>
|
||
|
the "guts" of the interpreter and compiler. This is because an<P>
|
||
|
implementation is free to use plain symbols internally to name<P>
|
||
|
functions, and use a hack like JonL's SETF:|3.FOO.BAR| mapping to<P>
|
||
|
convert non-symbol names to symbols. This conversion would be done as a<P>
|
||
|
part of parsing the handful of forms which accept function names, and<P>
|
||
|
then all other passes of the interpreter and compiler (the "guts") would<P>
|
||
|
just see symbols. (By "parsing" I mean ensuring the right number and<P>
|
||
|
type of syntactic subforms. You can see that this is a very early and<P>
|
||
|
simple stage of processing.) Or, Lisp compilers with an "alphatization"<P>
|
||
|
phase could perform function name symbolization at that phase.<P>
|
||
|
<P>
|
||
|
<P>
|
||
|
B. Finishing the Job of Regularization<P>
|
||
|
<P>
|
||
|
I'd like to suggest two additions to your smorgasbord of options in the<P>
|
||
|
<A HREF="iss174.htm">FUNCTION-NAME:LARGE</A> section of the proposal. One addition would<P>
|
||
|
regularize a major special case of functions--lambda expressions. The<P>
|
||
|
other addition would reaffirm an unstated regularity in the language,<P>
|
||
|
that function names can stand in for functions under <A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> and <A REL=DEFINITION HREF="../Body/f_apply.htm#apply"><B>APPLY</B></A>.<P>
|
||
|
Not only can the treatment of symbolic and setf-list function names be<P>
|
||
|
regularized, but <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> too can be treated in a consistent manner.<P>
|
||
|
<P>
|
||
|
If these two points are added to your proposal, the language as a whole<P>
|
||
|
would have a completely uniform treatment of functions and function<P>
|
||
|
names. Here they are:<P>
|
||
|
<P>
|
||
|
13. Declare that any function name is a suitable argument to <A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> and<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_apply.htm#apply"><B>APPLY</B></A>. In such a case, the function name is passed to <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A>,<P>
|
||
|
and the result (which may in turn be a function name) is called.<P>
|
||
|
That is, the following two expressions are equivalent, when fname<P>
|
||
|
is a function name:<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> fname x y)<P>
|
||
|
<==><P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> (<A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> fname) x y)<P>
|
||
|
Note that the definition is sought in the global environment.<P>
|
||
|
Compare with the rule which applies to a function name occurs,<P>
|
||
|
syntactically, as the <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> of a list in code:<P>
|
||
|
(fname x y)<P>
|
||
|
<==><P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> (<A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> fname) x y)<P>
|
||
|
<==> (under proposal item 9)<P>
|
||
|
(<A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> (<A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> fname <local-environment>) x y)<P>
|
||
|
<P>
|
||
|
12. Declare that any lamba expression (i.e., a list whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> is <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> and<P>
|
||
|
whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>cdr</B></A> is a well-formed <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> argument list and body) is a function<P>
|
||
|
name. The effects of the function name accessors on <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> expressions<P>
|
||
|
are as follows. <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> returns an implementation-defined value which<P>
|
||
|
is the function specified the <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> expression, closed in the global<P>
|
||
|
environment. This <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> value cannot be changed by <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A>.<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_fbound.htm#fboundp"><B>FBOUNDP</B></A> always returns T, and <A REL=DEFINITION HREF="../Body/f_makunb.htm#makunbound"><B>MAKUNBOUND</B></A> is an error.<P>
|
||
|
<P>
|
||
|
<B>Esthetics:<P>
|
||
|
</B><P>
|
||
|
The effect of items 11 and 12 is to complete the regularization of<P>
|
||
|
Common Lisp's treatment of functions and function names. The total<P>
|
||
|
effect of proposal items 1 through 12 is that Lisp has just two notions<P>
|
||
|
for referencing function objects: FUNCTIONS, which are Lisp objects that<P>
|
||
|
directly represent executable code, and <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> NAMES, which can denote<P>
|
||
|
functions. Symbols, <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> function names, and <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> expressions are all<P>
|
||
|
examples of the latter notion. The former notion is highly<P>
|
||
|
implementation dependent. Function names can occur as syntactic<P>
|
||
|
entities in code. <A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> and <A REL=DEFINITION HREF="../Body/f_apply.htm#apply"><B>APPLY</B></A> work uniformly on both functions<P>
|
||
|
and function names, with a consistent semantics.<P>
|
||
|
<P>
|
||
|
Lambda expressions are often thought to denote "anonymous" functions, so<P>
|
||
|
it may seem paradoxical to treat them as names. The paradox is only<P>
|
||
|
apparent, since the expression itself has the properties of a Lisp<P>
|
||
|
function name: It is (typically) a cons tree which can be read, printed,<P>
|
||
|
and stored in source files, and it denotes a well-defined Lisp function.<P>
|
||
|
<P>
|
||
|
<B>Benefit to Users:<P>
|
||
|
</B><P>
|
||
|
Function names are useful for representing objects in remote<P>
|
||
|
environments, because they need not be bound at all times to the same<P>
|
||
|
function, or to any function, and because they are typically stable in<P>
|
||
|
meaning across reads and prints, where plain functions are not.<P>
|
||
|
Programs which deal simultaneously with remote and local environments,<P>
|
||
|
such as CLOS, can probably be simplified, since function names<P>
|
||
|
can be used uniformly, rather than an ad-hoc mixture of functions<P>
|
||
|
and function names.<P>
|
||
|
<P>
|
||
|
The language as a whole become more uniform from these additions and<P>
|
||
|
clarifications, making it easier to learn and use. (See Esthetics.)<P>
|
||
|
<P>
|
||
|
<B>Cost to Implementors:<P>
|
||
|
</B><P>
|
||
|
Interpreters which currently have a special case check for application<P>
|
||
|
of <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> expressions would need to modify this check to call<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> when a list of any sort is encountered. Note that all<P>
|
||
|
Common Lisps already must perform some such check, since <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A><P>
|
||
|
expressions can be funcalled (and this is currently a very special case,<P>
|
||
|
the only <A REL=DEFINITION HREF="../Body/07_ffb.htm#standard"><B>standard</B></A> case of a list being funcalled). This means that<P>
|
||
|
every Lisp already has a place to insert the required call to<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A>.<P>
|
||
|
<P>
|
||
|
In some implementations, <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> of a <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> expression could be that<P>
|
||
|
lambda-expression itself. In others featuring a pre-eval codewalk, the<P>
|
||
|
walk would be done by <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A>, which would return an appropriate<P>
|
||
|
closure.<P>
|
||
|
<P>
|
||
|
<B>Cost of Non-adoption:<P>
|
||
|
</B><P>
|
||
|
Rather than two notions for function references (functions and function<P>
|
||
|
names), there would be several notions, each corresponding to the valid<P>
|
||
|
inputs for particular group of primitives. <A REL=DEFINITION HREF="../Body/f_apply.htm#apply"><B>APPLY</B></A> and <A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> would<P>
|
||
|
accept functions, symbolic names, and <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> expressions, but not <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A><P>
|
||
|
function names. <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> and its kind would accept symbols and <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>setf</B></A><P>
|
||
|
function names but not <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> expressions. If the :LARGE proposal is<P>
|
||
|
not adopted, this fragmentation would also apply to the various syntaxes<P>
|
||
|
involving function names; some names would be acceptable to <A REL=DEFINITION HREF="../Body/m_defun.htm#defun"><B>DEFUN</B></A><P>
|
||
|
but not to <A REL=DEFINITION HREF="../Body/s_flet_.htm#flet"><B>FLET</B></A>, etc.<P>
|
||
|
<P>
|
||
|
- - - - - - - - - - - - -<P>
|
||
|
> 13. Declare that any function name is a suitable argument to <A REL=DEFINITION HREF="../Body/f_funcal.htm#funcall"><B>FUNCALL</B></A> and<P>
|
||
|
> <A REL=DEFINITION HREF="../Body/f_apply.htm#apply"><B>APPLY</B></A>. In such a case, the function name is passed to <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A>,<P>
|
||
|
> and the result (which may in turn be a function name) is called.<P>
|
||
|
<P>
|
||
|
I don't think this is such a good idea. The case of automatically coercing<P>
|
||
|
a symbol to a function is needed because it provides a portable mechanism<P>
|
||
|
for indirect addressing of a function; I haven't seen a reason to need this<P>
|
||
|
for non-symbol function specs. But more important is that coercing a<P>
|
||
|
symbol to a function is a trivial operation that is reasonable to do at<P>
|
||
|
run time on each call without adding a significant amount of overhead.<P>
|
||
|
<A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A>, on the other hand, is a much more expensive operation -- at<P>
|
||
|
best it might use <A REL=DEFINITION HREF="../Body/f_get.htm#get"><B>GET</B></A> to do a property list lookup, or it could be using<P>
|
||
|
string-append and <A REL=DEFINITION HREF="../Body/f_intern.htm#intern"><B>INTERN</B></A> to convert the name to a symbol. In either case,<P>
|
||
|
I think this is more work than you want to do on each call.<P>
|
||
|
<P>
|
||
|
> 12. Declare that any lamba expression (i.e., a list whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#car"><B>car</B></A> is <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> and<P>
|
||
|
> whose <A REL=DEFINITION HREF="../Body/f_car_c.htm#cdr"><B>cdr</B></A> is a well-formed <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> argument list and body) is a function<P>
|
||
|
> name. The effects of the function name accessors on <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> expressions<P>
|
||
|
> are as follows. <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> returns an implementation-defined value which<P>
|
||
|
> is the function specified the <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>lambda</B></A> expression, closed in the global<P>
|
||
|
> environment. This <A REL=DEFINITION HREF="../Body/f_fdefin.htm#fdefinition"><B>FDEFINITION</B></A> value cannot be changed by <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A>.<P>
|
||
|
> <A REL=DEFINITION HREF="../Body/f_fbound.htm#fboundp"><B>FBOUNDP</B></A> always returns T, and <A REL=DEFINITION HREF="../Body/f_makunb.htm#makunbound"><B>MAKUNBOUND</B></A> is an error.<P>
|
||
|
<P>
|
||
|
The exceptions for <A REL=DEFINITION HREF="../Body/a_setf.htm#setf"><B>SETF</B></A> and <A REL=DEFINITION HREF="../Body/f_makunb.htm#makunbound"><B>MAKUNBOUND</B></A> show that this is not really as<P>
|
||
|
consistent as you might like. Furthermore, the <A REL=DEFINITION HREF="../Body/a_fn.htm#function"><B>FUNCTION</B></A> special form would<P>
|
||
|
have to treat a <A REL=DEFINITION HREF="../Body/a_lambda.htm#lambda"><B>LAMBDA</B></A> expression as a function, not a function name, in<P>
|
||
|
order for it to be lexically scoped. It seems like this might just cause<P>
|
||
|
confusion rather than consistency.<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>
|