Archive for February, 2008

イアン・マクラウド『夏の涯ての島』

Posted by on Sunday, 10 February, 2008

夏の涯ての島

一言で要約すると「渋い」と評されるイアン・マクラウドの初訳となる短編集。SFというかファンタジイというか、どれもこれも一言では説明しづらい味わいのある短編ばかりが揃っている。

表題作は第一次大戦でドイツが勝利した架空のイギリス。そこはやはりファシズムが支配し、全体主義に流れていく不穏な空気が支配しているのだが、物語はそういう架空の歴史を綴るのではなく、その場にあるひとりの人物を描く。幼少期の独裁者と知り合いだったという男を。

この表題作も素晴しかったのだけど、個人的なベストとしては、読むのは何度目かになるが「わが家のサッカーボール」を挙げたい。人類がなぜかほかの動物の姿に変身できるという世界。人々は自分の好きなように姿を変えられるわけだが、精神状態によってはつい何かに変身してしまったりすることもある(恥ずかしい気持ちになると赤面するのと似ているような表現だ)。そんなある日、主人公の母親はナマケモノに変化して戻れなくなってしまう。お医者さんは心の問題だというのだが……という、そんな家族の物語。ストーリーラインは凝っているわけではないのだが、それだけにラストの、主人公たちがサッカーボールで遊んでいるのを見守る母、というありがちな家族の風景が、ここまで奇妙で、しかしここまで感動的であったためしはない。

末尾をかざる一〇〇〇一世界という舞台の二つの作品については、ちょっとピンとこないまま読み進めてしまい、そのまま読み終えてしまった感じ。つまらなくはなかったけれど、惜しいことをしたかもしらん。


『最短経路の本 レナのふしぎな数学の旅』

Posted by on Wednesday, 6 February, 2008

読了。といってもかなり飛ばして読んだ。

ドイツの高校生レナが、自宅のPCにあらわれた不思議な人工知能ビムと対話しながらグラフ理論、最短経路探索に関する数学を学んでいくという話。

内容は平易に書かれているし、訳者も気を使っているらしくてそれっぽい訳である(といっても、なんだか二昔前の児童小説のような文体だが……)。ただそれ以前にドイツが舞台なのでちょっとわかりづらいところもあって、というのは具体的には地下鉄で「最良」の経路を探索するあたりの話があるんだけど、その説明はミュンヘンの地下鉄の路線図なのだった。もちろん路線図は掲載されているんだけど、どうにもこうにも(本質的でないところで)わかりづらくて、翻訳ではなく翻案の方がよかったかもね、なんて勝手に思ったりした。

あと、作中で紹介されているページのかなりの部分がデッドリンクになっているらしいところも気になる。訳注で「現在はデッドリンクのようだ」という説明があったりするんだけど……。せめて、サポートページも訳してほしいなーという気が。

教科書ではないし一般書(科学啓蒙書)としても一流ではないと思うけど、もしまったくこのテのネタを知らないならふつうにお勧めできる本。いちおう対象読者は高校生以上といったところ?(主人公が高校生なので)

最短経路の本


最近おもしろかったまんが

Posted by on Wednesday, 6 February, 2008

ここ一週間は、サーバがトラブったり、そうでなくてもいろいろあってあんまし本は読んでないんですが、とりあえずざっと読んだだけのまんがから、やたら面白かったのをピックアップ。といっても『おおきく振りかぶって』であるとか『大奥』であるとか『ハチワンダイバー』であるとか、そんなものはオレがいちいち書かなくても当然買われているはずのものなのでその辺は略す。

といっても、よしながふみの『きのう何食べた?』[1]もその範疇に入るかもしれないけれど。

弁護士事務所に勤めている筧史朗とその周辺の人たちの日常と料理のまんが、かな。筧はゲイで、美容師の矢吹賢二と同棲中、という側面もあるのだけど、そこはべつだんショッキングな何かではなく、日常的な事物としてさらっと描かれてる。このまんがのいいところは、ちゃんと自分で料理してんなーという雰囲気があるところ。っていうのはこの場合、「それから昨日ののこりの小松菜と厚揚げで煮びたしを作る」っていうあたりのことで、つまり日常の料理っていうのは食材をぜんぶ買ってえいやっと作るわけではなくて残ってる野菜をうまく消費しつつ作るわけだ。こういう生活感みたいなので全体的に覆われているのが、このまんがの良いところなのかも。

次。木村紺『巨娘』は gekka blogの感想を読んで買うことにした。

まーなんつーか面白いっつーかなんつーかよくわからんが、ユカイでした。身長180cmを越える巨娘、ジョーさんは焼き鳥屋の店長なのだが、身長のみならず態度とかスケールとか諸々がデカいジョーさんの日々、みたいな。下世話でパワフルでネームが多い。

あと、ジュンク堂をふらふらしていたら某コミック担当に勧められた『聖☆おにいさん』。

ふたりの聖人、キリストとブッダは現在、立川の安いアパートをシェアして休暇中――てなまんが。なぜかふつーの貧乏な若者風のメンタリティで生活しているのが妙に味わい深い。なぜかヤクザと仲良くなるあたりのくだりが個人的にはツボ。あと一コマだけ『デスノート』ネタとか。ヘンなTシャツ(「仏なんだものなあ ブッダ」とか書かれたモノ)を着こなしていたりとか。そんな感じで面白い。

てなところで。


lisp のカッコの話から

Posted by on Saturday, 2 February, 2008

あるとき思ったのだが、「Lispはカッコが優しくない」という言説は、すくなくともいまの日本においては、まつもとさんを介して広まっており維持されているのではないかという気がする。実際にはそんなことはないと思うが、まつもとさんがそう思うのは勝手だし、そう言われると、なんとなく気持ちはわかるのだよね。わかるので、わりとみんな「Lispのカッコとは」みたいな文章を書きたくなってしまうし書いてしまうわけだ。

まつもとさんは別の文脈では、言語の字句構文的なテイストみたいなものが思考をスイッチするという話も引き合いに出す。 C と Ruby はけっこう見た目が違うので、脳が簡単にスイッチできるっていうやつね。これはぼくもそう思うのだ。そして Lisp も見た目が違うのでスイッチは容易だ、とぼくは思うのだ。独特の見た目はべつに欠点ではない。ついでに、 Common Lisp と Scheme は似ているので、一方に慣れてしまうともう一方がどうにも気持ち悪く見えてしまうのかもしれない。ふむ、 CLer と schemer の宗教戦争のポイントはそこにあるのだろうか。

閑話休題。

さて、こういう風に2つの主張をとりだすと、まつもとさんの論旨は矛盾しているようにぼくからは見えるのであるが、もちろん彼の中では整合しているのだろう。だからべつにぼくはそれを問題視したいわけではないのだ。ただ、まつもとさんは当たり前だけど物凄く偏った人である。執拗に(とぼくには見える)Lispについてはカッコがよくない、と繰り返す姿勢はいただけないが、それがその人の中で重要な論点なのであればそれは仕方ない。その点についてはまともな議論にならないだろうが、言っても仕方のないことなのである。そういう偏りのない人の方が珍しいし、人間ってのは偏ってるもんだ。満遍なく均質な人間なんて気持ち悪かろう。

でまあ、つまり問題なのは主張が間違ってるとか矛盾してるとか主観的であるとか偏っているとか、そういったことではなく、発言者が影響力を持っているということだ、ということになる。影響力があるということは、まともに検証をせず鵜呑みにする層が生まれるということだからだ。まあ、「LispってAIの言語でしょ」みたいな20年前にはカビが生えていたようなことをいまさら言われて困るようなシチュエーション(実話)よりはだいぶマシだが……。

この辺を煮詰めるとネットイナゴ論やトンデモ理論のビリーバーたちと相通じるような気がする。だって、ひとことでまとめると鵜呑みにするやつが一番がバカなので困ると、ぼくはそのように主張しているわけだ。しかしまあ、ぼく自身がそんなに完璧なわけでもなかろうし、だいいちすべての話を検証していたんでは身が保たないので、ある種の「権威」を信じるというのは決して悪いことではないだろう。ではどうしたものか。

そういう視点を持つと、その都度反論するというのが、いちばん地味だがいちばん大切なことなのかもしれないようにも思える(笑い飛ばす、という「と学会」方式もありだ)。いずれにせよ、反論は鵜呑みにしている人に対して「あれっ、この人の意見は正しくないのかな、どうなのかな」という揺さぶりをかけることができる。揺さぶりは検証を促すはずである。たぶん、いくらかは。逆にいちばんまずいのは感情的な反論をすることだろう。たとえ相手の言い分がデタラメであっても、感情的な反論によっては聴衆に検証を促すことがやりづらいからだ。

 

で、ここまでは Lisp のカッコの話のふりをしてきたのだったよね。この話を、たとえばPHPとかに話を広げるのは、皆さんへの課題ということにしておこう(というかそれはマシントラブルのあいだに arton さんにされてしまっているという気もする)。

 

ところで話はずれるが、開発に非常に近いところにある人間とってのまつもとさんはべつに教祖ではないだろうと思う。というか教祖なのであれば、教祖の下知を皆が受け取ればいいわけであり、だから教祖にはならないしコミッタにもなる必要はない。逆にまつもとさんはダメだと思われているだろう。何もしなくてもまともな Ruby が出来上がっているなら、誰も開発に手を染めたりしない。自分がやらなきゃやってくれないのでやっているわけである。ということは、開発者やアーリーアダプターにとって、その対象の評価は「惜しい」がつねにベストということになりそうである。話題になっているモノとかは惜しいものなのかもしれない。


arc → gauche メモ

Posted by on Saturday, 2 February, 2008

「どうせ MzScheme なんだから Gauche への移植くらい簡単じゃね?」とは、たぶんすぐ思いつくことなんですが、やってみたら意外と大変ですね、というのが結論ぽい感じですね。

arc は MzScheme の上に乗ってるわけで、 Gauche に移行するには arc が使っている MzScheme の機能を移植、もしくは代替する機能に割り当てなければならない。で、そういう「MzSchemeの機能」なんて大して気にしていませんでしたが、一部のものは移植が大変であると。たとえばモジュールや名前空間は頑張ればそれほど大変じゃなさそうですし、セマフォも mutex と condition variable を組み合わせれば実装はできそうです。でも current-gc-milliseconds とかは Gauche レベルではちょっと実装できそうにないし、 Gauche の gc は Boehm を使ってるから Gauche を改造すればできるかどうかも怪しい。あと thread 関係は意味論が微妙に違うものがあり、 break-thread とか thread-dead? とかは Gauche でどう実装したものか、なんて問題もあるのかも。

というわけで飽きてしまった。だめだな。まあ arc にはそこまでして移植したいという気が起きないといったところか。

ところで、「ac.scm で使われていて Gauche で定義されていないシンボル」を取り出すというスクリプトを書いてみようと思ったらこれが意外と手間だった。とりあえず切り出したのは、

>

(ac-macex all-defined arc< arc> args break-thread call-with-semaphore char current-gc-milliseconds current-milliseconds current-process-milliseconds current-seconds delete-file directory-exists? directory-list else exn-message exn:fail? exn? flush-output fn hash-table-count hash-table-remove! int kill-thread lib make-limited-input-port make-semaphore make-thread-cell module mzscheme namespace-set-variable-value! namespace-variable-value once parameterize path->string pretty-print print-hash-table random sleep sym system tcp-accept tcp-addresses tcp-close tcp-listen tcp-listener? thread thread-cell-ref thread-cell-set! thread-dead? type vals with-handlers)

といったところ。まだノイズがあるのでイマイチですが、おおむねこんな感じなのかな。なお切り出しに使ったスクリプトは下記の通り。

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

(define (search-symbol sym)
  (define m (find-module 'gauche))
  (global-variable-bound? m sym))

(define (check-symbols-in-file filename)
  (define symbol-set (make-hash-table))
  (define defined-set (make-hash-table))
  (define (symbol-defined? tables sym)
    (any (cut hash-table-exists? <> sym) tables))
  (define (symbols-resolv tables obj)
    (match obj
           (('quote x) #t)
           (('define (var args ...) body ...)
            (if (hash-table-exists? symbol-set var)
                (hash-table-delete! symbol-set var))
            (hash-table-put! (car tables) var #t)
            (let1 new-set (make-hash-table)
                  (for-each (cut hash-table-put! new-set <> #t) args)
                  (symbols-resolv (cons new-set tables) body)))
           (('define var body ...)
            (if (hash-table-exists? symbol-set var)
                (hash-table-delete! symbol-set var))
            (hash-table-put! (car tables) var #t)
            (let1 new-set (make-hash-table)
                  (symbols-resolv (cons new-set tables) body)))
           (('let ((vs . ds) ...) body ...)
            (symbols-resolv tables ds)
            (let1 new-set (make-hash-table)
                  (for-each (cut hash-table-put! new-set <> #t) vs)
                  (symbols-resolv (cons new-set tables) body)))
           (('let* (vars ...) body ...)
            (let1 new-set (make-hash-table)
                  (for-each (lambda (def)
                              (cond ((pair? def)
                                     (symbols-resolv (cons new-set tables)
                                                     (cdr def))
                                     (hash-table-put! new-set (car def) #t))))
                            vars)
                  (symbols-resolv (cons new-set tables) body)))
           (('let-values ((vs . ds) ...) body ...)
            (symbols-resolv tables ds)
            (let1 new-set (make-hash-table)
                  (for-each (cut for-each 
                                 (cut hash-table-put! new-set <> #t) <>) vs)
                  (symbols-resolv (cons new-set tables) body)))
           (('lambda args body ...)
            (let1 new-set (make-hash-table)
                  (if (list? args)
                      (for-each (cut hash-table-put! new-set <> #t) args)
                      (hash-table-put! new-set args #t))
                  (symbols-resolv (cons new-set tables) body)))
           ((body bodies ...)
            (symbols-resolv tables body)
            (symbols-resolv tables bodies))
           ((? symbol? sym)
            (if (not (symbol-defined? tables sym))
                (hash-table-put! symbol-set sym #t)))
           (_ #t)))
  (define (read-and-scan p)
    (let1 obj (read p)
          (cond ((eof-object? obj) symbol-set)
                (else (symbols-resolv (list defined-set symbol-set) obj)
                      (read-and-scan p)))))
  (call-with-input-file filename read-and-scan)
  (filter (lambda (s) (not (search-symbol s)))
          (hash-table-keys symbol-set)))

jmuk.org の復活について

Posted by on Saturday, 2 February, 2008

えーと、マシンが壊れてました。

少し前に書いてましたがディスクが不調の兆しを見せておりまして、「いつ交換しようかなー」と思っていたらある日突然ブッ壊れて大変でした。本機は jmuk.org の DNS サーバ、メールサーバ、webサーバを兼任しているのでナンにもできなくなる。実際の復旧作業はそれほど時間はかかりませんでしたが、まだ復旧できてない機能があるんじゃないかとびくびく。あ、 darcs と mercurial 入れてないな、そういえば。