GNU bug report logs -
#69739
30.0.50; `type-of` is not precise enough
Previous Next
Reported by: Stefan Monnier <monnier <at> iro.umontreal.ca>
Date: Mon, 11 Mar 2024 23:22:01 UTC
Severity: normal
Found in version 30.0.50
Done: Stefan Monnier <monnier <at> iro.umontreal.ca>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
[Message part 1 (text/plain, inline)]
Your bug report
#69739: 30.0.50; `type-of` is not precise enough
which was filed against the emacs package, has been closed.
The explanation is attached below, along with your original report.
If you require more details, please reply to 69739 <at> debbugs.gnu.org.
--
69739: https://debbugs.gnu.org/cgi/bugreport.cgi?bug=69739
GNU Bug Tracking System
Contact help-debbugs <at> gnu.org with problems
[Message part 2 (message/rfc822, inline)]
>> +@example
>> +(object-type 1)
>> + @result{} fixnum
>> +@group
>> +(object-type 'nil)
>> + @result{} null
>> +(object-type (record 'foo))
>> + @result{} foo
>
> "object-type"?
Oops! thanks.
>> DEFUN ("type-of", Ftype_of, Stype_of, 1, 1, 0,
>> doc: /* Return a symbol representing the type of OBJECT.
>> The symbol returned names the object's basic type;
>> -for example, (type-of 1) returns `integer'. */)
>> +for example, (type-of 1) returns `integer'.
>> +Contrary to `cl-type-of' the returned type is not always the most
> ^^
> I think we want a comma there.
>> +DEFUN ("cl-type-of", Fcl_type_of, Scl_type_of, 1, 1, 0,
>> + doc: /* Return a symbol representing the type of OBJECT.
>> +The symbol returned names the most specific possible type of the object.
> ^^^^^^^^^^^^^^^^^^^
> I think "The returned symbol" is better here, as it prevents a
> possible confusion (whether "returned" alludes to "symbol" or to
> "names").
Agreed.
>> +for example, (object-type nil) returns `null'.
> ^^^^^^^^^^^
> "object-type"?
As you can see I had used `object-type` instead of `cl-type-of` in some
prior version of the code :-)
>> (defsubst subr-primitive-p (object)
>> - "Return t if OBJECT is a built-in primitive function."
>> + "Return t if OBJECT is a built-in primitive written in C."
>> (declare (side-effect-free error-free))
>> (and (subrp object)
>> (not (subr-native-elisp-p object))))
>>
>> +(defsubst primitive-function-p (object)
>> + "Return t if OBJECT is a built-in primitive function."
>> + (declare (side-effect-free error-free))
>> + (and (subrp object)
>> + (not (or (subr-native-elisp-p object)
>> + (eq (cdr (subr-arity object)) 'unevalled)))))
>
> Should these doc strings mention the special case of special form,
> which each one of them treats differently?
OK.
Pushed, thanks,
Stefan
[Message part 3 (message/rfc822, inline)]
Package: Emacs
Version: 30.0.50
`type-of` is supposed to return "the" type of its argument. Given that
ELisp has a notion of subtyping, "the" type is expected to mean "the
most precise type". This is used in `cl-generic` to decide which method
to apply, so it's important that it returns precise information.
Currently, there `type-of` fails to return precise enough information in
a few cases:
- When the argument is nil, it returns `symbol`. The problem here is
that `symbol` is not a subtype of `list`, whereas nil is a list.
- When the argument is a special form, a C primitive, or
a native-compiled function it returns `subr`. Currently our
type hierarchy says that `subr` is a subtype of `compiled-function`
(and hence of `function`), but a special form is *not* a function
(it fails the `functionp` test and can't be `funcall`ed).
Currently `cl-generic` works around the first point above by using
(if FOO (type-of FOO) 'null) instead of calling `type-of` directly.
Suggestion:
I suggest we change `type-of` to return `null` for `nil`,
`special-form` for subrs that are special forms, `subr-primitive`
for C primitives, and `subr-native-elisp` for native-compiled subrs.
There are a few other cases where we could improve the precision, tho
they are less important because they don't cause problems w.r.t
subtyping like the above does.
Further improvements could include:
- Return `boolean` for `t`. This would be nice otherwise (with the
above suggestion) `cl-generic` can dispatch on "nil is a boolean"
but not on "t is a boolean".
- Return `keyword` for symbols that are keywords.
- Return `fixnum` or `bignum` rather than just `integer`.
Probably not worth the trouble.
- We could go crazy and return `keyword-with-pos` for `symbols-with-pos`
that are keywords.
Of these further improvements, only the first (return `boolean` for `t`)
seems worth the trouble.
Still, any change as suggested here would be an incompatible change, so
there's risk it'll break some code out there (`type-of` is not used very
often, but it *is* used). Another option is to introduce a new function
which does the same as `type-of` but with changes like the ones above.
(we could even decide to give it a `cl-generic-` prefix to discourage
its use elsewhere so we can be more free to change its return value in
the future).
Stefan
This bug report was last modified 1 year and 121 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.