[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
type-of
Date: Wed, 19 Nov 86 09:11:01 MST
From: sandra%utah-orion@utah-cs.arpa (Sandra J Loosemore)
From: RWK@YUKON.SCRC.Symbolics.COM (Robert W. Kerns)
Date: 18 Nov 86 21:04:00 GMT
Here is an example of completely-portable code which depends on
TYPE-OF returning the MOST specific type.
(defun store-in-array-if-fits (object array &rest indicies)
(let ((object-type (type-of object))
(array-type (array-element-type array)))
(if (subtypep object-type array-type)
;; If the object fits, store it
(setf (apply #'aref array indicies) object)
;; Doesn't fit, so store 0 instead.
(setf (apply #'aref array indicies) 0))))
Sorry, I can't buy this motivation. All this example illustrates is that
there is a good reason for having the TYPEP function around.
(defun typep (object type)
(subtypep (type-of object) type))
Yes, my example is a bit oversimplified; I was more interested in
demonstrating portability than necessity. And the "important half"
of TYPEP is SUBTYPEP, not TYPE-OF. But TYPEP doesn't let you
make the decision about the type separately from the object in
question.
As it happens, in PCLS, TYPE-OF does go through a considerable amount of
work to find the most specific type that it can. So, (TYPE-OF 0) returns
BIT, which is correct but largely useless. My "gut feeling" is that what
the user probably wants is either FIXNUM or INTEGER -- something which
indicates how the object is represented internally, or (in other words)
one of the set of types which CLtL says are disjoint.
If the user is writing his code properly, he is using
type-comparison (i.e. SUBTYPEP), so he doesn't really
care. But your "gut feeling" is right, he probably
doesn't care about anything more specific than
FIXNUM.
That's why I think it would be advantagious to more
precisely specify TYPE-OF. Right now the spec could
be read as requiring (TYPE-OF 0) => BIT. If we specify
a "least specific" type (FIXNUM in this case), than
any implementation which returns something *at least*
as specific as FIXNUM is fine. If an implementation
has reason for being more specific, however, it should
be free to do so.
I'll have to agree that TYPE-OF as defined now is pretty bogus. The only
place I've ever had reason to use TYPE-OF in real code was to get a type
to pass to COERCE or CONCATENATE, etc., when I wanted to ensure that two
objects were of the same type; for example, both lists or whatever. But
this is full of holes, too. For example,
(coerce '#(a b c) (type-of (list)))
may fail, depending on whether your favorite implementation thinks NIL is
of type NULL, LIST, or SYMBOL. I ended up writing a specialized function
to do what I wanted, without relying on TYPE-OF.
This is just a matter of TYPE-OF not being specific enough
together with COERCE not being general enough. If TYPE-OF
is properly specific (i.e. NULL), and COERCE finds the
"least supertype" of the argument type that it supports
(for example, if you wrote it with TYPECASE or SUBTYPEP,
rather than EQL), then there's no problem.
Our entire user-interface in Release 7 is based on just
type sort of question. It is fundamental to any theory
of TYPEP, as well. I freely admit that it isn't often
called, but that's not a reason to eliminate it, or to
leave it sloppily specified.
In short, I am not convinced that TYPE-OF would be particularly useful even
if its definition were firmed up more. If nobody has any good use for this
function, arguing over how it should behave is rather pointless.
I think your own example contradicts this position.
- References:
- type-of
- From: sandra%utah-orion@utah-cs.arpa (Sandra J Loosemore)