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

祝Multics Emacsのソース公開

| 04:56 | 祝Multics Emacsのソース公開 - わだばLisperになる を含むブックマーク はてなブックマーク - 祝Multics Emacsのソース公開 - わだばLisperになる

Multicsのソースが公開されたとのことで、Multicsといえば、PDP-10以外でMaclispが稼働していたプラットホームになります。

それと、有名?なところでは、Multics Emacsがあり、Maclispで書かれていて、そのMaclisp自体で拡張可能だったところが画期的だったとEmacsの歴史が語られる際には良く出てきます。

確か未だにMulticsは稼働するエミュレータがなかったと思いますがこれを機にMultics周辺が盛り上がって、エミュレータが動くようになると楽しいなと思います。

ということで、Multics Emacsのソースとか、Maclispのソースを探してみましたが、どっちも公開されていたので、若干無理矢理ながらMultics Emacsのコードをお題にしてみたいと思います。

ここのソースのe_~とか、emacs_~がEmacsのソースっぽいです。

今回のお題は、emacros_.listから抜き出していて、眺めた感じでは、A product of Greenberg, 3/78という記載があるので、1978年の3月に最初のバージョンが完成したようです。

お題

Multics-Emacs-if

暗記で再現

(defmacro Multics-Emacs-if (condition &body forms)
  (do (ifs
       elses
       (l forms (cdr l)))
      ((endp l)
       (cond (elses `(cond (,condition .,(nreverse ifs))
			   ('T .,(nreverse elses))))
	     ('T `(cond (,condition .,(nreverse ifs))))))
    (let ((form (car l)))
      (cond ((eq 'else form)
	     (setq elses (list nil )))
	    (elses (push form elses))
	    ('T (push form ifs))))))

できた。ifでelseというキーワードが使いたかったらしく、拡張したマクロ。Multics Emacsでは、これがifという名前で使えたようです。

then節もelse節も暗黙のprognになっています。else節には、毎回nilが先頭に来ますが結果に影響はないので、良いのでしょう。

また、マクロの中で、,@ではなくて、.,と書かれていますが、'(foo . (bar) ) => '(foo bar)ということでこういう風に書いているのでしょう。また、ドットとコンマの間に空白文字があってもなくてもOKなのでくっつけて書いているのでしょう。

Multics Emacsでは、全般的に,@ではなくて、.,を使うスタイルのようです。順番が逆の,.もあったりして色々紛らわしいです(*'-')

;; 動作
(multics-emacs-if (= 6 (+ 3 3))
  "おそらく3 + 3は"
  "6という結果になるに違いない"
  else
  "3 + 3が6以外になるなんて"
  "コンピュータは壊れているに違いない")
;=> "6という結果になるに違いない"

お題

do-times

(defmacro do-times (howmany &body forms)
	(let ((dovar (gensym)))
	     `(do ,dovar ,howmany (1- ,dovar) (< ,dovar 1)
		. ,forms)))

暗記で再現

(defmacro do-times (howmany &body forms)
  (let ((dovar (gensym)))
    `(do ((,dovar ,howmany (1- ,dovar)))
	 ((< ,dovar 1))
       . ,forms)))

できた。シンプルなdotimesといった感じ。オリジナルdoの書式が何だか変ですが、これはdoの一番古い形式なので、Common Lispの形式に変更しました。Common Lispで使われる形式は、2番目のパターンで、Maclispには、全部で3パターンの形式があります。

;; 動作
(do-times 5
  (print "Hello"))
;=> Hello
;Hello
;Hello
;Hello
;Hello

お題

do-forever

暗記で再現

(defmacro do-forever (&body forms)
  `(do () (nil) . ,forms))

できた。do-foreverは、多分LispMに由来するマクロ。Zetalispには、do-foreverが標準で存在しています。名前の通り本体部を繰り返すだけのもの。

;; 動作
(do-forever
  (print "hello")
  (return t))
; => "hello"

お題

(defmacro with-mark (mark &body forms)
	`(let ((,mark nil))
	      (unwind-protect
	        (progn (setq ,mark (set-mark))
		     . ,forms)
	        (and ,mark (release-mark ,mark)))))

暗記で再現:間違えた

(defmacro with-mark (&body forms)
  (let ((mark (gensym)))
    `(unwind-protect 
	  (progn (setq ,mark (set-mark))
		 . ,forms)
       (progn (setq ,mark (release-mark))))))

;; でっちあげ関数
(defun set-mark ()
  (random 1))

(defmacro release-mark (mark) 
  `(setq ,mark nil))

間違えた。save-excursionを読むため補助関数を先に。

markにはgensymを入れるわけではなく、全体の動きも把握できていなかった。

ポイント位置においてのletのようなものだろうか。

お題

save-excursion

(defmacro save-excursion (&body forms)
       (let ((mark (gensym)))
	  `(with-mark ,mark
		    (unwind-protect
		      (progn .,forms)
		      (go-to-mark ,mark)))))

暗記で再現:間違えた

(defmacro save-excursion (&body forms)
  (let ((mark (gensym)))
    `(unwind-protect 
	  `(with-mark ,mark
	     . ,forms
       (go-to-mark)))))

;; でっち上げ関数
(defun go-to-mark (mark)
  (format t "Go to ~A.~%" mark))

間違えた。全体の仕組を全然把握できてなかった。go-to-markはどこにカーソルを飛ばすのかな、などど悩みましたが、with-markとunwind-protectとの入れ子関係を間違ってただけでした。

Emacsでもお馴染みのsave-excursionがGNU Emacsより前からあったとは意外です。

;; 動作
(save-excursion
  (print "どうも")
  (print "こんにちは"))

;"どうも" 
;"こんにちは" Go to 0.

雑多なこと

save-excursionや現在でお馴染の関数が、かなりMultics Emacsに存在していたというのが意外でした。

非常にタイムリーですが、Multics Emacsに関連しては、最近ブログを始めた様子の、Dan Weinreb氏もエントリの中で言及しています。

このエントリは、RMSの講演の内容My Lisp Experiences and the Development of GNU Emacs- GNU Project - Free Software Foundationへの反論だそうで、内容は細かく色々ありますが、Multics Emacs関連ではLispで拡張できるEmacs系エディタとしては、Weinreb氏のLispM用のエディタ(ZWEI[最初は、EINE])が最初のもので、Multics Emacsではない、ということです。また、Emacsは、Guy Steel氏とDavid Moon氏が最初に作ったもので、RMSじゃない、とか。コメント欄で、Multics Emacsの作者Bernie Greenberg氏や、David Moon氏と思われるコメントもあるので、お好きな方はどうぞ…。

まあ、何にしろ、RMS抜きでは現在のEmacsは存在していないと思うし、今日のフリーソフトの盛況もなかったと思いますが…。

また、Lispで拡張できるEmacs系のエディタに関しては、Zmacs系と、GNU Emacs系があるように思います。コマンドの拡張方法や、バッファや行の表現方法等が違うので、この二つに大別できるような気がするのですが…。

  • Zmacs系
    • EINE、ZWEI、Zmacs
    • LispWorksのエディタ
    • Hemlock
    • Climacs(両者の中間っぽい?)
  • GNU Emacs系
    • Multics Emacs
    • GNU Emacs
    • Xyzzy

以上、細かい割には詳しく調べていないどうでも良い考察でした…。