Posted 2020-10-27 16:47:47 GMT
自作のライブラリで、(coerce "foo" 'cons)
や、(coerce "" 'null)
のようなコードがAllegro CLでエラーになるので、おやもしかして処理系依存だったかと思いANSI規格を確認してみましたが、
sequenceIf the result-type is a recognizable subtype of list, and the object is a sequence, then the result is a list that has the same elements as object.
——ということなので、合法のようです。
ちょっと趣味的にAllegro CL 4.3(1996)で確認してみましたが、同様のエラーのようです。
そうなると時代的にCLtL1、CLtL2あたりでははっきり決まっていなかったかもしれないので確認してみましたが、明記されたのはANSI CL規格以降のようです。
とりあえず、Allegro CLのcoerce
をdisassemble
してみると、excl::vector-to-list*
という下請けに渡していることが分かります。
1023: 89 da movl edx,ebx
1025: 3b 56 26 cmpl edx,[esi+38] ; LIST
1028: 0f 85 1e 02 jnz 1576
00 00
1034: 8b 45 dc movl eax,[ebp-36] ; EXCL::LOCAL-0
1037: 89 7d f0 movl [ebp-16],edi
1040: c9 leave
1041: 8b 5e 2a movl ebx,[esi+42] ; EXCL::VECTOR-TO-LIST*
このexcl::vector-to-list*
自体は、適切にリストに変換できるようですが、前段では、cons
やnull
も出てこずにlist
としか比較していないので、すりぬけてエラーになっているように見えます。
(excl::vector-to-list* "")
→ NIL(excl::vector-to-list* "foo")
→(#\f #\o #\o)
list
のサブタイプはcons
やnull
以外にも複合した指定があるので、別途サブタイプの判定をきっちりしないと
(coerce "foo" '(cons (eql #\f) (cons (eql #\o) (cons (eql #\f) *))))
のようなものを判定できなさそうです。
ちなみに上記は、LispWorksではエラーになりますが、SBCLではエラーになりません(SBCLのバグもみつけてしまったか?)
Allegro CLへのバグはどこに報告したら良いのかと探してみましたが、報告の仕方の解説ページがあったので、こちらに沿って報告してみました。
Allegro CL 4.3(1996)でも同様なので、Allegro CL(ExCL)誕生時(1986)からこの仕様で来たような気がしないでもありません。
果してバグ認定されるのか、はたまたAllegro CLの仕様であるとして修正されないのか。
ちなみに、map
も変なところがありますが、話がややこしくなるので、今回は報告を見送りました。
#+Allegro
(map 'null #'identity "foo")
→(#\f #\o #\o)
■
HTML generated by 3bmd in LispWorks Personal Edition 7.1.2