From: sds on
(defparameter v (make-array 5 :element-type 'single-floar))
what should
(setf (aref v 0) 1d0)
do?
== coerce 1d0 to a single-float and store that
== signal an error
the first seems more useful while the second is what sbcl does.
it is not quite clear what the spec requires.
From: Barry Margolin on
In article
<b2eb7663-0197-437e-8fb6-90af372ca26d(a)h40g2000pro.googlegroups.com>,
sds <sam.steingold(a)gmail.com> wrote:

> (defparameter v (make-array 5 :element-type 'single-floar))
> what should
> (setf (aref v 0) 1d0)
> do?
> == coerce 1d0 to a single-float and store that
> == signal an error
> the first seems more useful while the second is what sbcl does.
> it is not quite clear what the spec requires.

In Common Lisp, the only purpose of declarations is to allow compiler
optimizations. A declaration is a "promise" that you'll never try to
store a value of some other type in the location. If you enable high
levels of optimizations, the generated code is expected to assume that
the promise is always going to be kept -- there's no need for it to
check the type of the argument to SETF. And if it doesn't check, it
obviously can't be expected to coerce it.

Another way to state this is that declarations don't change the
semantics of operations. The spec says that it's an error to try to
store a value in an array that doesn't meet the element type.

--
Barry Margolin, barmar(a)alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Tamas K Papp on
On Mon, 02 Aug 2010 15:42:02 -0400, Barry Margolin wrote:

> In article
> <b2eb7663-0197-437e-8fb6-90af372ca26d(a)h40g2000pro.googlegroups.com>,
> sds <sam.steingold(a)gmail.com> wrote:
>
>> (defparameter v (make-array 5 :element-type 'single-floar)) what should
>> (setf (aref v 0) 1d0)
>> do?
>> == coerce 1d0 to a single-float and store that == signal an error
>> the first seems more useful while the second is what sbcl does. it is
>> not quite clear what the spec requires.
>
> In Common Lisp, the only purpose of declarations is to allow compiler
> optimizations. A declaration is a "promise" that you'll never try to
> store a value of some other type in the location. If you enable high
> levels of optimizations, the generated code is expected to assume that
> the promise is always going to be kept -- there's no need for it to
> check the type of the argument to SETF. And if it doesn't check, it
> obviously can't be expected to coerce it.

I don't understand how the OP's problem has anything to do with
declarations and optimization settings. AFAIK array element types
have well-defined semantics regardless of the latter (with the
understanding that for certain speed/safety combinations, the setf
above may wreak havoc).

> Another way to state this is that declarations don't change the
> semantics of operations. The spec says that it's an error to try to
> store a value in an array that doesn't meet the element type.

Where does the spec say that? I agree that signaling an error is the
sensible approach, but I have never been able to find this in the
spec.

Thanks,

Tamas
From: Barry Margolin on
In article <8bpkfrF62nU1(a)mid.individual.net>,
Tamas K Papp <tkpapp(a)gmail.com> wrote:

> On Mon, 02 Aug 2010 15:42:02 -0400, Barry Margolin wrote:
>
> > In article
> > <b2eb7663-0197-437e-8fb6-90af372ca26d(a)h40g2000pro.googlegroups.com>,
> > sds <sam.steingold(a)gmail.com> wrote:
> >
> >> (defparameter v (make-array 5 :element-type 'single-floar)) what should
> >> (setf (aref v 0) 1d0)
> >> do?
> >> == coerce 1d0 to a single-float and store that == signal an error
> >> the first seems more useful while the second is what sbcl does. it is
> >> not quite clear what the spec requires.
> >
> > In Common Lisp, the only purpose of declarations is to allow compiler
> > optimizations. A declaration is a "promise" that you'll never try to
> > store a value of some other type in the location. If you enable high
> > levels of optimizations, the generated code is expected to assume that
> > the promise is always going to be kept -- there's no need for it to
> > check the type of the argument to SETF. And if it doesn't check, it
> > obviously can't be expected to coerce it.
>
> I don't understand how the OP's problem has anything to do with
> declarations and optimization settings. AFAIK array element types
> have well-defined semantics regardless of the latter (with the
> understanding that for certain speed/safety combinations, the setf
> above may wreak havoc).

I believe that specifying the array element type is equivalent to a
declaration of the type of any expression that accesses an element of
the array.

>
> > Another way to state this is that declarations don't change the
> > semantics of operations. The spec says that it's an error to try to
> > store a value in an array that doesn't meet the element type.
>
> Where does the spec say that? I agree that signaling an error is the
> sensible approach, but I have never been able to find this in the
> spec.

I never said "signal an error". But I slipped into the terminology used
by some other language specs. "Is an error" is analogous to
"consequences are undefined" in the CL spec.

--
Barry Margolin, barmar(a)alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Tamas K Papp on
On Tue, 03 Aug 2010 04:44:32 -0400, Barry Margolin wrote:

> In article <8bpkfrF62nU1(a)mid.individual.net>,
> Tamas K Papp <tkpapp(a)gmail.com> wrote:
>
>> On Mon, 02 Aug 2010 15:42:02 -0400, Barry Margolin wrote:
>>
>> > In article
>> > <b2eb7663-0197-437e-8fb6-90af372ca26d(a)h40g2000pro.googlegroups.com>,
>> > sds <sam.steingold(a)gmail.com> wrote:
>> >
>> >> (defparameter v (make-array 5 :element-type 'single-floar)) what
>> >> should (setf (aref v 0) 1d0)
>> >> do?
>> >> == coerce 1d0 to a single-float and store that == signal an error
>> >> the first seems more useful while the second is what sbcl does. it
>> >> is not quite clear what the spec requires.
>> >
>> > In Common Lisp, the only purpose of declarations is to allow compiler
>> > optimizations. A declaration is a "promise" that you'll never try to
>> > store a value of some other type in the location. If you enable high
>> > levels of optimizations, the generated code is expected to assume
>> > that the promise is always going to be kept -- there's no need for it
>> > to check the type of the argument to SETF. And if it doesn't check,
>> > it obviously can't be expected to coerce it.
>>
>> I don't understand how the OP's problem has anything to do with
>> declarations and optimization settings. AFAIK array element types have
>> well-defined semantics regardless of the latter (with the understanding
>> that for certain speed/safety combinations, the setf above may wreak
>> havoc).
>
> I believe that specifying the array element type is equivalent to a
> declaration of the type of any expression that accesses an element of
> the array.

I disagree. Specifying an element-type results in the array having
the corresponding upgraded-element-type (which is
implementation-dependent, but is invariant to declarations). If
unspecified, the element type defaults to T.

Declaring the type of the array (incl element-type) is an orthogonal
feature, and has the same effect as any other declaration. It will
not change the element type of the array. Eg if you compile

(defun foo ()
(let ((a (make-array 5)))
(declare (type (array fixnum (*)) a))
a))

in SBCL, you even get

note: deleting unreachable code
warning:
Asserted type (VECTOR FIXNUM) conflicts with derived type
(VALUES (SIMPLE-VECTOR 5) &OPTIONAL).
See also:
SBCL Manual, Handling of Types [:node]

>> > Another way to state this is that declarations don't change the
>> > semantics of operations. The spec says that it's an error to try to
>> > store a value in an array that doesn't meet the element type.
>>
>> Where does the spec say that? I agree that signaling an error is the
>> sensible approach, but I have never been able to find this in the spec.
>
> I never said "signal an error". But I slipped into the terminology used
> by some other language specs. "Is an error" is analogous to
> "consequences are undefined" in the CL spec.

Understood. But where exactly does it say that in the spec? (I am
not arguing with you here, I am simply trying to find out the answer,
because so far I haven't managed to locate this in the spec and I have
always been curious -- I work a lot with arrays).

Best,

Tamas