ET のあるくらし
まぁ,なんというか,最近いろんな人 (主に shinh さんと k.inaba さん) がいろんな言語を使いこなしていて素晴らしいなと.
■[Program][Ruby] Code Golf つづき
(この文章を読んで,僕の中で Ruby の株は,mixi ばりに高騰しました)
ゴルフ
(PHP は HTML Preprocessor なので,比較的どうでもよいですが.結局言語はどうでも良くて, k.inaba さんと shinh さんが素晴らしいという,いつもの結論に)
僕も Ruby とか Java とか PHP の素晴らしさを体験して悟りを啓きたいところなんですが,なかなか研究以外で,まとまったプログラミングを練習する時間が取れません (いいわけ)
# こういうプログラムソースが出て来ないヨタ話ならいくらでも書けるのに (プログラマの風上にもおけない)
たまーに,C でネタプログラミングをこのブログに晒す程度で精一杯ですな.今時,関数型言語もスクリプト言語も満足に使えず,お恥ずかしい限り.
僕が一番使いこんでいるプログラミング言語は,ET というちょーマイナーな言語なので,ネット上の誰とも話が合わないのが悲しい.
というわけで,ちょっと ET のプログラミングテクニックを紹介.
ET は,基本的には,リストと論理変数と単一化 (パターンマッチング) を使いまくる言語で,Haskell とか Prolog とかをディープに使っている人ならば,すぐにピンとくるはず !!!
(どう見ても全てマイナーです.何の宣伝にもならない)
まぁ,北海道大学の学生は,演習とかでちょっと使われているらしいので,初歩的なあたりはわかるのかもしれませんが.
ET は,その真価を知るまで,とても使い難い言語 (特に,C とか Java とか手続き型言語しか使ったことが無いような子は…) なので,いろいろ誤解されがちなのが悲しいところ.
# 処理系もライブラリも,そりゃ Java/Ruby/Perl/Python には負けますよ.
ET の真価は,情報付き変数にあり.情報付き変数ってのは,いろんな情報 (ようするに S 式) を付加できる論理変数のことで,情報は追加削除が自由にできる.いろいろな可能性を,例えば *A~(or 1 2 3) とか付けておいて,いざ *A が 2 で決定ということがわかったら,(rmInfo *A) して *A を普通の変数に戻して,(= *A 2) 単一化 (以後,*A は固定されて,再代入は不可になる).
例えば,Prolog とかは,関数型言語と違って,項の評価ではなく,式の推論によって計算が進むので,Lisp とかみたいに式を入れ子で記述はできないんですよね.
なんでかというと,論理変数は,一度値が固定されると,元に戻せないから,+(1, 2) => 3 みたいな簡約や式の値という概念が存在し得ない (ちなみに,Prolog は,項形式だけじゃなくて,普通の中間記法でも 1 + 2 みたいに書けます).パターンマッチングや単一化の力が十分に活かせないんですよね.
eval(add(X, mul(Y, fetch(2, $(1 2 3))))
みたいなのができない.論理変数経由で,eval(式, 評価) fetch(添字, 配列, 要素) みたいに値を取り出さないといけないから (配列のリテラル表記 $(1 2 3) は,SICStas Prolog だったかのもの.もうあんまり覚えて無いから,テキトー.ちなみに ET だと {1 2 3}).
# 関数論理型言語とかだと,ナローイングとかでできたかもしれない… 全然知らないけど.
ET だと,
みたいなルールを定義しておけば.
# あえて,Lisp っぽく S 式記法で書いてる.Prolog みたいな R 式 (Rewrite Expression) 記法も可能
# (eval *i~(*op *x *y), {(isOp *op), (number *x), (number *y)} --> (rmInfo *i), (:= *i (*op *x *y)).
#{} 内の条件を全て満たしたら,ヘッドをボディと置き換えるという変換 (unfold) ルールの集合がプログラム.
みたいなことができる (? は,Prolog とか OCaml とかでいうところの,無名変数 _ みたいなもの.他の全ての変数と違う変数であることが保証される).
というように,こーんな感じの再帰的な評価ルールを追加しておけば.
ちゃんと結果が (手でクエリーを入力すると,一見複雑で面倒に見えますが,普通はプログラムの途中に出てくる中間言語などに使われるものなので.gcc の RTL を手で書く人がいないのと同じですよ).
まぁ,これだけだと非常につまらないのですが,ちゃんと説明するのはかなり大変なのでこの辺で.どうせ誰も興味無いだろうし (ET や自分の研究についてマイナー記事書いてもページビューは稼げないので,やっぱり Ruby とか Python とか勉強すべきだよなぁ).
よーするに,ここらへんの機能を使いこなせるようになってくると,プログラム変換器とかちょっとしたインタプリタとかがとても楽に作れますよー,と.S 式をパターンマッチングでちょー楽にいじくりまわせるし,Prolog とかよりもはるかに効率も良いという (情報を削除するといった副作用も必須では無いし.もちろん,副作用を使った方が効率は良いですが).
結論 : 僕も Java とか PHP とかちゃんと勉強して,はやく世の中の流れに追いつく所存であります.
Prolog と ET は完全に別の言語ですが,単一化の概念を知らないといろいろ厳しいかも.
(1 2 3) みたいなリストと,(*X | *Xs) みたいなリストをマッチングして,*X = 1 と *Xs = (2 3) になることが理解できれば OK.Lisp の car/cdr,ML の fst/snd だね ☆ (*X *Y *Z),*X =1 *Y = 2, *Z = 3 とかもできるけど.
まぁ,Prolog とかだと,マッチングはもっと強力になってて,((*X *Y *Z | *R) *A *B | *C) みたいな感じで,木構造になっているリストを操作しまくるなんてのは,日常茶飯事.
単一化ってのは,双方向のパターンマッチングで,いわば記号で組み立てられた構造の連立方程式を解くような概念.項同士お互いにお互いの変数の中に変数を作っていって構造をどんどん論理変数を具体化しつつ再帰的に作って行くことができる.
ET だと,それに加えて配列や情報付き変数の中身までマッチングできる.{*A *B *C} とかだと,3 要素の配列にマッチする,とか.*A~{*A *B (*C | *R)} とか,3 要素で,最後の要素がリストの配列が情報として付加されている場合にマッチするとか.んで,*C とか *R とかを自由に取り出したり,再び単一化で木構造とかを組み上げていくことも簡単にできる.
… だんだん面倒になってきたので,この辺で.既存の言語と大きくかけ離れた言語なので.せめて Prolog がもっとメジャーだったら,もっと説明が簡単なのに… orz
# Prolog の本はけっこういっぱいありますし,処理系も,SWI-Prolog とか,GUI とかネットワークとか DB とかいろいろすごいライブラリが付いたのがいっぱいあるので,興味がわいた方は触って見ると,世界が広がって良いかもしれません (というか,Prolog は,もともと SQL と動作原理がほぼ同じなので,非常に自然に DB 操作用言語にも成り得るという).僕は,m.hiroi さんのサイトで Prolog の初歩を覚えました.プログラミングテクニックは,Prolog の技芸 (The Art of Prolog) がひじょーーーーーに素晴らしいのですが,もう邦訳は絶版ですからね… 洋書は健在みたいですが.僕は学部時代,研究室の先生に借りて熟読しまくりました.サンプルプログラムを ET で再実装したりもして,それが Prolog と ET の違いとかを深く理解するのに非常に役に立ったと思います (全然違うんですが,当時は何もかも良くわかってなかった.今もですが).
昔の AI ブーム,第五世代計画始動で,Prolog は一気にブームがきて,日本語の本が大量に出たのですが… その反動で,今の冷え込みぐあいには酷いものがあります.
Prolog (というか,ほとんどの処理系は拡張がされまくってるので,もはや純粋な Prolog というよりも,制約プログラミングというより広い概念をサポートするプログラミング言語ですね.SWI-Prolog は,CHR (Constraint Handling Rules) という,より複雑な制約を解消できるソルバーまでライブラリとして持ってるみたいです.CHR も ET のサブセットなんですが) は,凄い言語です.
SICP で散々がんばって得られる抽象化力が,最初からデフォルトなのですから.いわば,Prolog は,SICP の先の言語と言えるでしょう.Lisp でできるから,Prolog を学ばなくても良い,ということにはなりません.その理屈で行くと,C ができるなら Ruby を学ぶ必要はなくなりますから :-)
C++ (STL/Boost) ができるなら,関数プログラミングを学ばなくても良いか,といったら,それは全然違うのと同じですな.
(星の贈り物 2006年5月12日 : あらゆる分野で真の Expert であることはまずありえない より孫引き)
まぁ,私は Prolog の (というか,Logic Programming の.Prolog は,LP の不完全なサブセット) 駄目なところを正しくするための研究をしているわけなので,あんまり Prolog を擁護してもアレなんですが w
# Prolog のどうしようもない癖の強さ (もはや専用言語や DSL のレベル) に比べたら,ET ははるかに素直な汎用プログラミング言語です.
あまりにも Prolog がマイナーなので,ちょっとは広がって欲しいなぁと.関数プログラミング言語 (FPL) がどんだけ発展しようとも,制約プログラミング言語 (CPL) とは抽象度の階層が全く違います (FPL で CPL の処理系が実装できるとかいう話とは,全く違う話ですよ.繰り返しですが.抽象度が低い問題は,抽象度が合った言語の方が,効率的かつ簡潔に表現できるのは,あたりまえの話です.数値計算は FORTRAN,事務処理は COBOL です.なにかをカンタンにできるってのは,ある意味どうでも良い話).
とかいう話はおそらく間違っていて,そういう偉そうなことは,C++/Haskell/ML/Lisp/camlp4 をマスターしてから言うべき > 自分.
C++の素晴らしさ
まぁ,パラダイムを知らないと言語の機能は活かせないから,みんななるべくいろんな言語で経験を積んで,いろんな世界観を知らないと駄目だよ,というあたりまえの結論に行き着くわけですが.
いずれにせよ,だれも全てを知ることが不可能な現代において最も重要なことは,無知の知というか,自分が知らない世界がいくらでもあることを知るという心構えなのかも.何にせよ,満足したらそこどまりという.
僕はもう少し,じゃーねすっぽすっぽ様の素晴らしさを深く深く学ぶべきなのかもしれない.
■[プログラミング][C++]間違えて
一応昔,Effective C++ とか, PLC++ とかは一通り読んだつもりなのですが… もうすっかり忘却のかなたへ.
シンタクスに癖がありすぎる手続き型言語は,ちょっと使ってないとすぐ忘れちゃうんですよね ! (責任転嫁)
まぁ,もはや PLC++ や Modern C++ Design すら時代遅れ感がただようという,恐ろしい言語なんですが.
下手に,ちょっと知識があると,逆に使うのが怖くなって避けがちになってしまうという.昔,「こんなに覚えておかないといけないことがあるのか… C++ ! 恐ろしい子 !!」 とトラウマになった記憶が.
C 言語も C 言語で,いっぱい暗黙の知識はいるんですが,C の場合は計算機アーキテクチャやアセンブリ言語という,比較的汎用的な知識があれば何とかなるのに対して,C++ の知識は,C++ 以外では全く役に立たないような.
# C の暗黙の常識シリーズ : 例えば,配列の要素数とか文字列の長さとかは,2 の巾乗にしておくと,コンパイラが暗黙のポインタ演算のかけ算をシフトに最適化してくれる (かもしれない) から良いよ〜とか.1024 とかにしておけば,<< 10 で桶という.1 + 3.4 ができるステキポリモーフィズム言語 C は素晴らしいですよね ☆ (どうみても複雑怪奇な coercion です)
# 例外安全性とか,やたら賛美している人が多いですが,そもそもアレって,C++ の例外に特有の変態的知識なんじゃないの ? … とかいう話は,exceptional C++ を読んでから言うべきですね.すいません…
例外推論 前編
Exception Inference 後編
そういえば,今日の 「オープンシステム工学特論」 とかで,XML の素晴らしさを学んだわけなんだけど.
業界統一交換形式のメリットを享受するために重要なのは,普及度と標準化の水準ですよね.
となると,XML と YAML のどっちが優れているかなんていうちょっと前に流行った議論は,全くのナンセンスなわけで.
XML が流行っているんだったら,統一形式には XML を使えばよろし.他のが使いたかったら,YAML2XML を書けばよろし.本物の構造化フォーマットならばどれも,それは容易なはず.
ということなのかも.
人間が見やすいとかは,全く見るポイントがズレているというか.ナンセンスなのかも.
まぁ,XML と YAML の,共通処理用中間言語は,S 式になるのかもしれないけどね (笑)
# S 式さえあれば良いという話では全く無い.誤解無きよう.書きやすい形式読みやすい形式を,各々が問題領域に合わせて自由に使えばよろし.という話.
これは,今のプログラミング言語にも言えることだと,僕はずーーーーっと思って来た.
人間が書きやすいとかはどうでも良くて,機械的に処理がしやすい,変換が容易なフォーマットこそが重要なのではないかと.
# まぁ,プログラム合成研究している人間からすれば,プログラムは仕様から自動合成するものだ, 人間がいいかげんに書いている限りバグは入るし,未来は無い,と言いたいところですが (笑) それはまぁ,ここでは置いておく.
プログラムは人間が読み書きするもの,データは人間が読み書きするもの,という固定観念が,XML にせよ,多くのプログラミング言語にせよなんにせよ,発展を制約していると思う.HTML が,見た目と構造をごちゃまぜにしていたせいでどうしようもなくなったのと同じような意味で.本質と見ためは分離して考えるべき.
例えば,Perl の CPAN なんかは,もっともっとはるかにすごいものにだって成り得たわけなんですよ.本当は.なのに,コンクリートな Perl という,具体的すぎる一プログラミング言語で記述されているばかりに,いろいろ残念なことになってしまっているという.
Ruby に CPAN があったら,オイラも Ruby を使いますよ,とかいうことになっちゃう.
■現代という時代は、どのようなプログラミングを求めているのか?
結局ライブラリだ,とかいうどうでもいい話になっちゃう.Java には莫大なクラスライブラリがあるけど,あれはあくまでも Java だけのものであって,無駄が大きすぎる.Java はとてもじゃないけど,汎用プログラミング言語というにはチープすぎる (Java に限らないけど.そもそもこれだけ問題領域が広がった現在,汎用プログラミング言語ってのは古くさい幻なのかもしれない)..NET は方針としては正しいのかもしれないんだけど,やはりコンクリート過ぎる.もっとアブストラクトであって欲しい.じゃないと,ライブラリの腐った仕様に全ての言語が引きずられるという悲惨なことになる.ライブラリの設計は,言語の設計と同じかそれ以上難しい.
これって,莫大な社内重要文章の蓄積を,うっかり特定のアプリケーションフォーマットでやっちゃったっていう大失敗と照らし合わせて見ればわかりやすいとかも.
あれが全部,ロータス 1・ 2・ 3 じゃなくて,XML で保存されてあったら… みたいな.word で全部保存されてるから,全社員 word が強制されるとか.結局,時代が経てば,それらは単なるゴミ貯めになっちゃう.
# いや,CPAN が XML で記述されていれば… とかいう意味じゃないですよ.年のため.仕様記述言語も,まだいろいろと中途半端ですがねぇ… だから研究してるわけですが.いつも言ってますが,私は研究者とかには向いてないので,もっと偉い凄い人達にがんばって欲しいんですがね.なんで世の中は間違った方向にばかりブームが行くのか…
というか,根本的に間違っているのは,プログラムやデータをテキストデータとして扱うという貧弱な発想だな.まずは.高度な IDE のおかげで,だいぶマシにはなってきていると思うけど,全然足りない.
例えば,IDE の上の任意の関数をドラッグアンドドロップすると,関連する関数だけをズルズルとイモ蔓式に引っ張り出してリファクタリングできたりとか.プログラムを,3 D の世界で本当に現実世界の機械部品のように,インタフェースをはめ込んだり外したりと,本当に 「直感的」 に扱えるようになるべきだと思う.
インタフェースが型エラーならば,物理的に穴にはまらないように見えたり.
文章だと,うまく説明できないのがもどかしいのう.
Vista とか xgl が,莫大な量のメモリと高価なビデオカードをユーザに要求し,デフォルトを 3 D にしたとしても,そういう本当の意味での高度なデスクトップを実現してくれるならば,僕は素晴らしいと思う.
まぁ,現実的には,単に見た目が派手になるだけで,本質は何にもかわらないんだろうけどね.コンピュータをコンピュータとして,プログラミングをプログラミングとしてしか見れないという,従来的な価値観こそが,最も有害な固定観念なのかもしれない.
本当に新しい発想は,コンピュータが当り前,IDE があたりまえの,新しい世代 (僕はもう既に,古いタイプの人間です.UNIX と C は最悪のコンピュータウィルスですから) から生まれて来るのかもしれないし,そうあるべきなのだろうけど.今のところ,過去を知らない,新しい世代ほど,逆に無知故の様々な思い込みに縛られているカエルなような気がするけどね.
■コンピュータは人間を進化させるか■ アラン・ケイ氏インタビュー
まぁ,単に現在のコンピュータもウェブも,どうしようもないほど原始的なだけかもしれない.電霊もネミッサプログラムも,まだまだ遠い将来の話になりそうですな (笑) いつカドクラやパラダイム X が現れるのやら (ちなみにソウルハッカーズねた).
う〜ん,長くなりすぎた.眠すぎるので,この辺で投げっぱなしジャーマン.全くまとまりが無い勢いだけの文章になってしまた.
■[Program][Ruby] Code Golf つづき
(この文章を読んで,僕の中で Ruby の株は,mixi ばりに高騰しました)
ゴルフ
(PHP は HTML Preprocessor なので,比較的どうでもよいですが.結局言語はどうでも良くて, k.inaba さんと shinh さんが素晴らしいという,いつもの結論に)
僕も Ruby とか Java とか PHP の素晴らしさを体験して悟りを啓きたいところなんですが,なかなか研究以外で,まとまったプログラミングを練習する時間が取れません (いいわけ)
# こういうプログラムソースが出て来ないヨタ話ならいくらでも書けるのに (プログラマの風上にもおけない)
たまーに,C でネタプログラミングをこのブログに晒す程度で精一杯ですな.今時,関数型言語もスクリプト言語も満足に使えず,お恥ずかしい限り.
僕が一番使いこんでいるプログラミング言語は,ET というちょーマイナーな言語なので,ネット上の誰とも話が合わないのが悲しい.
というわけで,ちょっと ET のプログラミングテクニックを紹介.
ET は,基本的には,リストと論理変数と単一化 (パターンマッチング) を使いまくる言語で,Haskell とか Prolog とかをディープに使っている人ならば,すぐにピンとくるはず !!!
(どう見ても全てマイナーです.何の宣伝にもならない)
まぁ,北海道大学の学生は,演習とかでちょっと使われているらしいので,初歩的なあたりはわかるのかもしれませんが.
ET は,その真価を知るまで,とても使い難い言語 (特に,C とか Java とか手続き型言語しか使ったことが無いような子は…) なので,いろいろ誤解されがちなのが悲しいところ.
# 処理系もライブラリも,そりゃ Java/Ruby/Perl/Python には負けますよ.
ET の真価は,情報付き変数にあり.情報付き変数ってのは,いろんな情報 (ようするに S 式) を付加できる論理変数のことで,情報は追加削除が自由にできる.いろいろな可能性を,例えば *A~(or 1 2 3) とか付けておいて,いざ *A が 2 で決定ということがわかったら,(rmInfo *A) して *A を普通の変数に戻して,(= *A 2) 単一化 (以後,*A は固定されて,再代入は不可になる).
例えば,Prolog とかは,関数型言語と違って,項の評価ではなく,式の推論によって計算が進むので,Lisp とかみたいに式を入れ子で記述はできないんですよね.
なんでかというと,論理変数は,一度値が固定されると,元に戻せないから,+(1, 2) => 3 みたいな簡約や式の値という概念が存在し得ない (ちなみに,Prolog は,項形式だけじゃなくて,普通の中間記法でも 1 + 2 みたいに書けます).パターンマッチングや単一化の力が十分に活かせないんですよね.
eval(add(X, mul(Y, fetch(2, $(1 2 3))))
みたいなのができない.論理変数経由で,eval(式, 評価) fetch(添字, 配列, 要素) みたいに値を取り出さないといけないから (配列のリテラル表記 $(1 2 3) は,SICStas Prolog だったかのもの.もうあんまり覚えて無いから,テキトー.ちなみに ET だと {1 2 3}).
# 関数論理型言語とかだと,ナローイングとかでできたかもしれない… 全然知らないけど.
ET だと,
// *x と *y が数で,(+ 1 2) とかの形だったら,それを ETI の組み込み算術演算を使って評価して,情報付き変数の値を確定する
(as (eval *i~(*op *x *y))
(isOp *op)
(number *x)
(number *y)
:
(rmInfo *i)
(:= *i (*op *x *y)))
// -------------------------------------
// ETI 組み込み算術演算子の判定
// -------------------------------------
(as (isOp +) :)
(as (isOp -) :)
(as (isOp x) :)
(as (isOp d) :)
(as (isOp mod) :)
みたいなルールを定義しておけば.
# あえて,Lisp っぽく S 式記法で書いてる.Prolog みたいな R 式 (Rewrite Expression) 記法も可能
# (eval *i~(*op *x *y), {(isOp *op), (number *x), (number *y)} --> (rmInfo *i), (:= *i (*op *x *y)).
#{} 内の条件を全て満たしたら,ヘッドをボディと置き換えるという変換 (unfold) ルールの集合がプログラム.
[D]>(eval ?~(+ 1 2))
-------------------------D execution ---------------------
----------------------------------------------------------
succeeded.
(eval 3)
みたいなことができる (? は,Prolog とか OCaml とかでいうところの,無名変数 _ みたいなもの.他の全ての変数と違う変数であることが保証される).
// 数は数だよね.自己評価式だから変わらない.
(as (eval *i)
(number *i)
:)
(as (eval *i~(*op *x *y))
(isOp *op)
(number *x)
(number *y)
:
(rmInfo *i)
(:= *i (*op *x *y)))
// *x と *y が数じゃなかったから,数になるまで再帰的に評価を続ける
(as (eval *i~(*op *x *y))
(isOp *op)
:
(eval *x)
(eval *y)
(eval *i))
// 添字が整数だったら,配列から値を取り出して,情報付き変数の値を確定する
(as (eval *v~(getArrayElement *A *i))
(int *i)
:
(rmInfo *v)
(getArrayElement *A *i *v))
// 添字が整数じゃなかったら,整数になるまで評価し続ける
(as (eval *v~(getArrayElement *A *i))
:
(eval *i)
(eval *v))
というように,こーんな感じの再帰的な評価ルールを追加しておけば.
[D]>(eval ?~(+ 1 ?~(x 2 ?~(getArrayElement {1 2 3} 2))))
-------------------------D execution ---------------------
----------------------------------------------------------
succeeded.
(eval 7)
ちゃんと結果が (手でクエリーを入力すると,一見複雑で面倒に見えますが,普通はプログラムの途中に出てくる中間言語などに使われるものなので.gcc の RTL を手で書く人がいないのと同じですよ).
まぁ,これだけだと非常につまらないのですが,ちゃんと説明するのはかなり大変なのでこの辺で.どうせ誰も興味無いだろうし (ET や自分の研究についてマイナー記事書いてもページビューは稼げないので,やっぱり Ruby とか Python とか勉強すべきだよなぁ).
よーするに,ここらへんの機能を使いこなせるようになってくると,プログラム変換器とかちょっとしたインタプリタとかがとても楽に作れますよー,と.S 式をパターンマッチングでちょー楽にいじくりまわせるし,Prolog とかよりもはるかに効率も良いという (情報を削除するといった副作用も必須では無いし.もちろん,副作用を使った方が効率は良いですが).
結論 : 僕も Java とか PHP とかちゃんと勉強して,はやく世の中の流れに追いつく所存であります.
Prolog と ET は完全に別の言語ですが,単一化の概念を知らないといろいろ厳しいかも.
(1 2 3) みたいなリストと,(*X | *Xs) みたいなリストをマッチングして,*X = 1 と *Xs = (2 3) になることが理解できれば OK.Lisp の car/cdr,ML の fst/snd だね ☆ (*X *Y *Z),*X =1 *Y = 2, *Z = 3 とかもできるけど.
まぁ,Prolog とかだと,マッチングはもっと強力になってて,((*X *Y *Z | *R) *A *B | *C) みたいな感じで,木構造になっているリストを操作しまくるなんてのは,日常茶飯事.
単一化ってのは,双方向のパターンマッチングで,いわば記号で組み立てられた構造の連立方程式を解くような概念.項同士お互いにお互いの変数の中に変数を作っていって構造をどんどん論理変数を具体化しつつ再帰的に作って行くことができる.
ET だと,それに加えて配列や情報付き変数の中身までマッチングできる.{*A *B *C} とかだと,3 要素の配列にマッチする,とか.*A~{*A *B (*C | *R)} とか,3 要素で,最後の要素がリストの配列が情報として付加されている場合にマッチするとか.んで,*C とか *R とかを自由に取り出したり,再び単一化で木構造とかを組み上げていくことも簡単にできる.
… だんだん面倒になってきたので,この辺で.既存の言語と大きくかけ離れた言語なので.せめて Prolog がもっとメジャーだったら,もっと説明が簡単なのに… orz
# Prolog の本はけっこういっぱいありますし,処理系も,SWI-Prolog とか,GUI とかネットワークとか DB とかいろいろすごいライブラリが付いたのがいっぱいあるので,興味がわいた方は触って見ると,世界が広がって良いかもしれません (というか,Prolog は,もともと SQL と動作原理がほぼ同じなので,非常に自然に DB 操作用言語にも成り得るという).僕は,m.hiroi さんのサイトで Prolog の初歩を覚えました.プログラミングテクニックは,Prolog の技芸 (The Art of Prolog) がひじょーーーーーに素晴らしいのですが,もう邦訳は絶版ですからね… 洋書は健在みたいですが.僕は学部時代,研究室の先生に借りて熟読しまくりました.サンプルプログラムを ET で再実装したりもして,それが Prolog と ET の違いとかを深く理解するのに非常に役に立ったと思います (全然違うんですが,当時は何もかも良くわかってなかった.今もですが).
昔の AI ブーム,第五世代計画始動で,Prolog は一気にブームがきて,日本語の本が大量に出たのですが… その反動で,今の冷え込みぐあいには酷いものがあります.
Prolog (というか,ほとんどの処理系は拡張がされまくってるので,もはや純粋な Prolog というよりも,制約プログラミングというより広い概念をサポートするプログラミング言語ですね.SWI-Prolog は,CHR (Constraint Handling Rules) という,より複雑な制約を解消できるソルバーまでライブラリとして持ってるみたいです.CHR も ET のサブセットなんですが) は,凄い言語です.
SICP で散々がんばって得られる抽象化力が,最初からデフォルトなのですから.いわば,Prolog は,SICP の先の言語と言えるでしょう.Lisp でできるから,Prolog を学ばなくても良い,ということにはなりません.その理屈で行くと,C ができるなら Ruby を学ぶ必要はなくなりますから :-)
C++ (STL/Boost) ができるなら,関数プログラミングを学ばなくても良いか,といったら,それは全然違うのと同じですな.
(星の贈り物 2006年5月12日 : あらゆる分野で真の Expert であることはまずありえない より孫引き)
289 :デフォルトの名無しさん :2005/09/05(月) 19:58:21
>>288
C++ でユニフィケーションがいつでも書けることと論理プログラミングに
精通しているとは関係がありませんね。Prolog を5年も粘っていれば 誰でも
論理式が日常的なものになりますが、どんなに優秀な C++ のプログラマでも論理式は別物です。
データモデルの構築などという領域では C++ や Ruby、Python といった言語のプログラマ
には想像もつかない奥行きが Prolog にはあります。安定したレベルでの環境に身を置かないと
わからないこともあるのでそういう意味で>>286は不完全で一方的な見解ということになるでしょう。
まぁ,私は Prolog の (というか,Logic Programming の.Prolog は,LP の不完全なサブセット) 駄目なところを正しくするための研究をしているわけなので,あんまり Prolog を擁護してもアレなんですが w
# Prolog のどうしようもない癖の強さ (もはや専用言語や DSL のレベル) に比べたら,ET ははるかに素直な汎用プログラミング言語です.
あまりにも Prolog がマイナーなので,ちょっとは広がって欲しいなぁと.関数プログラミング言語 (FPL) がどんだけ発展しようとも,制約プログラミング言語 (CPL) とは抽象度の階層が全く違います (FPL で CPL の処理系が実装できるとかいう話とは,全く違う話ですよ.繰り返しですが.抽象度が低い問題は,抽象度が合った言語の方が,効率的かつ簡潔に表現できるのは,あたりまえの話です.数値計算は FORTRAN,事務処理は COBOL です.なにかをカンタンにできるってのは,ある意味どうでも良い話).
とかいう話はおそらく間違っていて,そういう偉そうなことは,C++/Haskell/ML/Lisp/camlp4 をマスターしてから言うべき > 自分.
C++の素晴らしさ
まぁ,パラダイムを知らないと言語の機能は活かせないから,みんななるべくいろんな言語で経験を積んで,いろんな世界観を知らないと駄目だよ,というあたりまえの結論に行き着くわけですが.
いずれにせよ,だれも全てを知ることが不可能な現代において最も重要なことは,無知の知というか,自分が知らない世界がいくらでもあることを知るという心構えなのかも.何にせよ,満足したらそこどまりという.
僕はもう少し,じゃーねすっぽすっぽ様の素晴らしさを深く深く学ぶべきなのかもしれない.
■[プログラミング][C++]間違えて
一応昔,Effective C++ とか, PLC++ とかは一通り読んだつもりなのですが… もうすっかり忘却のかなたへ.
シンタクスに癖がありすぎる手続き型言語は,ちょっと使ってないとすぐ忘れちゃうんですよね ! (責任転嫁)
まぁ,もはや PLC++ や Modern C++ Design すら時代遅れ感がただようという,恐ろしい言語なんですが.
下手に,ちょっと知識があると,逆に使うのが怖くなって避けがちになってしまうという.昔,「こんなに覚えておかないといけないことがあるのか… C++ ! 恐ろしい子 !!」 とトラウマになった記憶が.
C 言語も C 言語で,いっぱい暗黙の知識はいるんですが,C の場合は計算機アーキテクチャやアセンブリ言語という,比較的汎用的な知識があれば何とかなるのに対して,C++ の知識は,C++ 以外では全く役に立たないような.
# C の暗黙の常識シリーズ : 例えば,配列の要素数とか文字列の長さとかは,2 の巾乗にしておくと,コンパイラが暗黙のポインタ演算のかけ算をシフトに最適化してくれる (かもしれない) から良いよ〜とか.1024 とかにしておけば,<< 10 で桶という.1 + 3.4 ができるステキポリモーフィズム言語 C は素晴らしいですよね ☆ (どうみても複雑怪奇な coercion です)
# 例外安全性とか,やたら賛美している人が多いですが,そもそもアレって,C++ の例外に特有の変態的知識なんじゃないの ? … とかいう話は,exceptional C++ を読んでから言うべきですね.すいません…
例外推論 前編
Exception Inference 後編
そういえば,今日の 「オープンシステム工学特論」 とかで,XML の素晴らしさを学んだわけなんだけど.
業界統一交換形式のメリットを享受するために重要なのは,普及度と標準化の水準ですよね.
となると,XML と YAML のどっちが優れているかなんていうちょっと前に流行った議論は,全くのナンセンスなわけで.
XML が流行っているんだったら,統一形式には XML を使えばよろし.他のが使いたかったら,YAML2XML を書けばよろし.本物の構造化フォーマットならばどれも,それは容易なはず.
ということなのかも.
人間が見やすいとかは,全く見るポイントがズレているというか.ナンセンスなのかも.
まぁ,XML と YAML の,共通処理用中間言語は,S 式になるのかもしれないけどね (笑)
# S 式さえあれば良いという話では全く無い.誤解無きよう.書きやすい形式読みやすい形式を,各々が問題領域に合わせて自由に使えばよろし.という話.
これは,今のプログラミング言語にも言えることだと,僕はずーーーーっと思って来た.
人間が書きやすいとかはどうでも良くて,機械的に処理がしやすい,変換が容易なフォーマットこそが重要なのではないかと.
# まぁ,プログラム合成研究している人間からすれば,プログラムは仕様から自動合成するものだ, 人間がいいかげんに書いている限りバグは入るし,未来は無い,と言いたいところですが (笑) それはまぁ,ここでは置いておく.
プログラムは人間が読み書きするもの,データは人間が読み書きするもの,という固定観念が,XML にせよ,多くのプログラミング言語にせよなんにせよ,発展を制約していると思う.HTML が,見た目と構造をごちゃまぜにしていたせいでどうしようもなくなったのと同じような意味で.本質と見ためは分離して考えるべき.
例えば,Perl の CPAN なんかは,もっともっとはるかにすごいものにだって成り得たわけなんですよ.本当は.なのに,コンクリートな Perl という,具体的すぎる一プログラミング言語で記述されているばかりに,いろいろ残念なことになってしまっているという.
Ruby に CPAN があったら,オイラも Ruby を使いますよ,とかいうことになっちゃう.
■現代という時代は、どのようなプログラミングを求めているのか?
結局ライブラリだ,とかいうどうでもいい話になっちゃう.Java には莫大なクラスライブラリがあるけど,あれはあくまでも Java だけのものであって,無駄が大きすぎる.Java はとてもじゃないけど,汎用プログラミング言語というにはチープすぎる (Java に限らないけど.そもそもこれだけ問題領域が広がった現在,汎用プログラミング言語ってのは古くさい幻なのかもしれない)..NET は方針としては正しいのかもしれないんだけど,やはりコンクリート過ぎる.もっとアブストラクトであって欲しい.じゃないと,ライブラリの腐った仕様に全ての言語が引きずられるという悲惨なことになる.ライブラリの設計は,言語の設計と同じかそれ以上難しい.
これって,莫大な社内重要文章の蓄積を,うっかり特定のアプリケーションフォーマットでやっちゃったっていう大失敗と照らし合わせて見ればわかりやすいとかも.
あれが全部,ロータス 1・ 2・ 3 じゃなくて,XML で保存されてあったら… みたいな.word で全部保存されてるから,全社員 word が強制されるとか.結局,時代が経てば,それらは単なるゴミ貯めになっちゃう.
# いや,CPAN が XML で記述されていれば… とかいう意味じゃないですよ.年のため.仕様記述言語も,まだいろいろと中途半端ですがねぇ… だから研究してるわけですが.いつも言ってますが,私は研究者とかには向いてないので,もっと偉い凄い人達にがんばって欲しいんですがね.なんで世の中は間違った方向にばかりブームが行くのか…
というか,根本的に間違っているのは,プログラムやデータをテキストデータとして扱うという貧弱な発想だな.まずは.高度な IDE のおかげで,だいぶマシにはなってきていると思うけど,全然足りない.
例えば,IDE の上の任意の関数をドラッグアンドドロップすると,関連する関数だけをズルズルとイモ蔓式に引っ張り出してリファクタリングできたりとか.プログラムを,3 D の世界で本当に現実世界の機械部品のように,インタフェースをはめ込んだり外したりと,本当に 「直感的」 に扱えるようになるべきだと思う.
インタフェースが型エラーならば,物理的に穴にはまらないように見えたり.
文章だと,うまく説明できないのがもどかしいのう.
Vista とか xgl が,莫大な量のメモリと高価なビデオカードをユーザに要求し,デフォルトを 3 D にしたとしても,そういう本当の意味での高度なデスクトップを実現してくれるならば,僕は素晴らしいと思う.
まぁ,現実的には,単に見た目が派手になるだけで,本質は何にもかわらないんだろうけどね.コンピュータをコンピュータとして,プログラミングをプログラミングとしてしか見れないという,従来的な価値観こそが,最も有害な固定観念なのかもしれない.
本当に新しい発想は,コンピュータが当り前,IDE があたりまえの,新しい世代 (僕はもう既に,古いタイプの人間です.UNIX と C は最悪のコンピュータウィルスですから) から生まれて来るのかもしれないし,そうあるべきなのだろうけど.今のところ,過去を知らない,新しい世代ほど,逆に無知故の様々な思い込みに縛られているカエルなような気がするけどね.
■コンピュータは人間を進化させるか■ アラン・ケイ氏インタビュー
インターネットで今起きているのは、ダグ・エンゲルバートが'60年代にデモしてみせたものに似てきているということだ。Googleにエンゲルバート (Engelbart)と打ち込むと、3つめのエントリーは彼が行なったデモのビデオだ。現在のコンピューティングカルチャーの中にいる者は誰でも Googleにアクセスして、90分のビデオを見てエンゲルバートが考えたことを学ぶことができる。しかしそうする者はいない。
まぁ,単に現在のコンピュータもウェブも,どうしようもないほど原始的なだけかもしれない.電霊もネミッサプログラムも,まだまだ遠い将来の話になりそうですな (笑) いつカドクラやパラダイム X が現れるのやら (ちなみにソウルハッカーズねた).
う〜ん,長くなりすぎた.眠すぎるので,この辺で投げっぱなしジャーマン.全くまとまりが無い勢いだけの文章になってしまた.
