I'm tempted to try to address several issues with FUNCTION declarations at once.
1) I realize now that I do not understand the import of *any* of the argument
type specifiers, and specificly the language about "at least of the types
specified" that appears in CLtL p 47. However, I don't know what
(declare (function my-cons (float string) list) )
means. It says that my-cons is a function that can "accept a floating-point
number and a string (among other things), and its result is an object of type
list...."
The problem is that the argument type declaration here is of absolutely no use.
That the declared function can accept a float and a string among other things
has no content. It doesn't say that it is illegal to pass a non-float as the
first argument. It says that if you pass a float, its ok, and if you pass a
non-float, it might be OK too. Isn't that the same as saying (function my-cons
(t t) list)?
It would be more valuable as far as I can see to say that a (function (float
string) list) is one to which *only* a float and a string can be passed. Perhaps
someone familiar with an implementation that pays attention to these
declarations can explain what they are used to denote?
2) On the specific issue at hand: I'm inclined to be more sympathetic to
allowing &REST <element-type>; function type specifiers are, after all, already
a specialized little language -- the &KEY arguments have a separate syntax which
only vaguely resembles the original lambda list syntax, for example.
3) Should the function type specifier also allow &ALLOW-OTHER-KEYS?
Here is some (old) mail from the Common Lisp mailing list which touches on some
related issues:
!
Date: 18 Apr 1986 16:07-EST
Subject: Type Specifier: (OR (FUNCTION ...) ...)
From: NGALL@G.BBN.COM
Question: What is the 'most informative' type specifier for the CL function
COPY-SEQ?
How 'bout? (function (sequence) sequence)
Unfortunately, this does not tell the reader nor the compiler that if the
argument is a list, then the result is also a list, and vice versa. So how
about this:
(or (function (list) list)
(function (vector) vector))
This is syntactically valid CL, and the definition of the OR and FUNCTION type
specifiers makes it meaningful. Unfortunately, it is not clear from pg. 158
whether or not the following is legal:
(proclaim '(ftype (or (function (list) list)
(function (vector) vector))
copy-seq))
It is not legal in VaxLisp, and my guess is that there aren't any
implementations that would do the right thing with it. So I would like to
propose that such a use of OR/FUNCTION be considered legal CL.
Without such a declaration, one is forced to either wrap (the <result-type> ...)
around all calls to such functions or to DECLARE a restricted version of
FUNCTION in the appropriate places, e.g., (defun foo (alist avector)
(declare (list alist)
(vector avector)
(function copy-seq (list) list))
(zap (copy-seq alist)
(let ()
(declare (function copy-seq (vector) vector))
(zoop (copy-seq avector))))
Either method is a real pain.
This use of OR would give CL something akin to Ada overloading. It allows the
overloading of multiple 'function type signatures' on a single function name.
Such overloading is already implicit throughout CL (esp. the seq. functions).
My proposal would merely allow a way of describing it.
-- Nick
!
Date: Mon, 4 Nov 85 22:29 EST
From: Daniel L. Weinreb <DLW@SCRC-QUABBIN.ARPA>
Subject: Declaring Functions
To: shebs%utah-orion@UTAH-CS.ARPA, common-lisp@SU-AI.ARPA
Message-ID: <851104222904.2.DLW@CHICOPEE.SCRC.Symbolics.COM>
In-Reply-To: <8511012045.AA07112@utah-orion.ARPA>
Date: Fri, 1 Nov 85 13:45:55 MST
From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs)
The notion of a function type is mentioned in two places: p. 47 of the
CLM, where the (function ...) type specifier is defined, and p. 158-159,
where (ftype ...) and (function ...) are defined as options to declare.
Are they intended to be the same?
Read page 159 more carefully. It explains that they have the same meaning, but
are syntactically different. "function" has the disadvantage that you can only
declare one thing per clause, unlike most other declarations, but the advantage
that it looks mildly like "defun".
If so, then the second definition
should say that keywords and a (values ...) type specifier are allowed.
If by keywords you mean &optional and friends, it isn't strictly necessary to
repeat that, although it would sure clear things up if there were a cross
reference in the book.
However, there appears to be a typo on page 159. The form following the phrase
"entirely equivalent to", which currently reads
(ftype (function arglist result-type1 result-type2 ...) name)
ought to read
(ftype (function arglist (values result-type1 result-type2 ...)) name)
in order to be consistent with page 47.