昔新人にバグとは何かについて偉そうに語ったことがある。
バグとは何か。以下のようなものである。
- バグの定義
- 「Aという入力に対して、Bという結果を期待したのに、Cのような結果になった」
B≠Cな状態がバグである。
最低限必要な要素は三つ:入力条件、期待する動作、実際の挙動 である。
入力というのは関数への引数でもいいし、何かの操作とか設定とか環境とかでもいい。結果というのも返り値でも挙動でも表示されるメッセージとかでもいい。
プログラマがバグ報告をするならば、上記のような書き方が好ましい。
Aという入力が100%Cという結果を引き起こすならバグ報告としてなおよい。再現状況が判明しているということだからだ。
したがって、tracにバグ報告のチケットを作るならば、必ず上記の3要素(条件、期待する動作、実際に起きたこと)を書きなさいという風に教えた。
このようにバグを定義した場合、バグ"#the_bug"が直ったとは次のような状態である。
- あるバグが修正された状態の定義
- 「#the_bugの修正としてXを行った。結果、Aという入力に対して、期待通りBという結果が返ってきた」
最低限必要な要素は4つ:何をしようとしたか(どのバグを直そうとしたかのポインタ)、修正内容、入力条件、期待通りの動作をしたという事実
したがって、commit logには必ずバグ報告へのポインタ、修正内容、入力条件、実際の挙動を書きなさいと教えた。
そんな僕の commit log はこんな感じである。
$ svn log
------------------------------------------------------------------------
r3574 | y-sudo | 2007-11-13 20:01:09 +0900 (火, 13 11月 2007) | 2 lines
アレ直した
------------------------------------------------------------------------
r3572 | y-sudo | 2007-11-13 19:46:11 +0900 (火, 13 11月 2007) | 2 lines
hogehoge
------------------------------------------------------------------------
r3571 | y-sudo | 2007-11-13 18:49:09 +0900 (火, 13 11月 2007) | 2 lines
hogehoge
...(略)
$
※この物語はフィクションです。実在の人物団体コミットログ等とは関係ありません。
一方Buzzurlにはアイレップの渡辺さん(@SEMリサーチ)とかサイバーエージェントの小越さん(@今日のニッパウ)とか、SEOやらネット広告系でエッジの利いたブクマする人が結構いるんだよね。
別に一旦閉じなくてもそういうエッジの利いたブクマにフォーカスする方法があるような気がするので、Buzzurlのトップページに「特集 マーケティング SEO関連エントリー」という欄を作ってみたよ!
こういうジャンルに興味ない人はごめんなさい><
こないだ買ったSICPを通勤電車で読んでるんだけど、面白すぎる。
(でも通勤電車で本文を読んで家で練習問題をやろうと思ってたけど、家ではついニコニコなんぞを見てしまうので、本文は3章を読んでるのに練習問題はまだ1章の途中までしかやれてない。くやしいのうwwwwくやしいのうwwww)
例えば1章では、√xを求める関数を書くのを題材に、関数による処理の抽象化について説明している。
√xの近似値を guess として、(x/guess + guess)/2 でよりよい近似値が得られる(これはf(x)=√xに関するニュートンラプソン法による)というのを天下り的に与えられたとき、手続き型言語脳だとどう書くだろう?
new function(){
function average(a, b){ return (a + b)/2 }
function square(a){ return a * a }
//手続き型言語的に √x を求める
function procedual_sqrt(x){
var guess = 1.0; //暫定初期値
var EPSILON = 0.0001; //許容する誤差
//指定した誤差より大きい間ループ
//(あまりよい評価方法ではない)
while(Math.abs(square(guess)-x)>EPSILON){
//近似値をニュートンラプソン法により改善
guess = average(x/guess, guess);
}
return guess;
}
alert(procedual_sqrt(2));
}
JavaScriptで書くならこんな感じだろうか。average()とかsquare()とかは関数にするまでもないと感じる人もいるかもしれない。
短いプログラムながら、ループとか変数の宣言とか関数とか色んな要素がつまってる。
初心者向けの練習問題としてはいい感じだが、一方で色んな要素がつまってるからこれを書けるようになるように説明するのは大変といえば大変だ。
一方SICPでは、Schemeでこの問題を解くまでに、
- 式の評価のされ方
-
Schemeの式は (演算子 オペランド1 オペランド2 ... ) のようになっており、
(+ 1 2)
は 3 と評価される。
- 関数の使い方
-
(define (関数名 仮引数...) (関数本体の式))
のように関数を定義する。
(define (average x y) (/ (+ x y) 2)) (average 1 3)
は 2 と評価される
- 条件分岐
-
ifやcondの書き方。
絶対値を求める関数は次のように書ける
(define (abs x) (if (> x 0) x (- x) ))
以上3つだけ説明して、この知識だけで問題を解いてみせる。
ちょwww変数は?ループ制御構文は???
Schemeコード貼ってもアレなので、ほぼ等価なJavaScriptコードで示すと次のような感じ。
new function(){
function functional_sqrt(x){
function average(a, b){ return (a + b)/2 }
function square(a){ return a * a }
function good_enough(guess){
//近似値の評価
//(あまりよい評価方法ではない)
return Math.abs(square(guess)-x)<0.0001;
}
function improve(guess){
//ニュートンラプソン法
return average(x/guess, guess);
}
function sqrt_iter(guess){
return ( good_enough(guess) ) ? guess
: sqrt_iter( improve(guess) );
}
return sqrt_iter(1.0);
}
alert(functional_sqrt(2));
}
確かに変数もループも使ってない!
本質的に再帰的なアルゴリズムを実装してやることで、しれーっと再帰的手続きの概念を教えちゃう辺りがすごい。
このあともこんな感じで、2章など有理数や複素数の加減乗除を行うモジュールを作るのを題材に、データ抽象について説明するのだが、ここでも変数なんて軟弱な概念は出てこない。ちょwwww
3章で状態をどう取り扱うかという話題になって初めて変数とか出てきた。でもそれも変数使うと参照透過性が失われて色々ややこしいことが起きるから、後半では変わりにstreamを使える場合ががあるよとかいう話になってたり。
色々面白いのでみんなもっとSICPを読むべきだと思いました。
計算機プログラムの構造と解釈

価格 : ¥4830 (税込)
メーカー : ピアソンエデュケーション
→Amazonで詳細を見る
おすすめ度 :

レビュー
なんつーか、僕は本屋が好きで、本はなるべくなら本屋で手にとってから買いたい派なんですが、この手のやや学術側に行っちゃってる感じの本はリアル店舗で探すのがつらすぎて困ります。
良著とされる本でもK&Rだの、オライリー本だの、GoFデザパタだの、EffectiveC++だのはまだ割と色んな本屋で見かける。
レッドドラゴンブックは渋谷のブックファーストで買ったけど、売ってるところ探すの結構つらい部類だろう。もし渋谷のブックファーストになかったらあとは八重洲ブックセンターに行くか秋葉原の書泉に行くか・・
みなさんどういうところで本買ってるんでしょうね。みんなAmazonさんか。
コンパイラ―原理・技法・ツール〈1〉 (Information & Computing)

価格 : ¥5880 (税込)
メーカー : サイエンス社
→Amazonで詳細を見る
おすすめ度 :


