Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2007-10-03

BIND-LET (Maclisp/LET.LSP)

| 14:33 | BIND-LET (Maclisp/LET.LSP) - わだばLisperになる を含むブックマーク はてなブックマーク - BIND-LET (Maclisp/LET.LSP) - わだばLisperになる

今回は、MaclispのLET.LSPのBIND-LETをお題にしてみました。

これも大体30年位前のコードです。

お題:

(macro BIND-LET (x)
   ((lambda (ll w vars vals)
	    (do ((l ll (cdr l)))
		((null l))
		(push (cond ((atom (car l)) (push () vals) (car l))
			    ('T (push (cadar l) vals) (caar l)))
		      vars))
	    `((LAMBDA (,.(nreverse vars)) ,.w) ,.(nreverse vals)))
       (cadr x) (cddr x) () () ))

初見時の感想:

  • macroの動作は多分、
(defmacro macro (name (arg) &body body)
  `(defmacro ,name (&whole ,arg &rest bvl-decls-and-body)
     (declare (ignore bvl-decls-and-body))
     ,@body))

のようなものだと思う。

再現:

(defmacro BIND-LET (binds &body body)
  ((lambda (ll w vars vals)
     (do ((l ll (cdr l)))
	 ((endp l))
       (push (cond ((atom (car l)) (push () vals) (car l))
		   ('T (push (cadar l) vals) (caar l)))
	     vars))
     `((lambda (,.(nreverse vars)) ,.w) ,.(nreverse vals)))
   binds body () () ))

感想:

macroの個所をdefmacroに読み替えて再現してみました。

bind-letは要するに普通のletでした。

マクロの中で、letの代わりにlambdaを使って変数を束縛するというのも、場合によってはありなのかもしれないと思ったり。まあ、今回の場合は、letが無い環境なので、lambdaを使っているわけではありますが…。

技法的なこと:

(push (cond ((atom (car l)) (push () vals) (car l))
            ('T (push (cadar l) vals) (caar l)))
      vars)

pushを入れ子にすることで、atomかどうかの判定を一回にまとめている。

どうでも良いこと:

  • 「condのelse節のtは、大文字にしてクオートを付ける」派
  • 「nilも'()も、とにかく()と書く」派