BOA Lambda List の謎 — #:g1

Posted 2011-12-06 05:42:00 GMT

前回&AUXの謎を無駄に掘り下げてみましたが、defustructのBOA Lambda Listはどんな経緯で登場したのかは謎でした。今回は、これを掘り下げてみたいと思います。
まず、defstructの登場時期ですが、結構古く、1973年位のようです。具体的な文献がないのでなんともいえないのですが、Lispマシンで実装されていたのが最初で、後にMacLISPにバックポートされています。
Coders at workでもお馴染のL. Peter Deutsch氏によって書かれたLispマシン登場のきっかけとなったA LISP Machine with Very Compact Programsという論文がありますが、defstructとsetfも含めてこのアイデアを実現したものではないかなと思います
それはさておき、とりあえず、Lispマシンのマニュアルを遡っていくと、BOA Lambda Listの記述は、1981年の第3版にはありますが、1979年の第2版にはないので、この辺りに追加された様です。
少し違っているのは、Lispマシンの時代からCLtL2までは、BOA(by order of argument) Constructorではなく、By-Position Constructorと呼ばれているというところ。

これらは、Lispマシンの時代からあまり変化はなく、大体同じなのですが、&AUXの初期値を設定しなかった場合、LispマシンとCLtL2では未定義でしたが、HyperSpecでは処理系依存に変っています。
実際SBCLで試してみましたが、
(defstruct (hs (:constructor create-hs (a &optional b (c 'sea)
                                          &key (d 2)
                                          &aux e (f 'eff))))
  a b c d e f)

(create-hs :a) ;=> #S(HS :A :A :B NIL :C SEA :D 2 :E 0 :F EFF)

のように、:Eの値がどこから来たのか謎の0になっています(make-arrayのデフォルトの要素を指定しなかった場合の初期値が処理系依存というのと合せているのかもしれません)

いつ導入されたかの話に戻ると、マニュアルの年代からして1980位の出来事らしいということで、その辺りのメールをつらつら眺めてみたところ、Alan Bawden氏のこんなメールを発見しました。
ALAN@MIT-MC 08/23/80 04:45:16 Re: defstruct query
To: INFO-LISPM at MIT-MC
(Sorry about the empty message I just sent to you all, but this
keyboard has a key labeled "CALL" in the upper right corner that sends
a control-C.)

Does anyone use the obscure feature of defstruct where if you say:

(defstruct (foo) ((mumble 1010 234 (mumble-a mumble-b mumble-c))))

defstruct expands into code including:

(setq mumble-a 0 mumble-b 1 mumble-c 2)

???

I would like to flush this bit of syntax in favor of allowing a keyword options list in each slot (so you can specify type information etc. in an entendable way). I can still support the feature if anyone really insists, but it would be nice in any case if they could be convinced to convert their defstructs to a new format.

(I suspect there may be a better way of solving whatever problem this feature is addressing anyway, so I would like to hear from whoever is using it.)

当時のdefstructの実装は、内部のベクタも色々いじれるようになっていたのですが、書法が直感的でないので書き直したいというような提案です。
古いバージョンのdefstructもBawden氏が作っているのでdefstruct担当というところだったのかもしれません。そして、この提案の3ヶ月後には、どうやら取り込まれたようです。
Date:  7 DEC 1980 0348-EST
From: MOON5 at MIT-AI (David A. Moon)
Subject: New version of DEFSTRUCT installed
To: INFO-LISPM at MIT-AI

System 51.2 installs a new version of DEFSTRUCT (Alan Bawden's). It is supposed to be compatible; if there are any problems please report them. Documentation on the many new features available forthcoming shortly.

この辺りのソースを眺めてみましたが、この時に初期化の際に&AUXを使うという仕組みがはいったようでドキュメントストリングに、
:CONSTRUCTOR defaults to /"MAKE-/"
  More than one constructor may be specified. The syntax for defining a constructor is
  either: (:CONSTRUCTOR  [doc-string]) or (:CONSTRUCTOR   [doc-string])
  If no arglist is supplied, a constructor is defined which takes alternating slotnames
   and values (ie uses &KEY) as arguments and initializes those slots to those values.
  If an arglist is supplied, then the constructor defined will have this as its arglist.
   Meaningful lambda-list-keywords are &OPTIONAL &REST and &AUX.
   Use &AUX to initialize a slot to a value other then the usual default value.
という記述も現われます。

以上、この2エントリーで、&AUXとLETの歴史を眺めてみましたが、
  1. 1976: MDLからlambdaリストとして&AUXも輸入される
  2. 1976〜1978?: LETのフォーマットが確定して使われ始める
  3. 1980: defstructでも&AUXを利用するようになる
  4. 1982?: その後のCLに取り込まれる
という順番のようです。
そして、何故BOA Lamabda listのような仕組みで初期化することになったのかということに関しては、Bawden氏がこういう風に実装して、割と上手くはまったから以上の理由は特になさそうです。
また、CLに導入された時に、何故もっと分かり易いインターフェイスにしなかったのかということになると、恐らく過去との互換性を取ったということなのではないかと思います。 ■

comments powered by Disqus