2012/02/10
コードの適者生存
金谷さんの『プログラマへの誤解』に対して小飼さんもエントリを書いてて、私と議論が逆方向でおもしろい。
プログラムの書かれる背景をどう設定するかで違いが出てくる。Google+での議論参照。
私も、汚くても遅くても動くものをまず出すって点が重要で、ベストな解を求めるあまり頭で悩んで書けなくなってしまったら逆効果だっていうのには同意する。
ところで上のGoogle+の議論で私はあまり考えずに「淘汰」って言葉を使ったんだけど、 コードの栄枯盛衰は案外生存競争に似ているかもしれない。 性能要求がシビアなところで適者生存則が働いて、 「書かれたけど残らなかったコード」が大量に産まれる、というところだけじゃなくて、 哺乳類の眼の網膜の配線が逆になってるように、 たまたまある環境で「他よりマシだった」だけで定着したけどよく考えると効率悪いよね、ってコードが残ってることもかなりあるなあと。
特に仕事で書くソフトの場合、あーあそこ直したいなあと思ってても、 お客さんの要求に応える方が優先されて手がつけられないところは多い。 特定の場合に性能が悪くて、どう直せばいいのかも分かってるんだけど、 運用で回避できるのでとりあえずそうしてもらってる、というような。
そういう意味では「いろいろ試してベストを取る」というコーディングが出来るケースってのは 作り手にとっても恵まれた環境かもしれない。 ましてやそれが仕事上の要請と一致するなら、それはとてもラッキーなことなのかも。
Tag: Programming
2012/02/09
simple-vector
simple-vectorがよく分からない - conjの日記
Clozure CL や Steel Bank Common Lisp で以下のような挙動になった.
(subtypep 'fixnum 'integer) ;=> t (simple-vector-p (make-array 10 :element-type 'integer :initial-element 0)) ;=> t (simple-vector-p (make-array 10 :element-type 'fixnum :initial-element 0)) ;=> nil最後の式が nil を返す理由が分からない.
コメントを書こうと思ったら長くなったのでこちらで。
まず教科書的な答えを言うと、simple-vectorは「ジェネリックなLispオブジェクトを格納できるsimple-array」と決められているから。型表記で言えば (simple-array t (*))
ならsimple-vector
。上の二つのarrayをdescribeしてみると、前者はジェネリックだけど後者はfixnumに特殊化されているだろうと思う。下はAllego CLでの実行結果。
cl-user(7): (describe (make-array 1 :element-type 'integer :initial-element 0)) #(0) is a new (simple-array t (1)). There are 1 elements cl-user(8): (describe (make-array 1 :element-type 'fixnum :initial-element 0)) #(0) is a new (simple-array fixnum (1)). There are 1 elements
(simple-array fixnum (*))
はfixnumに特殊化されてるから、simple-vector
になれない。
でも、これだけだといくつか疑問が浮かぶんじゃないかと思う。
上のarrayも:element-type 'integer
してるのになぜintegerに特殊化されてないの?
Common Lispでの型情報はあくまで最適化のためのヒントにすぎないので、処理系は型情報を全て無視して全部ジェネリックなLispオブジェクトとして扱っても構わない。なので:element-type 'fixnum
してるarrayが(simple-array t (*))
になる(したがってsimple-vectorにならない)可能性だってある。ただ、普通の処理系では要素がfixnumの配列は特別扱いすると有利なことが多い。数値を保存しておくのに型情報をつけなくてよいとか。
一方、要素がintegerの場合はbignumも格納しないとならないんで、そうすると特殊な配列を使うメリットがあまりない。bignumは普通ヒープに置かれて型タグもついたLispオブジェクトになるから。だから処理系はえいやっとジェネリックな配列を使っちゃうわけ。
そもそもsimple-vectorって何のためにあるの?
効率のため。Lispの配列は高機能で、要素の格納形式が指定できたり、動的に大きさが 変えられたり、他の配列の一部分を別の形の配列としてアクセスしたりできるんだけど、 その場合、アクセスの度にいろいろ確認したり変換したりというコードが必要になる。
でもsimple-vectorなら、それはC言語でいう配列 LispObj x[]
と同じものと
みなせる。(declare (optimize (safety 0)))
すればインデックスの範囲チェックも
省かれるので svref
はCで書いた配列アクセスと同等のコードになる。
というわけで高速なLispコードを書くときにはsimple-vectorとsvrefは強い味方。
(subtypep 'fixnum 'integer) => t
なのに前者の配列が後者の配列のsubtypeにならないのはなぜ?
これはCommon Lispに限らずパラメタライズされた型に一般的な性質。
型S
が型T
のサブタイプでも、パラメタライズされた型X<T>
は型X<S>
のサブタイプになるとは限らない。
S
がT
のサブタイプである (S <: T
) ということは、T
を期待してる文脈に実際はS
であるオブジェクトを渡してもいいということ。例えば Fixnum <: Integer
ということは、Integer
のインスタンスを期待してるところに Fixnum
のインスタンスを渡せる、ということ。
ここでもし Fixnum <: Integer
だからといって Array<Fixnum> <: Array<Integer>
であることを許すと、Array<Integer>
を期待している文脈に Array<Fixnum>
を渡せることになる。例えば次の式ではiarray
がintegerのarrayであることを期待して、bignumを代入しているが:
(setf (aref iarray 0) 47874827583458281495927465923753928)
このiarrayにfixnumのarrayを渡したらまずいでしょ、という話。
もっときっちりした話はTAPLの15章あたり参照。
Tags: Programming, Lisp
2012/02/09
ピアノレッスン35回目
- スケールとアルペジオ M=144。直前に家で弾いた時はなんかうまくいかなかったんだけどレッスン室のピアノではなんとか弾けた。家では日によってM=152で指が回ることもあるし144できついこともある。
- Bach: Fantasia in C minor。M=120で。難しいところで集中すると、そのあと気が抜けて簡単なところでミスる。来週はきめられるかなあ。
- Kapustin: Op40-7。M=72。このくらいのスピードでようやくリズムがいい感じになってきた。
Tag: Piano
2012/02/09
新宿ジュンク堂閉店なのかあ。リアル書店は厳しいのかなあ。東京帰った時は必ず寄っていたものだった。
【閉店のお知らせ】
ジュンク堂書店新宿店は、平成24年3月31日(土)をもちまして、閉店させていただくことになりました。
せっかくだから記念写真を貼っておこう。ふむふむ本の柱。
Tag: 生活
2012/02/08
Genius is in the choices
前のエントリ(『書かれなかったもの』)ではプログラミングにおける具体的な取捨選択を取り上げたけれど、 さらに考えてゆくと、やっぱりどんな分野でも創造過程の中心にあるのは選択なのかもしれないと思えてきた。
表題の "Genius is in the choices" はデニーロだったかショーン・ペンだったかが "Inside the Actors' Studio" の中で言ってたことなんだけれど、 つまり、脚本が与えられた時、それを何らかの形で演じることは誰にでもできる、 差が出てくるのはその先、全ての可能性からどれを選択して演じるかってことなんだ、という話。 ("choice"という言葉は芝居の現場で良く使う。"You made an interesting choice."とか"Brilliant choice!"とか。)
役者は個人作業で様々な可能性を検討し、実際にやってみて練り込んでゆくし、リハーサルの場でも色々なアイディアを試して選択してゆく。試せば試すほど、新しいアイディアが産まれる土壌が醸成されてゆく。
何でもいいからとにかく何か作る、って時に必要なのは体力と技術で、 これは誰でも訓練すれば伸びる。伸びれば作れるものの幅が広がり、出来も良くなる。 でもそれは、その後により良い「選択」をするための、準備なのだろう。 体力と技術が足りないと、そもそも出来るものの幅が狭いので、選択のしようがないから。
Comments (0)