Derive Your Dreams

19:52 06/03/30

反応とか

Schemeのマクロは 自分も好きなので、人間コンパイラコンパイラ的に楽しいっていうのは同意です。 ただ、マクロはともかく言語自体が、「なんでもS式」と「型宣言がない」のコンボのおかげな 気がするのですが、Schemeで書いてるとどうもコードが10KB越える辺りで自分の頭の把握能力が 追っつかなくなってしまうもので、最近は敬遠してました。 これは経験と修行でなんとかなるような気がするのでなんとかしたいなーと思い中です。 頑張るます。

テンプレートの型検査は、最低限、実行される可能性のあるinstanceにはコンパイル時にC++の型検査が入るので、 まあなんとか…。そもそもマクロやアセンブリではせいぜいパラメタ多相もどき までしかできなくて別の意味で困るような。module typeもどきになるとPOPL06のアレや例によってそのテンプレートでの実現(実際gcc付属の標準ライブラリでも 使われてたり)ですが、高階テンプレートはお手上げだし そもそも型システムじゃないしで、"まともにできない"のはご指摘の通りかと思います。 ガベコレもそうですね、修論のあいだBoehm GC遅!と言いまくってた身としては…(^^;

Move Semantics は盛り上げまくって下さい!ついていきます。 あと、別の方向の言語機能拡張によって Boost.Lambda のようなライブラリでのソリューションが現状抱える問題点が改善される,という方向性 の方が私は個人的には好きなんですが、 Stroustrup氏自身はわりとこういうのは直接言語として取り込みたがるという印象が なんとなく。

知ってる?

マルチリンガルの時代。 「ある言語を知っている」というのは、自分の場合こんな感じに分類するんですけど

  1. 名前は知ってる
  2. ソースを見たら、その言語で書かれているということはわかる
  3. 他人のソースを参考にしながらならば、一応は何か書ける
  4. 標準的なライブラリやパッケージシステムについて、ざっと把握している
  5. 「その言語っぽい書き方」というのが感覚として掴めている
  6. 何も見ないでも文法的に正しいソースが書ける
  7. 言語の機能はだいたい全部理解している
  8. 何も見ないでも標準的なライブラリなどは結構使える
  9. ...

メインで「使える」と言えるのは 6 からだろうけど、その手前…になるか後ろになるかは 人それぞれ言語それぞれかな…の 5 が、かなり重要なんですよね。例えその言語を普段は 使わなくても、ある言語風の「考え方」っていうのは、他の言語で書くコードにも影響を 与えてくれる。言語を習得するときは最初っから6~7を目指すんじゃなくて、4~5を ゴールとしておくと良いかも、と思っています。4~5まで行った時に性に合ってたら 自然に6~7まで進んじゃうものですし。

私の場合、人に勧めるときも おんなじで、その言語を「使って」欲しいとは全然考えなくて。一向に筆の進む気配が見えない D Memo 改訂版(未公開)の冒頭には ”目標は、「これからもこれまでもDを使うつもりが全くない人でも、このサイトさえ流し読んどけば『Dっていうのはこういう言語なんだぜ』と茶飲み話のネタにはできる感じ」です。” と書いてあるんですが、いっつもそういう勢いで 物を書いてます。はい。

00:49 06/03/30

おしゃれ

ここの93に 驚愕してしまった俺は orz

23:35 06/03/28

λx.(x+1)

驚異の短さ、 C++の無名関数

_1 + 1 // 第一引数(_1)に1を足した値を返す関数

などと言ってみる。要するに Boost.Lambda を使っただけなのでC++使いには何をいまさら感漂いすぎだとは思います けど、そうでない人向けになんとなく。わざわざ言語に組み込まなくても、例えば

int n = 0;
function<int(int)> f = (n += _1); // fは、nに第一引数を足し込んで値を返す関数

cout << f(1); // 1
cout << f(2); // 3
cout << f(3); // 6
cout << n;    // 6

この程度なら、今でも十分可能だし実際よく使うのです。ただし Paul Grahamのアキュムレータの例

template<typename T>
  function<T(T)> foo( T n ) { return (n += _1); } // ダメ

こうは書けなくて(関数fooが終わると変数nの載ったスタック領域が破棄されるのでダメ) 色々面倒になるのがちょいと残念ですが。純粋関数型言語のクロージャやJavaの内部クラスの ように外の変数をimmutableなものとして取り込むのは余裕でできるので許してください的な。

template<typename T>
  function<T(T)> adder( T x ) { return (x + _1); } // OK:第一引数にxを足す関数を返す

↑これは可能。

無名関数の中での関数呼び出しがキモいとか文(if,while,try-catch,...)を 書こうとすると構文がキモいとか副作用のある処理が混じると注意が必要とか… ここまでは自分は特に気にならないんですが…とどめにコンパイルが激しく遅いとか、 実は色々あるんですけど、まあ、こんな感じ。

何が言いたいかというと

Powerfulな言語のインタプリタを書いたり人間コンパイラとなったりするのはなるほど 馬鹿らしいかもしれない。けれど、「Powerfulな言語の人間コンパイラコンパイラとなる」 という選択肢は捨てた物じゃないと思うのですよ。誰か一人が一度書いてしまえば、 もうその後は言語に備わってる機能と思ってみんなが普通に使えるわけで。 例えばBoost.Lambdaがクロージャを実現すれば後はみんなそれを使えばいいし、 State Monadが変数への代入を実現すれば、後はみんなそれを使えばいい。

なんだろうなあ。C++を使っていると、関数型言語の人には、「そこまで(Boost.Lambdaみたいな ことまで)して関数型に近づける努力をするくらいならC++をやめて関数型言語使えば いいじゃん」 と言われることがありますが、それは全然違うよ、と思うのです。 Javaの人にも似たことを言われるんだけどこれも同じ。

C++から、例えばHaskellやOCamlに移ると、functorと型クラスの合いの子みたいな処理が現状 自分の知識では難しいし、 変数のスコープと束縛されたオブジェクトの寿命を一致させる書き方(要はC++の普通のローカル 変数)も見たことがないし、多相型に関する記述力もtemplateと比べてどうも貧弱だし (←これは最近のghcはそうでもない気がする?)、それらをどうにかする人間コンパイラ コンパイラすら見あたらないし自分で書こうとしてもうまくいかないし。副作用周りの話を 除いても、ちょっと表現力の面で捨てる物が多すぎる。

逆にOCamlやHaskellからC++に移ると、パターンマッチとかパターンマッチとかパターンマッチが 無いので頭を掻きむしりたくなりますが、タプルや無名関数やクロージャやカリー化やGCは (多少不格好かもしれませんが)人間コンパイラコンパイラによって実現されているので、 なんとかなってしまう。

…と感じていて、だから C++ なのです。 もちろん、C++のような変態的な実現が"よい"とは思いませんが、というかあの コンパイル速度は流石にしんどいので私もいろいろ浮気してますが、もっとクリーンで 表現力のある言語が出てくるまでは手放せないかなあ、と。

追記

うーん、読み返してみると自分の書いたことに違和感が。別にC++を関数型言語に したいわけじゃなくて、そりゃ無名関数やクロージャはあれば便利だから使うし取り込むん だけど、それは「使える道具を一つ増やすため」でしかない、んだよね。「関数型言語にしたい」 のならいっそのことHaskellやOCamlに移行するのはありだろうけど、「道具を(しかも多少 使い勝手はアレかもしらんけど既に手に入ってる道具を)手に入れる」ために別の言語へと 移行せいというのは、それは、違う。移行先の言語が表現力の面でほぼ 包含してくれるのならばそれでも良いのだけど、ことC++とHaskellやOCamlを比べる限り、 そうは見えない。…と言いたかったらしい。

もちろん C++ ⊇ Haskell とか言いたいわけではなくて。幾らでもHaskellの方が優れている 点はありますし。その点が重要ならHaskellを使うべき。でも、全体としてどっち向きの 包含関係も成り立っちゃいないと思うので、ほげ言語のパラドックス に陥らずに相手の言語のふわふわしたおまけも見極めといて 欲しいな、という感じ。うーん。

21:38 06/03/25

旅に

出たい

camlp4

昔、camlp4(OCaml用のプリプロセッサ)のマニュアルとチュートリアルを見て 全く理解できずに挫折した経験があります。のですが、先日jijixiさんとこ経由で晩ごはんの履歴というCamlp4使いの 方のblogを知って、そちらのコード例を追いながら勉強すれば今度こそわかるんじゃ ないか、と再挑戦開始。

しかしまた4時間くらい苦戦したんですが、えーと、結局、こんな感じかな…

「Parser」はそんなに強力ではないので、文法定義するときに左再帰の除去や左Factoringや ゼロ幅先読みを使わないといけない場面が時々生じて、読むときにはそれを念頭に置いた 方が良いっぽい(?)。で、プリプロセッサとして使うには…

と。なんとなくわかった気がします。Camlp4で書かれたコードは読めるようになりました。 バンザイ。

しかし、その整理された頭で「まったく、最初っからこう説明してくれればいいのに…」と 思いながら マニュアルチュートリアル を もう一度読み直してみると……最初っからそう説明してあるなあ。あれー??

22:27 06/03/22

ほんにゃくこんやく

リファレンスのそこかしこに "To D, or not to D." とか "Et tu, D? Then fall, C!" みたいな微笑ましい文句をつけてみるのが最近のWalter氏のマイブームのようで、 これを訳すべきか訳さざるべきか、それが問題なのです。原文のまま残しておくのは なんとなく負けのような気がするし、でも、下手な日本語に変換してしまうのは無粋だし。 "来た。書いた。クラッシュした!"

んで、D言語のキャッチフレーズを決めようぜスレ なんか建ててノリノリだなあと見ていたら

_ 「"Power, Performance, Productivity" ってちょっと良くない?」
_ 「↑今からでも "P言語" に改名したらどうでしょうか。」
_ 「密かに BCPL→B→C の次の字でもあるしね。」
_ 「じゃあ、Lは? Lisp? そして歴史は繰り返すww」

みんな楽しそうですなあ。や、個人的には、すべての言語はLispに云々…とかは 全く思ってないんですけど。

ひとに勧められた Daniel Powter の 『Bad Day』 という曲が良い案配です。まったり明るく。

23:12 06/03/21

脳力

タッチ・デ・ズノー』 time attack モードで75秒を切れない…。配置の善し悪しに合わせて90±15秒の範囲を 振動し続け中。何回もやれば慣れるかと思ったけれど、変化無いみたい。

能力

はてブで見かけた記事… 固定思考と成長思考。 どっちも広義単調増加を仮定してるという意味で似たり寄ったりにポジティブなのでは。 私なんか「自分の賢さはずっと衰え続けている」と(過去ログを見る限り5年以上は前から) 考えている退化思考タイプなので、実際いつも"昨日の自分"に適う気がしなくて、 その退化を知識や経験で取り繕うために必死に足掻いておりますよ。 これはこれで悪くないと思うんだけどなー。

23:46 06/03/19

you may...

「使う色は黒だけで、人の目にはカラフルに見える絵が描ける」という謎の技術を 持った絵描きさんになった夢をみました。 その微妙に細かい設定はなんなんだ俺?…と起きた瞬間に自問自答したところ、思い当たる ものが一つ。一ヶ月前に読んだ ホロフォニクス なる記事の影響っぽいです。うーむ。

ホロフォニクス録音したデータというのは確かに言われてみればそう聴こえる気もする、 みたいな感じでした。視界に入ってない音源が前にあるという事態を脳が想定できないせいか、 こういう音って全部後ろの方から聴こえると認識してしまう。 そもそも視覚その他の補助情報なし、首を動かすのもなしで、耳だけで前後上下を 聞き分けることってできるもの?でも映像と合わせると面白そう。

Balance the Tree (続)

Syntax Error (2006-03-10) のコメント欄の解が簡潔で巧いですね。 で、そちらを見て思い出しました。この問題、「正の数」しか 出てこないという条件が入っていることで、たぶん簡単になっています。 ゼロが出てくるくらいならもしかしたら大丈夫なような気もしてきましたが、 負の数まで出る可能性がある時の効率的な解き方は、自分でもまだ思いついてないのです。 O(N3) は簡単。それより小さい計算量で解けるだろうか?

00:04 06/03/16

AA折れ線グラフ

今日の一行 03-14 via あちこち。

#!/usr/local/bin/rdmd
import std.cstream;

void main( char[][] arg )
{
    char[int][int] buffer;
    int x, y;

    foreach(_; arg[1]) switch(_) {
        case 'R': buffer[y--][x++] = '/' ; break;
        case 'F': buffer[++y][x++] = '\\'; break;
        case 'C': buffer[y  ][x++] = '_' ; break;
    }

  with(dout)
    foreach(yi; buffer.keys.sort) {
        for(int xi=0; xi<x; ++xi)
            write( xi in buffer[yi] ? buffer[yi][xi] : ' ' ); // umm...
        write('\n');
    }
}

素直に描画しちゃうのがわかりやすくて好みです。 bufferはとても疎で連想配列を使うまでもなくリスト一本で管理できるので、 そこをちゃんと潰して処理すると皆様の解と同じ方法に落ち着く、はず。 D言語specificな話だけど、昔のように、存在しないkeyにアクセスしたらT.initを 返してくれる仕様ならumm...の部分も

typedef char schar = ' ';
schar[int][int] buffer;
...
  write( buffer[yi][xi] ); // !!!

と書けて満足だったのだけどなあ。 あとD界隈ではギャグと思われてる節がないでもないけど dmd -run や rdmd は便利だと思うのです。むしろ最近こいつら経由でしか実行してないかも。 WindowsでもPATHEXTに.dが入ってる始末。

01:09 06/03/15

Wine

そういえば。 PPLの時に飲んだ このワイン がおいしかったのでメモっとこうと思ってメモしたことを忘れてた そのメモが今発掘されたのでここにメモ。まあ、普段は酒類は飲まないのですけど。

でざぱた

woさんの一連の記事(, , ...)が、プログラミングにおけるMonadについてというか、Haskellでは副作用を どうするか問題の物凄くわかりやすい説明になってる気がする。 あとは「コマンドをパイプで繋げてもコマンド」重要とか。パイプと言うと違うかなあ。

ふと、GoFのアレはオブジェクト指向の話だけど、関数型は関数型でよくある「デザイン パターン」を集めて整理してみると面白いんじゃないかと思ってみたり。 少なくとも、いわゆる関数型言語を使ってアプリを書く気は今のところ全く起きないけど、 考え方/思考スタイルは参考にしようと思っている自分のような層には便利そうです。 要は自分が欲しいだけなのですが。 Combinatorパターン。Monadパターン。Foldパターン。Unfoldパターン。 パターンと言うには具体的すぎたりなんか抽象化のレベルが揃ってない気もするけど、 まあ、その辺は適当に。書いてみると既に100個くらいありそうな気がしてきました。

なんだか

やる気がでない

21:29 06/03/13

ネットワーク

数日前にWindowsを再インストールして以来、IEの反応がやけに悪い(お気に入りや戻るボタン やリンクをクリックしてからページ遷移を始めるまでに1秒くらいのラグが…)のだけど、 なんでだろ。と思ったら、裏で Media Player を動かしている時だけは普通に動く。なんで??

※理由・直し方等ご存じの方は伝言板に情報お願いします。m(_ _)m

ネットワーカ

●ある文章を評価する際、「誰が書いたか」ではなく、「何が書いてあるか」によって純粋に判断すべきである。そうしない人は、真実よりも肩書きや知名度が重要と考える人であり、自分の妄想にふけっているだけである。

良い悪い価値判断はともかく、 誰も引用してないのはなんでだろう。

23:26 06/03/09

Balance the Tree

tanakhさんトコで ちょっと触れられてたので、先日作った問題を晒してみます。

各ノードに正の数が振られた二分木を、次のような文法で表現することにします。

Tree ::= PositiveInteger                   // leaf
       | (PositiveInteger Tree Tree)       // (値 左の子 右の子)

例えば (1 (2 1 1) 3) だったら BinTree.png という木を表すということで。こういう二分木のうち、ルートからリーフまでのどの経路の 値の和も等しいヤツを、"balanced" と呼ぶことにします。例えばさっきの例は、1+2+1 と 1+2+1 と 1+3 のどれも和が 4 なので、balanced です。

さて、二分木を見て balanced かどうか判定する問題…では簡単すぎてつまらない。 そこで、二分木の表現から括弧を外して数字の列だけ残したヤツだけ考えます。 つまり例えば 1 2 1 1 3 にはうまく括弧を入れると、(1 (2 1 1) 3) という balanced な二分木にできます。ただし下手に括弧を入れると (1 2 (1 1 3)) のような balanced じゃない 二分木になってしまいますが、それは無視。一方例えば、1 1 1 2 3 という 列には、どう上手く括弧を入れても balanced な二分木は作れません。

というわけで問題。正の数の列が与えられたときに、その列にうまく括弧を入れて balanced な二分木が作れるかどうか判定するプログラムを書いてください。 入力が 1 2 1 1 3 なら yes を返して、1 1 1 2 3 なら no を返すようなプログラムを。

入出力の細かいところは適当にやりやすいように変えてください。 お気づきの方が多そうですが、某Tree Summingが発想元です。 いろいろな解法があるのですが、より速い方がベター。 以下どーでもいい話を挟んだあとで思いっきりヒントになりそうな分析を 書きますので、ノーヒントで解きたい人はここでこのページを閉じるべし。

運転免許

免許更新してきました。 めでたくゴールドカードです。無事故無違反無運転です。

講習で 飲酒自転車運転 も道路交通法違反です、という話をきいて、知らなかったもんで反省中。 言われてみれば当たり前ですね。自転車には乗らないのであんまり関係はなさそうだけど 覚えておこう。あとあの講習ビデオの「あぶない! キキーッ(ブレーキ音)」の繰り返しは すごい頭に残って、通りで車をみるたびに思い出して笑いそうになり危険です。

閑話休題

入力の数列の長さを N とすると、問題文の言ってることに素直に従うと O(N3) で解けます。ちょっと考えると O(N2) の解き方もあります。実は、慣れた人が 思わず O(N3) で解いてしまいそうになるように後で問題文を意図的に複雑に しただけなので、自分はむしろ先に O(N2) の解法を思いついていたりします。 で、もっといい解があるような気がするんだけど思いつかないなーと思いながらこの問題を 出したらtanakhさん達に O(N) で解かれました。ぐは。

要は、LL(∞)構文解析っぽく解くと2乗で、LARL?(1)っぽく解けば線形、というか。 確かに postorder なら bottomup に見ていけるので、そういう方法で 再帰的に作れる木を確定的に再構成する場合一般に使えそう。

00:30 06/03/09

いろいろ

そういえば滋賀でIP unreachableな間に24才になっていたのでした。 お祝いくださった皆様ありがとーございます。20代前半もあと1年!うがー。

最寄りのコンビニで ポーション 売ってたので買ってきました。とりあえず友人が横で一口飲んで「ポーション吹いたwww」 とか言っていますよ。

0.149 Added limited support for implicit function template instantiation キタ━━━━(゚∀゚)━━━━!!!!

23:57 06/03/07

滋賀

PPL2006 行ってました。 初琵琶湖。 初id:syd_sydさん。 初id:soutaroさん。

電通大の高野さんの発表に出てきた "Improving Sequence" というのが面白そうでした。 真の解を返すかわりに、最終的に真の解で終わるような近似解の遅延リストを 返すようにアルゴリズムを書いておいて、その近似解の列がなんらかの順序で単調増加に なっていることが保証できる(そういう列をImproving Sequenceと いう)と、枝狩りや探索の打ち切りみたいな処理が綺麗に書けるというお話、なのだと 思う。例えばリストの長さを返す処理が

let rec ilength n = function [] -> [<'n>] | x::xs -> [<'n; ilength (n+1) xs>]
let length = ilength 0

こんな風になってたとしたら、Improving Sequenceにはその単調性を使うと要素との大小比較が 定義できるので、そうすると (length lst < 5) みたいに普通に書くだけで、リストの5番目 まで見たらlengthの計算を途中で打ち切って判定結果を返してくれるようになるぜ素晴らしい! という。リストの長さ程度の例ではあんまり面白くないけど、例えばImproving Sequenceを 使ってオセロの最善手探索をストレートに記述すると、自動でα-β枝狩りが入ったり しちゃうらしい、などなど。ちなみに発表の内容は、Improving Sequence を生成する関数を 書くとそれがホントにちゃんと単調増加な列を出すようになっているか静的に判定してくれる Scheme 処理系、でした。

あと京大の原さんの発表で jsScheme などというイカれたもの(褒め言葉)の存在を知りました。こちらはフルJavaScriptで書かれて ブラウザ上で動くScheme処理系とのこと。インタプリタモードも、JavaScriptへのコンパイル 機能も両方あり。素晴らしすぎ。ところでなんで自分はSchemeの話ばかり記憶に 残ってるんだろう。

帰り

標識を見ると23kmと書いてあったので、せっかくだから会場から京都まで歩いて 戻ってみようと試みました。まずは琵琶湖沿いを 雄琴 → 西大津 …まで南下。 しかし、西大津駅の案内地図にはちょっと進むと山越えのハイキングコースがあるように 書いてあったので結構探し回ったんですが、車道しかなくて危なそうな道しか 見つからず…。今Googleってみたら、 小関越え という道を突き進めばよかったらしい。リンク先の記事に書いてある老人ホームの入り口と やらまでは行ったんですけど、そこで引き返してしまいました。うーん残念。

仕方がないので三井寺を巡ってから浜大津に出て電車で山越え。しかし直接京都駅に 行ってしまうのは悔しいので、適当に市役所前まで進んでそこから新京極を見て回ったり しながら歩いて駅へ。新幹線。帰宅。

22:56 06/03/03

あーく

例のアレ。 arcdllのメンバの大半はうちの掲示板によく書き込んでくれる方だったりで、 自分は割と関係者度が高いような気がするので何か書こうと思ったんだけど…特に 書くようなこともないんだよなあ。とりあえず 唐突な 342-345 は褒めてるのか皮肉ってるのかわからんけど、もし褒めてるつもり ならスレのPart1とか2辺りを見ると面白いと思うよーとか。

事務的には、統合アーカイバのMLに投げたように、とりあえず一旦バッサリ消しちゃって、 仮にやる気のある人がいたら続けてもらう、でいいんじゃないかなあと。

あとは、HALさんは、個人宛にメール送ってる暇があったらサイトを 復活させるなり統合アーカイバのMLに投げるなり、公の場で、ちゃんと自分の口で説明責任を 果たした方がよいと思いますよ。このまま消えるつもりならともかく、 そうでないのなら、「謹慎」なんぞと言って黙っているのは最もオススメできない行動。

My life is so cool.

"Since U Been Gone" を買いに行こうとCD屋に行ったら試聴できた YUI という歌手の "Merry-go-round" という曲がいいなあと思ったんですけどアルバム内の他の曲がイマイチぴんとこなかったので 結局一枚 sweetbox の "Adagio" を 買ってきましたよ、という流れのお買い物。パッヘルベルのカノンがモチーフの曲を見ると 問答無用で購入してしまう。危険。13曲目の "Miss you" / 威風堂々もお気に入りです。 最近こんなのばっかり聴いてる気がするけど。うーん。

presented by k.inaba (kiki .a.t. kmonos.net) under CC0