[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Arg count checking



Larry's message had an idea that coud be developed to handle both what I
take to be the motivations of arg count checking and the motivations for
optional arguments and more.

1. I remember that programming in Stanford Lisp 1.6, the mismatched
number of argument was one of the most effective checks for getting out
nuissance bugs quickly, especially the kind that comes where you change
the arguments of the callee and miss some occurrences of calls to it.

2. The main offsetting advantage from giving this up in Interlisp-D
seems to be that for functions with complicated arguments that are
infrequently used.  A simple calling sequnce is available for simple
calls, more complicated calls for complicated situations.  But there
would seem to be be more graceful (from the point of view of the program
reflecting the user's intentions) methods of achieving this.

3. It is certainly eaiser for the programmer to call

	(NSPRINT 'MYPRINTER)

than to have to write

	(NSPRINT 'MYPRINTER NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL).  

Thus optional arguments are handy.  But they are not really handy enough
because

	(NSPRINT 'MYPRINTER NIL NIL NIL NIL NIL NIL NIL NIL T)

is still required to request stapling on the printed output.  This call
is not programmable without reference to the manual or a system aid such
as ?=.  It is a likely location for error (miscouting the arguments) and
it is not readable by someone looking over the code.

If (1) arguments could be addressed by argument name and (2) could be
optional, then such problems would disappear.  A notation that would
stay within the Interlisp tradition, would be to pattern it after
DLAMBDA declarations in DECL.  Thus OPTIONAL would become a property of
arguments in the same way as FIXP.

DEFINEQ
((NSPRINT
	(LAMBDA     (PRINTER
				(FILE.NAME OPTIONAL)
				(DOCUMENT.NAME OPTIONAL)
				(DOCUMENT.CREATION.DATE OPTIONAL)
				(RECIPIENT.NAME OPTIONAL)
				(#COPIES OPTIONAL)
				(MEDIUM OPTIONAL)
				(PRIORITY OPTIONAL)
				(STAPLE? OPTIONAL)
				(TWO.SIDED OPTIONAL)))))

implements a function where the first argument PRINTER is mandatory and
the remaining are all optional.

The function could be called with the syntax

	(NSPRINT 'MYPRINTER STAPLE?=T)

or perhaps a prefix syntax syntax such as

	(NSPRINT 'MYPRINTER (& STAPLE? T))

or

	(NSPRINT 'MYPRINTER / STAPLE? T) .

ANY argument ought to be callable this way.  (A more elegant proposal
might even be able to encompass the current syntax of (FOR X IN L
SUCHTHAT ...) as an instance, thus serving as a unifying abstraction for
Interlisp syntax).  Of course, the OPTIONAL property would be made to
fit into DECL as just one more property:

	(DLAMBDA ((A LISTP SPECIAL )
			     (B FIXP LOCAL OPTIONAL))  . . . ).

Arguments described by name and optional arguments would probably be a
slight bit slower than fixed arguments, but (1) this would be well worth
the convenience and readability is most cases (e.g. NSPRINT).  (2) The
fixed argument called by place would still be about as the same speed as
they were, probably, and (3) Fast versions of complicated argument calls
where small gains in speed were very important would be programmed in
fast versions, as at present  (FRPLACA).

Thus both bug detection and optional argument calling flexibility can be
had within a unified framework that generalizes both.  It would seem
that one can car one's cake and cons it too.