び:log-2006

:log-2006


Kahua 1.0(あるいは裏リリースノート)

(2006/12/27 19:37:03 PST): リリースした。便宜上安定版を名乗っているが、そのココロは「マニアじゃない人にも少しだけ優しい」だ。

大詰め

(2006/12/26 14:39:17 PST): さぁ、いよいよ明日ですぞ。

日本語と格闘中

(2006/12/25 02:30:31 PST): Kahua 1.0に向けてドキュメントを書き直し中。いやぁ日本語って難しい。だからって英語で書けるわけもなく、脳内の別人格に「この文章、読んで意味わかる?」と問いながらひたすら書く。

ドッグフード

(2006/12/19 00:33:02 PST): 作っているものが本当に正しいのか、使ってみなければわからない。使えばまた、アイディアが湧いてくる。

プログラマヒエラルキー

(2006/12/14 05:45:32 PST): /.Jで話題になってた。ADAプログラマだけ何だか妙に唐突な気がするんだけど、USだといっぱい仕事があったりするんだろうか。

俺のイメージだと、Schemeプログラマはこの図の外で「ふーん」と気乗りしなさげに眺めている感じだな(笑)。

Kahua 0.9.1リリース

(2006/12/14 05:33:55 PST): IEでの表示に問題が出たのでマイナーバグフィックスリリース。1.0までは細かく刻んでもいいかも(笑)。

Kahua 0.9リリース

(2006/12/13 06:49:41 PST): 遅れを取り戻すべく、0.9をリリース。ごくシンプルなページテンプレートを実装してみた。これで、大部分が固定で一部分だけ動的にしたいようなWebアプリケーションが作りやすくなるはず。

0.9の次はいよいよ1.0。その次は1.1(あれ)。

Kahua 0.8リリース

いやぁ、今回は苦戦した。やはり理解が怪しいところでは必ず地雷を踏むということだなぁ。

Rubyの生産性の高さはどこまで本当か?(2)

これ最高。ここにSchemeを割り込ませるとするとどうなるんだろう。変人はとられちゃってるしなぁ。しばし考えて思いついたのが、

仙人

Gaucheはともかく、素のSchemeは浮世離れした感じだし。ちなみにCommonLispは超人もしくは狂人か。よくも悪くも常軌を逸している(笑)。

Rubyの生産性の高さはどこまで本当か?

(2006/10/10 16:20:39 PDT): ここでも「マクロとMOP最強」というところに話がまとまってる(主旨はそういうことじゃないけど)。で、ふと考えたのだけど、Rubyが急速に人気を得た理由のひとつは「Rubyがスゴイ」からではなく「Rubyがヌルイ」あるいは「Rubyがユルイ」からなのかも。何かこう突き詰めてないところがとっつきやすくてなじみやすいんじゃないかなぁ。だから、スペック競争的な話で「Rubyはこんなにすごいんです」と言ったところで、その魅力は伝わらないんじゃないかと思う。もっと言うと、Rubyが優れている、という主張には、多分にムードが含まれているのだけど(もしくはほとんどムード)、そのムードをまとっていることが非常に重要なんだろう。これはちょっとやそっとで言語に取り込めるものじゃない。

なーんてね。Rubyを捨てた人間が言っても説得力ないですね。

なんでRubyは心地良いのか?

reddit経由。この理屈だと、マクロとMOP最強という話になっちゃうな。 いや確かに俺的には最強なんだけど、世の中的にはそうじゃないらしいし。むしろそっちの方が謎だなぁ。

Kahua 0.7リリース

(2006/09/29 09:21:54 PDT): リリース作業中、ドキュメント書きに嫌気がさしてちょっとしたハックをしようとしたら、20行と書かないうちに見事にutil.matchのバグを踏んだ(gauche-devel-jpに報告済み→CVS HEADでは修正済み)。現実逃避しないでちゃんとドキュメント書けという神のお告げか(笑)。

iPod nano 8GB

(2006/09/22 22:25:40 PDT): 届いた。これまでは第4世代(最後のモノクロ画面)のiPodを使っていたのだが、いい加減重いし(ポケットに入れているとズボンが下がってくる)、12GBある音源も、全部聞いているわけではあるまいということで、乗り換えることにしたのだ。

で、同期する音源を絞り込む作業をしたわけなんだが、これがなかなか減らない。案外いろいろ聞いているんだな。1曲が長いものが多い、アルバム単位で聞くっていう個人的特性があるんだろうが、ようよう絞り込んで同期してみれば、すでに空きは60MB弱。これじゃあ、アルバム1枚買うごとに何かを同期対象から外すハメになりそうだ。最近はあんまり買わなくなったからいいのか。

iPodの強みは、「とりあえず手持ちの音源を全て突っ込んで持ち歩ける」ということにあったんだなぁということを痛感した。意識して絞り込むのは案外面倒くさい。この差は大きい。

追記: でもこの小ささ、軽さは代え難いね。もうHDD内蔵型のiPodには戻れそうもない。PowerBook 17"からMacBookに替えたときも感じたけれど、最近は好みがより軽薄短小に向いているようだ。

Packrat Parser とJSON reader/writer

(2006/09/14 01:02:22 PDT): Schemeで使えるJSONモジュールを探すとイの一番に見つかるMzScheme用のライブラリをGaucheで使えるようにいじってみた。と言っても、極めてポータブルに作られているので、Gaucheのモジュールの作法に合わせるだけですぐ動くようになるんだけど。他にいじっているのは多分に自分の好みと、多少Gaucheっぽくしておきたいな、と思ったから。特にレコードとして定義されている型の名前は、全て<>で囲むように変えてある。それと、ジェネレータを使っているところがあったので、Scheme:generatorとdoとwhileで議論になっていたmake-generatorを使って書いてみた。

一応JSON reader/writerのテストは入れてある。Packrat Parser Combinatorについては、まだアルゴリズムも動作も理解し切れていないから、HTTPのパーザだの、HTMLのパーザだのを自分で書いてみて理解しようと思っている。

ダウンロード: Gauche-parser-0.1.tgz

Kahua 0.6リリース

(2006/09/08 01:53:11 PDT): 本当はLL Ringに間に合わせたかったんだけどね。いろいろ手間取ってしまった。

LL Ring 2006(2)

(2006/08/29 08:26:56 PDT): 実は、「家計簿って地味だから、彩りとしてグラフ機能をつけときゃいいんじゃない?」ってな安易な発想で、GDChartバインディングを作った。最初はc-wrapper使えば楽勝と思っていたのだが、koguroさんも書いている通り、GDChartはc-wrapperからは使えず、仕方なくバインディングコードを書いたのだった。バインディングは、26日の朝の段階でほぼ使える状態になっていたのだが、組み込む気が起こらなかったんだな。すでに飽きていたこともあるし、何よりGDChartのあんまりな設計に辟易していた。まぁ、家計簿に必要かどうかはともかく、グラフを手軽に描ける仕組みはやっぱり欲しいから、GDなりImageMagickなりを直接使う形でいずれきちんと作ろうとは思う。GDChartはステ。

ちなみに、案の定DjangoチームとRailsチームはしっかりグラフ機能をつけてきていた。

LL Ring 2006

(2006/08/26 07:50:11 PDT): Kahuaチームの一員として参戦してきました。とはいえ、俺はもっぱら口先大魔王でちょろちょろ口を挟むだけ。お題の実装はもっぱらcut-seaさんがやってくれたし、リング上でのプレゼンもお任せ。ただ、NetBSDなThinkPadからプロジェクタへの出力がうまくいかなかった(VGAになっちゃう)ために、急遽俺のMacBookをデモに使うことになり、必然的にスライドの操作やお題アプリ(タグ付き家計簿)の操作も俺がやるハメになった。つーか、当初は「1チーム15分〜20分くらいでデモ+プレゼン」という話だったと思うんだが、いつの間にか1時間40分超出ずっぱりになってるし。リング上は暑いし、照明が目に堪えるしでけっこう疲れた。

何かね、イベント屋だったくせに、表に立つことはほぼ皆無だったので、ああいうシチュエーションは苦手なんだよね。それでも、中の人の立場からKahuaについてちょっとだけでも語れたことはよかった。関係者の皆様、お疲れさまでした。ShiroさんのLanguage Update(Skypeを使ったハワイからの生中継)も無事できてほっとしました。

個人的に興味深かったのは、Squeakのデモかな。最近注目しているSeasideのデモもあったし。でも、あれを使って何かを作っている自分は想像できないなぁ。

(2006/08/27 07:41:38 PDT)追記: Kahuaチームの入場曲は大熊ワタルユニット(現CICALA-MVTA)の演奏で「吾妻八景」という曲です。別にKahuaともGaucheとも何のつながりもなくて、俺のお気に入りというだけで選んだんだけど、原曲は江戸時代の下座音楽で、現在でもちんどんのレパートリーに残り、ああいうアグレッシブな形で今も演奏されているところが、何となくLisp(Old Lisp)とSchemeとGaucheの関係に似ているとこじつけられなくもない。かな。無理かな(笑)。

thread_get_state failed(2)

(2006/08/10 22:49:31 PDT): Gauche:MacOSXに報告しました。原因は追えていません。

thread_get_state failed(1)

まだ状況が完全に把握できていないのでこっちに書く。

(2006/08/08 21:44:56 PDT): Xcode 2.4がリリースされたのでさっそく入れてGaucheをビルド、インストールしてみたら、何と「thread_get_state failed」とのたまってmake install-check中に落ちるようになった。make checkは問題ない。また、kahua-httpd(こいつはスレッドプーリングを使っている)を動かしてみると、しばらく使っているうちに(数十リクエストを処理したところで)やはり同じエラーで落ちる。うーん。Xcode 2.3に戻して再ビルドするとこの現象は起きない。さらに追求する予定。

Kahua 0.5 リリース

(2006/07/30 21:16:22 PDT): リリースしました。構成を大幅にいじっています。 かなり安定したはずですが、どうかなぁ。というか、中の人になってこれが実質最初のリリースですな。

オブジェクトデータベース

(2006/06/26 21:43:32 PDT): Franzのサイトに置いてあったプレゼン資料やらデモムービーを眺めながらお勉強。 恥ずかしながらオブジェクトデータベースというものを真剣に使ったことがなかったので、 ZODBやCacheの記事を斜め読みした程度の知識しかないのだ。 さらっと通して見た範囲では、すごそうだけど、実装がよほどがんばらないとね、という印象。 KahuaのようにRDBMSをバックエンドに据える方法はけっこう難しいかも。ただ、:indexという スロットオプションは(ちょうど自分でも同じようなことを考えていたのだけど)そこいら辺のギャップを 埋めるのにうまく使えるかもしれない。かと言ってHibernateの設定ファイルみたいなクラス定義は 書きたくないし、バランスが難しいところ。

消滅

知らん間に消滅していた。どうやって復活させるのかわからなくて焦ったのだけど、何でもいいから同名のページを作れば、過去の履歴もまとめて蘇るのだった。素晴らしい。

MOP勉強中

必要に迫られてMOPを再々...勉強中。ネタはもちろん「The Art of Metaobject Protocol」とGaucheの実装。 CMUCLも使おうかと思ったのだが、やっぱりCommonLispは好きになれない。

で、やっと前回挫折したあたりまで読了。あわせていろいろと実験。「Metaobject」と言われる所以をやっと 少しだけ垣間見た気がする。なるほど確かにえらく柔軟な仕組みで、やりたいことは何でもできちゃいそうだ。 プログラマに制約を課すことでその負担を軽減すると主張するメインストリームのOOPとはだいぶ毛色が違う。 これを「柔軟でステキ」と思うか「メンドクセ」と思うかで道が分かれる気がする。解決したい問題の大きさ にもよるか。正直、世の中のプログラマが解決しようとしている問題で、この柔軟性を要求するほどの複雑さ を持っているものはそう多くない気がする。

でも、「これを使いこなせたらすごいことができそう」と思わせる何かがMOPにあるのもまた事実。

pthread地獄

プログラムをマルチスレッド化/スレッドプール化しているのだが、pthread関係の穴にハマりまくり。Mac OS XとNetBSDとLinuxそれぞれで問題が発生するポイントが違うし、プログラムの問題なのか、Gaucheの問題なのか、Boehm-gcの問題なのかうまく切り分けられん。あげくの果てにこんな論文見つけちゃったりして、萎えまくり。

pthreadキライ...

pthread_spinlock()で落ちる現象再現&NetBSDに修正

Ruiさんのwriteへのパッチを当てて、ほくほくしながらGaucheを再ビルドしてインストールしてたら、make install-check中にあのpthread_spinlock()がらみのエラーが再現した(下記参照)。coreが落ちているのを確認し、あわててツリーぐるみコピーして現場を確保。これでじっくりと追いかける準備ができた。coreが落ちると嬉しくてわくわくするって性癖ってどうなんだ(笑)。

Garbage Collection

数ヶ月前にAmazonに注文したままになっていたGarbage Collectionがやっと到着した。Boehm-gcに手を突っ込んで以来、一度ちゃんと勉強したいと思っていたのだ。とはいえ、他にも積ん読状態の本はかなり溜まっているから、その山をより高くするだけになる可能性もあるんだけど。

AA折れ線グラフ再び

(2006/03/15 07:01:17 PST): 最初の解があまりにダメダメなので、リベンジ。ただ、これでも遅い。単にfold2とfold3を使ってみたかっただけかも。

#!/usr/bin/env gosh
;;; -*- coding: utf-8-unix -*-

(use gauche.sequence)

(define (draw-graph str)
  (define (string->plot-list str)
    (sort! (values-ref
            (fold3 (lambda (cmd res y x)
                     (case cmd
                       ((#\R) (values (cons (list y x #\/) res) (- y 1) (+ x 1)))
                       ((#\F) (values (cons (list (+ y 1) x #\\) res) (+ y 1) (+ x 1)))
                       ((#\C) (values (cons (list y x #\_) res) y (+ x 1)))))
                   '() 0 0 str)
            0)
           (lambda (a b)
             (and (<= (car a) (car b)) (<= (cadr a) (cadr b))))))
  (define (plot-line cur x c)
    (dotimes (_ (- x cur)) (write-char #\space))
    (write-char c))
  (let1 l (string->plot-list str)
    (unless (null? l)
      (fold2 (lambda (e prev-y prev-x)
               (if (or (not prev-y) (= prev-y (car e)))
                   (apply plot-line prev-x (cdr e))
                   (begin
                     (newline)
                     (apply plot-line 0 (cdr e))))
               (values (car e) (+ 1 (cadr e))))
             #f 0 l)
      (newline))))

(define (main args)
  (draw-graph (cadr args))
  0)

AA折れ線グラフ

(2006/03/14 21:10:50 PST): 今日の一行(2006-03-14)より。とりあえずは真っ正直に。テーブルを使わなくてもできそうな気がするんだけどなぁ...

#!/usr/bin/env gosh
;;; -*- coding: utf-8-unix -*-

(use srfi-1)
(use util.list)

(define line-table
  (alist->hash-table
   `((,#\R . ,#\/)
     (,#\F . ,#\\)
     (,#\C . ,#\_))
   'eq?))

(define motion-table
  (alist->hash-table
   `(((,#\. . ,#\R) .  0)
     ((,#\. . ,#\F) .  0)
     ((,#\. . ,#\C) .  0)
     ((,#\R . ,#\R) . -1)
     ((,#\R . ,#\F) .  0)
     ((,#\R . ,#\C) . -1)
     ((,#\F . ,#\R) .  0)
     ((,#\F . ,#\F) . +1)
     ((,#\F . ,#\C) .  0)
     ((,#\C . ,#\R) .  0)
     ((,#\C . ,#\F) . +1)
     ((,#\C . ,#\C) .  0))
   'equal?))

(define (make-loc-table! in ht)
  (let loop ((ch (read-char in))
             (prev #\.)
             (x 0)
             (y 0))
    (if (eof-object? ch)
        (sort! (hash-table-map ht (lambda (k v)
                                    (cons k (sort! v (lambda (a b) (< (car a) (car b)))))))
               (lambda (a b) (< (car a) (car b))))
        (let1 y (+ y (hash-table-get motion-table (cons prev ch)))
          (hash-table-push! ht y (cons x (hash-table-get line-table ch)))
          (loop (read-char in) ch (+ x 1) y)))))

(define (draw-per-line l)
  (let loop ((l l)
             (cursor 0))
    (unless (null? l)
      (let* ((c (car l))
             (offset (car c)))
        (dotimes (_ (- offset cursor))
          (write-char #\space))
        (write-char (cdr c))
        (loop (cdr l) (+ offset 1)))))
  (newline))

(define (main args)
  (for-each (lambda (l) (draw-per-line (cdr l)))
            (call-with-input-string (cadr args) (cute make-loc-table! <> (make-hash-table 'equal?))))
  0)

(2006/03/14 21:42:29 PST): やっぱり... fold2なんて知らなかった。fold系はどうもぴんとこなくて、直観的に使いこなせないんだよねぇ... しょぼん。

R6RSへの道は険しい

(2006/03/08 03:10:49 PST): 「Scheme Language Steering Committee Report to the Community」というのが出ていた。ここまでの紆余曲折がわからないので何とも言えないが、やはりひとつの標準を作るということは厳しい仕事なんだなぁと思う。

NetBSDスレッドサポート本家へマージ!!(Boehm-gcとGauche)

(2006/03/05 20:49:42 PST): GaucheFest 9thに参加する朝にBoehm-gc 6.7がリリースされるという、恐ろしいまでの偶然が重なったおかげで、一気にGauche CVS HEADに取り込んでもらえた上、けっこう致命的なバグを指摘していただけて潰すことができた。充実した週末(というか土曜日)だった。

それにしても、mutexを初期化しないでlock/unlockしても、問題になるのはassertionでひっかかるNetBSDだけというのはいいんだか悪いんだか。NetBSDのlibpthreadのコードを見ればわかるが、山のようにassertionが埋め込まれている。おかげで今回のバグを見つけられたとも言えるからいいのか。

実は、このassertionがらみで落ちるケースをもうひとつ見つけている。再現性が極めて悪いためにまだ追い切れていないのだが、make check中にpthread_spinlock()内のassertionに引っかかって落ちるケースがあるのだ。発生するのは make check 100回に1回くらい、しかも落ちるところが微妙に違っているというのが困る。おまけに、前回取得したcoreをうっかり消してしまって以降、再現しないため手も足も出ない。こういう時は潔癖NetBSDが恨めしくなる。

サーバ復旧作業中

2/13夜にスーパーブロックが吹き飛んだメインサーバ(NetBSD/i386)のHDDだが、何とかデータのほとんどをサルベージできた。サーバ自体の復旧はこれからだが、作りためたものやメールを失わないですんだのは非常に大きい。せっかくなのでこの顛末は後ほどまとめる予定。概要だけ列挙しとくと、

  1. とりあえず吹き飛んだHDDと同一サイズのHDDとそれより大きいHDDを用意する。
  2. dd で吹き飛んだHDDの丸コピーを行う。このとき、bs=512 conv=sync,noerrorがポイント。
  3. HDDに貼付けたら、fsck_ffs -b 代替スーパーブロックを試す。うまくいけば、少なくともマウントできるところまでは持っていける。
  4. ただし、FFSv1とFFSv2では代替スーパーブロックの位置が違うことに注意。fsck_ffs(8)には「Block 32 is usually an alternative super block.」とあるが、FFSv2の場合、これは32ではなく144である。代替スーパーブロック位置の見当は、newfs -Nやnewfs -N -O 2でつけられる。
  5. マウントできたら、何はともあれcp -pRで全てのファイルをバックアップする。選択は後でもできる。

まぁ普段からきちんとバックアップ取ってりゃ何の問題もないのだけど、やはり同じHDD上の別パーティションに取っても意味は薄いってことで。HDDを惜しむべきではない。昨今のHDDの低価格ぶりだと、バックアップ専用にHDDを用意するのが一番いいと思った。ちなみに今回は事故の夜に160GBと250GBのSATA150なHDDを注文して2万円弱だった。

最後に、上記の手順はそのほとんどを「復活の日: FreeBSD ディスククラッシュ事件総括」によった。心からの感謝を。

スレッドとシグナルとBoehm-gc

マルチスレッド化されたkahua-spvr.scmを眺めていてふと気になったことがある。 gauche.threadsにおいて、make-threadで作成されたスレッドは、 thread-start!時に全てのシグナルをブロックするようにマスクが設定される。 具体的には、sigfillset(3)したシグナルマスクをpthread_sigmask(SIG_SETMASK,...) で設定しているわけだ。

で、ここで問題。Boehm-gcはpthreadサポートの中で、stop worldとrestart worldにシグナルを使ってる。Mac OS XとかSolarisとかは多分関係ないけど、その他のpthreadなシステムでは、全部のシグナルをブロックされちゃうと、かなり困ったことになる気がする。

気がするだけでまだ確認したわけではないので、これから調べてみる。

寄り道多すぎ

(2006/02/06 19:41:31 PST): Firebird-1.5.3が出たのを機に、自分の環境で気持ちよく使えるようにいろいろとhackしてみた。おかげで改訂を進めているインハウスシステムはなかなか進まない。時間があるとつい寄り道が多くなって、結果的に元々やろうと思っていたこと自体はそれほど進まないという典型かもしれない。

それでも、こういう時の蓄積が切羽詰まった時にものをいうのも確かなので、遠慮せずにやることにする。ちなみにここでもSubversionが大活躍している。Gauche-firebirdのリポジトリもCVSからSubversionに移した。挙動が直観的であること、ベンダドロップの管理のしやすさはCVSの比ではないと思う。他のコードもいずれSubversionリポジトリにまとめてしまうつもり。

Kahuaをhackする

(2006/01/16 23:42:20 PST): 暇なので、以前から懸案になってるインハウスなシステムをKahuaで作り直すための調査と準備を始めているのだが、kahuaアプリケーションのコードを書くよりKahuaそのものをいじっている時間が長いってのはどうなんだ。特にKahuaをプライベートなSubversionリポジトリに突っ込んでから、いじり方に遠慮がなくなった気がする。目的と手段が逆転しているとも言えるな。


Last modified : 2007/01/04 09:53:44 UTC