Archive for 2010年7月21日|Daily archive page

newLISP で On Lisp する...第12章(番外編)

 前回の 第12章 汎変数(その1)から、いきなり、番外編です(笑)。
 さて、前回見たように、newLISP では、参照を返すマクロは作れませんでした。つまり、setf の汎変数に自作のマクロを適用できないということ。そこで、以前それを可能にするマクロを考えました。
 しかし、newLISP の進化はそれより早く、現在では、参照を返す記述が可能です。マクロではなく macro を使って。だから、番外編(笑)。

 前回記述したcontext 関連の参照を返すマクロ friend-of

(define-macro (friend-of)
  (letex (_p  (args 0)
          _q  (args 1))
       ((*friends* _p) _q)))

 を macro にします。

(module "macro.lsp")
(macro (friend-of P Q)
  ((*friends* P) Q))

 あとは、前回使った toggle を用意して、

(define-macro (toggle)
  (letex (_obj (args 0))
    (setf _obj (not $it))))

 データを定義します。

> (new Tree '*friends*)
*friends*
> (*friends* "marry" (new Tree 'marry.*friends*))
marry.*friends*
> ((*friends* "marry") "john"  true)
true
> ((*friends* "marry") "john")
true
> (setf ((*friends* "marry") "john" ) nil)
nil
> ((*friends* "marry") "john")
nil
> (toggle ((*friends* "marry") "john"))
true
> ((*friends* "marry") "john")
true
> (gethash "john" (gethash "marry" *friends*))
true
> 

 ここまでは、前回と同じ。これで、動作確認の準備完了です。
 macro の friend-of を試します。

> toggle
(lambda-macro () 
 (letex (_obj (args 0)) (setf _obj (not $it))))
> friend-of
(lambda-macro (P Q) (expand '((*friends* P) Q)))
> (toggle (friend-of "marry" "john"))
nil
> (friend-of "marry" "john")
nil
> (setf (friend-of "marry" "john") true)
true
> (friend-of "marry" "john")
true
> 

 といった感じで、違和感なく使えます(笑)。もちろん、macro ならではの制限もありますが(汗)、toggle と friend-of を直行的に使えます。(もちろん、setf とも)

 newLISP では、macro を使って、プログラムを "見事にモジュール化され、なおかつ美しくエレガント" にできるというわけです。

 これで、前回の問題点は、クリアされました。次回は再び、第12章 汎変数(その1)に戻ります。

 以上、如何でしょうか?

広告