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 |
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-05-21
TAOの!!
Lispの問題集を解くのも行き詰まって来てしまったので、何か他のことをしようと思い立ち、関数やマクロを組んで遊んでみることにした。
ちょっと変ったところということで、マニュアルが公開されているマルチパラダイムなTAO Lispの関数を真似てつくってみることに。
色々変った関数があるけれども、今回は、自己代入式の`!!'を真似てみる。
C等の、i++とか、i += 2などに該当するのだろうか。
http://www.nue.org/nue/tao-manual/tao-0.txt:マニュアルを眺める限りでは、
(!!cons !x y)
のように使用し、
(setq x (cons x y))
の結果と同じ様子。
!がついた変数に式の結果が代入されることになるらしい。
色々考えてみたけれど、マークを付ける方法が思い付かなかったので、selfというquoteの別名マクロを作成して、自己代入式のマクロで展開される際にcarがselfかどうかで判断してみることにした。
そして、TAOでは、!!や、!を使用しているけれども、リーダーマクロをどういう風に組んだら実現できるのか、さっり検討も付かず、また、!や、!!を使うと、通常の環境に影響するので、'!!'は'☺'で'!'は'☞'という風にUnicodeで一文字のリーダーマクロにしてみた。
(let ((a '(1 2 3) ) (b '(a b c))) (☺cons ☞a b) (values a b)) => ((1 2 3) a b c), (a b c) (let ((a '(1 2 3) ) (b '(a b c))) (☺append ☞a b) (values a b)) => (1 2 3 a b c), (a b c) (let ((i 64) ) (☺1+ ☞i)) => 65 (let ((i 11) (j 22) ) (☺(lambda(m n) (* n m 33)) ☞i j) (values i j)) =>7986, 22 (let ((i '(4 64 8 77) ) (j '(77 1 1024 4))) (☺(lambda(l m) (remove-duplicates `(,@l ,@m))) ☞i j) (values i j)) => (64 8 77 1 1024 4), (77 1 1024 4)
という感じ。
(defmacro self (var) `(quote ,var)) (defmacro selfass (fn &rest args) "<説明> 形式 : (!!func arg1 arg2 ... !argI ... argN) 上式は (setq argI (func arg1 arg2 ... argI ... argN)) と同じ。 自己代入式を作る。関数 func を arg1 ... argN を引数として実行し、 結果を argI に代入する。" (let ((self (dolist (item args) (and (listp item) (eq 'self (car item)) (return (cadr item))))) (vars (mapcar #'(lambda (item) (if (and (listp item) (eq 'self (car item))) (cadr item) item)) args))) `(setf ,self (,fn ,@vars)))) (set-macro-character #\☞ #'(lambda (stream char) (declare (ignore char)) (list 'self (read stream t nil t)))) (set-macro-character #\☺ #'(lambda (stream char) (declare (ignore char)) 'selfass))
コメントを書く