Re: Unportable ways to add non-trivial type constraints.
Marco Antoniotti <[email protected]> Mon, 3 Feb 2025 14:05:18 +0100
| Newsgroups | gmane.lisp.steel-bank.general |
|---|---|
| Message-ID | <CAG0Nw2mNrbnJT0ecYg4Tk3Bf-zJ2pPc5A0Go+NnWoBEGDy3Vpg@mail.gmail.com> |
There is a fully portable way (if you want to pay and have a varying
mileage).
(defmethod *equals* :before ((a T) (b T) &rest keys &key &allow-other-keys)
(declare (ignore keys))
(assert (cl:equal (type-of a) (type-of b)))
Of course, you need CDR 8.
All the best
MA
On Mon, Feb 3, 2025 at 1:49 PM Vasily Postnicov <[email protected]>
wrote:
> Thanks! No luck, I guess.
>
> пн, 3 февр. 2025 г. в 12:43, Stas Boukarev <[email protected]>:
>
>> Constraint propagation is changing all the time, it's going to be not
>> just non-portable but non-portable between different versions. And
>> possibly in subtle ways where you can't catch it.
>> So, don't do this.
>>
>> On Mon, Feb 3, 2025 at 3:40 PM Vasily Postnicov <[email protected]>
>> wrote:
>> >
>> > Hi! Suppose I want to write a specialized eql comparison function which
>> has a type a -> a -> BOOLEAN (i.e. types of its arguments must be equal).
>> >
>> > There is no portable way to specify such a type in Common Lisp. But, in
>> src/compiler/fun-info.lisp I found this:
>> >
>> > ;; If true, the function can add flow-sensitive type information
>> > ;; about the state of the world after its execution. The COMBINATION
>> > ;; node is passed as an argument, along with the current set of
>> > ;; active constraints for the block. The function returns a
>> > ;; sequence of constraints; a constraint is a triplet of a
>> > ;; constraint kind (a symbol, see (defstruct (constraint ...)) in
>> > ;; constraint.lisp) and arguments, either LVARs, LAMBDA-VARs, or
>> > ;; CTYPEs. If any of these arguments is NIL, the constraint is
>> > ;; skipped. This simplifies integration with OK-LVAR-LAMBDA-VAR,
>> > ;; which maps LVARs to LAMBDA-VARs. An optional fourth value in
>> > ;; each constraint flips the meaning of the constraint if it is
>> > ;; non-NIL.
>> > (constraint-propagate nil :type (or function null))
>> >
>> > So I thought this is what I need and tried the following:
>> > (defpackage foo
>> > (:use #:cl)
>> > (:export #:foo #:bar #:baz))
>> > (in-package :foo)
>> >
>> > (sb-c:defknown (foo) (t t) boolean
>> > (sb-c:movable sb-c:flushable sb-c:foldable))
>> >
>> > (defun foo (x y)
>> > (eql x y))
>> >
>> > (sb-c:defoptimizer (foo sb-c::constraint-propagate) ((x y) node gen)
>> > (let ((type-x (sb-c::lvar-type x))
>> > (type-y (sb-c::lvar-type y))
>> > (var-x (sb-c::ok-lvar-lambda-var x gen))
>> > (var-y (sb-c::ok-lvar-lambda-var y gen)))
>> > (when (and var-x var-y)
>> > (print
>> > (list
>> > (list 'typep var-x type-y)
>> > (list 'typep var-y type-x))))))
>> >
>> > (declaim (ftype (function (integer string) (values boolean &optional))
>> bar))
>> > (defun bar (x y)
>> > (foo x y))
>> >
>> > When compiling bar I have this printed:
>> > ((TYPEP
>> > #<SB-C::LAMBDA-VAR
>> > :%SOURCE-NAME X
>> > :TYPE #<SB-KERNEL:NUMERIC-TYPE INTEGER>
>> > :WHERE-FROM :DECLARED {1111651493}>
>> > #<SB-KERNEL:UNION-TYPE STRING> T)
>> > (TYPEP
>> > #<SB-C::LAMBDA-VAR
>> > :%SOURCE-NAME Y
>> > :TYPE #<SB-KERNEL:UNION-TYPE STRING>
>> > :WHERE-FROM :DECLARED {1111651553}>
>> > #<SB-KERNEL:NUMERIC-TYPE INTEGER> T))
>> > but no compile-time or run-time when I use bar:
>> >
>> > CL-USER> (foo:baz 543 "dsd")
>> > NIL
>> >
>> > Can you please give me a hint how type information about arguments can
>> be added to a function? My goal is to learn how I can write a bit
>> type-safer code and non-portability does not bother me.
>> >
>> > Also, if there are any publications about how SBCL handles types,
>> please tell me.
>> > _______________________________________________
>> > Sbcl-help mailing list
>> > [email protected]
>> > https://lists.sourceforge.net/lists/listinfo/sbcl-help
>>
> _______________________________________________
> Sbcl-help mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/sbcl-help
>
--
Marco Antoniotti, Professor, Director tel. +39 - 02 64 48 79 01
DISCo, University of Milan-Bicocca U14 2043 http://dcb.disco.unimib.it
Viale Sarca 336
I-20126 Milan (MI) ITALY
_______________________________________________
Sbcl-help mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sbcl-help