ラムダ算法では、Church booleanを用いて、論理値を以下の様に表わせる。 TRUE := λ x y. x FALSE := λ x y. y すると論理演算子を次のように定義できる。 NOT := λ p. λ a b. p b a AND := λ p q. p q p OR := λ p q. p p q IFTHENELSE := λ p a b. p a b
def iota (s) $s = s rec = lambda do i = $s[0] $s = $s[1..-1] if i == ?* then f = rec[] f[rec[]] elsif i == ?i then lambda {|c| c[lambda {|x| lambda {|y| lambda {|z| (x[z])[y[z]] } } } ][lambda {|x| lambda {|y| x} } ]} else raise "invalid char" end end rec[] end
使い方は、こんな感じだ。irbを使うと便利だ。
irb> t = iota("*i*i*ii") => #<Proc:…> irb> f = iota("**i*i*ii*ii") => #<Proc:…> irb> n = iota("***i*i*i*ii***i*i*i*ii*ii***i*i*i*ii**i*i*ii*i*i*ii**i*i*ii*ii**i*i*ii*i*i*ii") => #<Proc:…>
いまだにラムダ計算がわかりません (スコア:1)
妖精哲学の三信
「だらしねぇ」という戒めの心、「歪みねぇ」という賛美の心、「仕方ない」という許容の心
Re:いまだにラムダ計算がわかりません (スコア:4, 興味深い)
よっしゃ、リンゴとバナナね。 おいしい果物に置き換えれば、 小難しいラムダ算法も簡単になるに違いない!
そもそも、ラムダ算法の教科書なんか眺めても、なんだか意味がわからないし。 どれどれ、例えば、こんなことが書いてあるぞ……。
ほうら、変な記号が並んでいてワケワカメだ。 そういやRubyにもtrue, false, and, or, not, if〜then〜elseってのはあるけど、 ラムダなんちゃらいうこの記号でどうして計算ができるっていうだ?
そこで、リンゴとバナナだ。
使うのはリンゴとバナナだけ、わけの分からない記号は一切使わない。
実はどんなラムダ式も、リンゴとバナナを並べて代用できる、と言ったら驚くかな? さてここからはリンゴとバナナを沢山使うから、先にスーパーに行って、 懐の許す限りリンゴとバナナを買って来よう!
準備は良い? じゃあ、手始めにさっき出てきた、 TRUEとやらをリンゴとバナナに置き換えるよ! 一緒にリンゴとバナナを並べてね!
並べたかな? 順序を間違えちゃ駄目だよ。
甘い香りが漂ってくる。無味乾燥な記号と違って、一目瞭然、とっても美味しそうだね! ん? 今一実感が湧かないって? お金が無くてリンゴとバナナを買えなかった? そうか、まあスーパーで買い占めなんかしても人様に迷惑だし、 ここは臨場感溢れる絵文字を並べて我慢しよう。
言うするまでもなく、σがリンゴでιがバナナだ。 なんて写実的な表現だろう! よだれが出てくるね!
じゃあどんどん行くよ。っていうか、もう面倒だからまとめて書くよ。
うーん、おいしそうだ。え、ANDやORはどうしたって? あんまり続けてると、荒らしモデが付きそうだから自粛したんだ。
ともかく、これでラムダ計算がリンゴとバナナに置き換えられたから、 もうラムダ計算が分かったよね! そう、つまり、「リンゴとバナナはおいしい(でもあんまり沢山有っても飽きる)」ということだ。以上。さあ、帰った帰った。
は? 本当にラムダ式がリンゴとバナナに置き換えられているのか信用できない? 疑い深いなあ、じゃあストーリーの趣旨に合わせて、Rubyプログラムを置いておくから、 自分で試してごらんよ。
使い方は、こんな感じだ。irbを使うと便利だ。
iotaって何かって? なんだかバナナの絵文字ιのことを、そう言うらしいよ。 なので、バナナの代わりにiと書いてある。 リンゴの代わりは*だ。 こっちは陽を浴びて輝く真っ赤なリンゴを表わしているわけさ。
ラムダ計算をリンゴとバナナだけで表わしたバナナ言語を Rubyオブジェクトにコンパイルするのがiota関数だ。 コンパイル
Re:いまだにラムダ計算がわかりません (スコア:1)
有名だから乗ってて然るべきだと思いますがねぇ。unlambdaもRubyにはcallccがあるからunlambdaの実装も楽でしょう。
Best regards, でぃーすけ
Re:いまだにラムダ計算がわかりません (スコア:1, おもしろおかしい)
まず、バナナ2本でこうする。これがラムダだ。
そこにリンゴとバナナを加える。これがオングストロームだ。
もうわかったな?
Re:いまだにラムダ計算がわかりません (スコア:1)
そしてそれが大きく育って、りんごがたわわに手に実るようになるまで育てなさい。
そしてそうやって実った実をひとつ食べて御覧なさい。
あなたが植えた種が持っていたDNAがラムダ関数に与えた入力、あなたが今食べたりんごが実行結果です。
大雑把に言うとそういうこと。
fjの教祖様
Re:いまだにラムダ計算がわかりません (スコア:1, 興味深い)
プログラマの視点から見たラムダ計算はコールバックや関数オブジェクトをさらに
柔軟にしたものと考える事が出来ます。つまり、関数同士で演算を行って新しい関
数を作る事が出来るのがラムダです。
背後にある理論から勉強するより、先にHaskelやC++のboostで実際に使ってみたほ
うが感覚が掴みやすいものの典型かと思われます。
# 間違ってたらレスで指摘よろ
Re:いまだにラムダ計算がわかりません (スコア:1)
関数って実はマクロ展開で表現できるんだなーと思った24歳の春。
関数のインライン展開とかまさにマクロ展開だしねと納得したものであったことよ。
ただし展開順序(関数で言うなら評価順序)は決まってないので式の形によっては展開順序の違いで結果が変わる。
(どう展開しても変わらない式もある。)
また展開が永遠に終わらないような式もある。
この性質のため展開される過程によって計算過程としての関数が表現できる。
(数学では普通、関数と言えば計算過程じゃなくて値の対応関係を表す。)
でも、考えてみれば数学では人間が規則に従って式の書き換えを繰り返すことで様々な計算を実現してるんだからそれを突き詰めて
普通の代数式ですらない純粋な書き換えのためのマクロとしての関数と変数だけからなる形で
計算手順を抽象化したモデルとして書き換えシステムだけを抽出したのがλ計算といえばそう。
ただそんななんで変数と1引数関数定義と書き換え規則だけしかなくて他のオブジェクトもタイプも何もないから、
何か計算をするには関数定義をいろいろに見立てないといけない。
で見立てると論理や自然数、それらを利用した制御構造、そしてそれらを使った各種の計算が記述できることがわかって
エライ人がその記述&計算能力がチューリング・マシンと同等だと証明したと。
そうなってみるとチューリングマシンよりは式を書くのが楽なのでプログラム関係の様々な性質の証明によく使われるようになったと。
(特にそれを拡張した型付きλ計算が人気)
さらにはλの成功にヒントを得て関数ではなくてオブジェクトを基本単位とするσ計算とか、π計算(こっちはよく知らない)とかが近年では出てきたと。
Re: (スコア:0)
>オブジェクトを基本単位とするσ計算とか
全然知らんのですが、もしかして
「メンバ変数が1つだけのオブジェクト」
とかをたくさん使う方法論なんでしょうか??
「複数のメンバ変数が有る1つのオブジェクトは、1つのメンバ変数だけを持つオブジェクトの複数の組み合わせに変形できる」
といったところとか??
#JSPの拡張タグライブラリって、拡張タグのHTML(XML)の「属性」がJavaクラスの「属性」にマッピングされるんだよね。初めて見たときショッキングだったよ。なんとなくメソッド呼び出しの引数にマッピングされるもんだと思い込んでいたので。まあ確かにJavaのメソッド引数は(コンパイル後に)名前情報が残らないからXML属性にマッピングするのは無理なんだけど。
Re:いまだにラムダ計算がわかりません (スコア:1)
これがラムダだ。(リンゴとバナナだと、ほとんど食べれるからダメ)
the.ACount
Re: (スコア:0)
#いえ、本当は私も全然理解してません。ゴメン。
Re:いまだにラムダ計算がわかりません (スコア:1, おもしろおかしい)
実に短絡的に「ランバダ」と読んで大爆笑されました。
#ちゃーららららん、ちゃらららららららーん、な思い出なのでAC
Re: (スコア:0)
抽象化に失敗するとこうなるんですね
Re: (スコア:0)
無駄無駄無駄無駄
アッーーーー!!
Re: (スコア:0)
Re: (スコア:0)
Re: (スコア:0)
for (;;){
}
return truth;
}
Re: (スコア:0)
Re:いまだにラムダ計算がわかりません (スコア:2, 参考になる)
function(n) { return n < 1? 1 : n*arguments.callee(n-1); }(5)
で済みます。
Best regards, でぃーすけ
Re: (スコア:0)
そうだよなあ。
OOP言語に「今アクセスされてるレシーバ」を表すthisとかselfとかいう言葉が有るなら、
関数型(純粋関数型かどうかは問わない)言語にも
「今呼び出されてる関数」を表すcalleeのようなものが有ってしかるべきだ。
というかC言語にだって凄く欲しいぞ。
(まあCは無名関数やローカル関数を原則作れない言語だから、単にグローバルな関数名を呼べば済んでしまうんだけどね)
#MSX-Cではmain()のローカル変数にマシン語を積んだりしたのでAC。
#割り込み処理を置ける領域とスタックが置けるのとが同じ(バンク切り替えを食らわない0