[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Type Specifier: (OR (FUNCTION ...) ...)
Date: 21 Apr 1986 16:31-EST
Date: Sun, 20 Apr 86 16:14 EST
From: Guy Steele <gls@THINK-AQUINAS.ARPA>
Date: 19 Apr 1986 17:08-EST
Date: Sat, 19 Apr 1986 16:24 EST
From: "Scott E. Fahlman" <Fahlman@C.CS.CMU.EDU>
Regarding your proposal that we allow forms like the following
(or (function (list) list)
(function (vector) vector))
as a way of specifying that the output type of a function matches its
I don't think it is a proposal. I can find nothing in CLtL that forbids
using such a form right now. I find no justification in CLtL for a
compiler's insisting that a type specifier given to FTYPE be of the form
What I said in my original letter was:
"Unfortunately, it is not clear from pg. 158 whether or not the
following is legal: ... 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."
I guess I should have said "So I would like to propose that pg. 158 be
'clarified' to explicitly state that such a use of OR/FUNCTION be
considered legal CL." To be more explicit: Clarify the def. of FTYPE
(pg. 158) by changing (FTYPE type ...) to (FTYPE function-type ...)
and defining function-type to either (FUNCTION ...),
(NOT function-type), (AND function-type ...), or (OR function-type ...).
I would still like to know if there are any implementations that do
consider (OR (FUNCTION ... meaningful!
Unless a compiler can prove that a declaration is
actually inconsistent, it should not signal an error. (Warnings are
another matter and, as always, subject to judements of taste.) A compiler
is not justified in signalling an error just because it doesn't know
how to make use of a perfectly legitimate declaration.
... If someone were to say
(or (function (list sequence) foo)
(function (sequence list) bar))
then what do we do?
According to the definition of the OR type-spec on pg. 45, "it always
tests each of the component types in order from left to right and
stops procesing as soon as one component of the union has been found
to which the object belongs."
But hold on here, now. That specification applies specifically to the case
of TYPEP processing the type specifier, not to the case of using the type
specifier in a declaration. Also, do not make the mistake of thinking
that one can decide which of several function type specifiers applies to
a function call by examining the argument types only. If function BAZ has
the type shown above, then we are entitled only to conclude that the
call (BAZ '(a) '(b)) will return an object of type (OR FOO BAR).
I stand corrected.
But here is a more subtle point. The above type states that BAZ is either
a function of type (FUNCTION (LIST SEQUENCE) FOO) or a function of type
(FUNCTION (SEQUENCE LIST) BAR). Assume FOO and BAR to be disjoint types.
Suppose BAZ is called twice in succession, and the result of the first call
is determined to be of type FOO:
(WHEN (TYPEP (BAZ '(a) '(b)) 'FOO)
(BAZ '(c) '(d)))
We have no cause to believe that BAZ will change between the two calls,
I disagree for the same reason as REM.
and so we are entitled to deduce that the second call to BAZ, if
executed, will necessarily return a FOO and not a BAR, because the first
call produced a FOO and thus BAZ is of type (FUNCTION (LIST SEQUENCE) FOO).
So maybe Nick isn't actually expressing quite what he wanted to in the
No I guess I'm not. But I am quite happy with Guy's correction. I
can still do things like:
(proclaim '(ftype (or (function (t list &rest t) list)
(function (t vector &rest t) vector))
And expect that a very good compiler would be able to deduce that the
call (remove 1 '#(1 2 3 4)) will return a vector. I think I will now
try to come up with a declaration for +.