Island Life

2006/01/26

CVS管理してるもの以外のデータは以前は適宜CD-ROMに焼いてバックアップと していたのだが、1枚に入りきらなくなって面倒になってきた。 こういう大事な仕事が面倒だとプロクラするようになって後で悲劇が起きる ことになっている。 付ける場所が無くて転がってたEIDEのディスクがあったのでHDDエンクロージャを 買ってきてバックアップディスクにすることにした。 USB2のだともう安いねえ。デザインで選ぶようなものになってるんだなあ。

バックアップそのものはrsync --link-destで。Gauche:gdumpfs?もあるけど、 まあ出来合いのコマンドがあるならそっちがいいかと思って。 でもいちいちコマンドラインをタイプするのも面倒なので 結局wrapperを書いてしまった。

Tag: Programming

2006/01/23

センター試験のリスニングのトラブルのニュースを読んでいて思ったんだが、 新しい機械を50万台近く配って、一回限りの試験をやらせようっていう発想が 何というか、日本人的だなあと思う。「ちゃんと動いて当然」という頭 があって、付けたしのようにトラブルへの対応手順を考えたんじゃなかろうか。 こっちじゃそういう発想は出てこない。うまくいきっこないから。

人間が相手の場合、失敗に大きなペナルティを課すことで「ちゃんとやる」 圧力をかなりの程度まで増やすことができ、実際に日本社会の多くの部分が そのようにして動いているのだが、機械の故障率ってのは人間ほど柔軟じゃない。 メーカーにプレッシャーをかけて多少調整することは出来たとしても、 結局はコストとのトレードオフになる。入試センターは当初 「故障はゼロと思っていた」と言ってたそうだが、 本気で故障率を10^-6以下にしたつもりだったんだろか。

エラー処理が醜くなる時っていうのはだいたい設計をしくじっている。 トラブルが一定率で起きることを織り込んでいれば、 トラブル時の再テストや再試験などにあまり複雑な手順を設定できないはずだ。 例えば「一度しか聞けない」という制限をはずせばずいぶんすっきりすると 思うのだが。装置に頭出しをつけなくちゃならないけれど、機器トラブルは すぐに交換すれば済むし、操作ミスのリカバーも容易になる。 それによって故障率のマージンが広く取れるならコスト的には どっこいどっこいになるかもしれない。

何度も聞けていいのか、に関しては、そもそもリスニングで何を 試験したいのかってことになる。ネイティブのスピードで読まれた英語を 一発で聞き取れる受験生なんてほんのごく一部だろうから、問題はかなり ゆっくり読み上げられていたのだろうと想像する。 だが、今後受験生が英語を使ってゆく場面で、(1)相手がゆっくりと 一度だけ喋ってくれる (2)相手は普通に喋るが、聞き返したら何度でも 言い直してくれる、のどちらに遭遇することが多いだろう。

自分の経験からすると、リスニングの能力はリニアに向上するのではなく、 不連続な段階がある。その一番重要なものは、「どの単語が聞き取れな かったかが自分でわかる」という段階だ。それをクリアすると実用上 あまり不自由することがなくなる。 で、複数回聞くことによって救われるのはその段階に達している受験生 だけなので (それ以下だと何回聞いてもわからない)、複数回聞けるように することの影響ってあんまり無いんじゃなかろうか。

Tag: 生活

2006/01/17

昨年、short filmで一緒にやった役者さんが亡くなっていたことをついさっき知った。 Entertainer Ray Bumatai, 52, succumbs to brain cancer。 撮影が6月半ばだったから、撮影のほとんど直後に脳腫瘍が再発していたのだ。

一緒に仕事をしているだけで勉強になった。もっと経験を積んでから また共演できたらいいと思っていた。 チャンスというのはいつでも一回限りなのだ。舞台でも、人生でも。

Tags: 芝居, 生活

2006/01/10

関数型言語でfor文が無いのは、という話がどこかでもりあがってるのを見た。 それについては「再帰が基本で、forはsyntax sugar」でいいと思うのだけれど、 もうひとつ、for文みたいなイディオムは、ファーストクラスクロージャと 組み合わさると、変な落とし穴を作ることがある。

ナイーブな実装を考える。

(define-syntax for
  (syntax-rules ()
    ((for (var init) test update body ...)
     (let ((var init))
       (let loop ()
         (when test
           body ...
           update
           (loop)))))))

gosh> (for (i 0) (< i 5) (set! i (+ i 1))
           (print i))
0
1
2
3
4
#<undef>

一見うまく動く。しかし、for文のbodyでクロージャが作られ、それが for文のエクステントを越えて生き延びると、困ったことが起きる。

gosh> (define p '())
p
gosh> (for (i 0) (< i 5) (set! i (+ i 1))
           (push! p (lambda () i)))
#<undef>
gosh> p
(#<closure #f> #<closure #f> #<closure #f> #<closure #f> #<closure #f>)
gosh> (map (cut <>) p)
(5 5 5 5 5)

処理の本体をクロージャにして抽象化するのはSchemerなら息を吸うように やってることだが、ループ変数を破壊的に変更してしまうとそれが 等価な変換ではなくなってしまうのだ。 些細なことに思えるかもしれないが、こういうところにトラップがあると まるで息を吸うのに不自由する感じがある。

Schemeのdo構文は再帰のsyntax sugarなのでこの問題はない。forも ループ変数を破壊的変更でなく再帰関数の引数にして持ち回ればこの問題は 起きないのだが、手続き型言語のfor文は(C++の「イテレータ」イディオムを 含めて)破壊的変更を暗黙のうちに仮定しているかのようだ。

なおCommon Lispのloopマクロやdotimesマクロはループ変数を 破壊的変更しくさるのだが、これはきっと破壊的変更の悪をプログラマに 教えんとするSteeleの親心に違いない。そうに違いないのだ。 過去に学ばないプログラマは何度も何度も何度も何度もクローズした はずの変数がいつのまにか書き換わってることに悩んで何時間も デバッグに費すのだ。おかげで昨日も締切前の貴重な時間を無駄にした。くそぅ。

Tags: Programming, Lisp, Scheme

2005/12/31

最近、故あって「1バイトの整数を読み、そこに示された数だけ4バイトの符号無し整数を読む」 みたいなバイナリデータを扱っているのだが、SRFI:42のeager comprehensionが 思いのほか便利。

(let* ((count (read-binary-uint8 input))
       (data  (list-ec (: n count) (read-binary-uint16 input 'big-endian))))
  ...)

Tags: Programming, Gauche

More entries ...