Функция принуждения в общем lisp - массивах и списках
Я наблюдаю разное поведение принуждения между различными версиями Common Lisp - интересно, какая из них "правильная" или является стандартом неоднозначного в этом, казалось бы, простом вопросе:
является
(coerce '(1 2 3) 'array)
правильный лисп? Он отлично работает в Clozure Common Lisp, но не в sbcl.
И когда это не работает, какой самый простой способ привести список в массив?
Спасибо
2 ответа
В спецификации сказано:
Если тип результата является узнаваемым подтипом
vector
и объект являетсяsequence
, то результатом являетсяvector
который имеет те же элементы, что и объект.
array
не является подтипом vector
- векторы являются одномерными массивами, но array
включает в себя массивы с любым количеством измерений.
Вы можете использовать один из этих
(coerce '(1 2 3) 'vector)
(coerce '(1 2 3) '(array t (*)))
Во второй версии (*)
указывает одно измерение, размер которого не указан.
Ваше использование не определено, поэтому реализации могут осуществлять его по своему усмотрению. Если он возвращает значение, значение должно быть ARRAY
какой-то
Чтобы добавить к ответу Бармара (это действительно комментарий, но он слишком длинный), хотя для CCL вполне нормально делать то, что он делает, я думаю, ясно, что что-то подобное будет очень трудно определить в стандарте.
Рассмотрим что-то вроде этого:
(coerce '((1 2 3) (4 5 6) (7 8 9)) 'array)
Каков будет результат этого? Должно ли это быть:
- вектор, каждый элемент которого представляет собой трехэлементный список?
- эквивалент
(make-array '(3 3) :initial-contents '((1 2 3) (4 5 6) (7 8 9)))
? - транспонирование этого массива?
Я думаю, что любая из первых двух является разумной интерпретацией: иногда вы захотите одно, иногда другое. Третий, вероятно, не является разумным, учитывая, что CL - язык строк.
Так что если (coerce ... 'array)
были в стандарте, как бы вы указали, какой из них вы хотели? Если вы просто выбрали один, который должен быть (и как вы теперь достигнете соглашения с людьми в комитете, которые думают, что это должен быть другой!)?