DECLAIM FTYPE: invalid suggestion to use &OPTIONAL in place of &REST
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
Invalid
|
Undecided
|
Unassigned |
Bug Description
SBCL 2.0.10 on Linux amd64.
(in-package #:cl-user)
(defstruct (foo
(type nil :type symbol))
(defstruct (bar
(declaim (ftype (function (symbol &rest t) foo) make-foo))
(defun make-foo (type &rest args)
(if (subtypep type 'foo)
(apply (alexandria:
(error "~s is not defined." type)))
; note: Type assertion too complex to check:
; (VALUES COMMON-
; It allows an unknown number of values, consider using
; (VALUES COMMON-
I will gladly learn how I can pass an unknown number of values (which is fully intentional here, the arguments get passed to another constructor function via APPLY) by using &OPTIONAL, as SBCL suggests.
"Michał \"phoe\" Herda" <email address hidden> writes:
> (declaim (ftype (function (symbol &rest t) foo) make-foo)) symbolicate '#:%make- type) :type type args) LISP-USER: :FOO &REST T). LISP-USER: :FOO &OPTIONAL).
> (defun make-foo (type &rest args)
> (if (subtypep type 'foo)
> (apply (alexandria:
> (error "~s is not defined." type)))
>
> ; note: Type assertion too complex to check:
> ; (VALUES COMMON-
> ; It allows an unknown number of values, consider using
> ; (VALUES COMMON-
>
> I will gladly learn how I can pass an unknown number of values (which is
> fully intentional here, the arguments get passed to another constructor
> function via APPLY) by using &OPTIONAL, as SBCL suggests.
SBCL is not suggesting that the arguments part of the FTYPE declaration
is changed.
The declamation
(ftype (function (symbol &rest t) foo) make-foo)
means "this function MAKE-FOO, when it's called, will always take a
symbol as its first argument, and any number of other arguments; its
primary return value will be a FOO". It's equivalent to
(ftype (function (symbol &rest t) (values foo &rest t)) make-foo)
SBCL's optimization note is that that is too complex a restriction for are-assertions to apply. Why? Because as well
the normal declarations-
as the primary return value, the function could return an arbitrary
number of other values, and inserting code for checking just the first
while preserving all the others is a bit horrible. The note is
suggesting to you that if you changed the declamation to
(ftype (function (symbol &rest t) (values foo &optional)) make-foo)
then you would be declaring that make-foo always returned precisely one
value, a FOO, which is more amenable to checking and/or derivation.
I hope that helps clarify things.