Lispと一緒(20) ラズパイPico2でもuLisp、Macroはどこ?

Joseph Halfmoon

Common Lispの系譜を継ぐマイコン上のuLispをラズパイPico2上で練習中。今回はCommon LispとuLispの大きな違いの一つ、マクロについて調べてみます。Lispの中には、関数、マクロ、スペシャルフォームなどあり、その挙動が異なります。しかし、どうもuLispにはマクロはないみたい。

※Lispと一緒 投稿順 index はこちら

※実機確認は Raspberry Pi Pico2で行ってます。

※使用させていただいとります uLisp のバージョンは 4.6b (Arm用)です。

※uLispとCommon Lispとの動作比較のために使わせていただいている処理系は以下です。

SBCL 2.2.2  (SBCL =  Steel Bank Common Lisp )

関数、マクロ、スペシャルフォーム

カッコで括られた( )の中に、最初に書いたお名前が、いつも関数名だと思うとさにあらず、以下の種別があり~の。

    1. 関数
    2. マクロ
    3. スペシャルフォーム(Special form)

上記のものどもの挙動の差については、Lisp素人のお惚け老人は詳しい思想を述べられませぬ。各種Lispの文献等をご参照くだされ。お惚け老人の理解では、関数に渡された引数共を先に評価してもらってから受け取る関数、とりあえずS式のまま受け取って、マクロの中の構造に埋め込んでから評価するマクロ、という感じっすかね。スペシャルフォームはその中間で如何ようにも自由に処理することが可能だと。ここでまず重要なのは、

    • Lispの世界の中で、関数とマクロは自前定義できる(Common Lispでは。)
    • スペシャルフォームは、Lispの世界の外、多分Cのソースをいじらんと新設不能。

ということであります。

しかし、uLispの場合、規模の小さなマイコンメモリに押し込むためなのか、

defmacro

という「マクロ」を欠いているようです。マクロを定義するためのマクロね。実際 defmacro と打ち込んでみたけどundefined とか言われて怒られました。

しかし、「よくつかう」ものどもの中にもマクロはいます。いつもお世話になっている、関数定義するときに使う defun とか、変数定義の defvar などもマクロですぜ(Common Lispでは。)

uLispの場合、Common Lispでマクロとして定義されているものどもの多くは

スペシャルフォーム

ということで実装しているみたいです。つまり新たな自前のマクロを定義するためのマクロは欠いているけれども、よく使うマクロどもには同名のスパシャルフォームがあると。さらにいうと、普通のスペシャルフォーム以外に、

Tail-recursive form

というお名前のスペシャルフォームの分家?もあるみたい。知らんけど。

uLispでの実装

以下は、Arm用の uLisp 4.6b でスペシャルフォーム、SP(およびTail-recursive form、TF)として実装されているものどもがCommon Lisp上でどう扱われているのかを列挙してみた表なんであります。作成には結構苦労したのよ。

name Common Lisp uLisp
progn Special Form TF
if Special Form TF
cond Macro TF
when Macro TF
unless Macro TF
case Macro TF
and Macro TF
or Macro SP
decf Macro SP
defun Macro SP
defvar Macro SP
do Macro SP
do* Macro SP
dolist Macro SP
dotimes Macro SP
error Function SP
help Function SP
incf Macro SP
let Special Form Built-in
let* Special Form Built-in
loop Macro SP
pop Macro SP
push Macro SP
quote Special Form SP
setf Macro SP
setq Special Form SP
time Macro SP
trace Macro SP
untrace Macro SP
with-output-to-string Macro SP

上記以外にも、ハードウエア制御などのための uLisp 特有のスペシャルフォームなども多数あり。そのあたりは今回パスということで。

なお、みんな大好き let と let* ですが、ソース上ではビルトインのキーワード枠で、eval処理の内側に隠れていたので独立したスペシャルフォームとか関数にはなっておりませなんだ。結構、奥が深いなuLisp。。。

Lispと一緒(19) ラズパイPico2でもuLisp、list関連関数 へ戻る

Lispと一緒(21) ラズパイPico2でもuLisp、マクロでない者共 へ進む