2009年 3月 (1)。

Last Modified: Sun Mar 16 08:43:45 JST 2008

あたりまえのことだが、 欲しがるということは、所有していないということである。

おしらせ:
tabesugi.net は、そろろそ復活すべき。

Mar 15 [Sat]


(14:08)
キホン的にいって、

技術者の目標というのはものをつくることだ。 しかし新山は、トランプの家 (20階建て) を 10分でつくってしまう“技術者”よりも、 一生かけて固いレンガ 1個をつくるような技術者でありたい。

(21:41)
もうまぎれもない春である。鬱々と考えこむ人間にとっては危険な季節、 一年のサイクルの中でぽっかりと落ちこむ時だと、ダヴィドは前にどこかで 読むか聞くかしたことがある。ふっと気がゆるんでしまう夜中の 4時ごろのようなものだろう。ダヴィドは自分の陰鬱な思考をおし殺そうとはせず、 四方八方からおしよせてくるあらゆる励まし、赦しや忠告や問いかけを すべて断って、身も世もなく悲痛な思いにふけるようになった。
-- トーヴェ・ヤンソン 「エンメリーナ」
(22:08)
きょうの夕食の献立: どうも品目数がすくない。しかしまあそれはいいとして、 一人ぐらしの問題点は似たような献立ばっか続くことだ。 かき菜は一回おひたしにすれば2〜3日はもってしまうし (これでも新山はわりとおひたしを食うほうなのだが)、 アジもふつう 2〜3枚のパックになったやつを買ってくる。 そんでさらに会社で昼食のときによく買ってるオリジン弁当の お惣菜 (ご飯は持参する) もンネリ化してるので、なおさらである。 なにかいい解決策はないもんか…。

どうでもいいけど (どうでもゆおろ)、 「オリジンべんとう」という言葉をきくと、 どうしても「リベンジべんとう」というふうに解釈したがる、 オレの脳というやつは。

自由かい?

自楓です

Mar 14 [Fri]


(20:11)
Python の名前空間に関する 絞殺 考察。

次のプログラムを考えてみよう:

import os.path

def foo():
  if os.path.exists('/etc'):
    import os
    print os.listdir('/etc')
  return

foo()

(追記: この部分に「↑↑読みとばすな↑↑」って書いていたのですが、 あとで見て自分でムカついたので消しました)

これは、実行するとエラーになる。

$ python foo.py
Traceback (most recent call last):
  File "foo.py", line 8, in ?
    foo()
  File "foo.py", line 4, in foo
    if os.path.exists('/'):
UnboundLocalError: local variable 'os' referenced before assignment

なぜか? これは Python の変数スコープというものが、 ひとつの関数内で、すべて並列に定義されるためである。

もっとわかりやすい例をあげる。

a=1
def bar():
  b=a  # ← この a は、実は
  a=2  # ←           この a を見ている。

bar()

このコードでも、同じエラーがでる:

$ python bar.py
Traceback (most recent call last):
  File "bar.py", line 7, in ?
    bar()
  File "bar.py", line 4, in bar
    b=a
UnboundLocalError: local variable 'a' referenced before assignment

なんでなのか? Python はレキシカルなスコープを許している。 つまり、ある変数が現在のスコープで定義されていなかったら、 その「外側の」スコープを参照することが許される。 だから最初の b=aa は、 普通に考えればグローバルな (外側の a=1 で定義されている) "a" をさすと考えていいはずだ。 ところが、実際にはそうならない。 実は、Python の関数では、 その中で定義される (代入される) 変数はすべて関数の先頭で 並列に定義されたことになっているのだ。

ここで関数の内と外のスコープを視覚的にあらわすと、こうなっている:

# グローバルな定義
int a;
a=...
def bar():
# 関数内の定義
int a,b;
b=...
a=...

ここで bar() 内の式に現れるローカル変数 ba は最初からどちらもスコープに入っている、 つまり「見えた」状態になっている。ただし、各変数には "まだ値が代入されていない" という印がついている。 このため、上のようなエラーが出るのだ。

しかし、いったい Python はなぜこんな構造をとっているのだろうか? スコープを「直列に」、つまり新しい代入文が現れるたびに ネストしたスコープが定義されるようにしてもいいはずだ。 その場合にはこうなる:

# グローバルな定義
a←...
def bar():
# 関数内の定義1
b←a   # グローバルな a を見る
# 関数内の定義2
a←...

こうするとすべては平和におさまるであろう…と思うだろうが、 そうならない。Python がこのようにしなかった理由のひとつは、 効率の問題がある。代入文が現れるたびに新しい環境 (Scheme 用語、Python では正式に何ていうのか知らない) を作るのは効率がわるいので、全部いっぺんにやっておきたい。 しかし、本当の理由は、おそらく「相互再帰呼び出し」を 定義させるためだと思われる。

def foo(x):
  if x == 0: return 0
  return bar(x-1)

def bar(y):
  if y == 0: return 0
  return foo(y-1)
このような関数は、名前 foobar が 同時に見えているような環境でなければ定義できない。 ところが、ソースコードを上から読んで解釈していく段階では、 foo を定義している最中には bar が見えず、 かといって bar を先に持ってくると 今度は foo が見えなくなる。 Python には C のプロトタイプ宣言のようなものがないので、 ふたつの名前 foobar を同時に 束縛 (またも Scheme 用語) するしか方法はない。

実際には、このテクニックは多くの Scheme 実装でも使われていると思われる。 なぜって、どこにでも再帰を使う Scheme のような言語で、 再帰的な (末尾再帰を含む) 関数を定義するたびに letrec を書くなんてのはやっていられないから:

(define foo #f)
(define bar #f)
(letrec ((real-foo
           (lambda (x) (if (= x 0) 0 (real-bar (1- x)))))
         (real-bar
           (lambda (y) (if (= y 0) 0 (real-foo (1- y))))))
  (set! foo real-foo)
  (set! bar real-bar))

ほとんどの Scheme 実装ではこう書ける:

(define (foo x) (if (= x 0) 0 (bar (1- x))))
(define (bar y) (if (= y 0) 0 (foo (1- y))))
これは、foobar が並列に 見えている (と想定できる) 状況でなければ書けない。 まあ、たぶん、インタプリタであれば define 時には 関数の中身まで評価せず、実行時まで名前解決を延期できるので、 別の方法でも実現できるだろうけど…。コンパイラでは無理だ。

話が脱線した。Scheme のことは、どーでもいい。 ふつうは Python のこういう例は気づきやすいけど、ヤッカイなのは 実際に明示的な代入文がなくても変数が「定義」されることである。 たとえば、こんなのだ:

a=1
def baz():
  print a
  for a in range(10):
    print a
それからこんなのも:
a=1
def yo():
  print a
  try:
    dog()
  except Exception, a:
    pass

さて、ここでとりあえずエラーを防ごうとして global なんてのを つけると、結果はまったく意図しないものになる:

a=1
def bar():
  global a
  b=a
  a=2

たしかにエラーはこれで出なくなるが、ここでは a はすべて同じ変数を指すことになってしまい、 「a=2」が代入しているのは関数内にローカルに定義された a ではなくて (そもそも、ここではそんなものは存在しなくなる) グローバルな a である。 つまり、グローバル変数を変更してしまっていることになる。

きょうの教訓: 名前をつけるときは気をつけよう。なまえ、なまえ! トントン。

(ややキチガイ的に)

(22:31)
ところで、雨はもうあがったのかい?
(23:31)
yikes!!!

Mar 13 [Thu]


(23:49)
looks like shit. smells like shit. tastes like shit. that's shit.
(00:48)
前略 ははうえ様

毎秒400回のクシャミと格闘しながら同時に python の構文木とも格闘しております。 つまり、「ふたついっぺんに格闘」ですが (そのままだ)、 お元気ですか。ぼくわもう寝ますよ、眠れればの話ですが。 (ゴミ箱がテッシであふれないうちに!)

Mar 11 [Tue]


(18:55)
あの醜態はいったい何??
(21:24)
おお、そういえばいつのまにか Flapjax などという言語ができていたらしい。 (じつは 1年ぐらい前にすでに ML に出ていたのだが、見落としてた。) これはデータフローにもとづいた FrTime 型の言語だが、 それにしてもなんでこんなふうに HTML とゴチャまぜな形に したんだろう。これじゃ web アプリにしか使えない…って、それが狙いなのか。 しかしこれは ajax の存在がはじめて (Flash やアプレットのアホな代用品としてではなく) 説得力を持つ例だと感心した。世の中には頭のいいやつがいるもんだ!
(22:56)
きょうの youtube動画 (音量注意)。
なんて言ってるのかはわからないけど、この曲は耳につく。 (まあ、punjabi 風の曲ってだいたいこんな感じらしいが)

新山にはこう聞こえる:「なんとかかんとか ホネホネ なんとか…ホゲェ〜〜〜!!」

オレはこんなとこばっか見てるわけではないよ!

Mar 09 [Sun]


(08:56)
なぜか朝からどっかのレストラン街を食べあるきしている夢を見た。 そんなにハラへってるのか? おれは。
(09:36)
やがて死にゆく小さな生き物たちの愛すべき奮闘…

とか、書いてある。

(23:39)
きょうは朝からなぜか歩きたくなり、家からさまよい出て フラフラとしているうちに大久保近辺まで来てしまい、 焼肉の煙で窒息しそうになったがなんとか逃げ出す。 その後、はるか向こうのほうになんか見慣れない形の ビルが見えたので、吸い寄せられるように行ってみたらそれは ドコモタワー だった。自宅からこんなトコまで歩いてきたことに、われながら愕然とする。 そのあと代々木 (だいだいぼく) から電車にのり、そのまま おとなしく中央線で帰ればよいものを、下方向の山手線に乗ってしまい、 なぜか久しぶりに東急池上線に乗りたくなって乗ったら、日曜の午後で アホみたいに空いていた。さてどうやって帰ろうか? このまま蒲田まで行くとアレかな、と思ったので、旗の台で乗り換えて 二子玉へ行き、そしたらまたもや意味もなく南武線に乗りたくなり、 溝の口から立川まで行ってえらく遠回りして帰ってきた。午後は 花粉症で大変だった。

この発言は、あまりにも要出典すぎる。

きょうのyoutube動画

「アニメーションって何。」
「アニメーションとはフレームごとに処理する写真技術で、 ものが動いているかのような幻想が創り出されるんだよ、 アニメーションの世界ではなんでも起こりうるんだ」
「人々はいまぼくらを見てるわけ?」
「まさに今ね!」
「…でもぼく今、パンツはいてないんだけど」
「ぼくもだよ!!」
「アニメーションは嫌いだ!」
「オレの頭はいま巨大なタマゴだ!!」
「ぅぉおおお〜〜〜?!」
「egg〜〜〜!」
「ぅおぁあ〜〜〜!?」
「flower〜〜〜!」
「わぁアー」
「egg〜〜〜〜!」
「ぅあああお〜〜〜!!」

Mar 08 [Sat]


(10:55)
土曜日なのに、日曜日でムカつく! という夢を見た。
おきたら土曜日だった。
(12:25)
きょうは花粉がスゴそうだなああ。 ちなみに新山は昨日がひどかったので、 今日は朝から Allegra を採ったが、鼻がカサカサしている。 できるだけ抗ヒスタミン剤は採らないようにしているのだが、 どういうわけかここ数日、手も荒れているのだけど、 花粉症と相関があるのだろうか? というか、最近またけっこう涼しかったという 印象があるのだけど。

まあいい。今日はやっといつものセンタクも終了して、午後は 図書館へ行く予定。そのあとどうしよう?

(18:10)
新山は「割り切れた」研究者を軽蔑する。 この 5年か 6年の生活で学んだのは、(おそらく言語処理の研究にかぎらず) 一般に学術研究というのは割り切れない部分をずっと持っている、ということだ。 といっても博士論文を書くときにはすべてが割り切れているかのように 書くのだけど、これは儀式のようなもので、本質的には割り切れていない -- むしろやればやるほど「割り切れなさ」が増えていく -- ということが 本当に「哲学」の Ph が相当するゆえんだとすれば、(に対して)。

図書館というところは“受信する”ために行くところで、 本を借りるのは 2のつぎ。かもしれなくない。

(20:35)
GOOD Magazine のドキュメンタリー "Skid Row" 全5回が終了した。 LA におけるホームレス問題を扱った番組である。 このような番組が、ネットで、(通信料を除けば) タダで 提供されている世界で、いまだにどこぞの海外コンプレックスな人々は 英語の教材をとっかえひっかえ探している、 というアホな現実を新山は理解できない。 「英語 教材」とでも検索してみよう。 ぅおぉう 世の中バカばっかりだ。

ちなみに新山がいま欲しいのは日本手話のネット教材である。 ASL はあるのに、日本の手話が動画でアップロードされている場所は 今のところほとんどない。こういうものは本を見ても、 絵じゃダメなんだよ。しょうがないから 4月から区の講習会に行くけどさ…。

Mar 07 [Fri]


(19:55)
ふと、思ったの<br>
ですが。。 。。。

何げなくオレは気づいてしまうのだが、 われわれ人類はこの世の中をもっとツマラナクするように 努力しなければだめだ、と思う。なぜなら人が何万年も変わりばえのしない テレビ番組に釘づけになったり、ネットの同じサイトに目から指が生えるほど アクセスしたり、あるいは宇宙誕生前からあるC++ライブラリをひたすら 変更したりするのは、ひとえにこうした行為が おもしろすぎるからである。それではだめなのだよ。 この世の中がもうどうしようもなくツマラナクなった時、 人は新たな世の中を模索しはじめる。そういう意味で、世界を変えるためには 世の中をもっともっとつまらなくするべきだ。もっともそれが意味するところは、 さしあたっては、何もしないということだが!

(あまりにも皮肉をひねりすぎると三周して元に戻ってしまうのであった。 なぜ一周ではなく三周か? というと、それは折りたたまれた次元のせいであって、 銃規制とは今のところ関係がない。)今のところ;

(20:20)
いやーまったく気がつきませんでしたね、はい。どうもどうも、ええ、
(01:08)
実は、いまここに、ある非常に個人的なことを書きたい気分なのだが、 どうせあんたらは知らないだろうし、知りたくもないだろうから、書かない。 まあ、そういうことは気象庁にでも任せておけばいいんだ。それとも。

Mar 06 [Thu]


(23:11)
<びg>(たからかに)</bg

はぁあ〜〜〜っはっはっはっはっは!

...ばか。

さあ、もう一度!
はぁああ〜〜〜っはっはっはっはっはぁ!!!

...ばか。

一言いっておく。 おまえがバカならオレはうましかだ!!

(ボンギヘウェレだと? ←目玉 ←目玉)
(23:19)
きょうも平和でしたことね。

世の中における (世界の中の、における) アブクどもを、 ペッコン、ペッコンとクリック (あるいは、雉のひとごえ) だ(de)きるこの後事正においては、 そんんぬムんも棚ごとさっぱり扉があかねぇ。うりゃ!

And crealy, I dodon't untarschtand thos mispronounsiaizionne, y, misspronunciationkel.

Mar 05 [Wed]


(20:36)
きのう、今日とかけて、またぞろ意味不明なバグに悩まされていた。 Win32 の、やや低水準な、ある API を使おうとしていたのだけど、 どうも特定のマシンでだけ動かない機能があるのである。古くからある API で、 かなり伝統的な使い方 (MS のサンプルで示されている手続きに従った) なのだが、なぜか一部の古いマシンでは動かない。ややハードウェア寄りの 処理なので、ハードウェアの差異なのか、 Windows の差異なのか (でもどちらもメジャーバージョンは XP で、 古いったってそんなに古くない)、はたまた ドライバの微妙なバージョンの差異なのか、原因は不明である。 でもその機能がそのマシンでも「使える」ことははっきりしているのだ。なぜならまったく 別の、もうちょい高水準なサブシステムを使うとちゃんと動くのだから…。 しかし、こいつらも内部では低水準の関数を使っているんじゃないのかね? なんでこいつらだけ動くんだろ? それとも別の方法があるのかな? さっぱりわからん。 というわけで今日はその「高レベルな」サブシステムを使うように コードを変更していたのだが、なんかフに落ちなかった。どうでもいいけど、 麩 (fu) っていいよね。とくに新山はあのマルい奴 (でっかくて、中にアナあいてる) が好きである。煮物には入れないけど。

さて、そういうわけで、今日は また python のモジュールをうだうだと…。C(++) でムカつくのは、 こんなドーでもいい部分のコードで必要以上にだらだらと長くなることだ。 っていうか、これは API の設計がまずいせいなのかしらん。 でも一部の人々は、まさにこの C++ のダラダラ感が好きなのだと思う。 なぜなら、長いし、しかも適度にワケわかんなそうだし (thanks to templates!)、作ってるもののロジックはアホみたく簡単でも、 いかにも「ボクはこんだけ仕事しました!」って感じの、 上司をだませそうなコードになるじゃん。 あとは誰も読まない (読みたがらない) doxygen とか UML (うむる) のダイアグラムをえんえん時間かけて書くと。 こういう給料ドロボーがどれくらいいるのか知らないが、 少なくとも新山のまわりには今んとこいないのでよしとする。

とにかく、python モジュール書くのにはかなり慣れてしまった。 これっていいことなのか? どうも、そうでないような気がする (気のする)。who cares? (どうでもよろ)

Mar 04 [Tue]


(07:26)
MSを見ていてムカつくのは、彼らの政治力を駆使したマーケティング… もムカつくことは確かだが、本当にムカつくのは、彼らが 計算機というものをこれほどまでに「複雑なもの、ワケのわからないもの、 信用できないもの」にしてしまった、という事実だる。 ああ、はいはい、ソフトウェアがでかくなればバグが増えるということは知ってるよ。 でも連中は積極的にこれをワケのわからないものにしようとしているふうに見える。 ケッキョク (血虚危)、かれらはほとんどの設計を「やっつけ仕事」で やっているんだと思う。つまり、上から「これこれの仕様を入れろ」って言われて、 「ハイハイ、入れりゃいいんでしょ」ってな感じで作っている、ように見える。 たぶん、ほかの多くのソフト会社も同じだろうけど、MSの場合は この品質を、この程度の品質を 世界の標準として認めさせてしまった。不幸、というより、ムカつく! で、さらにムカつくのは GNOME などのオープンソースの連中が、 (シェアを気にするあまり) MS (や adobe や google) の代替品をつくることにのみ地道をあげていて、 結果として「MSのできそこない (場合によっては、 それよりちょっといいソフト)」ばっかりできている、ということだ。 結局、世界は一律に MS 製品化されているのである。まったく別の可能性を 探ることもできたはずなのに、連中はそれをつぶしてしまった。 これはじつに不幸なことだ。というか、ムカつく!

Mar 03 [Mon]


(21:32)
ゲヒンな話。風邪は治ったのだが、風邪の最後のほうって だいたいすごい粘着性の鼻水が出るじゃない? あれすごいよね。 今日は鼻を思いっきりかんだら (あまりの肺活量 (の少なさ) のために かるい酸欠になり、あとで頭痛がしたが)、出てきたカタマリを見て われながらビックリであった。こんなもんが自分の鼻の中に入っていたと 考えるとなんか感動する。この感覚は、ときどき予想を超えるサイズのウンコがでたあとに 便器をじっと見て「オレの胃腸は、かくもスゲー量の物体を格納できたのか」と 少なからず感動するあの感覚にやや似ている。以上ゲヒンな話です。 <げひん></げひん>
(21:52)
米国の Paul Tilley 氏は、 ブログロの匿名コメントを気に病んで自殺したといわれている。 で、 コメントを放置したブログロはこれに対して責任があるや否や? 答。ほとんどの人が「まったくなし」と断定しているのは、 どこぞの掲示板が訴訟されている国と比べるとかなり違う。 これが米国だからか。しかし同時に、むこうの国では名前を名乗らない発言は (Slashトッdや4chanの一部をのぞいて) ものすごく恥ずかしいとされている 文化であることも事実なんだよ。というか、これらは関連していると思う。 米国ではたしかに日本に比べて言論の自由が (相対的に) 「ある」と思われるが、 ここでは名前を出して大っぴらに批判しあうのは「いいこと」だと思われている。 感情があとまで残らない (ゼロではないが、日本よりはずっと少ないと感じた) ので、 ここでは「言論の自由」はそれ自身を維持する働きをしている。 これに対して、日本ではそれが反対の方向に動くので、人々はますます萎縮していく。

オレが日本に言論の自由はあると思っているかって? たぶん、ない。 実質的には。日本で好き勝手なことを言おうとした人間は法的には 何もおとがめがなくても、非公式な処刑がなされるようになっている。 法律に文字でどう書いてあろうと、観測結果をみれば「ない」んだからしょうがない。 この国はそういうところだ (たぶんアジア一般がそうだ)。 社会的なマインドセットの変化は氷河のごとくのろいので、 たぶん今後もあと 100年ぐらいはないままだろう。あなたは100年待つ根気がありますか?

まあ、100年ぐらいなら。

Mar 01 [Sat]


(08:53)
きのうはわが社の月次売上げがン千万を達成したので、 社長がよろこんでミカンを配っていた。なぜミカンなのか? といえばとくに理由はなく、たまたま社長が自分で食うために 大量に保有していたというだけのことである。うちはそういう会社なんです。

あといろいろ書きたいことあったんだけど忘れた。

(11:55)
なんだ、さっきまでよく晴れてたのに、曇ってきたぞ?
(19:13)
図書館へ行く。なんか知らんけどまた風つよい。 今日は何を血迷ったか、Python の例外チェッカー (のようなものといえばいえるもの) を 作り始めてしまった。仕事で実際にこういうのが欲しいのである。 てゆうか、絶対、すでに誰かが同じようなことをやってる気がするんだけど。

たとえば以下のようなコードがあるとする:

def foo(x):
  if x == None:
    raise FooError
  return x+1

def bar(y):
  for i in range(y):
    print foo(y)
  return

def zzz():
  try:
    bar(10)
  except FooError:
    pass
  return

ここで、関数 foo が例外 FooError を送出する 可能性があることは明らかだが、ここから推論して、bar も 例外 FooError を送出する可能性があることを警告してもらいたい。 しかし zzz は警告してほしくない (捕捉してるから)。 プログラムが複雑になってくると、思わぬところで例外を捕捉し忘れて 全体が落ちることがあるので、こういうのを警告してくれるツールが欲しかったのである。 ちなみに、pychecker はそこまでやってくれない。

この問題は一見したほど簡単ではない。なぜなら、上のような例で 関数がすべてグローバルに特定できる場合はいいけど、 多態のあるクラスで obj.foo() とかいう メソッドを呼び出した場合、どのメソッドが実行されるのかわからないからだ。 Python の場合は lambda もあるのでさらに話はややこしくなる。 つまり、これをやるためにはどの変数がどの型かを知っていなければならなくって、 とはいっても、ここで真面目に型推論なぞをやろうとすると話が爆発してしまう。 型がいいかげんな Python では ML風のまともな型推論などはしょせん無理なので、 もうちょい現実的な方法を考えたい。関数の引数の型を指定しておけば (つまり C風の関数宣言を書くってこと)、なんとかいけるだろうと思った。 でもそれを Python の枠組みでどこに入れるか? docstring を使うのがいいか。

…つうことで、しばらくやってみたのだが、これはけっこう大変だ。 簡単なコードならば動くサンプルができたのだが、現実的なコードで これを走らせようとするとカバーしなければならないケースがすごく多いのである。 完全な型推論はしなくても、再帰呼び出しは扱いたいので unification もどきは ある程度やらなけりゃならないだろう。ちなみにどうやって実装したかっつうと 最初は parser モジュールで 構文解析した木をじかに扱っていたのだが、 じきに compiler という パッケージをみつけたので、これを使うとだいぶ楽しくなった。 しかし組み込みの関数や定数をぜんぶ制約として書かなきゃいけないし、 使えるものになるまでに、まだまだ道は長いであろうと思はれる。

(19:11)
久しぶりにこのアニメをみた: (悪趣味につき注意)
http://www.jwz.org/images/love_your_job.gif

これって jwz が最初に作ったんだろうかね?


Document ID: 3225f50bdb0ad05ad841ac3e86175076

Yusuke Shinyama