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-05-21

TAOの!!

| 01:53 | TAOの!! - わだばLisperになる を含むブックマーク はてなブックマーク - TAOの!! - わだばLisperになる

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))

ゲスト



トラックバック - http://cadr.g.hatena.ne.jp/g000001/20070521