1

I am seeing different behavior of coerce between different versions of Common Lisp - wondering which one is "right" or is the standard ambiguous on this seemingly simple question:

is

(coerce '(1 2 3) 'array) 

correct lisp? It works fine in Clozure Common Lisp but not in sbcl.

And when it does not work what is the easiest way to coerce a list into an array?

Thanks

Rainer Joswig
  • 136,269
  • 10
  • 221
  • 346
PaulM
  • 305
  • 1
  • 8

2 Answers2

7

The specification says:

If the result-type is a recognizable subtype of vector, and the object is a sequence, then the result is a vector that has the same elements as object.

array is not a subtype of vector -- vectors are 1-dimensional arrays, but array includes arrays with any number of dimensions.

You can use one of these

(coerce '(1 2 3) 'vector)
(coerce '(1 2 3) '(array t (*)))

In the second version, (*) specifies a single dimension whose size is unspecified.

Your use is unspecified, so implementations are free to implement it as they please. If it returns a value, the value has to be an ARRAY of some kind.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thanks, I see how to proceed now. But out of curiousity -- Is ccl incorrect to allow my first coerce? Is the spec ambivalent? Does the spec not say what should not work, only what should work? – PaulM Aug 12 '19 at 21:59
  • 1
    The spec doesn't say what to do in other cases, so implementations are free to extend it. – Barmar Aug 12 '19 at 22:01
1

To add to Barmar's answer (this is really a comment, but it's too long), while it's fine for CCL to do what it does, I think it's clear that something like this would be very hard to define in a standard.

Consider something like this:

(coerce '((1 2 3) (4 5 6) (7 8 9)) 'array)

What is the result of this meant to be? Should it be:

  • a vector each of whose elements is a three-element list?
  • the equivalent of (make-array '(3 3) :initial-contents '((1 2 3) (4 5 6) (7 8 9)))?
  • the transpose of that array?

I think either of the first two are reasonable interpretations: sometimes you will want one, sometimes the other. The third is probably not reasonable given CL is a row-major language.

So if (coerce ... 'array) were in the standard, how would you specify which of these you wanted? If you just chose one, which should it be (and how do you now reach agreement with the people on the committee who think it should be the other!)?