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-12-18

祝Pitmanual改訂版発表ということでdesetqをつくってみる

| 03:23 | 祝Pitmanual改訂版発表ということでdesetqをつくってみる - わだばLisperになる を含むブックマーク はてなブックマーク - 祝Pitmanual改訂版発表ということでdesetqをつくってみる - わだばLisperになる

どうしてなのかは知りませんが、急に12/16日の日曜日にMacLISPのマニュアルの改訂版(The Revised Maclisp Manual (The Pitmanual))が発表されました。

結構前からMACLISP infoというサイトはありまして、Maclispの情報が纏められるサイト予定地ということだったんですが、ずっとコンテンツは不在でした。

作者のKent M. Pitman氏は特にどっかに完成を発表したという訳でもないようでcomp.lang.lispにタレこみがあって初めて周知された様子。

しかし、仕上がりは結構気合いが入っていて、原稿をHTMLに直しただけでは全然なく、Common Lispとの比較や現在の視点からの考察が加えられています。

需要と供給のバランスからすれば、かなりの過剰供給っぷり。

製作には、奥さんと娘さんと本人が当たったということで、これまた不思議な家族。

ということで、なんとなく記念にMaclispのdesetqを作って遊んでみることにしました。

こないだ、Maclispのletの分割代入版を作ったときに、desetqも作ろうと思っていたのですが、こっちは放置してました。

desetqは、setqに分割代入機能が付いたものでPitmanualでの解説はThe Pitmanual: Control Formsです。

Pitman+Manualで、Pitmanual、これの前のDavid Moon氏が作ったのは、Moonualと呼ばれていたとのことで、その辺の文化を継承してるみたいです。

動作としては、

(let ((a 1) (b 2) (c 3) (d 4) (e 5) (f 6))
  (desetq (((a) b . c) d e f)  (list (list* (list a) b c) d e f) )
  (list a b c d e f))
;==> (1 2 3 4 5 6)

という感じになります。

(defmacro desetq (&rest bind-specs)
  (unless (evenp (length bind-specs))
    (error "Too many arguments in form ~S." bind-specs))
  (do ((l bind-specs (cddr l)) 
       body vars)
      ((endp l) `((lambda ,vars ,@body) ,@(mapcar (constantly ()) vars)))
    (let ((var (car l)) (val (cadr l)))
      (if (consp var)
	  (let ((tem (gensym)))
	    (multiple-value-bind (varlist vallist) (des- var tem)
	      (setq vars `(,@vallist ,@vars ,tem))
	      (setq body `(,@body (setq ,tem ,val) ,@varlist))))
	  (setq body `(,@body (setq ,var ,val)))))))

(defun des- (bind sym)
  (let (vars)
    (values 
     (labels ((frob (bind sym)
		(cond ((null bind) nil)	
		      ((atom bind)
		       `((setq  ,bind ,sym)))
		      ((null (car bind))
		       `((setq ,sym (cdr ,sym))
			 ,@(frob (cdr bind) sym)))
		      ((and (atom (car bind)) (null (cdr bind)))
		       `((setq ,(car bind) (car ,sym)))) ;last -1
		      ((atom (car bind))
		       `((setq ,(car bind) (car ,sym))
			 (setq ,sym (cdr ,sym))
			 ,@(frob (cdr bind) sym)))
		      ('T (let ((carcons (gensym)))
			    (push carcons vars)
			    `((setq ,carcons (car ,sym))
			      ,@(frob (car bind) carcons)
			      (setq ,sym (cdr ,sym))
			      ,@(frob (cdr bind) sym)))))))
       (frob bind sym))
     vars)))

  • 動作
(desetq (((a) b . c) d e f)  (list (list* (list a) b c) d e f))
;==>

((LAMBDA (#:G2 #:G1 #:G0)
   (SETQ #:G0 (LIST (LIST* (LIST A) B C) D E F))
   (SETQ #:G1 (CAR #:G0))
   (SETQ #:G2 (CAR #:G1))
   (SETQ A (CAR #:G2))
   (SETQ #:G1 (CDR #:G1))
   (SETQ B (CAR #:G1))
   (SETQ #:G1 (CDR #:G1))
   (SETQ C #:G1)
   (SETQ #:G0 (CDR #:G0))
   (SETQ D (CAR #:G0))
   (SETQ #:G0 (CDR #:G0))
   (SETQ E (CAR #:G0))
   (SETQ #:G0 (CDR #:G0))
   (SETQ F (CAR #:G0)))
 NIL NIL NIL)

と展開されます。

オリジナルのものはもうすこし綺麗に展開されるのですが、若干面倒なので、これで良しとしました。

Practical Common Lisp (10)

| 23:11 | Practical Common Lisp (10) - わだばLisperになる を含むブックマーク はてなブックマーク - Practical Common Lisp (10) - わだばLisperになる

引き続きPractical Common Lisp 第4章4. Syntax and Semanticsを読んでメモしてみています。文字ばっかりだと、英語が苦手な自分には何だか良く分かりません…。とりあえず、ウェブ翻訳で訳したりして適当に妄想してるメモになっております。

Breaking Open the Black Box

  • Lispの文法と意味論の詳細に立ち入る前に他の言語とはどういったところが違うのかを考察してみる。
  • 殆どの言語の処理系(コンパイラ、インタプリタ共に)はブラックボックスのようなものになっている。ユーザはテキストをそれに読み込ませて結果を受けとる。
  • ブラックボックスの詳細に立ち入るならば、もちろん沢山のパートに分けられる。字句解析や用いられるデータ構造等様々あるが、ブラックボックスたる所以は、その構造や機構が専らブラックボックス内部の処理プロセスで用いられるのみで、それ自体は、処理系製作者向けのものといった感じになっているところ。
  • Common Lispはちょっと違っていて、どう処理系を実装するかと、どう言語が定義されるかの二つが考慮された帰結として、一つのブラックボックスで処理されるのではなくて、二つのブラックボックスで二段階に処理される。テキストをLispのオブジェクトに変換するリーダが最初のもので、それを評価する評価器がそれに続く。
  • リーダは文字列をLispオブジェクトたるS式への変換を担当する。Lisp以外の言語でいうと処理系内部での構文木の生成にあたる。
  • 評価器は構築されたS式からLispの文法を定める。S式が全部正しいLispオブジェクトという訳ではない、例えば、(foo 1 2)、("foo" 1 2)は共にS式としては正しいが、Lispのフォームとしては、最初が文字列のリストはLispフォームとして意味を成していない。
  • ということで、リーダがどのようにS式を組み立てるか、と、評価器がどのように式を評価するのかの二つに焦点を当てて考察したい。