Posted 2015-07-14 05:53:46 GMT

Allegro CLにはmlispというモードがありますが、これは、ANSI CLの規格(以下ANSと略)とは異った仕様にすることで利用者の便宜を図るというものです。

具体的なANSとの違いは、

common-lisp パッケージのシンボル名は全部小文字で構成されている

パッケージのシンボル名は全部小文字で構成されている リーダーの読み取りモードは、 :preserve で標準の :upcase と異なり大文字に畳み込まない

というのが主な所です。

この仕様についてCommon Lispの大文字と小文字を区別しない所を改善した、と思っている人が割といますが、端的にいえばANSの仕様の勘違いをしています。

主な勘違いとは、

ANSでの common-lisp パッケージのシンボル名は全部大文字で構成されていることを知らない

パッケージのシンボル名は全部大文字で構成されていることを知らない ANSでも大文字小文字は区別するがデフォルトでは、 :upcase となっていて大文字に畳み込む。 :preserve にすればmlispと同様になる。

というところです。

読み込みについては :preserve にすれば良いので簡単に解決できますが、clパッケージが全部小文字というのが厄介な所です。

一見エイリアスを作って解決に思えますが、スペシャル変数はエイリアスを作ることができないので、規格の範囲で対処するのは恐らく無理だと思います。

リーダーマクロを使う方法も試してみたことはありますが(**で囲むと大文字に変換する)、やはり無理があるという印象です。

ちなみに、Allegro CLの場合ですが、実行ファイルをmlispと、alisp(ANSモード)とに分けることによって対応しています。

こんなmlispとANSの関係ですが、ANS尊守の人からは、規格外のもの広めようとするなどFranzはけしからん、という声もあったりします。

自分もどちらかといえば、ANSに準拠していて欲しいのでmlispの利用は回避していました。

Allegro CLのin-case-mode

そんなmlispなのですが、ふとマニュアルを眺めていた所、 in-case-mode というものを見付けました。

Allegro CL 8.2から標準搭載のようですが、それまでは読み取りモードを手動で設定していたのを、 in-package 的に簡単に指定できるようにしたもののようです。

これは、ソースファイルにも、faslファイルにも対応しているものですが、動作を確認してみます。

alispでコンパイルしたものをmlispで読む

互換性の問題で云えば、alispでコンパイルしたものをmlispで読めれば全て解決と思われます。

こんなファイルを作成して

am.lisp

defpackage "AM" ( :use :cl ) (cl:in-package "AM") (defun barp (x) (eq 'Bar x)) (defun bazp (x) (eq '|Baz| x))

alispでコンパイルし、mlispで (in-case-mode :common) で読み込みます。

ANSモードでの意図はそのまま保存できているようです。

ソースコードをコンパイルしないで読み込んでも (in-case-mode :common) なら意図通りです。

mlispでコンパイルしたものをalispで読む

同様に、こっちは畳み込みがないので余裕でOKかと思いきや、

ma.lisp

defpackage "MA" ( :use :cl ) (cl:in-package "MA") (defun barp (x) (eq 'Bar x)) (defun bazp (x) (eq '|Baz| x))

エスケープが無視されてしまうようです。

まあ、mlispで、 FooBar を |FooBar| と書く人もいなさそうなので致し方ないのでしょうか。

まとめ

以上、mlispでの in-case-mode について書いてみました。

要約すると、ANS準拠派の人は、mlispのことは一切考えなくても良いということです。

また、mlispの人も、Quicklispに収録のライブラリでもソースコードを手動で修正したりせずに、ANSで書いた人の意図通りに読み込めると思われます。

(具体的には、quicklisp/asdfを利用しているなら、コンパイル/ロード時に (in-case-mode :common) のフックが掛かるようにすればOK)

ちなみに、mlisp用に手動でちょこちょこ直すという話は、割合と世界的なものな気はします。

例えば、 defpackage でのパッケージ名を #:foo のように書くのはmlispフレンドリーになるから良い、というようなものですが、mlisp側で吸収する仕組みがある以上、ANSで書いてる人は、そんなことは気にする必要はなく、この豆知識は放棄した方が良いと思います。

また、mlispはけしからん、という話もFranzが頑に対応していないなら兎も角、mlisp側に吸収する仕組みを用意しているからには、規格から外れた方が遵守の方に合せるという姿勢はあるように思えます。

■

