From: dremon on
On Jan 16, 10:01 pm, Tamas K Papp <tkp...(a)gmail.com> wrote:
> On Sat, 16 Jan 2010 12:05:24 -0800, dremon wrote:
> > When compiling the following code I am getting compiler warnings:
>
> > note: unable to optimize due to type uncertainty: The first argument is
> > a SEQUENCE, not a (SIMPLE-ARRAY * (*)). note: unable to optimize due to
> > type uncertainty: The first argument is a SEQUENCE, not a LIST.
>
> > (defclass mtest()
> >   ((data :accessor data
> >             :type (simple-array float (*))
> >             :initform (make-array 10
> >                                                       :element-type
> 'float
> >                                                       :initial-
> element 0.0
> >                                                       :adjustable nil
> >                                                       :fill-pointer
> nil
> >                                                       :displaced-to
> nil))))
>
> > (defmethod value((obj mtest) (i fixnum) (j fixnum))
> >   (declare (optimize (speed 3) (safety 0))) (elt (data obj) (+ i j)))
>
> > What is wrong with this code? Seems like all the types are known but
> > still it it doesn't optimize.
>
> AFAIK SBCL won't infer types from defclass's :type declarations.
> Think of the latter as documentation for yourself, not a hint to the
> compiler.
>
> Just use something like
>
> (defclass mtest()
>   ((data :accessor data
>          :type (simple-array float (*))
>          :initform (make-array 10 :element-type 'float
>                                :initial-element 0.0))))
> ;;; note how you don't need to supply the defaults to make-array
>
> (defmethod value((obj mtest) (i fixnum) (j fixnum))
>   (declare (optimize (speed 3) (safety 0)))
>   (aref (the (simple-array float (*)) (data obj)) (+ i j)))
>
> HTH,
>
> Tamas

That worked indeed, thanks!
From: dremon on
On Jan 16, 9:59 pm, Christophe Rhodes <cs...(a)cantab.net> wrote:
> dremon <dmitry.pankra...(a)gmail.com> writes:
> > (defclass mtest()
> >   ((data :accessor data
> >             :type (simple-array float (*))
> >             :initform (make-array 10 [...]))))
>
> > (defmethod value((obj mtest) (i fixnum) (j fixnum))
> >   (declare (optimize (speed 3) (safety 0)))
> >   (elt (data obj) (+ i j)))
>
> > What is wrong with this code? Seems like all the types are known but
> > still it it doesn't optimize.
>
> All types are not known.  At any point, and between any calls to VALUE,
> it would be legal to add methods to the DATA generic function, such as
> an :AROUND method specialized to MTEST, which can return any object of
> any type at all; it would legal to redefine the MTEST class to remove
> the type declaration for the slot; it would legal to redefine the MTEST
> class to remove the DATA slot and accessor entirely, such that the next
> access to any MTEST instance would drop the contents of its DATA slot.
> In all these circumstances, the VALUE method must continue to function
> in accordance with the standard CLOS behaviour.
>
> There are ways of getting the compiler to make the kinds of assumptions
> that you want in CLOS code; most of them involve going into
> implementation-specific territory.
>
> Christophe

Thanks Christophe, that's very clear explanation.