Common Lispの系譜を継ぐマイコン上のuLispをラズパイPico2上で練習中。今回は配列、arrayを練習してみます。今回はCommon LispとuLispの差というより、処理系依存な部分がちょいと見えましたかな。まあ、注意してたらその差は見えないような使い方は十分できそうな気がするけど(個人の感想デス。)
※Lispと一緒 投稿順 index はこちら
※実機確認は Raspberry Pi Pico2で行ってます。
※使用させていただいとります uLisp のバージョンは 4.6b (Arm用)です。
※uLispとCommon Lispとの動作比較のために使わせていただいている処理系は以下です。
SBCL 2.2.2 (SBCL = Steel Bank Common Lisp )
配列関係系の関数
今回練習してみるのは以下の関数どもです。
-
- make-array、配列を生成する。
- aref、配列から読み出す。配列に書き込む先の「場所」を示す。
- arrayp、配列であれば真。
- array-dimensions、配列の次元を返す。
uLispに存在しない関数は見て見ぬ振りをしてます。
配列を生成
配列は以下のようにべたな定数で書きあげても良いみたいです。
#2A((1 2 3) (4 5 6))
頭の#2Aは、2行3列の配列の「2行」の部分を示しているとか、いないとか。
ただし、大きな配列を手書きで書ききるのはメンドイので、配列を生成するための関数が存在します。make-array とな。まずは Common Lisp(SBCL 2.2.2)上でmake-arrayしてみた結果が以下に。
上下の結果で差が見えてますが、今回の差は Common LispとuLispの差ではなく、Common Lispの実装の一つである SBCL と uLisp の差というべきみたいです。SBCLは、初期化値を無指定のまま配列を作った場合に「0」を詰めてくれるみたいです。一方、uLisp では nil です。Common Lispでも nil な流儀のものはあるみたい。知らんけど。
それにしても、ビット・ベクタを生成しているケース、Common Lispでは動くに決まっているけれども、uLisp でも動いてしまいました。uLisp、意外に強い?
配列要素へのアクセス
Common Lispの場合、以下のようにして生成した配列を変数 a0 に紐づけることが可能です。
(setq a0 (make-array 3 :initial-element 1))
ただし、過去回でもやったとおり、未定義の変数 a0 に setq するのは、お作法ではマズイ行動みたいです。まあ、Common Lispは懐が深い?ので許してくれるみたいですが。未定義変数に対しては以下のようにdefvar するのがお作法にかなっているみたいです。
(defvar a0 (make-array 3 :initial-element 1))
そして、uLispの場合、defvar でないとエラーになります。
a0に格納されている配列の要素へ読み書きするケース。まずはCommon Lisp。配列要素からの読み出しは良いですが、書き込みの setf で警告が出ている(しかし書き替えは上手くいっているみたい)のは、もしかするとMaxima様からSBCLを呼び出しているがためのローカルな問題じゃないかと思います。
先ほど述べたように、直接 setq するなどという無作法を uLisp は許してくれませぬ。defvarすれば、こちらは何の警告もなく、要素の読み出し、書き込みともに成功しております。
配列の大きさを知る
細かくて伝わらないかもしれない差はあるものの、まあ、フツーに配列使えるんでないの?ホントか?