Posted 2017-01-23 20:28:36 GMT
パッケージ名を短かく表示する自作ユーティリティをLispWorksに移植してみていて、妙なエラーに遭遇
(proclaim '(optimize (debug 3) (safety 3)))(defun foo (string package)
(system::find-external-symbol String Package))
のようなものをコンパイルして呼び出すと
(foo "PROGN" (find-package :cl))
⊳ Error: The results of SYSTEM::FIND-EXTERNAL-SYMBOL, (PROGN 403), do not satisfy the ftype specifier (VALUES SYMBOL SYMBOL).
とエラーになってしまう。
system::find-external-symbol
の型を確認してみると、
(function-information 'system::find-external-symbol)
→ :function
nil
((ftype function (simple-string package) (values symbol symbol)))
となっているが、実際に呼び出してみると
(system::find-external-symbol "PROGN" (find-package :cl))
→ progn
403(system::find-external-symbol "PROGZ" (find-package :cl))
→ 0
nil
となっているので返り値の型宣言である(values symbol symbol)
とは不整合があるのが問題のようだ。
またコンパイラの設定にも依存していて、safety 3
でないとチェックには引っ掛からない。
(defun foo (string package)
(declare (ftype (function (simple-string package)
(values (or symbol fixnum) (or symbol fixnum)))
system::find-external-symbol))
(system::find-external-symbol String Package))
こんな感じに宣言をシャドウ?してやれば通る。
また、グローバルにproclaim
とかファイルローカルにdeclaim
とかしても良いっぽい。
(proclaim '(ftype (function (simple-string package)
(values (or symbol fixnum) (or symbol fixnum)))
system::find-external-symbol))
どうでも良さそうなバグだけど一応報告してみた。
回答は、内部シンボルは使わないで、ということで終了。
結局、LispWorksの内部的に型宣言は合っているのか、それとも間違っているのかは不明なままだった。
コンパイラのセッティングで無視するなら、(values t t)
にでもしちゃえば良いのにね、と思ったり。
(proclaim '(optimize (debug 3) (safety 3)))
しておくと、コンパイラが型宣言の間違いを発見してくれることが多いのでお勧め。
自作のライブラリを公開する時にも、(optimize (debug 3) (safety 3)))
で一度通るか確認してから、出荷設定でビルドするのが良いと思う。
ちなみに、パッケージ名を短かく表示する自作ユーティリティとは、こちら
端的に言ってしまうと処理系の改造なのでLispWorksのような商用処理系で試すのはお勧めしない(ソースが公開されている処理系でもお勧めはしないが)
一応LispWorksでも動くようになったので使ってみている。
■
HTML generated by 3bmd in LispWorks 7.0.0