ryos36の日記 (Scheme Switch)

2008-01-27

cl-ppcre

00:32

つかってみる。lisp ぽくないきもするが便利。

clisp

00:32

sbclasdf がはじめから入っているのでらく。しかし、取り扱いは clisp の方が楽。readlineラッパーをつかえば sbcl も快適になるかもしれない。それより slime 入れたほうがいいのか?

まぁとにかく clispcl-ppcre を使いたい。

(load "/usr/local/lib/common-lisp/asdf/asdf.lisp")

いくつかのウェブページに path-to-asdf.lisp という記述があるがどうやら間違い。/path/to/asdf.lisp という最初の記述が誤って伝播している模様だ。

FreeBSD で (asdf:oos 'asdf:load-op 'cl-ppcre) としてもエラーになる。どうやら cl-ppcre/load.lisp 内のppcre-tests がインストールされてない模様。tests はなくてもよさそうなので、load.lisp から削除し、毎回コンパイルされるのもいやなので root で一度ロードしてコンパイルしておいた。

core のロードセーブ

00:32

sbcl で毎回 cl-ppcre をロードすると遅い。core を作ることで劇的(というほどでもないか)に早くなった。

(progn
  (require :asdf)
  (require :asdf-install)
  (require :sb-sprof)

  (require :cl-ppcre)

  (pushnew :michaelw-core *features*)
  (save-lisp-and-die "/tmp/test.core"))

clisp では

(ext:saveinitmem "lispinit.mem")

cl-ppcre を予め core に登録したかったので

(asdf:oos 'asdf:load-op 'cl-ppcre)
(ext:saveinitmem "lispinit.mem")

実行は lisp -M lispinit.mem か --norc をつける。わたしは -E EUC-JP -q もつけている。

コアのセーブとか SmallTalk みたいだな。

おまけ

(setf *tp* "\\[\\[([^\\[\\]]+)\\]\\]")

(defun my-make-list (str &optional (i 0) (lst nil) &key (test *tp*))
  (multiple-value-bind (starti endi sub) (scan test str :start i)
    (if (null starti)
      (nreverse lst)
      (progn
        (setf lst (cons (list starti endi (subseq str (+ starti 2) (- endi 2)))
lst))
        (my-make-list str endi lst)))))

2008-01-24

hunchentoot 再び

01:37

意外によい。誰だか知らんが、アクセスもある。

どこがいいか?

allegro もそうだが、HTMLlisp が完全に融合しているのがよい。

その昔、Servlet を始めてさわって(あるいは perlcgi 書いて)、ウワーなんだと思ったことがあった。print で HTML を生成しなければならない。仕方がないんで、HTML の雛形を作って、パターンマッチングさせて埋め込んだ覚えがある。ちゃんと HTML を解析してないから(誰か悪い?わたし)、かなりごまかしっぽい。

つぎに JSP をさわったとき、オー素晴らしいと思ったが、結局 HTML とごちゃまぜになる。だめだーこりゃと。そこで、tag を自分で一生懸命作った。公開してメジャーかすればよかったな。今思えば。で悲惨な tag が一杯出来て、こりゃだめだと。

しりあいがうまく ServletJSP を組み合わせてプログラミングしているのを見て(自分で考えろ!!といいたい気もするが)、オーなるほどこの手があったかと。これと標準のタグを組み合わせると結構使える。いける。う~ん、でもページ遷移が難しい。

ページの遷移は Struts で出来る。おおすごい。web.xml に書けば、サーブレットの開発もいらないじゃないか。遷移は XML か、、、オーすごい。しかし、確認までが重い。開発が進まない。ここまで重く設計する必要があるのだろうか?というところでストップ。その後の Java の成長にはついって行っていない。Struts も新しくなっているようなので、Eclipse と組み合わせるとよい開発環境が出来るのでしょう。(きっと)。でもなんか興味なくなった。重すぎるから。

そこで、Phython, PHP, ときて結局 Perl の MAISON に戻ってきた。Ruby on Rails は本買っただけ。どれもこれもだめだ。もーウェブ開発なんてやめた。と思っていたところに LispFastCGI が出来ることを発見した。その後、停滞気味だったが、ここにきて allegro server を動かしてみてこれはいけると思った。

しかし、、、Allegro Server は高い。あーこういう商売していたから、Web の大きなパイを見逃したんだな、、、と思った。簡単に言ってしまえば、大型コンピュータ時代の発想から抜けていない(プログラムがという意味ではなく、商売の姿勢として)。Lisp Works もそれに近いかな。が、どちらも FreeBSD をサポートしていることは大きく評価したい。まぁ、分野が違うんだろうな。そういう商売ということ。

そういう意味で gauche にはがんばって欲しい。そこがスキマだからね。

できれば、with-html-output のような形式で互換性がある世界があるといい。

5年後には Lisp の時代が来るぞ。(あったためしなし。Smalltalk-80 不発。Objective-c 不発。Apple Script, Script-X 不発。Bento (Open なんとか) 不発。ついでに書くと OS/2 も不発。FreeBSD は不発じゃないけど Linux に抜かれた)

ついでに書くと JavaScript と XML の組み合わせは早くから知っていたが、こんなにはやるとは思わなかった。じゃ、SVG はこれでいくのか、、、と思ったけどいかなかった。今後、SVG は携帯電話に入っていくのだろうか?

SICP はどうした?

01:37

再度読んだ。非決定性はいいね。あれは prologue なのか?数式の証明とか出来そう。しかし、あそこで語っている本質はそこじゃないと思う。(そこかもしれないけど、、、)

Prologue 的なルールを入力したら、それで生成できるパターンの一覧を出すなんて言語があればかなり有用だ。これはこれでアイデアをとっておいてと。(そういう要求は顧客からあるのだ。そしてその多くはコンピュータを知らない人。このパターンいくつあると思っているの?とか、これとこれが矛盾するでしょとか。説明するのに相当骨が折れる)

まだ、はっきりしたことは言えないが(違ってるかもしれない)、あそこでやっている解析と評価の分離は中間言語をつくっているということではないだろうか?中間言語というと VM を思い浮かべるが、そんな高級なものではなく、昔懐かしい、Basic中間言語みたいな感じ。N88-Basic とかは打ち込むと中間言語で記憶していたじゃないか。

でメモリをのぞいてぐちゃぐちゃ弄り回したりしてね。(どうでもいいか)

まだ結論は出ていないが、あそこで書かれていることは、中間言語の親戚だと思う。(恐らく作った人はそう思っていない。あるいは言及されていないだけか?読み落としているだけか、、、弱気だな)

言語プロセッサ

01:37

で、こっちの本もつまみ食い。学生のときに勉強した本を探してもう一度読んだりもする。今読むと、First とか Follow とかそう意味があったのか、、、、数学の式より Lisp で解説するほうが直感的じゃないか。

ついでに、「数学の限界」(だったかな?)も読む。あーわからない。これは Lisp か?

2008-01-19

hunchentoot

00:47

なんて読むんだ?Frank Zappa と関係あるかもしれない。

ここで書く hunchentoot は Common Lisp で書かれた http サーバ

軽くインストールしてみた。

http://tech.sinby.com/wiki_ja/index.php?hunchentoot

さらにいろいろ見ていくと、

(defmacro with-template (title user-details &body body)
  `(with-html-output-to-string (*standard-output*)
    (:html
     (:head (:title (fmt "Hunchentoot demo - ~a" ,title)))
     (:body (:h1 "Hunchentoot Demo")
            (:div (:a :href "/" "Menu") " - "
                  (:a :href "/events" "Events")
                  (if user-details
                      (htm " - " (:a :href "/logout" "Logout"))))
            ,@body))))

なる記述を発見。

http://myblog.rsynnott.com/2007/10/doing-more-with-hunchentoot-cl-server.html

AleglloServe に似ている?cl-who とか、html-template とかあるらしい。

資料が少なく、大変。

ソースを見ると port-acl.lisp, port-cmu.lisp port-sbcl.lisp とか、、、苦労してらっしゃる。

最近もアップデートしているので活発な開発をしているように思う。

いっちょのってみるかな。

2008-01-14

ちょっとたのまれごとでホームページを立ち上げることに、、、

http://www.sinchiba.com/touhougarou

lisp で書くのはどうだろう?

aserve は簡単そうだがユーザがなさそう。mod_lisp なんてのもあるみたいだが、、、あとどっかにテンプレートもあった。

2008-01-06

vim で lisp

10:52

vimlisp に対しても tag が使えることがわかった。[ [が出来るとなおいいが、、、

子供と一緒に common lisp

10:52

小学3年生の子供に lisp を教えることにした。さて、プログラマーとしての英才教育が出来るか?(なんちゃって)

SICP の5章

10:52

goto を実現するための習作

(defun jump-test (lst stack)
  (let ((one (car lst))
        (remain (cdr lst)))
    (format t "do ~a~%" one)
    (cond ((consp one) (cond ((eq (car one) 'goto) (gethash (cadr one) stack))
                             (t remain)))
          (t (setf (gethash one stack) remain)
             remain))))

(setf stack (make-hash-table))
(setf lst '(
            label
            (op something)
            (goto label)))

(setf lst (jump-test lst stack))
(format t "~a~%" stack)
(setf lst (jump-test lst stack))
(setf lst (jump-test lst stack))
(setf lst (jump-test lst stack))
(setf lst (jump-test lst stack))
(setf lst (jump-test lst stack))

一応動くぞ。 basic 位作れそうだな。

make-machine の習作

SICP のソースを見ずに作ったのでめちゃくちゃ。しかも中途半端。あくまで習作。

(defun niy (func) (error "NIY ~a" func))

(defstruct register-machine-instance
  regs
  opes
  controller)

(defun make-machine (regs opes controller)
  (let ((machine (make-register-machine-instance
                   :regs regs
                   :opes opes
                   :controller controller))
        )
    (let* (
           (eval-operand #'(lambda (operand)
                             (let ((s (car operand)))
                               (cond ((eq s 'regs) (gethash (cadr operand) regs)
)
                                     ((eq s 'const) (cadr operand))
                                     (t
                                       (assert (eq s 'op))
                                       (niy "eval-op"))))))

           (assign #'(lambda (regs-name operand)
                       (setf (gethash regs-name regs)
                         (funcall eval-operand operand)))))
      (let ((dispatch #'(lambda (m)
                          (cond ((eq m 'machine) machine)
                                (t nil)))))
        (funcall assign 'a '(const 33))
        (format t "eval ~a~%"
                (funcall eval-operand '(regs a)))
        dispatch))))
;--------------------------------------------------------------------------
(setf regs (make-hash-table))
(setf (gethash 'a regs) 4)
;(push 0 (gethash 'a regs))
(setf machine (make-machine regs nil nil))
(format t "~a~%" machine)
(format t "~a~%" (funcall machine 'machine))
(format t "~a~%" (eval-operand '(const 4)))

一応動いているようだが、、、SICP とは直接関係ない。

ついでに CLOS による習作

19:05

(defclass register-machine-instance()
  (
  regs
  opes
  controller))

(defmethod make-register ((m register-machine-instance) regs)
  (let ((h (make-hash-table)))
    (mapcar #'(lambda (r) (setf (gethash r h) nil)) regs)
    (setf (slot-value m 'regs) h)))

(defmethod assign ((m register-machine-instance) regs-name operand)
  (labels ((eval-operand (operand)
                         (let ((s (car operand)))
                           (cond ((eq s 'regs) (gethash (cadr operand) (slot-val
ue m 'regs)))
                                 ((eq s 'const) (cadr operand))
                                 (t
                                   (assert (eq s 'op))
                                   (niy "eval-op"))))))
    (setf (gethash regs-name (slot-value m 'regs))
          (eval-operand operand))))

(let ((*debug-flag* t)
      (m (make-instance 'register-machine-instance)))
  (do-test-case
    (print (make-register m '(a b c)))
    (print (assign m 'a '(const 312)))
    nil
    ))

書いたはいいがいまいちだな。 defstruct でいいじゃん。 On Lisp の defmethod を斜め読み。なるほど、オブジェクト指向というよりは関数主体なんだな。

継承が必要ないなら(そして、本当に必要なさそうだし)、CLOS の必要性はない。(とおもう) CLOS 自身も信者っている、じゃなくて死んじゃっているみたいだし。でその作者?のSonya E. Keene は dylan に移行したみたいだしね。

いやそもそも私の設計が間違っているぞ、、、やっぱりプログラムは設計(メタファーの構築)が重要だ。