■ C++ for Haskeller ■ D for Haskeller ■ C for Haskeller (追記) ■ 2D for Haskeller (追追記) awk for Haskeller
も り あ が っ て ま い り ま し た .とりあえず祭には乗っかっとけ !!
なんとなく Haskell とゆとり教育が同義語になりつつあるような今日この頃,みなさまいかがお過ごしでしょうか ?
以下,偉い人たちのパクリです (略) もうあらかた書き尽くされてますが (略) というわけで,C 言語から C++ への以降という,全くもって面白くもなんともない記事を (略) 対象読者は,C も C++ も Haskell も Scheme も熟知している人です (略)
※ ネタをネタと見抜けない子は,この一連のシリーズ (頭痛が痛い) は見ない方が良いです.
C++ は,もともとは C をインクリメント (++ (文字列の連結関数ではありません)) した言語でしたが,現在 (After C99) では C とは何の関係も無くなってます.
そのため C++ は,以下のような特徴を持った言語となっており,C 言語のプログラマから見るとかなり異質な印象を受けるかもしれません.また,Scheme や Haskell の知識があれば,C++ の理解はより早くなるかもしれません.
・ 参照透明 ・ 純粋関数型言語 (ただし,特殊なトリックを使用することにより,副作用も扱えます) ・ マクロネタプログラミング (このように,いかがわしい単語は積極的に使う) ・ プログラムアズデータ ・ デフォルト (コンパイルタイムオンリー) 遅延評価 ・ 自動メモ化 (call by need)
代表的なプログラムとして,以下のようなものが上げられます.
#include<stdio.h>
template<int n> struct fact{enum{fn = n * fact<n - 1>::fn};}; template<> struct fact<0>{enum {fn = 1};};
main(){printf("%d\n", fact<10>::fn);}
$ g++ fact.cpp $ ./a.out 3628800
C++ はデフォルトが遅延評価なため,結果の画面への出力の際には '\n' により,強制的にサンク (古い用語では,バッファとも言う) をフォース (古い用語では,フラッシュともいう) してやる必要があります.Haskell の >= や do 構文をイメージするとわかりやすいかもしれません.
(と,ここで)
(SICP の stream_cons/car/cdr を template でやろうとしばしがんばる)
(が (駄目 (あたりまえ (後述))))
(実は C++ は文法すらよー知らん子です)
(人生の貴重な数時間を軽く浪費)
(あれれ ? きょうはがんばってはやおきしたはずなのに,なんでもうごごのたそがれどきなんだろう ?) (ぼくのきゅうじつはどこにいっちゃったんだろう ? きんぐくりむぞんにふっとばされたのかなぁ ?) (めいどいんへぶん !!)
(面倒になってきたので略)
(生まれて来てすいませんでした)
// 見かけだおしプログラム #include<stdio.h>
template<int _car, int _cdr>struct cons {static const int car = _car;static const int cdr = _cdr;};
main(){printf("%d\n", cons<1, cons<2, cons<3, cons<4, 5>::car >::car >::car >::cdr);}
気を取り直して.
では,最後に,以上の知識の応用として,fibonacci(10) の値を静的にコンパイルして効率的に出力してみましょう.
#include<iostream> // fibonacci(10) = 55 int main() {std::cout << 55 << std::endl;}
やったね ☆
またへたれっぷりを晒してしまった.ごめんなさい,template とか boost とか全然わかりません.
(というか C++ の基本文法すらもう忘却の彼方です)
もう C++ のわるくちは言いません.template はエライです.ちゃんとセロリも残さず食べます.
とかいうのはどうでも良いとして.template は非常に面白そうだということはわかった.
最初は lisp の macro みたいなもんかねー と思って気軽に始めたんだけど,当り前の話,template はサンクにはならなくて,全部静的に展開されてしまうからマクロみたいに call by name の実装には使えんのね…
※ template<int n> struct ints {static const int i = ints<n + 1>::i;}; とか無理.ints<512> とかまで展開されてコケる.
# いや,Boost まで踏み込めば,何でもできそうですけど… せっかくの休日を潰したくなかったので.
あと,どこまでインスタンス化が進んで,どこが実体生成が遅延されたのかとかさっぱりわからん.そこらへんを出力してくれるとありがたいんやけんど,もしかして遅延評価の表示にはいろいろ問題がある ? コンパイルタイムだから大丈夫そうな気もするけど.
コンパイル通すだけで,エライしっくはっく.難儀やったわー.とりあえず,C++ のプログラムネタをブログに張っている人は,とても偉大だということがよくわかった (裏に隠れている,莫大な数の,いなくなってしまったコンパイルを通らなかったプログラムとネタのこと… ときどきでいいので,思い出してください).
なんというか,Boost みたいなレベルの抽象化ってのは,ある程度以上の規模のシステムやライブラリの構築じゃないと効果を実感できないと思うんだけど,本来それが役に立つべき規模になると,コンパイル時間が非現実的になるような… Boost で組まれた,一番大きなプログラムって何なんだろう ? Boost ?
とりあえず,Modern C++ Design と C++ Template Metaprogramming と exceptional C++ と Boost C++ Library プログラミングは読むべきなのかもしれない.C++ は,それをものにしたときの悟り体験のための学びましょう.それはあなたをより良いプログラマにする上できっと役に立つでしょう (ほんとかなあ).たとえ,実際には C++ を使わなくとも.
# 注 : C++ 0X が制定され, TC++PL 4 th の邦訳が出るまで遅延評価される予定です (2010 年以降 ?).
しっかし,リアルに一番最初のプログラミング言語が Haskell とかいう子も,そのうちボツボツと出て来るのかねぇ.もう来年から,大学の新入生が平成生まれだし.
はてな使ったら負けだと思っている C++ for Haskeller
副作用もモナドも遅延評価も無いのに、プログラムが書けるのかと思うかも知れません。しかし、おどろいたことに可能なのです。
又、副作用が許されている関係上、C++には「変数」という物があります。
変数とは、計算の結果や入力などの値を一時的に仕舞っておく箱の様なものです。また、仕舞っておくだけではなく、後々場合に応じて中身を別の値に変更したりすることが出来ます。
そんな物が役に立つのか、という疑問も尤もです。しかし、意外なことに、変数はC++でプログラムを書くときには頻繁に使う部分なのです。
とかってのが,ジョークにならない世代ってのが出て来たら,なんかすごいな.
うちの大学では,C は必修だったので実感が沸かなかったんですが,何げにもう今では,C を知らないって方が普通みたいな感じらしいですし.
Java ってのが普通なのかな.一番最初が Ruby とか Python ってのも,けっこう多そう.MIT とかだと,Scheme って子も多いのかね ? さすがに,一番最初 Prolog から入ったってのはいなそうだけど w
ちなみに,僕は C → Prolog → いろいろ.という感じでした.まともにネイティブに書けるのは,その二つぐらいかなぁ… 今はもうほとんど ET しか使ってないから,いろいろ怪しいけど.
|