トップページ⇒tech
1001コメント388KB

【激突】関数型言語 VS オブジェクト指向言語2

■ このスレッドは過去ログ倉庫に格納されています
0001営利利用に関するLR審議中@詳細は自治スレへ2012/04/07(土) 21:26:47.61
一般的には、オブジェクト指向型言語が優勢でが
一部には関数型言語を崇拝している人もいます

どちらが上なのか、この際はっきりさせましょう

前スレ http://toro.2ch.net/test/read.cgi/tech/1331328955/
0709デフォルトの名無しさん2012/05/07(月) 18:09:54.21
>>707
一体いつからgetterに副作用が無いと錯覚していた?

getで内部キャッシュを生成,保持しても良く
副作用は外から分からずとも、仕様(期待)通り動作すればいい
0710デフォルトの名無しさん2012/05/07(月) 18:47:24.86
しかし実際にはオブジェクトが他のオブジェクトの参照を握ってたりして、
一回のメソッド呼び出しがどんどんたらい回しされてって。
特にオブジェクト指向では多態のためにメソッドのシグネチャを固定化するから、
オブジェクトが他のオブジェクトの参照を握る傾向は強い。
つまり、オブジェクト指向で副作用の局所化はされないし、元々狙っても無い。
オブジェクト指向はオブジェクトに関するコードや変数の依存関係を纏めたってだけ。
これを手続き型で実行すれば、処理がオブジェクトを跨いであちこちに飛び回る。
このとき、副作用は局所化されない。
副作用の局所化するためには、処理がオブジェクトを跨がないように
する必要がある。
しかし、それはオブジェクト指向とは関係無く、手続き型一般における、設計のテクニックだ。
0711デフォルトの名無しさん2012/05/07(月) 19:01:14.42
・シグネチャを固定化 → 他のオブジェクトの参照を握る
・副作用の局所化するため → 跨がないように
この辺前後の関連がよく分からないので詳しくお願いします
0712デフォルトの名無しさん2012/05/07(月) 19:09:28.48
どう言えばよいんだろうね。
オブジェクト指向はオブジェクト単位で色々纏めるが、これらは変数やコードといった、
静的な要素を分類したに過ぎない。
言い換えれば、「ソースコード」をオブジェクト単位で分類したに過ぎない。
一方で副作用はソースコード上には現れない。
実行時に「処理」にくっ付いて現れる。
だから、副作用を局所化するためには、処理の流れそのものを
局所化する必要があって、これは手続き型一般の設計の問題で、
OOだからどうこうという話ではない。
OOはあくまでソースコードをオブジェクト単位で局所化するだけで、
それ以上は助けてくれない。
0713デフォルトの名無しさん2012/05/07(月) 19:26:38.69
>>709
それはgetterを作って良いし副作用が有って良いという意見だな
そういう自由な考え方が定着すれば、OOに反対する人はいなくなると思う
0714デフォルトの名無しさん2012/05/07(月) 19:29:05.25
そんでついでに言うと、
オブジェクト指向は処理の流れに関して凄く無頓着な一面がある。
というのも、仮想関数だ多態だといってな。
そんで、むしろソースコードみたいな静的なものは怖くねーよ、
こんなの綺麗に分類するより、
処理の流れとその副作用の方がよほど怖えーよ、そっち整理しろよ、
って考え方もあって、OOは使いどころが難しく、2chなんかで議論もこじれる。
だから皆だんだん嫌になってきて、
処理の流れそのものを気にしなくて良い関数型に白羽の矢が立ったってわけ。
0715デフォルトの名無しさん2012/05/07(月) 19:48:12.05
俺にとっての副作用を局所化というのは
「この変数を触るのはこの処理だけ」といった
スコープを小さくしたり責任範囲の壁を作ったりすることなんだけど

>>712にとっての副作用の局所化というのは
何かのメソッド呼んだときに変化するN個のオブジェクトのN個の変数とか
その辺りに言及してるのかな?

メソッドの中で自身(A)が持ってる別のオブジェクト(B)のメソッドを呼んだとして
そこから先でファイルアクセスが発生しようと
それはBの範疇なのでAの中での局所化には関係無い
というスタンスかな、俺はね

>処理の流れに関して凄く無頓着
そうかもね
他のオブジェクトは外面(インターフェイスと仕様)しか見ないので
処理の内容は「あとは任せた」って感じだし
0716デフォルトの名無しさん2012/05/07(月) 20:17:37.37
>>715
これは物凄く悪い例なんだけど、
AがBのメソッドを呼び出して、
そのメソッドの中でBがAのメソッドを呼び出したら、
カプセル化は壊れるんだよね。
そんな設計はするな、と言われそうだが、
これが結構良くあるんよ。
親が子の参照を持ってて、子も親への参照を持ってるとか。
0717デフォルトの名無しさん2012/05/07(月) 20:22:02.86
循環参照は注意だが、カプセル化は別に崩れてなくね?
0718デフォルトの名無しさん2012/05/07(月) 20:22:28.51
カプセル化は言葉が悪かった。
整合性だね。
0719デフォルトの名無しさん2012/05/07(月) 20:40:40.96
AがcallするならBはreturnすればいいのに、なぜかBもcallしようとするんだな
なぜreturnを避ける設計をしてしまうのか
0720デフォルトの名無しさん2012/05/07(月) 20:46:15.19
>719 てめぇ、CPSさんDisってんのか?
0721デフォルトの名無しさん2012/05/07(月) 20:49:59.90
>>716
>これが結構良くあるんよ。
わかる・・・

イベントハンドラとかのインターフェイスの実体として子に自身を渡すとか
木構造で高速化のためAが別のA(親)を持つとかは許容出来るけど
一つずつ順にコンパイル出来ないような定義レベルでの循環参照は俺も嫌い
0722デフォルトの名無しさん2012/05/07(月) 21:04:21.69
>>720
末尾呼出しなら問題なさそうだ
問題は、Aのメソッドの途中でAが参照されること
0723デフォルトの名無しさん2012/05/07(月) 21:18:02.26
>>718
言葉が悪いんじゃない。関係ないんだよ。
0724デフォルトの名無しさん2012/05/07(月) 21:29:27.23
>>722
ACTORさん(以下略
0725デフォルトの名無しさん2012/05/11(金) 20:23:27.60
それぞれのオブジェクトがメッセージを投げ合い、
その結果でたらめな順序で副作用が起こっても問題が無い
仮に問題あっても例外投げときゃ無問題

そういうイイカゲンなシステム開発にオブジェクト指向は最適
0726デフォルトの名無しさん2012/05/11(金) 21:46:23.18
さすがにそこまでいい加減なシステムは品質を確保できないだろ。バカにし過ぎ。

「そのように組むことができる」ことと「実際にそうする」は別問題。
Haskellでも副作用が発生する処理と、そうでない処理をごちゃ混ぜにすることは可能は可能だし。
0727デフォルトの名無しさん2012/05/12(土) 18:57:50.97
ここの人らなら詳しそうだから教えてくれ。

0 :: Integer
0 = 0

みたいな感じで、数値を関数化できる言語ってないの?
0関数にラムダ与えたら、ラムダの実行を無視して、
0以外の数値関数にラムダ与えたらラムダを実行するようにしたい
0728デフォルトの名無しさん2012/05/12(土) 19:03:59.81
は?

関数なら 'a -> 'b みたいな型を持ってるはずだけど。
Integer という型は整数の型であって、関数じゃないよ。
0729デフォルトの名無しさん2012/05/12(土) 19:09:46.34
別にそこの式は、数値を関数化したいって例であって
関数を返すとかとは関係ないよ
0730デフォルトの名無しさん2012/05/12(土) 19:21:16.56
「数値を関数化」ってのが、たとえば「文字列を虚数化」みたいに意味不明。

むしろ、
> 0関数にラムダ与えたら、ラムダの実行を無視して、
> 0以外の数値関数にラムダ与えたらラムダを実行するようにしたい
こっちをソースコードで表現できたら、少しはなんとかなるかもしれない。
0731デフォルトの名無しさん2012/05/12(土) 19:41:40.45
あ゛?チャーチ数ディスってんのかメーン
0732デフォルトの名無しさん2012/05/12(土) 23:05:55.96
>>727
「0」というシンボルと、何らかの関数を結び付けたいということ?

関数型ならそもそも、既に何かに結び付けられてるシンボルに
別の値を結び付けるのは再代入そのものだろうし
手続き型関数型問わず、特定リテラルの意味だけを変更するのはちとマズくないかな
0733デフォルトの名無しさん2012/05/12(土) 23:10:21.88
common lispに変数としての値と関数としての値を区別するということなのか
0734デフォルトの名無しさん2012/05/12(土) 23:11:42.30
ごめん、脱字した。

common lisp(のよう)に変数としての値と関数としての値を区別するということなのか
0735デフォルトの名無しさん2012/05/13(日) 00:06:48.19
>>732
Smalltalkなら実現してたべ

value := 0.
value message.
こんな感じで、数値にメッセージを送ると、
数値に紐付いたメソッドを呼ぶ事ができた。
1にメッセージを送れば、1のメソッド。
2にメッセージを送れば、2のメソッドみたいにね。
0736デフォルトの名無しさん2012/05/13(日) 01:07:22.66
本のお題がどういうものだが今一歩ピンとこないが、
チャーチ数を計算する型なしラムダ式処理系なら結構転がってる。
数値や真理値は短形表示できるが。
0737デフォルトの名無しさん2012/05/13(日) 02:06:34.64
>>735
何が言いたいのか分からん
value message と function value は語順が違うだけじゃね?
0738デフォルトの名無しさん2012/05/13(日) 02:12:38.75
>>737
Smalltalkが解らないとなるとlispなら解るかい

(0 arg) 0関数を実行
(1 arg) 1関数を実行

別バージョン
( (lambda ( x arg ) ( x arg ) ) 0 arg ) 0関数を実行
( (lambda ( x arg ) ( x arg ) ) 1 arg ) 1関数を実行
0739デフォルトの名無しさん2012/05/13(日) 02:36:28.73
>>738
なるほど分かった
0や1といったリテラルに関数を割り当てたいってことだね

どっちかというと関数型 vs. オブジェクト指向じゃなくて
静的型 vs. 動的型になりそうな気配
0740デフォルトの名無しさん2012/05/13(日) 02:40:45.66
ところで>>727のいう「ラムダ」の引数は何?
それは何時渡すの?
0741デフォルトの名無しさん2012/05/13(日) 02:44:08.62
>>740
値が関数だって事の説明用だから引数はなんでもいいんですが
0742デフォルトの名無しさん2012/05/13(日) 02:49:18.06
>>741
意味論的には関数型言語の値は「ゼロ引数関数」という関数
0743デフォルトの名無しさん2012/05/13(日) 08:04:27.03
いずれにしろ 0 :: Integer では、関数になってないから
0744デフォルトの名無しさん2012/05/13(日) 10:20:35.18
OO信者の俺ですら数値クラスにメソッド追加するような
コードは勘弁して頂きたい
オープンクラスではしゃぐのは初心者時代で終わらせてほしい
0745デフォルトの名無しさん2012/05/13(日) 11:09:32.18
>>735>>738
シングルディスパッチでは第一引数を特別扱いしてるだけで
x.foo y z と foo x y z に本質的な差は無い

シングルディスパッチ脳には理解出来ないかもしれんけど
0746デフォルトの名無しさん2012/05/13(日) 11:16:35.94
難しい問題だね。
func( o1, o2 )
こういった関数は後からいくらでも追加できるけど、
o1.func( o2 )
との本質的な違いはスコープだけだからな。
多態出来る出来ないの違いは有るけど、それは言語上の制約ってだけだからね。
クラスの外のスコープにいくらでも関数が定義できるのに、
クラスの中のスコープにメソッドを追加することは出来ません、
って制約に一体どれほどの意味があるかって言われると、ねぇ。
特に動的言語では。
0747デフォルトの名無しさん2012/05/13(日) 11:37:40.06
あんたの恣意的な分類で「本質」とか「言語上の制約ってだけ」とか言われても
わかりませんわ。
0748デフォルトの名無しさん2012/05/13(日) 12:25:07.97
別に恣意的ではないと思うけど。
本来、どこのスコープに何を追加しようが勝手なものなんじゃないの?
静的言語では実行効率の理由で制限がかかってくるのも分かるけどさ。
0749デフォルトの名無しさん2012/05/13(日) 12:32:53.64
Haskellでやっつけ
お題の真意が掴めてないので、たぶん条件を満たしてない

http://ideone.com/pTYEL
0750デフォルトの名無しさん2012/05/13(日) 12:39:04.98
0がどうのこうのの話は、まだ続いてたの?
0と1は同じ型だろうから、同じ関数にディスパッチされるのが当たり前だしさ。
0751デフォルトの名無しさん2012/05/13(日) 15:59:42.13
>>742
そういう形式化もあるという程度の話。
0752デフォルトの名無しさん2012/05/13(日) 18:30:14.35
このスレには時代遅れのSmalltalkを使ってる
奇特な人が居るから質問するんだけど、
あのIDEモドキを立ち上げずにプログラム実行する方法無いの?

それと動的型付けで実行が遅いから、せめてボトルネックだけでも
C/C++で書いて実行できないとトイプログラムでしか
使いモノにならないと思うけど、簡単にC/C++のライブラリとリンクできるの?
0753デフォルトの名無しさん2012/05/13(日) 19:25:11.00
たとえばVisualWorksやPharoといったSmalltalk処理系には
headlessといって、サーバーなどの用途に使う目的でIDE抜きで起動したり、
その際に指定した.stファイルを読み込んだり実行できる機能があります。

またGNU Smalltalkのように、標準入出力から使うことに特化して開発された
特殊な処理系もあるのでこういう処理系を最初から選ぶのもよいでしょう。

ただIDE抜きの使い方は他の言語と同様の使い方ができるというメリットがあると反面、
Smalltalkの独自の機能や優位性をかなりスポイルする使い方ということにもなるので
他の言語が選択できる状況であるならば、よほどSmalltalkを使い慣れた人でもなければ
そこまでしてSmalltalkを使うメリットはあまりないような気もします。
GNU SmalltalkやAmber Smalltalkといった特殊なSmalltalk処理系を使っての
Smalltalk入門があまり推奨されないのも同様の理由です。

SmalltalkからC/C++で書いた関数をコールするにはいくつか方法がありますが、
たとえば、商用のSmalltalkであるVisualWorksにはDLL and C Connectという方法が使えます。
http://www.cincomsmalltalk.com/pdf/DLLandCConnectGuide.pdf

PharoやSqueakではVMプラグインを書いてバイトコードを拡張したり、FFIが使えます。
http://wiki.squeak.org/squeak/1448
http://wiki.squeak.org/squeak/1414
0754デフォルトの名無しさん2012/05/13(日) 19:48:37.96
727です。
なぜかOOの話がでてますが関数型の話でOOは関係ありません。
OOPLでも同じ表現ができるというだけです。

で、本題ですが、最終的な目的としては下のようなラムダ演算ができる言語は
存在しないのかという話です。

( 0 (lambda () "true" ) ) 0関数はlambdaを評価せず、nilを返す
( 1 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す
( 2 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す

( (- 1 1 ) (lambda () "true" ) ) 0関数を評価する事になるのでlambda
07557272012/05/13(日) 19:54:33.33
間違えて途中で書き込んでしまいました。すみません。

( 0 (lambda () "true" ) ) 0関数はlambdaを評価せず、nilを返す
( 1 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す
( 2 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す

( (- 1 1 ) (lambda () "true" ) ) 0関数を評価する事になるのでlambdaを評価しない
( (+ 1 1 ) (lambda () "true" ) ) 2関数を評価する事になるのでlambdaを評価しない

数値を関数化できないかというのは、数値を評価したとき、このような
振る舞いをするように数値を定義できなる言語は無いかという事でした。
尤も、言語レベルで最初から数値をチャーチ数と同じように評価できるなら
新たに関数として数値を再定義できる必要は無いんですが。
0756デフォルトの名無しさん2012/05/13(日) 20:00:39.51
>>752
時代遅れってアホか、通信・製造・金融・保険・政府。
お前がしらんだけで第一線で新規開発されとるわ。
国内企業なら、東洋ビジネスエンジニアリングとかが導入してんだぞ。
0757デフォルトの名無しさん2012/05/13(日) 20:17:42.17
F#でやってみた。
拡張メソッド定義してるだけなので、実質「Execute(0, fun () -> printnf "zero")」と同じ

type System.Int32 with
    member x.Execute func = match x with 0 -> () | n -> func()

> (0).Execute (fun () -> printfn "zero");;
val it : unit = ()
> (1).Execute (fun () -> printfn "one");;
one
val it : unit = ()
> (1 - 1).Execute (fun () -> printfn "zero");;
val it : unit = ()
0758デフォルトの名無しさん2012/05/13(日) 20:19:29.56
>>755
Integer と () -> Bool は違う型なので、
同じ数値(関数)の型が文脈に応じて変化する言語でなければ不可能。
07597272012/05/13(日) 20:19:44.31
むちゃくちゃになっていたので直します。何度もすいません。
( 0 (lambda () "true" ) ) 0関数はlambdaを評価せず、nilを返す
( 1 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す
( 2 (lambda () "true" ) ) 2関数はlambdaを評価し"true"を返す

( (- 1 1 ) (lambda () "true" ) ) 0関数を評価する事になるのでlambdaを評価しない
( (+ 1 1 ) (lambda () "true" ) ) 2関数を評価する事になるのでlambdaを評価する
0760デフォルトの名無しさん2012/05/13(日) 20:20:46.22
>>758
できる言語はあるかと聞いているのですが?
あとboolは関係ないですよね
0761デフォルトの名無しさん2012/05/13(日) 20:24:09.03
>>760
じゃあ Integer と (() -> a) -> a

それはともかく、関数型とか全然関係なくって
まともな静的型なら無理って言ってるんだけど、
動的型しか使った事無い馬鹿には分からないかな?
0762デフォルトの名無しさん2012/05/13(日) 20:25:17.06
>>761
だから、できない言語の事は聞いてなくて、出来る言語はあるかと聞いてるんですけど。
0763デフォルトの名無しさん2012/05/13(日) 20:29:16.10
>>762
スレ違いだし問題としても糞詰まらんから
どっか行けって言ってんだけど?
0764デフォルトの名無しさん2012/05/13(日) 20:29:54.03
何か値を返さなきゃならないみたいなので、>>757を修正
nilと値じゃなくてoption型使ってるけど

type System.Int32 with
    member x.Execute func = match x with 0 -> None | n -> func() |> Some

> (0).Execute (fun () -> "zero");;
val it : string option = None
> (1).Execute (fun () -> "one");;
val it : string option = Some "one"
> (1 - 1).Execute (fun () -> 1 - 1);;
val it : int option = None
0765デフォルトの名無しさん2012/05/13(日) 20:32:20.89
>>763
NGにしたいんでトリでも付けてもらえます?
スレ違い以前に話が通じないので
0766デフォルトの名無しさん2012/05/13(日) 20:42:57.75
>>763
まず日本語の通じないお前がどっか行けよ
0767デフォルトの名無しさん2012/05/13(日) 20:44:48.51
>>764
オブジェクトで出来てもあんまり嬉しくないんですが・・・
0768デフォルトの名無しさん2012/05/13(日) 20:46:00.83
>>765>>766
型付けの問題だって理解できない自分の低能さを
日本語の問題にすり替えるなよw
0769デフォルトの名無しさん2012/05/13(日) 20:52:46.02
>>761
「コンセントの付いている車はありますか?」
「軽トラなら無理です」
お前が言ってるのはこういう事だという自覚は有るのか?
普通は「あります」「ありません」この2択だろ
頭おかしいな
0770デフォルトの名無しさん2012/05/13(日) 20:53:58.75
>>767
Int32はラッパークラスとかではなく、プリミティブかつオブジェクトなんだけど。
まぁそれでもダメというならどうしようもない。
0771デフォルトの名無しさん2012/05/13(日) 20:55:35.08
>>764 のような Execute 的な関数を使うのってダメじゃね?
これアリなら難しくも何ともないじゃん


(|.) 0 _ = Nothing
(|.) x f = Just $ f ()

main = do
  print $ 0 |. (\_ -> "zero")
  print $ 1 |. (\_ -> "one")
  print $ (1 - 1) |. (\_ -> "zero")
  print $ (1 + 1) |. (\_ -> "two")
0772デフォルトの名無しさん2012/05/13(日) 20:57:08.31
>>770
すいません。
関数と互換性をもってて欲しいんですよ。
0773デフォルトの名無しさん2012/05/13(日) 21:06:51.99
>>771 >>772
てっきり拡張メソッド的なものを要求してるのかと思ってた。
Scalaなら暗黙型変換あるからできそうな気がする。
0774デフォルトの名無しさん2012/05/13(日) 21:08:02.77
>>773
なるほど。Scalaですか、調べてみます。
0775デフォルトの名無しさん2012/05/13(日) 22:46:41.69
で、Scalaなら出来たの?
0776デフォルトの名無しさん2012/05/14(月) 00:37:38.04
マイナー言語使い共が
可読性皆無のコード書く御題で
型付けの弱さを競うスレはここですか?

時代に逆行してて笑えるwww
0777デフォルトの名無しさん2012/05/14(月) 01:46:05.41
誰だって0と1は同じ型だと考えるのに、違った振る舞いをさせたいってのは、
何か前提がおかしいんだろうね。
元々何がしたかったのか聞ければよいんだけど、
彼にそういった振る舞いが出来るとも思えないしなぁ。
0778デフォルトの名無しさん2012/05/14(月) 07:07:11.76
うーん。一番良く分からんのは、>>767を読むと出題者は>>764を見て
オブジェクトとしてなら「出来ている」認定してるっぽい処だな。
0779デフォルトの名無しさん2012/05/14(月) 07:40:52.01
出題者がOOP厨だからオブジェクトには甘いだけだろ
別に不思議でもなんでもない

もちろん出題者は底なしのアホだけど
0780デフォルトの名無しさん2012/05/14(月) 17:54:42.36
お題:
等確率N種類のカードをコンプするのに必要なガチャ回数のM回試行時の頻度分布から、
最小および最大のガチャ回数と最多頻度のガチャ回数を抽出して出力するコードを書き、
N=10、M=1000000のときの結果とその算出にかかった時間を示せ。

遅い処理系ではMを減らした際の結果を示しても構わないがその旨を明記すること。
0781デフォルトの名無しさん2012/05/14(月) 18:47:07.65
OOPLでもメソッドの中は大体手続き型みたいなもんだから
関数型 VS 手続き型 って感じになりそう
0782デフォルトの名無しさん2012/05/14(月) 19:41:29.94
では手続き型の Squeak Smalltalk で。
最低 10ガチャ、最高 156ガチャ、頻度最多は 23ガチャで 45475回出現。
1.8GHz Core i7 で 66秒程度。(CogVM 使用)

| N M histo cards time |
N := 10.
M := 1000000.
histo := Bag new.
cards := 1 to: N.

time := [
   M timesRepeat: [
      | player |
      player := Bag new.
      [player add: cards atRandom; includesAllOf: cards] whileFalse.
      histo add: player size]
] timeToRun.

^{time. histo min. histo max. histo sortedCounts first} "=> {66128 . 10 . 156 . 45475->23} "
0783デフォルトの名無しさん2012/05/14(月) 19:54:50.29
>>778
これで、できてると言ってる訳ではなくて、
数値を関数化してラムダ演算をするのが目的であって
オブジェクトで雰囲気が近いことできても仕方ない
という事を書いたつもりです。

最終的な目標は>>759の様な(欲を言えばチャーチ数)演算が
できる言語を見つける事です。

>>775
よく知らないので、調べてる最中ですよ。
0784デフォルトの名無しさん2012/05/14(月) 20:17:53.30
チャーチ数?

型無しラムダな処理系なら、学生演習レベルのものならいくらでもあるだろ。
0785デフォルトの名無しさん2012/05/14(月) 21:01:05.79
チャーチ数が欲しいのか>>759が出来る何かが欲しいのかどっちだよ
0786デフォルトの名無しさん2012/05/14(月) 21:07:37.59
>>785
存在すればどちらでも構いません。
ただし誤解されてるかもしれませんが、
チャーチ数というのは、f x.x を直に表現できて
欲しいと思ってる訳ではなく。0なら f x.xと同じ振る舞いを
して欲しいという話で、今までの話とは大きく違いません。
チャーチ数と今までの話は、2以上の時、1回関数が評価されるのか、
2回評価されるのか程度の違いの意味で書いてます。
0787デフォルトの名無しさん2012/05/14(月) 21:14:35.72
間違えました

×2回評価されるのか
○その数だけ評価されるのか
0788デフォルトの名無しさん2012/05/14(月) 21:50:45.36
いよいよ何がしたいのか良く分からないが、
再起でよいんじゃないの?
0789デフォルトの名無しさん2012/05/14(月) 22:49:56.49
>787
型なしラムダ計算でやりたいことがかける?
もしそうならLazy Kやunlambdaを使えばできるな。
0790デフォルトの名無しさん2012/05/15(火) 00:51:10.23
lispならevalいじりゃ何とか出来そうな気がするが
関数名が数値型だったら特別扱いすりゃいいだけだろ
0791デフォルトの名無しさん2012/05/15(火) 08:00:22.83
>>790
変数名が値だったらって何か変だぞ

変数は単に置き換えるのが目的であって
置き換えた後にどのような演算が出来るかというと、確かに何でも出来ると思う
しかしLispは要らない
0792デフォルトの名無しさん2012/05/15(火) 10:10:16.80
関数名って書(ry
0793デフォルトの名無しさん2012/05/15(火) 10:31:41.96
定数0を(\ f x -> x)に置き換えることはできないかもしれない
変数zを(\ f x -> x)に置き換えることはできる
なら定数を使わない言語を考えるのが普通で
定数の定義を書きかえるのは変だ
0794デフォルトの名無しさん2012/05/15(火) 14:05:34.62
定数というか、リテラルかな。
いずれにしろ、リテラルの意味を再定義できる言語、というのは珍しいが、無いわけじゃない。
Forthなんかモード切り替えで、"100" というワードが 10 進にも 16 進にも解釈される、
っていう仕様だったと思ったし。
0795デフォルトの名無しさん2012/05/15(火) 16:30:18.62
>むちゃくちゃになっていたので直します。何度もすいません。
>( 0 (lambda () "true" ) ) 0関数はlambdaを評価せず、nilを返す
>( 1 (lambda () "true" ) ) 1関数はlambdaを評価し"true"を返す
>( 2 (lambda () "true" ) ) 2関数はlambdaを評価し"true"を返す

>( (- 1 1 ) (lambda () "true" ) ) 0関数を評価する事になるのでlambdaを評価しない
>( (+ 1 1 ) (lambda () "true" ) ) 2関数を評価する事になるのでlambdaを評価する

こう言ってるから、処理系の持ってる整数型はそのまま使いたいんだろうと思う。
その上で、整数値を関数としても定義したいと。
良く分からないのは、整数値を関数で定義せず、
引数で渡せばよさそうなものなのに、なぜそうしないかだな。
07967952012/05/15(火) 16:41:00.21
あー、だから、整数の無い処理系もNGだろうし、
単純に整数をfunctorにしたいんだろう。
分からないのは、普通ならパラメータで渡せば直ぐ済むのに、
なぜそうしないかだとおもう。
その辺の説明が何も無いから、誰も答えられないんだと思う。
0797デフォルトの名無しさん2012/05/15(火) 18:43:21.09
チャーチ数でも良いらしいので、Haskellでチャレンジ

http://ideone.com/0LiFz
0798デフォルトの名無しさん2012/05/15(火) 18:49:15.95
ついでに>>780
1.6GHz Core i5 で 3.5秒 (GHC 7.0.4)
最小10, 最大162, 最多頻度23(45003回)

import Control.Applicative
import Data.Ord
import Data.List
import Data.HashTable as H
import System.Random.Mersenne

cardNum = 10
iterateNum = 1000000

count n = (+ n) . sum . map (length . f) . zip [1..n-1]
  where f (x,p) = let q = fromIntegral x / fromIntegral n
                  in takeWhile (< p) $ iterate (\x -> x + (1-x) * q) q
07997982012/05/15(火) 18:50:05.32
続き

main = do
  ht <- new (==) hashInt :: IO (HashTable Int Int)
  gen <- newMTGen Nothing
  mapM_ (trial ht gen) [1..iterateNum]
  xs <- sort <$> H.toList ht
  print $ (fst $ head xs, fst $ last xs, maximumBy (comparing snd) xs)
  where
    trial ht gen _ = do n <- count cardNum <$> (randoms gen :: IO [Double])
                        incr ht n =<< H.lookup ht n
    incr ht k Nothing = H.insert ht k 1
    incr ht k (Just v) = H.update ht k (v + 1) >> return ()
0800デフォルトの名無しさん2012/05/15(火) 20:22:09.35
>>780
R
N = 10
M = 100000 (!= 1000000)
Intel(R) Atom(TM) CPU N455 @ 1.66GHzで、
user system elapsed
180.467 0.084 180.719
最小 10、最大 130、最頻値は4548回の23。

gacha <- function(N, M) {
  print(system.time(t <- table(sapply(1:M, function(x) {
    count <- 0
    card <- logical(length=N)
    while(!all(card)) {
      count <- count + 1
      card[sample(N, size=1)] <- T
    }
    count
  }))))
  print(t[1])
  print(t[length(t)])
  print(t[which.max(t)])
}
0801デフォルトの名無しさん2012/05/15(火) 23:05:25.41
>>780
JavaScriptで多分ベタなOOP
Core2Duo(3.16GHz) Node.js(Windows)で
試行回数=1000000 所要時間=1398msec 最小=10 最大=144 平均=29 最頻=23(44951回)

ソース(※こっちは10000回)
http://ideone.com/DkeKE
0802デフォルトの名無しさん2012/05/15(火) 23:14:59.88
>>801
コードそのものよりもNode.jsがspidermonkeyより
44倍も速いのが興味深い
0803デフォルトの名無しさん2012/05/15(火) 23:30:56.13
Node.jsの中身のV8はJIT持ってるので
0804デフォルトの名無しさん2012/05/15(火) 23:32:18.16
1000000回も試行してるのに各人の最大値がおおきくばらついてるのが気になる。
各処理系の乱数の質の差が反映されているのか。
0805デフォルトの名無しさん2012/05/15(火) 23:52:23.55
何度も気軽に試せるようにCで書いてみた
さすがに速い

http://ideone.com/WPpbW

同じプログラムでも試行ごとに最大値はばらつくみたいね
0806デフォルトの名無しさん2012/05/16(水) 00:08:03.51
書き捨てなのは分かるけど、
せめて void gacha(int n, int m, RESULT *r); くらいにロジック分離しようぜ。
0807デフォルトの名無しさん2012/05/16(水) 12:23:32.14
>>803
しかもx86,x64,ARMに特化されたかなり先進的なJITだしね。
0808デフォルトの名無しさん2012/05/16(水) 13:57:24.59
ところで、数値を関数にしたいと言ってた彼は
結局Scalaで望みのことが出来たの?

それとも、実はSmalltalk辺りのOOPLで
やりたいことは既に出来てて、あとは
「関数型言語で出来ないことがOOPLで出来る!OOPサイコー!!」
って言い出すタイミングをはかってるの?
0809デフォルトの名無しさん2012/05/17(木) 16:49:24.16
Smalltalkは実社会で何の価値もないので
せめてこういうスレのトイプログラムの御題でくらいは
存在感を出さないとね。
■ このスレッドは過去ログ倉庫に格納されています