alex-gutev / cl-form-types

Library for determining the types of Common Lisp forms based on information stored in the environment.
MIT License
19 stars 1 forks source link

Better handling `the` forms #2

Closed digikar99 closed 3 years ago

digikar99 commented 3 years ago

This was originally suggested by @commander-trashdin: (cl-form-types:form-type '(the number 5) nil) should result in (and number (eql 5)) rather than the simpler number; that way, no information is lost.

alex-gutev commented 3 years ago

To what extent should the value form in a THE form be examined, i.e. should the type of the value form only be returned if the value form is a constant value such as in the example above? Or should all forms be examined? Then that brings me to my second question, which type should be returned if the two types are different or even contradictory? That should not happen in a well-formed program but can happen never the less. In the above example, i.e. when the value form is a constant, it's obvious but what if the type of the value form is determined to be integer, should integer be returned instead of number?

commander-trashdin commented 3 years ago

(form-type '(the typename form)) should be (and typename (form-type form))

alex-gutev commented 3 years ago

OK I will make that change.

commander-trashdin commented 3 years ago

If it turns out to be a bottom type (nil that is) -- that's on user not on us.

alex-gutev commented 3 years ago

Added in commit 4035067. This is more complicated than a simple (and typename (form-type form)) since either the type of the form, or the type specifier, or both, can be a (VALUES ...) and (AND (VALUES ...) (VALUES ...)) is not a valid type specifier. Currently, if both type specifiers are VALUES types, each corresponding value type, in both type specifiers, is combined with AND. If only one of the type specifiers is a VALUES type, the other is treated as a VALUES type of a single value.

Example:

;; Assuming return type of F is (VALUES FIXNUM STANDARD-CHARACTER)
(the (values integer character) (f x))

FORM-TYPE on the above will return

(values (and integer fixnum) (and character standard-character))

If either type specifier has an &optional keyword it is placed in the result returned by FORM-TYPE, at the position it is found in the values type specifier where it is closed to the start of the list. &rest and &allow-OTHER-KEYS keywords are also handled.

This also fixes an issue with IF form types, where either branch may be of a VALUES type.