Month of 7月, 2009

clippyがMacFanで紹介されました

in

clippyMacFanで紹介されました。いや、ほのぼのするくらい小さな記事ですが、ホンワカうれしいです。ま、今後ともひとつよろしくお願いします。

List comprehensionsとrubyのeach

in

すっかり堅くなった頭をほぐしながらですが、Haskell勉強中です。

今日、リスト内包表記のサンプルとして取り上げられることの多いqsortのコードを眺めていて気がついたのですが、

qsort[] = []
qsort(x:xs) = qsort smaller ++ [x] ++ qsprt lerger
              where
                smaller = [ a | a <- xs, a<=x]
                larger = [ b | b <- xs, b> x]

リスト内包記法(smallerとlargerの)部分って、どこかで見たことあると思ったらこれってrubyの"each { | a |”にそっくりなんですよね。

xs = [1,2,3,4,5]
xs.each { |a|
  print a if a <= x
}

Haskellの記法は

A ∩ B = { x | x ∈ A and x ∈ B }

みたいな、とおお〜い記憶の彼方にある数学の集合演算の記法をもとににしているようで、rubyのeach構文もきっとこれをもとにしたのだろうなということが今日わかりました(もちろん、たぶんですが....)

Haskellの構文は数学の素養豊な人にはHaskellの記法もスンナリ頭に入るのかもしれませんが、僕の場合だとrubyの構文のほうがやっぱりわかりやすい気がします。今日の今日まで、なぜeachは"each { | x |"という記法なのか?などということは考えたこともなかったので、"あるプログラミング言語の構文がなぜこのような記法となっているのか?”ということに思い至っただけでもHaskellの勉強を始めた意義があるってモン
ですね。それにしてもHaskellの勉強は遅々としてすすみません!(^^ゞ

C#/.NET Frameworkに移行を決意。さらばVC++

in

悩んだ末、Windows系の開発環境をC#/.NET Frameworkに移行することに決めました。長らく親しんだVisual C++は世間的にも傍流へと向かいつつあるいま、慣れたVC++でもう少し行くかどうかは悩ましいところだったのですが、やはり"流れに棹さす"ために移行を決めました。とりあえず、Office2000系で作成されたアプリをC#/.NETに移植(というか書き直)すのが目下のミッション。一日かけてDB周りのコードとListViewあたりの感触をつかむためお試しコードを書いて遊びましたが意外とスムーズに移行できそうな予感がします。

気になっていた実行速度も意外や意外ベンチを取ったわけではありませんが体感的には十分速い。というかむしろVC++より速いのじゃないかという気がしました。それだけ僕の書いていたVC++のコードがイモでまだまだ最適化の余地が大きいということなのでしょう。.NETを使うことで最適化の恩恵をロハ(んな、分けないとは思うけど)で享受できるのはイイ取引な気がします。まぁ、勉強しなくてはいけないことは山とありそうですが、どこまで楽しめるか?ちょっと面白くなってきました。

引数をポインタで渡すと、保存するのかも???

in

C++の実装で関数の引数をリファレンスにするか値またはポインタにするかについては一応の目安があって

  1. オブジェクトを引数とする場合はリファレンスを使う
  2. 組込型を引数とするときは値で渡す
  3. 関数内で組込型を変更する場合はポインタ渡し

もちろん、変更の有無に関してconst付けたりとか、3.についてchar*で文字列を渡す場合はどうなんだ?(僕の場合文字列を渡すには99%がstd::stringにしてますからあまり考えなくとも済みます)とか他にも考えることはあるのですがまぁおおよそこんなガイドラインで不自由今日までやってきました。ところが、積ん読だったC++ スタイルブック (IT Architects’ Archive―CLASSIC MODERN COMPUTING)という本をパラパラ眺めていたら、

非constの参照パラメータは、その関数がオブジェクトに非const演算を実行する可能性があることを示すが、その関数がオブジェクトへの参照を保存するかどうかは示さない。参照の代わりにポインタを使用して、引数として渡されたオブジェクトへの参照またはポインタを、その関数が格納することを示すべきである。
(中略)
ポインタを使用すると、オブジェクトへの参照が格納される可能性があるというヒントを与えることになる。

恥ずかしながらこれ全然知りませんでした。考えたこともなかったです。基本的には上記のようなガイドライン、つまり受け渡しの効率(と変更の有無)だけに注目してインタフェースを決定していたわけです。しかもなぜポインタで受け渡しすることがオブジェクトへの参照が格納される可能性があることになるのかいまひとつよくわかりません。同書の例にもあるように、

class foo
{
  public:
    foo() {};
    void voice_of_woo() { pw_->voice(); };
    void var(const woo& w) { pw_ = &w ; };
  private:
    const woo* pw_;
};

なんてコードもアリにはありなのでvar()が必ずしも

void var(const woo* w) { pw_ = w ; };

が、関数が「オブジェクトへの参照を保存するだろう」と予測できるわけではないと思うし、オブジェクトへの参照を保存するからといって必ずしも引数がポインタである必要はないと思うのですが....少なくとも、少なくとも僕は、関数宣言だけをみて「wooオブジェクトへの参照が保されるんだな」なんてことは気がつかない。どちらの場合も、ドキュメントやソースコードを読んではじめてその挙動を理解するってことになる気がします。

単なる慣習のことを言っているとも思えませんしもう少し突っ込んだ解説が欲しかったのですが、残念ながらその理由は書いてありませんでした。こんな単純なサンプルで説明できることではなくてもっと深淵な理由を孕んでいる気もしますが無知なる僕にはハッキリとしたワケが解りませんでした。かとにかくすっきりしませんね。