1 名前:営利利用に関するLR審議中@詳細は自治スレへ mailto:sage [2012/04/07(土) 21:26:47.61 ] 一般的には、オブジェクト指向型言語が優勢でが 一部には関数型言語を崇拝している人もいます どちらが上なのか、この際はっきりさせましょう 前スレ toro.2ch.net/test/read.cgi/tech/1331328955/
294 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 18:35:01.97 ] >>292 まずコード出せ。話はそれからだ。
295 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 18:57:18.70 ] 数値がobjectとしてmethodを持たない言語ではどうするかってお題だったのかよ…
296 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 19:00:25.49 ] >>290 自分の足を自分で撃ちたいなら、それに向いた言語ある、という話、でFA
297 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 19:35:12.73 ] >>290 RubyはメソッドチェインOKなのに 関数型言語はfizz(buzz(gizz))しか認めないんだろ? そりゃ静的型じゃ無理っつーか制限する意味が分からん 後からgizz等を追加できる拡張性あるコードを 書けないならともかく、そうでもないしな
298 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 19:40:42.95 ] >文字列オブジェクトにインスタンス変数(状態)を持たせられるのが強みだなぁ。 -- String "has-a" Integer data HasA = HasA String Integer instance Show HasA where show (HasA s n) = if s == "" then show n else show s fizz (HasA s n) = HasA (s ++ if mod n 3 == 0 then "Fizz" else "") n buzz (HasA s n) = HasA (s ++ if mod n 5 == 0 then "Buzz" else "") n gizz (HasA s n) = HasA (s ++ if mod n 7 == 0 then "Gizz" else "") n main = print $ map (gizz . buzz . fizz . HasA "") [1,3,5,7,15,21,35,105]
299 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 19:47:44.31 ] >>298 似たようなコード書いてたら先に張られてた 個人的には hasA = HasA "" を定義しておくのが好み それはともかく、.演算子使ってるからケチ付けられると思うぜ多分w
300 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 19:56:22.62 ] >>294 おまえはどれかのコード書いたの?
301 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 20:00:44.98 ] ここまでJava無し
302 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 20:30:30.61 ] JavaScriptできた。俺の使ってるブラウザ以外で動くかどうかはわからん。 var def_fizz = function (name, m) { var fun = function () { var tp = typeof this.valueOf(); var n = (tp === 'number') ? this : this.fizzbuzzval if (n % m === 0) { var s = name.charAt(0).toUpperCase() + name.slice(1); if (tp === 'string') { s = this + s; } s = new String(s); s.fizzbuzzval = n; return s; } else { return this; } } ; Number.prototype[name] = fun; String.prototype[name] = fun; } ; def_fizz('fizz', 3); def_fizz('buzz', 5); for (var i = 1; i <= 30; ++i) { document.writeln(i.fizz().buzz()); }
303 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 20:36:17.98 ] >>301 toro.2ch.net/test/read.cgi/tech/1313183984/190 ‥‥ごめんなさい。
304 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 22:09:50.27 ] あるいはこうかな? toro.2ch.net/test/read.cgi/tech/1313183984/191
305 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 22:25:54.85 ] newはダメらしい…>>288
306 名前: ◆QZaw55cn4c mailto:sage [2012/04/13(金) 22:40:22.27 ] >>305 ΟΓΖ 基本データ型のリテラル単独でクラスのインスタンスになり得ない言語である以上、new しないことにははじまらない‥‥。
307 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 22:42:51.66 ] >>306 newを隠蔽すればいいだけ
308 名前:デフォルトの名無しさん mailto:sage [2012/04/13(金) 23:24:10.63 ] いやいや。基本データ型がオブジェクトでなかったり 組み込みクラスにメソッドを追加できない言語では 普通に関数で実装すればいいと思うよ。gizz( buzz( fizz( n ) ) )みたいに。
309 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 00:02:15.95 ] >>308 それが一番シンプルだと思う。 速度も早いだろうしね。
310 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 00:25:40.80 ] >>309 それがね、gizz() buzz() fizz()の三関数をどれも特別扱いせず、 いずれの戻り値もいずれの引数となり得る柔軟さを備える仕様にし、かつ print gizz( buzz( fizz( n ) ) )で 1 "Fizz" "Buzz" "Gizz" "FizzBuzz" "FizzGizz" "BuzzGizz" "FizzBuzzGizz" という出力を得るのは、以外とマンドくさいのよ。 gizz()だけは文字列を返すなどそれぞれの関数のIFを個別に制約すれば子供の使いなみに楽。 つかこういう要求仕様でnewは使うなとか制限もうけること自体が仕様策定の段階でミスなんだろ。
311 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 00:32:11.23 ] その意外と面倒くさいところをどう回避するかがこのクイズの味噌なんだが。(´・ω・`)
312 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 00:51:08.06 ] >>299 > .演算子使ってるからケチ付けられると思うぜ多分w 志村! HasA! HasA!
313 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 01:11:55.03 ] >>311 そしたら、こうだな。 sub com { my ($mod, $zz, $num, $str) = @_; $str .= $zz if 0 == $num % $mod; $str ? ($num, $str) : $num } sub fizz {com(3, 'Fizz', @_)} sub buzz {com(5, 'Buzz', @_)} sub gizz {com(7, 'Gizz', @_)} print "$_: " . gizz(buzz(fizz($_))) . "\n" for qw(1 3 5 7 15 21 35 105); 実効例: $ perl p_FizzBuzzGizzAret.pl 1: 1 3: Fizz 5: Buzz 7: Gizz 15: FizzBuzz 21: FizzGizz 35: BuzzGizz 105: FizzBuzzGizz perlのscalar context/list contextを巧みに?利用してるんで、 それを知らない人には分かりにくいかもしれず、申し訳ないんだか… ※もうちょっと考えて出題して欲しいな、言っちゃ悪いがこういった仕様策定ミスをcodeでカバーすることに何の意味が…
314 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 01:16:27.94 ] perlのscalar context/list contextの説明。 関数の引数にフラグを一個追加したもの つまり、 foo(value, false) ・・・ スカラ呼び出し foo(value, true) ・・・ リスト呼び出し foo(value, flag)関数の説明 flagがfalseの場合、スカラタイプの値を返します。 flagがturの場合、リストタイプの値を返します。 まあ、こんなもん。
315 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 01:24:45.45 ] >>314 志村、ここ、ここ。 my ($mod, $zz, $num, $str) = @_; ↑ $str ? ($num, $str) : $num sub xxx {com(3, 'Fizz', @_)} ↑ print "$_: " . gizz(buzz(fizz($_))) . "\n" と print "$_: " , gizz(buzz(fizz($_))) , "\n" の動作の違い なんか、中途半端に知っている人が出てきたな… 寝るか…。ノシ
316 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 01:45:08.21 ] 核の部分はこれだけか sub com { my ($mod, $zz, $num, $str) = @_; $str .= $zz if 0 == $num % $mod; $str ? ($num, $str) : $num } sub fizz {com(3, 'Fizz', @_)} sub buzz {com(5, 'Buzz', @_)} sub gizz {com(7, 'Gizz', @_)}
317 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 02:13:05.47 ] Perlは良く知らないのだが、 print が ($num, $str) の $num を都合よく読み捨ててくれるのは何故? print fizz(3) の出力は、3Fizz になりそうに思うんだが。よーわからん。
318 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 02:16:18.43 ] >>317 そゆ話は質問スレ ttp://toro.2ch.net/test/read.cgi/tech/1330666216/
319 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 02:40:58.54 ] >>317 結局 Perl のはこのクイズの要求には到達できてなくて(関数単体では完結できていない)、 出力時の文字列との結合でごまかしているってカラクリ。map とかすればズルが露呈する。
320 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 02:52:04.92 ] >>319 ズルはしてないよ。返戻contextの何番目を数値、何番目を文字列とし後続を省略時はundefとなる 利用しているだけでこういうやり方は使うときは使う。 でも、こういうズレたクイズはもういいよ。 関数型言語、オブジェクト指向言語の比較としてこの題材がどういう意味を持っているの? これ単に>>297 とか排除して特定の機能を持った言語を有利に導きたかっただったんじゃない?
321 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:04:43.03 ] じゃあ、map版です。 use 5.12.0; sub com { my ($mod, $zz, $num, $str) = @_; $str .= $zz ;if 0 == $num % $mod; $str ? ($num, $str) : $num } sub fizz {com(3, 'Fizz', @_)} sub buzz {com(5, 'Buzz', @_)} sub gizz {com(7, 'Gizz', @_)} map{say "$_: " . gizz(buzz(fizz($_)))} qw(1 3 5 7 15 21 35 105);
322 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:07:01.05 ] >>321 しくったorz、ifの前の;が余計だった。 use 5.12.0; sub com { my ($mod, $zz, $num, $str) = @_; $str .= $zz if 0 == $num % $mod; $str ? ($num, $str) : $num } sub fizz {com(3, 'Fizz', @_)} sub buzz {com(5, 'Buzz', @_)} sub gizz {com(7, 'Gizz', @_)} map {say "$_: " . gizz(buzz(fizz($_)))} qw(1 3 5 7 15 21 35 105);
323 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:07:30.38 ] そっちじゃなくて、print時の文字列連結による$numの読み飛ばしの件についてでしょ。 print "$_: " , gizz(buzz(fizz($_))) , "\n" だと 3: 3Fizz とかなる。
324 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:14:00.28 ] >>323 「gizz,buzz,fizzの三関数をscalar contexで評価すると判定文字列が得られ list contextで評価すると数値と判定文字列のリストが得られる関数である ただし数値が3,5,7の倍数でない場合は返戻リストの第二要素の判定文字列は undef(文字列として評価すると空文字列)」 という仕様の関数として書いている。 のだよ。code嫁よ。
325 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:17:44.46 ] >>297 の主張もじっさい意味不明なんだけど。。。 メソッドチェーンっていうのは関数の入れ子の呼び出し gizz(buzz(fizz(n))) と実質同じだろ? 組み込みの関数合成関数の使用を禁じている訳ではないのだから、要求通り関数で完結できてさえいれば それらを合成しようがぜんぜん問題ないし、型システムのモデルが足を引っ張っている以外、 なにが不利なのかさっぱり分からん。Perl のズル同様で、関数で完結できてないくせに 合成関数のオーバーロードでつじつまを合わせようとするからなんだかなーとなる。
326 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:19:31.46 ] >>322 "$_: " . ってのを無しでやっみてくんない?
327 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:21:01.17 ] >>325 ずれてないよ。 値と評価文字列をlistdで返戻する。 scalarで評価するかlistで評価するかで 返戻を両方参照するか、そのうちの判定文字列だけを印字出力などのために使うか 選択しているだけだよ。
328 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:25:52.86 ] >>326 sub com { my ($mod, $zz, $num, $str) = @_; $str .= $zz if 0 == $num % $mod; $str ? ($num, $str) : $num } sub fizz {com(3, 'Fizz', @_)} sub buzz {com(5, 'Buzz', @_)} sub gizz {com(7, 'Gizz', @_)} map {print gizz(buzz(fizz($_))) . "n"} qw(1 3 5 7 15 21 35 105);
329 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:27:01.29 ] ニヤニヤ
330 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:27:10.20 ] Perlは醜いラクダどころか白鳥だったのか 他の言語の立場がないな
331 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:27:54.81 ] >>328 しくった。 "n" → "\n"
332 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:38:24.58 ] 天然?
333 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:41:23.69 ] いや、コピペミスw
334 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:43:40.92 ] 多数値の返り値の、主値かそれ以外か、を使う手があるわけか
335 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:43:48.91 ] >scalarで評価するかlistで評価するか そんなの認めるんなら、C++だと型キャストのオーバーロードがあるから楽勝じゃねーか。 operator const char*(); operator const int(); こんなんすりゃ良いんだろ? ちなみに当たり前にオーバーロードがあるから、Fizz(3)とFizz(FizzBuzzObj)との区別もつくし。 C++ですら出来るんなら、この話もう終わりになっちまうじゃねーか。
336 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:45:12.07 ] しかし、ruby以外はズル、という結論にしたくて必死らしいが、 むしろrubyやJavaScriptがチートだろw リフレクション使いまくってるしw
337 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:46:02.04 ] >>335 書け書け。だれもC++をけなしてないぞw 後出しじゃんは、なしね。
338 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 03:59:30.30 ] >>337 すでに >>261 に書いた。
339 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 04:40:06.83 ] C++の>>261 がありなら Haskellの>>283 もありだよな ていうか、>>325 がズルと言ってるの理由がさっぱり分からん 演算子オーバーロードのある言語でそれ使って何が悪いの? 別にmapもできるぜ? main = print $ map (fizz.buzz.gizz) [1,3,5,7,15,21,35,105]
340 名前:339 mailto:sage [2012/04/14(土) 05:12:10.70 ] まあいいや、関数合成のオーバーロードは無しで >>312 の言う通りHasAも隠蔽すれば良いんだな? data HasA = HasA String Integer deriving Eq instance Show HasA where show (HasA s n) = if s == "" then show n else s instance Num HasA where (+) (HasA r m) (HasA s n) = HasA (r ++ s) (m + n) (-) (HasA r m) (HasA s n) = HasA "" (m - n) (*) (HasA r m) (HasA s n) = HasA "" (m * n) negate (HasA s n) = HasA s (-n) abs (HasA s n) = HasA s (abs n) fromInteger n = HasA "" n signum (HasA s n) = HasA s (signum n) fizz (HasA s n) = HasA (s ++ if mod n 3 == 0 then "Fizz" else "") n buzz (HasA s n) = HasA (s ++ if mod n 5 == 0 then "Buzz" else "") n gizz (HasA s n) = HasA (s ++ if mod n 7 == 0 then "Gizz" else "") n main = print $ map (gizz . buzz . fizz) [1,3,5,7,15,21,35,105]
341 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 05:12:11.99 ] F#で演算子オーバーロードなし。 let threadLocal = new System.Threading.ThreadLocal<_>() let makeFizzBuzz name condition (x : obj) = match x with | :? int as number -> threadLocal.Value <- number if condition number then box name else box number | :? string as names -> box (if condition threadLocal.Value then names + name else names) | _ -> failwith "ロジックエラー" let fizz = makeFizzBuzz "Fizz" (fun x -> x % 3 = 0) let buzz = makeFizzBuzz "Buzz" (fun x -> x % 5 = 0) let gizz = makeFizzBuzz "Gizz" (fun x -> x % 7 = 0) > [1; 3; 5; 7; 15; 21; 35; 105] |> List.map (fun x -> gizz(buzz(fizz x)));; val it : obj list = [1; "Fizz"; "Buzz"; "Gizz"; "FizzBuzz"; "FizzGizz"; "BuzzGizz"; "FizzBuzzGizz"]
342 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 05:26:59.93 ] さーて、また関数型言語が不利になるルールが追加されるよー
343 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 05:45:13.46 ] 次は関数型言語使いがお題を出したらいいんじゃないか Rubyじゃこんなの書けないだろ的なのを スレタイの趣旨にも沿ってる
344 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 05:58:16.50 ] それ以前に「使える言語機能を恣意的に制限する」アホを 排除しておかないと比較にも議論にもなんねーんだよ
345 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 05:59:25.03 ] じゃあ、型的に間違ってるプログラムをコンパイルエラーにしてください、という問題はどうだろうか。 fizzbuzzのscheme多値版ね。マクロ使っちゃっちゃったけど。 (define-syntax fizz (syntax-rules () ((_ arg) (receive it arg (fuzzbuzz it "Fizz" 3))))) (define-syntax buzz (syntax-rules () ((_ arg) (receive it arg (fuzzbuzz it "Buzz" 5))))) (define fuzzbuzz (lambda (arg name m) (let* ((is-num (null? (cdr arg))) (s (if is-num "" (car arg))) (a (if is-num (car arg) (cadr arg)))) (if (= 0 (mod a m)) (values (string-append s name) a) (if is-num a (values s a)))))) (define main (lambda (_) (letrec ((loop (lambda (n) (if (<= n 30) (begin (print (buzz (fizz n))) (loop (+ n 1))))))) (loop 1))))
346 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 06:40:24.02 ] ループ禁止で再帰だけで書いてください、とかでも良いな 末尾再帰最適化の無い実装じゃスタックオーバーフロー
347 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 06:51:51.42 ] >>325 組み込みクラスを弄るのはOK 組み込み演算子を弄るのはNG 何故?
348 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 10:00:34.73 ] 初学者といっても 1.プログラミングを学ぶことが目的 2.作りたいものがあって、その手段としてプログラミングが必要 で違う。 1なら関数型言語は良い選択 2ならオブジェクト指向言語やLLの方が早い こういうスレの喧嘩は 1の人の多くは、プログラミングを座学として勉強しただけで実は何も作れない 2の人の多くは、作りたいものが動けばいいというだけでプログラミングに対する向上心がない という現実を反映しているだけ。
349 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 10:10:56.56 ] そしてモマエは 3向上心のカタマリのオレ様にケンカうってんのかーーー カワネーゾ
350 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 10:28:07.46 ] >>343 いまは人工的に作ったお題の信用がなくなってるんだよ そこでまた中立でない人間がお題を出しても、紙屑のように無視されるんじゃないの
351 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 10:47:19.60 ] >>306 QZってこんなスレまで見てるんだな
352 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 11:03:19.87 ] >>350 >>290 や>>325 のような上から目線で変なルール押し付けてくるウザいヤツが 居なければ、言語ごとのアプローチの違いが見れて 遊びとしては面白いんだがなぁ しかもウザいのに限って口だけでプログラム書けないんだ あ、もしかして>>290 や>>325 がこのスレに書いたコード在る?だったら謝るけど
353 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 11:31:51.96 ] すまんけどちょっと確認させてください。これまで出てきた関数型言語の回答で、 関数合成演算子(あるいは関数)を定義が必須な場合でも、関数 fizz だけ用いた fizz 1 や fizz 3 はちゃんと組み込み型の数値や文字列である 1 や "Fizz" を返せるのでしょうか? これって一応要件だと思うんですよね。C++ の回答についても同様です。 Ruby や JS 、Smalltalk の回答はすべてこれが出来ているみたいなんだけど。
354 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 11:49:35.83 ] C++は型キャストをカスタマイズできるからそれで対応したら良いと思う。 FizzBuzzオブジェクトから文字列型と数値型へのキャストをそれぞれ用意すればよし。
355 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 12:28:02.63 ] >>352 今でも十分おもしろいと思うよ。せっそうのない動的言語(OOといえばOOだけど、 ストラウストラップの抽象データ型OOでなくて、ケイの動的OO寄りの考え方)では 可能だけど、理論的にきっちりした関数型言語では実現不可な境界がはっきりしてきてて。 出来ないと分かっていることを出来ないときちんと理由付きで示せる勇気も見れるし。 他方で、動的言語でもすんなりできるとは限らないから各言語での工夫の仕方も興味深い。
356 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 12:29:01.02 ] >>353 >>341 だけど、関数fizz, buzz, gizzをそれぞれ単独で使用した場合をテスト。 > [fizz; buzz; gizz] |> List.map(fun f -> [1; 3; 5; 7] |> List.map f);; val it : obj list list = [[1; "Fizz"; 5; 7]; [1; 3; "Buzz"; 7]; [1; 3; 5; "Gizz"]]
357 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 13:02:32.74 ] あ、すいません。F#さんを見落としていました。 F#以外の関数型言語の回答で、ですね! わざわざの検証、いたみいります。
358 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 14:04:34.17 ] スレッドローカルに状態を保持するのはいいアイデアですね。
359 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 14:10:22.10 ] いいアイデアですねw
360 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 14:42:43.34 ] >>353 >>340 だけどテストしてみた *Main> [map f [1,3,5,7] | f <- [fizz, buzz, gizz]] [[1,Fizz,5,7],[1,3,Buzz,7],[1,3,5,Gizz]]
361 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 14:50:32.97 ] >>353 ついでに>>283 もテスト 正しく動かなかったので修正 fizzT f s = (\x -> Left x) . fizzT' where fizzT' n | f n == 0 = Right s fizzT' _ | otherwise = Right [] これで >>360 と同じコードが動いた
362 名前:361 mailto:sage [2012/04/14(土) 15:07:31.88 ] 面白かったのは>>283 に>>360 を試して動かなかったとき ちゃんとコンパイル時に型エラーになったこと Haskellの型システムやるじゃん、みたいな
363 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 15:54:35.13 ] ねえねえ、1 から 3 までの fizz n の戻り値に対して、文字列なら全大文字化、整数なら 10 倍にして map するコードを [1, 2, "Fizz"] に対して同じことをするコードとまったく同様に書いて 問題なく実行できるかどうか試しみててよ! クイズの要件をみたしていればできるよね! もちろんいうまでもなく追加定義や修正は無しだよ。Ruby や F# のはもちろんできるよ!
364 名前:340 mailto:sage [2012/04/14(土) 16:01:06.17 ] >>360 fizz (HasA s n) = HasA (s ++ if mod n 3 == 0 then "Fizz" else "") (10 * n)
365 名前:340 mailto:sage [2012/04/14(土) 16:02:40.14 ] あ、ごめん>>363 だった それはさておき、後だしでルール追加するの本当に好きだね
366 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:06:40.84 ] >>363 じゃあ、組み込みクラスをグローバルに汚染するのも禁止しようぜ classbox等で一部に制限できるならアリ
367 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:07:57.17 ] というか、ここのHaskellerはどうしてこうも要求仕様を読み取れないくせに あまつさえ勝手な解釈で適当なコード書いてドヤ顔なの? バカなの? 死ぬの?
368 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:11:06.66 ] >>367 誰もお前の頭の中なんて知らないし興味ないんだから 言わないと分からないっつーの ここはお前の要求仕様を満たす場じゃねーし 馬鹿はお前 あと、まさかコードも書かずに議論参加してたとか無いよな 書いたコードのレス示せよ 俺は>>340 書いたぞ
369 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:16:29.12 ] (defmacro defun-fizz-buzz (name divisor) `(defmacro ,name (form) `(multiple-value-bind (int str) ,form (values int (if (= (mod int ,',divisor) 0) (concatenate 'string str (string ',',name)) str))))) (defun-fizz-buzz fizz 3) (defun-fizz-buzz buzz 5) (defun-fizz-buzz gizz 7)
370 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:21:51.37 ] >>367 > ドヤ顔なの?バカなの? 死ぬの? w いまどき、こんな台詞をわざわざ書くやつがいるんだww
371 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:23:54.35 ] 勘違いしたふりして頓珍漢なコード出してきて、 言語や自分の発想の限界とかクリティカルなところはなんとか避けようとしているんだよ。 仕様を取り違えてるよってやんわりチェック方法をしめすと、 ルールを増やすな、後出しだ、仕様が欠陥だってなんやかやクレームつけて 相手が根負けして要求仕様のほうが変わるのを粘り強くじっと待つ戦略なんだ。 ある意味、賢いよ。
372 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:26:54.36 ] お題提出者の解答ってもう出てるの?
373 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:29:32.45 ] >>363 > map するコードを [1, 2, "Fizz"] に対して同じことをするコードとまったく同様に書いて Haskellは静的型付けだから数と文字列を同じリストには入れられないんだ そんなことも知らずに議論してたんじゃないよね?
374 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:32:03.01 ] >>371 >>368 > あと、まさかコードも書かずに議論参加してたとか無いよな > 書いたコードのレス示せよ って書いてるのに示さないってことは、まさか本当にコード書いてなかったの?
375 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:33:37.46 ] まさかの口だけ野郎説浮上www
376 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 16:44:57.11 ] >>363 は問題が頓珍漢だけど(静的型で [1, 2, "Fizz"] はねーよw) 最大限エスパーして書いてみた >>283 はこんな感じ conv (Left n) = Left $ 10 * n conv (Right s) = Right $ map toUpper s main = do print $ map conv [Left 1, Left 2, Right "Fizz"] print $ map conv $ map fizz [1,2,3] >>340 はこんな感じ conv (HasA s n) = HasA (map toUpper s) (10 * n) main = do print $ map conv [1, 2, "Fizz" `HasA` 3] print $ map conv $ map fizz [1,2,3]
377 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 17:03:29.49 ] >> xs = (1..3).map{ |n| n.fizz } => [1, 2, "Fizz"] >> xs.map{ |x| case x when Integer then x*10 when String then x.upcase end } => [10, 20, "FIZZ"] >> ys = [1, 2, "Fizz"] => [1, 2, "Fizz"] >> ys.map{ |x| case x when Integer then x*10 when String then x.upcase end } => [10, 20, "FIZZ"]
378 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 17:45:03.77 ] ◆QZaw55cn4c が出てきて有耶無耶になってるけど 「Javaドカタはコード書けない」説はまだ有効
379 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 17:57:01.51 ] ◆QZaw55cn4c はドカタではないとでも
380 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 18:26:18.94 ] Haskellでコード書くだけで天才になれた気がした15の夜
381 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 18:49:30.59 ] 敵はハスケラだけと思ってるところがウケるw どんな言語使いから見ても口だけ野郎は最底辺のゴミだぞwww
382 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 18:52:07.05 ] おまえもなw
383 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 19:54:38.00 ] コード書けないドカタは「なでしこ」使えば良いんじゃないか? 運が良ければ日本語で書いた戯れ言が 実行されるかもしれないぞ
384 名前:デフォルトの名無しさん mailto:sage [2012/04/14(土) 21:39:02.30 ] >>383 お前は詳しそうだな、その言語。 興味持って使ってみたのか?w
385 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 10:22:56.77 ] まだPythonは出てなかったので class F(object): def __init__(self, f): self.fs = f if hasattr(f, '__iter__') else [f] def __call__(self, x): if isinstance(x, int): s = ''.join(f(x) for f in self.fs if isinstance(f(x), str)) return x if s == '' else s else: return F(self.fs + [x]) fizz = F(lambda x: 'Fizz' if x % 3 == 0 else '') buzz = F(lambda x: 'Buzz' if x % 5 == 0 else '') gizz = F(lambda x: 'Gizz' if x % 7 == 0 else '') print [fizz(buzz)(gizz)(x) for x in [1,3,5,7,15,21,35,105]]
386 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 10:31:36.36 ] F#、さすがだな。
387 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 10:48:20.05 ] >>385 可能なら、 gizz(buzz(fizz(105))) is "FizzBuzzGizz" となるようなヤツをお願いします。
388 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 10:55:31.60 ] >>387 理由を聞いても良い? Pythonでは>>385 のほうがデコレータでも使えて良いんだけど…… @fizz @buzz def bizz(x): if x % 11 == 0: return 'Bizz' else: ''
389 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:03:37.43 ] 静的型言語にIntを返したりStringを返したりする関数って縛りがそもそも無理
390 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:07:14.65 ] >>388 >>254
391 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:08:32.55 ] PerlとかSchemeの、多値をうまく使ったのが一番エレガントかな。 RubyとかJSは、同じようなコードをStringとNumberの両方に生やすとか、 見事に汚い解だw
392 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:13:32.41 ] 関数を返す関数(カリー化されてりゃ普通)にケチがつくとか スゲーなこのスレ
393 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:16:23.31 ] >>390 ちゃんと「など」って書いてるぞー > オープンクラス機構やメソッドのない言語では関数(buzz(fizz(3)) #=> "Fizz" など)で。 それとも高階関数は関数じゃないんですかー
394 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:20:37.25 ] >>389 それだけじゃない。 継続の状態如何で関数に振る舞いを変えさせるとか 関数型には無理な事ばかり要求している。 悪意に満ちたクイズだ。
395 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:23:20.66 ] >>394 素直に考えれば、オープンクラスのある言語が良いという 意見に持っていきたい問題だからね でも出てきた解はRubyが一番汚いという
396 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:25:11.88 ] >>389 型クラスとかってこういう時には使えないの?
397 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:30:40.55 ] 要求による。 問題の「#=> "FizzBuzz"」が意味しているものが、REPLでそのように表示されるもの、 という意味なら、Show型クラスでいいんだけど、String型([Char]型)を要求してるなら無理。
398 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:32:07.68 ] 静的型 vs 動的型スレ向きの問題だよね
399 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:52:01.47 ] >>391 いやあ俺は>>341 のF#(er)が一番エレガントだと思うぞ。 無茶な要求仕様も黙ってすべて満たしつつ、簡潔できれいなコード出してきてるし。
400 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 11:57:38.79 ] >>399 ThreadLocalが一番エレガントって どういうセンスしてんだよ
401 名前:デフォルトの名無しさん [2012/04/15(日) 12:04:48.59 ] #include <stdio.h> #include <string.h> int v,w,t;char buf[4<<10];void*fizz(void*n){if(!t&&!v){v=(int)n;t=!t;} if(!(v%3))goto a;else if(!(w&0x7))goto b;else goto c;a:{size_t (*f)(char*restrict,const char*restrict,size_t);f=(w&0x7)?strlcat :strlcpy;w|=0x1;f(buf,"Fizz",4<<10);}goto c;b:{char b[2<<8];;;;;;;;;;; snprintf(b,2<<8,"%d",v);strlcpy(buf,b,2<<8);}goto c;c:return buf;}void *buzz(void*n){if(!t&&!v){v=(int)n;t=!t;}if(!(v%5))goto a;else if(!(w&0x7))goto b;else goto c;a:{size_t/**/(*f)(char*restrict,const char*restrict,size_t);f=(w&0x7)?strlcat:strlcpy;w|=0x2;f(buf,"Buzz", 4<<10);}goto c;b:{char b[2<<8];snprintf(b,2<<8,"%d",v);strlcpy(buf,b, 2<<8);}goto c;c:return buf;}void*gizz(void*n){if(!t&&!v){v=(int)n;t=!t;} if(!(v%7))goto a;else if(!(w&0x7))goto b;else goto c;a:{size_t (*f) (char*restrict,const char*restrict,size_t);f=(w&0x7)?strlcat:strlcpy; w|=0x1;f(buf,"Gizz",4<<10);}goto c;b:{char b[2<<8];;;snprintf(b,2<<8, "%d",v);strlcpy(buf,b,2<<8);}goto c;c:return buf;}int main(void){printf ("%s\n",gizz(buzz(fizz(105))));}
402 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 12:22:36.47 ] >>368 >あと、まさかコードも書かずに議論参加してたとか無いよな >>395 >でも出てきた解はRubyが一番汚いという このスレの特徴まとめ
403 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 12:34:01.13 ] >>399 グローバル変数ではまずいと考えてThreadLocalにしたみたいに見える まずいという認識がありながら、それを上に報告しないのはおかしい 結局、要求に対する不平不満は正直に言えばいいんだよ
404 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 12:52:12.22 ] コード書けないドカタとプログラマでは綺麗さの認識が違う
405 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 13:06:57.34 ] そうだね お前のコードかけないドカタって概念がおかしいけどねw
406 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 13:29:07.47 ] >>405 あれ?まだこのスレに居たの? 派遣仕事で使い慣れたJavaを使って良いから 早くエレガントな解を出してくださいよwww
407 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 13:32:57.13 ] くやしいんだねw
408 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 13:55:54.00 ] 仕事しろ。言語の勉強はするだけ無駄。 求められているのは動くアプリだ。
409 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 14:23:06.70 ] そもそも関数としての体をなしてないのだから、 副作用を使わずにこのクイズは解けない。 よって純粋な関数型パラダイムでは対応不可。終了。
410 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 14:32:35.61 ] Scalaならいろいろ駆使して書けそうだけどな
411 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 14:38:59.15 ] >>393 この場合の「など」は、関数呼び出しにもいろいろありますよね、 buzz(fizz(3)) 、 (buzz (fizz 3)) 、buzz fizz 3 など―とかの「など」だと思われ。
412 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 15:23:11.97 ] 関数じゃないものを 関数型言語で作るには どうしたらいいのだろうか?
413 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 15:27:19.67 ] >>409 副作用なしに解いたSchemeさんが涙目です
414 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 15:35:03.47 ] >>411 三つ目が>>385 だね(カリー化されてれば) それとも見た目だけの問題?
415 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 16:42:00.03 ] F#でThreadLocal等の副作用もないバージョン。 type MainBuilder() = member this.Return x = x |> List.map (function | _, Some names -> box names | number, None -> box number) let main = MainBuilder() let makeFizzBuzz name condition (x : obj) = match x with | :? int as number -> number, if condition number then Some name else None | _ -> let number, names = x :?> int * string option number, if condition number then (defaultArg names "") + name |> Some else names // fizz, buzz, gizzの定義は>>341 と同じなので省略 > main { return [1; 3; 5; 7; 15; 21; 35; 105] |> List.map (fun x -> gizz(buzz(fizz x))) };; val it : obj list = [1; "Fizz"; "Buzz"; "Gizz"; "FizzBuzz"; "FizzGizz"; "BuzzGizz"; "FizzBuzzGizz"]
416 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 17:46:44.23 ] 新ルール「カリー化禁止」
417 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 17:53:43.12 ] >>415 mainがダウト、なんじゃないか?
418 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:08:11.82 ] >>417 main { return ... } 部分をただのコードブロックとみせかけて 実は戻り値を変換しているという作戦だったのに、バレたか。
419 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:31:37.86 ] Smalltalkが流行らないように関数型メインは流行らないよ
420 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:34:04.58 ] ついに「流行らない」以外に縋るものがなくなっちゃったか
421 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:34:51.92 ] 副作用ありとは言え、唯一まともな解出しててF#△だったのに この期に及んで汚ないチートとかなにこのものすごい残尿感。
422 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:40:05.54 ] .NET発表時のHaskell.NETはどこに行ったんだよ?
423 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:43:46.95 ] マクロ使っていいならそもそも多値なんぞ使わんでも楽勝だろ。
424 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:47:39.47 ] FizzBuzzって流行ってるけど何が面白いの?
425 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:52:45.85 ] 低能はFizzBuzzすら書けないという事実が面白い
426 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 18:53:02.18 ] >>423 具体的にドーゾ
427 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:04:47.51 ] オープンクラスとか副作用有り等の 汚いコードだけが「合格」www 勝手に判定してる(コード書けない)バカのセンスが露呈してますな
428 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:05:21.22 ] >>423 perl書いたのオレなんだけれどもさ、その通りなんだよな…
429 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:08:10.88 ] C#とかも関数型言語のエッセンスを取り入れるけど すげえ無理矢理くさくて笑えるw 関数型がオブジェクト指向を取り入れるのはもっと自然なのに オブジェクト指向っていうかC系列はもう駄目なんだと思う
430 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:18:55.29 ] 守らなければならない資産がたくさんあるからな そりゃ無理やりくさくもなるさ
431 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:28:01.70 ] 後付で入れなきゃならなくなる時点で失敗だったはずなんだけどなぁ。 最近のC#の機能なんてC#以前から概念として存在してたはずなのに。 必要ないという当初の目論見は外れてるわけだ。 というか、資産っていうのはC風の構文そのものなんだよね・・・ C風じゃないとヤダヤダいう人が多すぎてD言語とかいちいち作られてる気がする。 C++、Java、C#、D言語 このへんは全て老害でしょ。
432 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:30:26.05 ] C#、D言語は設計に一貫した思想がないからアホっぽくなるのは仕方ない。
433 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:41:07.47 ] fizz 1 -- "1" fizz 3 -- "Fizz" buzz 5 -- "Buzz" buzz fizz 15 -- "FizzBuzz" だったらHaskellでも解ける?
434 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:45:23.42 ] 可変長引数とかさーー
435 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:50:00.84 ] >>431 C系列でまともなのはCだけ
436 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:50:26.06 ] >>433 型の不整合が生じるから無理
437 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 19:52:02.10 ] >>432 C#はどんどんダメな方向に向かってる気はするわー。
438 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:01:50.15 ] Javascriptは結構好きなのよん > C系文法族
439 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:11:47.98 ] >>406 >>303-304
440 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:19:32.18 ] >>431 後付で入れてもらったのがScala、Clojure、F#でしょ なんで後付を悪く言うのかな
441 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 20:41:24.35 ] C#は言語設計に一貫性がなく節操のないところが最大の魅力 偉い人にはそれがわからんのです
442 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:08:30.57 ] >>440 アホか それらは最初から関数型言語として作られてるでしょ。 関数型は糞、オブジェクト指向最高ってスタンスで作ってたはずのもんが なんで今更関数型の要素を入れようとするんだよ。
443 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:16:51.80 ] >>439 オーバーライドした toString() を println() に暗黙に呼ばせるとかいう 使い古されたチートをキメ顔で出してこられても…。 new myInteger(3).fizz() が "Fizz" を返せるとか少しは挑戦しようよ。
444 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:17:08.32 ] 「.Netファミリーに関数型言語入ったからC#でも使えるようにすっか!」 くらいのノリだろ。たぶん dynamic型導入したときもそんな感じだったし
445 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:18:37.55 ] いやC#の場合は「C#で〜が出来ないと言わせない」という一貫した姿勢があると思う。 もともとJavaへの嫉妬から始まった言語だし。
446 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:21:52.66 ] >>442 手続き型言語がまずあって、 そこへOOの機能を取り入れた。 こんどはさらに関数型の機能も取り入れようとしているだけ。
447 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:40:30.50 ] C#厨ってVB.NETをVB厨のための言語って馬鹿にしてたけど C#だってCっぽくないとヤダヤダっていう老害のために 無理矢理作ってるんだから全然人のこといえねーわ。 ラムダとかそんなに良いんならなんで最初から関数型言語使わないんだよw
448 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:46:15.09 ] >>442 > 関数型は糞、オブジェクト指向最高ってスタンスで作ってたはずのもんが > なんで今更関数型の要素を入れようとするんだよ。 オブジェクト指向最高はそうかもしれないが、 関数型は糞なんて言ってないだろ。 現実世界における物質(オブジェクト)に対応づけやすい 自然な発想に基づくオブジェクト指向。 そこに便利な関数型を取り入れただけ。 りんごの方程式とは何か?を考えれば オブジェクト指向と関数型の関係がわかるだろう。
449 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:48:54.81 ] C#作った奴らはvoidを型と思っていなかった。 だから、C#じゃクロージャ作るのに引数や戻り値にvoidがあると作れないw やるには予めデリゲートを定義しなきゃならん。 クロージャを使うのを考えさせられる。 ありえん。手軽さが全然ない。 F#はローカル変数(厳密には違うが)を定義するのもクロージャを定義するのも同じ手間しかかからない。 クロージャをバンバン使っていけるのでクロージャの応用もどんどん閃ける。 F#やった方がC#が上手くなるという現実。 C#はやればやるほど馬鹿になる言語。
450 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:50:04.90 ] 速度やメモリ・言語ごとの風習で最適かどうかは変わるのだろうけれど、 関数型でOOPをするときは、返り値として変更したオブジェクトを返すより、新たなオブジェクトを返したほうが関数型ぽいのかね?
451 名前: ◆QZaw55cn4c mailto:sage [2012/04/15(日) 21:51:05.55 ] >>447 F#のことも思い出してあげてください
452 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 21:59:08.45 ] 関数型言語でWindowsアプリを開発したいっつー需要がどれだけあるかだな
453 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 22:00:17.15 ] >>442 どちらが糞でどちらが最高かなんて、問い詰められても答えなくていいと思うんだが 沈黙が正解って小学生でも知ってる奴は知ってるだろ
454 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 22:54:52.02 ] >>443 >>443 がんばってみたんですが、糸口がみえてきません。もしよろしければアドバイスをいただけないでしょうか。 >new myInteger(3).fizz() が "Fizz" を返せる @ これは、「メソッド fizz() が副作用として "Fizz" を出力する」ということですか? この場合、fizz(), buzz(), gizz() を通過してきて 3 でも 5 でも 7 でもわりきれなかった場合に元の数字を出力する、ということが不可能だと思います。 >>303 では妥協して endl() というメソッドを準備してこの処理を行うしかありませんでした。 A それとも「メソッド fizz() の返り値が String("fizz") であるべき」ということですか? String にメソッド fizz() を追加したいのであれば、 String から新しいクラスmyString を継承して、そこにメソッドを定義するということだろうと思いますが、 (new myString(3).fizz() が myString("Fizz") を返す) A-1 java.lang.String は final。 A-2 メソッド fizz() が "Fizz" を返してしまうと、もとの String("3") を忘れてしまい、buzz(), gizz() が処理できない。多値を返したいのですが >>304 で精一杯。 >>304 の toString()#Object をオーバーライドする、ってこういうときには普通にすることだと思っていたんですが、何かまずい問題でもあるのでしょうか?
455 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:40:26.22 ] トイプログラムしか書かない奴は言語なんて何でもいいだろw
456 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:47:29.56 ] >>443 >>303 の方針でがんばってみました。gizz() は最後に置かなければならない、と決めうちすることにしました。 toro.2ch.net/test/read.cgi/tech/1313183984/194
457 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:49:17.32 ] 苦しいねぇ
458 名前:デフォルトの名無しさん mailto:sage [2012/04/15(日) 23:50:41.61 ] >>454 > fizz() が "Fizz" を返してしまうと、もとの String("3") を忘れてしまい、buzz(), gizz() が処理できない その一見回避不可能な問題を解決する方法を考えるのがこのクイズがクイズたるゆえんです。 言語によっては型システムの制約によりどうやっても実現できないこともあります。
459 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 00:02:21.18 ] >>450 関数型に限らず、GCのあるOOPLだと 属性変更をせずに新規オブジェクトをサクサク作るやり方も結構使うね
460 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 00:45:51.08 ] >>454 >>341 の方法(元の数値をどこかにメモしておいて適宜参照)はJavaでも使えます。
461 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 01:11:55.59 ] >>458 OOとPFの言語比較としてこのようなクイズを出したのは、 どのような観点からこれら両者のパラダイムの優劣を比較しようとしたのか 聞きたい
462 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 01:13:44.79 ] もうこのお題はcloseでいいんじゃないの? このクイズではせっかくの労力を生産的でないことに費やしている
463 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 01:30:58.12 ] >>462 クイズなんかそんなもんだろ。しょせん暇つぶし。 つーか、こんな程度のクイズ解くのに「労力」なんか大仰なもん必要か?
464 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 01:38:59.77 ] このクイズのくだらなさはかなり問題。
465 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 01:48:07.75 ] くやしいのうw
466 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 02:07:04.82 ] 全然くやしくないぜよ。perlでobjectのnew版も多値版もさらりと書いた。 tieとマクロ使ったのも書こうと思ったけれど手間がもったいなくなってやめた。 パラダイム比較としてもうすこし書く値打ちのあるテーマ出せよ、 このクイズじゃ再帰は使いどころないし javaのnewだめ静的型システムダメ 何を有利に誘導したいんだか せめて前スレのpermutationレベルのテーマを出題の下限レベルとしてクレヨ
467 名前:466 mailto:sage [2012/04/16(月) 02:18:35.03 ] 大体fizz buzzってのが下らないんだよ プログラムプロムナード、ナノピコ教室、Cマガ課題、オイラー4、AIアルゴリズム、OR最適化、 パーサ、マッチング、グラフ問題あたりの 小問題で再帰・高階/部分適用、遅延・カーリー化vsOOの比較できる題材が妥当かもな step数は2chの1レスに収まるくらいの小問題でいいからサ
468 名前:466 mailto:sage [2012/04/16(月) 02:26:58.99 ] 最悪、基本アルゴリズムの再実装でもいいや たとえばqsortはperlやhaskellでpivotを適当に選択して再帰した短いコードと pivot選択くどくど頑張ったCやjavaの長いコード比較してファンクショナルの再帰はマンセーみたいな サイトがあちこちにあるだろ、 あのレベルでも今回のFizzBuzzGizzよりましだろ
469 名前:466 mailto:sage [2012/04/16(月) 02:35:35.13 ] あと、言い出しっぺの法則はナシだぞw
470 名前:466 mailto:sage [2012/04/16(月) 02:44:04.67 ] つか、OOとPFの単純比較って何か意味あるのか? どのみち記述する言語の特徴または弱点、癖の比較レベルの議論に落ちがちな稀ガス ズット前スレでヨンだが、意味論的にはOOとPFは相容れない物らしい しかし生々しい実装レベルではいまんとこ清濁併せ呑んで実現するし まあいいや寝るか。ノシ
471 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 02:46:25.77 ] 多値使うアイデアはイケてたはずなのに、仕上げの文字列との結合やprintとの併用で ズル呼ばわりされるわ、Rubyの>>377 の挙動も再現できなかったしで散々だったしね。
472 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 02:53:06.66 ] なぜかC++で挑み続ける俺。 これ以上C++では無理かも。0xだと知らんが。 template< int e, unsigned t > struct fizzbuzz { int in; std::string out; fizzbuzz( int i ):in( i ){ init(); } template< int e2, unsigned t2 > fizzbuzz( const fizzbuzz< e2, t2 > &r ) :in( r.in ),out( r.out ){ init(); } void init(){ if( in%e ) return; unsigned tmp=t; out.append( (char*)&tmp, 4 ); } operator const char *(){ return out.c_str(); } operator int(){ return in; } }; typedef fizzbuzz< 3, 'zziF' > fizz; typedef fizzbuzz< 5, 'zzuB' > buzz; typedef fizzbuzz< 7, 'zziG' > gizz; int main() { int i = (gizz)(buzz)(fizz)1; std::string t = (gizz)(buzz)(fizz)15; std::string u = (gizz)(buzz)(fizz)105; std::string v = gizz((buzz(fizz(105)))); //こうも書けるね return 0; }
473 名前:466 mailto:sage [2012/04/16(月) 02:54:29.65 ] >>471 あれはね最初に書いたnewはだめって言われて仕方なくの面はあるのよ $scalar = 関数(関数 と明示的にscalarで主値だけを受けとるように明示するのがホントは作法なんだ。 Rubyの>>377 に関しては読んでなかったから挙動の再現にそもそも着手してないよ。 rubyは文法がかなりカオスになって来ちゃって残念だね
474 名前:466 mailto:sage [2012/04/16(月) 02:59:22.51 ] fizzbuzzgizzはいいんだどうでも。 それより前スレのpermutaion perl版はwebなど参照せず一から考えて書いて オレなりに結構な自信作だったのに なんの反応もなかったことの方が寂しかったな
475 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 03:19:21.92 ] 何このスレ
476 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 06:20:08.75 ] ruby無双をしたかった奴が、もっとエレガントな解を他言語で出されて、 涙目でdisるスレです
477 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 06:53:26.91 ] Rubyと違う解法が出る度に 必死に難癖付けてて笑ったわww
478 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 08:13:17.85 ] 頭が固くて馬鹿だから 数や文字列に状態持たせる以外の方法が 理解できないんだろう
479 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 08:32:48.03 ] 頭が固くて馬鹿だから 数や文字列に状態持たせる方法が 許容できないんだろう
480 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 08:38:53.99 ] 世の中は状態がある世界なのにねw
481 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 08:50:48.96 ] じゃあFixnumのインスタンスに特異メソッド定義してみろRuby厨
482 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 09:44:46.42 ] 元ネタのCLのEQLスペシャライザならそういうことできたよな。 Haskellとかでコンストラクタ無しで1以外の引数をとるとコンパイル時に 型エラーになる関数って定義できたっけ?
483 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 10:00:08.87 ] template< int n > void func(){int i="";} template<> void func<1>(){} ・・・ func<2>();//エラー
484 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 12:34:04.90 ] > cat FooTH.hs {-# LANGUAGE TemplateHaskell #-} module FooTH where import Language.Haskell.TH foo 1 = [| 1 |] foo _ = error "" > cat Main.hs {-# LANGUAGE TemplateHaskell #-} import FooTH main = print $(foo 1) -- foo 2 に変えるとコンパイルエラー
485 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 12:50:08.98 ] >>474 あれ覚えてるよ、実は感心してた ていうか、このスレでPerlの評価が結構変わったよ(もちろん高い方へ) でも、読み易さ優先で書いてあれとは Perl使いとは分かり合えないな...と思ったけどw
486 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 20:25:48.62 ] >>479 許容はしてるだろう エレガントさから程遠いと言ってるだけで
487 名前:デフォルトの名無しさん mailto:sage [2012/04/16(月) 22:19:41.52 ] 俺の基準における エレガントってやつかw
488 名前:285 mailto:sage [2012/04/17(火) 00:46:48.85 ] 正直、あの問題は無いと思うよ 問題があれだし書き捨てだからやったが、実際には絶対にやりたくないな
489 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 00:47:44.00 ] >>487 FizzBuzzすら書けない口だけ野郎の基準よりマシだろwww お前はこのスレでは最底辺のカスなんだから敬語使えw
490 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 00:53:04.36 ] >>481 ぶっちゃけ>>479 のバカが理解できたのが たまたまRubyのコードだっただけでRuby厨ですらねーと思うぜ むしろバカにクソコード褒められてRuby可哀想ってなもんだ
491 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 00:59:54.74 ] あの問題出したのぶっちゃけPython使いだと思う(陰謀説)
492 名前:466 mailto:sage [2012/04/17(火) 01:35:17.45 ] >>491 アレは学部・卒研レベルの課題をここに投げたのかなーと オレは感じた。(真相はシラネ) もしかしてオレ様はボクちゃんに利用されたのかなとww
493 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 10:56:11.26 ] F#のスレッドローカル(有り体にはグローバル変数)と同様の方法でSqueak Smalltalkの解。 オープンクラスは使わずにブロック(無名関数)で。 | fb fizz buzz gizz | fb := [:x :cond :str | | p n | p := Processor activeProcess. (x isKindOf: Integer) ifTrue: [p instVarNamed: #env put: (n := x). x := ''] ifFalse: [n := p instVarNamed: #env]. (cond value: n) ifTrue: [x, str] ifFalse: [x ifEmpty: [n]]]. fizz := [:x | fb value: x value: [:n | n isDivisibleBy: 3] value: 'Fizz' ]. buzz := [:x | fb value: x value: [:n | n isDivisibleBy: 5] value: 'Buzz']. gizz := [:x | fb value: x value: [:n | n isDivisibleBy: 7] value: 'Gizz']. self assert: (fizz value: 1) = 1. self assert: (fizz value: 3) = 'Fizz'. self assert: (buzz value: (fizz value: 1)) = 1. self assert: (buzz value: (fizz value: 3)) = 'Fizz'. self assert: (buzz value: (fizz value: 5)) = 'Buzz'. self assert: (buzz value: (fizz value: 15)) = 'FizzBuzz'. self assert: (gizz value: (buzz value: (fizz value: 105))) = 'FizzBuzzGizz'. self assert: (buzz value: (gizz value: (fizz value: 105))) = 'FizzGizzBuzz'.
494 名前:デフォルトの名無しさん mailto:sage [2012/04/17(火) 12:02:41.83 ] >>493 Pythonも同じ方針のやつ import threading fbdata = threading.local() def fb(x, cnd, msg): if isinstance(x, int): fbdata.m = n = x s = "" else: n = fbdata.m s = x if cnd(n): return s + msg elif s <> "": return s else: return n def fizz(n): return fb(n, lambda n: n%3==0, "Fizz") def buzz(n): return fb(n, lambda n: n%5==0, "Buzz") def gizz(n): return fb(n, lambda n: n%7==0, "Gizz") assert fizz(1) == 1 assert fizz(3) == "Fizz" assert buzz(fizz(1)) == 1 assert buzz(fizz(3)) == "Fizz" assert buzz(fizz(5)) == "Buzz" assert buzz(fizz(15)) == "FizzBuzz" assert gizz(buzz(fizz(105))) == "FizzBuzzGizz" assert buzz(gizz(fizz(105))) == "FizzGizzBuzz"
495 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 13:10:30.34 ] っていうか問題どこだよ
496 名前:デフォルトの名無しさん mailto:sage [2012/04/18(水) 13:31:40.56 ] スレタイに惹かれて開いたけどゴミスレだった・・・
497 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 02:49:08.33 ] $t = sub { my $f = shift; sub { my $x = shift; $f->($f->($x)) } }; $rst = $t->($t)->($t)->($t)->( sub{ my $x = shift; $x + 1 })->(0); print $rst, "\n";
498 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 09:02:56.87 ] 同じくRubyも。 ケチがついた、オープンクラス、メソッドチェーン、リフレクションは無しで require 'test/unit' def fb(x, cnd, msg) th = Thread.current x.kind_of?(Integer) ? (th[:m] = n = x; s = "") : (n = th[:m]; s = x) cnd[n] ? s + msg : !s.empty? ? s : n end def fizz(n); fb(n, proc{ |n| n%3==0 }, "Fizz") end def buzz(n); fb(n, proc{ |n| n%5==0 }, "Buzz") end def gizz(n); fb(n, proc{ |n| n%7==0}, "Gizz") end class FizzBuzzQuizTest < Test::Unit::TestCase def test_fbq assert_equal( fizz(1), 1 ) assert_equal( fizz(3), "Fizz" ) assert_equal( buzz(fizz(1)), 1 ) assert_equal( buzz(fizz(3)), "Fizz" ) assert_equal( buzz(fizz(5)), "Buzz" ) assert_equal( buzz(fizz(15)), "FizzBuzz" ) assert_equal( gizz(buzz(fizz(105))), "FizzBuzzGizz" ) assert_equal( buzz(gizz(fizz(105))), "FizzGizzBuzz" ) end end
499 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 09:53:30.31 ] リフレクションやらスレッドローカルやら組み込みクラス汚染やら使った クソみたいな実装が出てくる出題だったけど 言語比較に役立つ何かは得られましたか?
500 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 10:07:54.14 ] あるときは数値またあるときは文字列を返すような関数は 動的型であれ作るもんじゃないという幼稚園児並みの洞察が得られました
501 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 10:43:06.55 ] >>499 「数値と文字列の組」と「数値または文字列」の違いが不明瞭だった。 リフレクションや継承で二つのクラスを一組にしたいのか、 それとも一つのクラスを数種類に分けたいのか明示されていなかった。
502 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 10:53:45.22 ] どうしてもスレッドローカル変数が必要になったとき 関数的にはどう記述したらいいのかよかったら教えてください。
503 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 11:37:33.00 ] そもそもスレッド自体が処理系に依存した、言語パラダイムとは関係ない概念だから、 関数型的にもオブジェクト指向的にも、どう記述したらいいかとか答えようがない。
504 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 12:23:49.22 ] Readerモナドでグローバル変数っぽいことをするには どうすればいいのでしょうか。たとえば、状態をfizzとかbuzzから (引数として渡すことなしに)参照したり更新したりしたいのです。
505 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 12:50:34.08 ] ttp://www.haskell.org/haskellwiki/Thread-local_storage いまんとこHaskellからTLSを使う、「これ」といった定番はないようだ
506 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 12:58:07.14 ] 個人的に、関数型でスレッドとかハードに近い領域の制御はしたくないな。
507 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 13:20:53.20 ] >>504 それは基本的にStateモナドの領域。 Readerモナドの中で、さらにサブルーチン的に他のReaderモナドを呼び出す時に、 一時的に書き換えたように見せかけたい、っていう場合ならばlocal関数が使えるけど。 Readerモナドで更新したいって、読み取り専用変数に書き込みたいって言ってるのと同じ事なのはわかってるよな…?
508 名前:デフォルトの名無しさん mailto:sage [2012/04/19(木) 17:54:57.76 ] Reader (s -> a) -> (a -> s -> b) -> s -> b Writer (a,s) -> (a -> (b,s)) -> (b,s) State (s -> (a,s)) -> (a -> s -> (b,s)) -> s -> (b,s)
509 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 11:54:43.80 ] >>500 あるときは a またあるときは m a m a -> (a -> m b) -> m b
510 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 17:52:20.76 ] なんつーか、FizzBuzzしたいんならHQ9F+使えばいんじゃね?
511 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 22:29:27.34 ] お題出していい?
512 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 22:55:07.28 ] ・コンソール上で動く、カード(つーてもただの数字を表示するだけだが)を使ったミニゲーム ・1〜9のカードを各4枚ずつ用意、それをシャッフルして「ストック」とする ・ストックから7枚のカードを引く ・引いたカードの中から、プレイヤーは合計が15になるように数枚を選んで捨てる (選ばせ方はプログラマが考える、ギブアップ手段も用意) ・捨てなかったカードと合わせて再び7枚になるか、もしくはストックが空になるまでストックからカードを引く ・また15になるように捨てる ・引いては捨ててを繰り返し、ストックと手札が共に空になったらおめでとう的な言葉を吐いて終了
513 名前:デフォルトの名無しさん mailto:sage [2012/04/20(金) 23:16:37.51 ] つまらない。
514 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 01:27:35.30 ] >>512 Squeak Smalltalk で。 | ui stock player | ui := UIManager default. stock := (1 to: 9) gather: [:each | Array new: 4 withAll: each]. stock := stock shuffled asOrderedCollection. player := (stock removeFirst: 7) asOrderedCollection. [ | choice | [ | input | input := ui request: player asSortedArray asString, 'から合計が15になるようにチョイス'. choice := input subStrings collect: #asInteger. choice ifEmpty: [(ui confirm: 'ギブアップ?') ifTrue: [^self] ifFalse: [choice := {nil}]]. (choice allSatisfy: #isInteger) and: [choice sum = 15] and: (player includesAllOf: choice) and: [choice asSet allSatisfy: [:card | (player occurrencesOf: card) >= (choice occurrencesOf: card)]] ] whileFalse. player removeAll: choice. player addAll: (stock removeFirst: (choice size min: stock size)). player notEmpty] whileTrue. ui inform: 'おめでとう!'
515 名前:デフォルトの名無しさん mailto:sage [2012/04/21(土) 02:46:31.71 ] >>514 なぜこの人は今どきSmalltalkの末裔を使っているのか理由をうかがいたいので おしえてくださいです
516 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 01:52:01.88 ] # Ruby版、指定は半角空白区切り、EOFでギブアップ class CardNotFoundException < RuntimeError; end def remove_cards(specs, tableau) specs.each do |spec| if idx = tableau.find_index{|card| card == spec } then tableau.delete_at idx else raise CardNotFoundException.new(spec.to_s) end end end stock = ((1..9).to_a * 4).shuffle tableau = [] until tableau.empty? && stock.empty? tableau.push stock.pop until tableau.size >= 7 || stock.empty? printf "stock=%d tableau=%p\n? ", stock.size, tableau k = gets or exit specs = k.chomp.split(' ').map{|s| s == 'giveup' ? exit : s.to_i } begin remove_cards specs,tableau.dup if (total = specs.inject{|result,n| result + n }) == 15 then remove_cards specs,tableau else puts "total(#{total}) not equal to 15" end rescue CardNotFoundException => e puts "not found `#{e}'." end end puts 'Congraturations !'
517 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 02:31:25.32 ] >>514 をRubyに翻訳してみた版 stock = ([*1..9]*4).shuffle player = stock.shift(7) loop do choice = nil loop do puts player.sort.inspect + "から合計が15になるようにチョイス" choice = gets.split(/[, ]/).map(&:to_i) choice.delete(0) if choice.empty? puts "ギブアップ?[Y/n]" !(gets=="n\n") ? exit : choice = [0] end break if choice.all?(&:integer?) and choice.reduce(&:+) == 15 and choice.uniq.all?{ |card| player.count(card) >= choice.count(card) } end choice.each{ |e| player.delete_at(player.index(e)) } player += stock.shift([choice.size, stock.size].min) break if player.empty? end puts "おめでとう!"
518 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 12:27:13.72 ] Squeakは入れたことあるが(てか今も入ってるけど)何をどうしたらいいのか判らん >>514 のコードをどこに入力して、どう実行したら動くんだ?
519 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 17:54:43.65 ] >>518 1. sourceforge.jp/projects/squeak-ja/ から Squeak4.2-ja-all-in-one.zip を入手して展開。 2. 同梱 ReadMe-ja.txt などを参考に手元のOSでなんとか起動までこぎつける。無印VMでも新CogVMでもOK。 3. 「ツール」メニューから「ワークスペース」を選択してスクリプトなどのお試し実行用ウインドウを開く。 4. >>514 の | ui stock player | から ui inform: 'おめでとう!' をコピーして 3 のウインドウにペースト。 5. 改めて alt(Macならcmd)+a やマウスドラッグで全選択してから、alt(同cmd)+d で実行。 6. うまく動作すると入力欄がポップアップするので、そこに数字をでスペースなどで区切ってタイプ。 7. 「了解(s)」ボタンクリック(あるいはリターンキー)で入力決定。以降はこれの繰り返し。空決定でギブアップ。 ざっと調べた感じ最新の日本語化版である 4.2ja にこだわらなくても 3.9以降であれば動作するようです。 ただし公式英語版などでは日本語が化けますので適宜英語などに置き換えてからペーストしてください。 日本語版であってもペースト時にエラーがでるようならそのときの対処も同様です。
520 名前:デフォルトの名無しさん mailto:sage [2012/04/22(日) 21:05:31.50 ] // F#で入出力以外の副作用なし let rec input hands = printfn "合計が15になるように捨てるカードをスペース区切りで指定(ギブアップの場合は指定なし)" match System.Console.ReadLine() with | "" -> None | inp -> try let discardCount = inp.Split([|' '|]) |> Seq.map int |> Seq.countBy id |> Map.ofSeq let handCount = hands |> Seq.countBy id |> Map.ofSeq if discardCount |> Map.exists (fun n c -> defaultArg (Map.tryFind n handCount) 0 < c) || discardCount |> Map.toSeq |> Seq.sumBy ((<||) (*)) |> (<>) 15 then input hands else handCount |> Map.map (fun n c -> c - defaultArg (Map.tryFind n discardCount) 0) |> Map.toList |> List.collect (fun (n, c) -> List.replicate c n) |> Some with _ -> input hands let rec play hands stocks = if (hands, stocks) = ([], []) then printfn "おめでとう!" else let cards = stocks |> Seq.truncate (7 - List.length hands) |> Seq.toList let nowHands, nextStocks = hands @ cards, (stocks |> Seq.skip cards.Length |> Seq.toList) nowHands |> Seq.sort |> Seq.map string |> String.concat " " |> printf "手札 : %s, " printfn "山札の残り枚数 : %d" nextStocks.Length match input nowHands with Some nextHands -> play nextHands nextStocks | None -> () let random = System.Random() [for i in 1 .. 9 do yield! List.replicate 4 i] |> List.sortBy (fun _ -> random.Next()) |> play []
521 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 00:28:55.28 ] >>519 ありがと。何か前に入れたバージョンでやってみたら「[ | input |」の行の左に「Period or right bracket expected ->」とか出たけど、実行の仕方自体は判ったから色々試してみる。
522 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 00:33:02.59 ] ああ、インデントを一旦削って入れ直したら動いたわ。thx
523 名前:デフォルトの名無しさん mailto:sage [2012/04/23(月) 07:26:59.30 ] あ、動的にいたスモールトーカーだ。よろしく!
524 名前:デフォルトの名無しさん mailto:sage [2012/04/24(火) 12:35:28.99 ] 日本語でおk
525 名前:デフォルトの名無しさん mailto:sage [2012/04/25(水) 13:12:07.32 ] お題: コンウェイのライフゲームで、 配列の配列(あるいはリストのリスト)で表わされた格子を受け取り 次世代を返す関数lifeを定義せよ。 life([ [0,1,1,1,0], [0,1,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]]) #=> [ [0,1,1,0,0], [0,1,0,1,0], [0,0,0,0,0], [0,0,0,0,0], [0,0,1,0,0]] また作成した同関数を用いて、500x500のランダムな状態の格子の 500世代目を算出するのにかかった時間(無理なら、算出可能な 世代数とその時間)を計測して示せ。
526 名前:デフォルトの名無しさん mailto:sage [2012/04/25(水) 13:54:49.01 ] くだらん
527 名前:デフォルトの名無しさん mailto:sage [2012/04/25(水) 14:03:57.26 ] Java8でラムダ式が言語仕様に入るようだね javaもマルチパラダイム化が進むな OOPLが関数型言語の特徴の一部を取り込む中 スレタイの通り言語比較した場合 「副作用の有無」が一番重要なんじゃないかと思ったけどどうだろう? 機能を取り込むことはあっても無くすことはしないだろうから 副作用の有無が、開発速度や可読性、保守性にどのように影響してくるか・・・ と考えても良いお題は思いつかないんだけどね
528 名前:デフォルトの名無しさん mailto:sage [2012/04/25(水) 15:26:58.18 ] Javaって今でも組み込み型以外は参照型でしか扱えないの? 関数型言語使うようになってから、nullを持たない参照型とか、イミュータブルな値型がいかに重要か思い知った。 しかも、イミュータブルな値型を基本として、nullを持った参照オブジェクト型、nullを持たない参照オブジェクト型って形で扱えないと厳しい。 これは言語仕様として取り込まれていないとどうしようもない。 そういう意味では、C++は結構惜しいところまで行ってたと思う。
529 名前:デフォルトの名無しさん mailto:sage [2012/04/25(水) 16:37:33.03 ] C++にはpure virtual function callというのがあって、仮想関数がnullを持つ。 値型でも仮想関数があったら元も子もない。 仮想関数をやめてswitchを使う覚悟がないと厳しい。 関数型言語のパターンマッチはswitchと同じ方式だ。
530 名前:デフォルトの名無しさん mailto:sage [2012/04/25(水) 16:43:26.43 ] >>528 関数型言語はむしろ全てが参照型とも言えるんだが
531 名前:デフォルトの名無しさん mailto:sage [2012/04/25(水) 17:35:29.26 ] >>525 Squeak Smalltalk (4.2-ja w/CogVM), 1.8GHz Core i7で5分弱。 life := [:ary2d | | sum survivs | sum := ary2d * 0. #(-1 0 1) do: [:dx | #(-1 0 1) do: [:dy | sum := sum + ((ary2d collect: [:row | row flipRotated: dx*2]) flipRotated: dy*2)]]. survivs := #(3 4) collect: [:alive | sum collect: [:row | row collect: [:cell | (cell = alive) asBit]]]. survivs first + (survivs second * ary2d)]. life value: #( (0 1 1 1 0) (0 1 0 0 0) (0 0 1 0 0) (0 0 0 0 0) (0 0 0 0 0)). "=> #( (0 1 1 0 0) (0 1 0 1 0) (0 0 0 0 0) (0 0 0 0 0) (0 0 1 0 0)) " cells := (1 to: 500) collect: [:row | (1 to: 500) collect: [:cell | #(0 1) atRandom]]. [500 timesRepeat: [cells := life value: cells]] timeToRun "=> 267282(msec) "
532 名前:デフォルトの名無しさん mailto:sage [2012/04/25(水) 20:45:17.23 ] >>531 をRubyに翻訳してみた版。1.9だが50世代に4分以上かかってしまう。 翻訳の手間を省くのにArray#*,#+を置き換えちゃったのが足を引っ張ったか? require "benchmark" class Array def *(x); zip(x.kind_of?(Array)?x:Array.new(size,x)).map{|e|e.reduce(&:*)} end def +(x); zip(x.kind_of?(Array)?x:Array.new(size,x)).map{|e|e.reduce(&:+)} end end def life(ary2d) sum = ary2d * 0 (-1..1).each{ |dx| (-1..1).each{ |dy| sum += ary2d.map{ |row| row.rotate(dx) }.rotate(dy) } } survivs = [3,4].map{ |alive| sum.map{ |row| row.map{ |cell| (cell == alive)?1:0 } } } survivs.first + (survivs.last * ary2d) end p life([ [0,1,1,1,0], [0,1,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]]) #=> [[0,1,1,0,0],[0,1,0,1,0],[0,0,0,0,0],[0,0,0,0,0],[0,0,1,0,0]] cells = (1..500).map{ (1..500).map{ [0,1].sample } } p Benchmark.measure{ 50.times{ cells = life(cells) } }
533 名前:デフォルトの名無しさん mailto:sage [2012/04/25(水) 22:15:29.46 ] 1.6GHz Core i5で2分 import qualified Data.Vector.Unboxed as V import qualified Data.List as L import System.Random.Mersenne data Lattice = Lattice! Int Int (V.Vector Int) (!) (Lattice m n v) (i,j) = v V.! (n * mod i m + mod j n) next b i j = case (sum xs, b ! (i,j)) of (3, _) -> 1 (4, 1) -> 1 (_, _) -> 0 where xs = [b ! ((i+m),(j+n)) | m <- [-1,0,1], n <- [-1,0,1]] updateBoard board@(Lattice m n v) = Lattice m n $! V.fromList [next board i j | i <- [0..m-1], j <- [0..n-1]] randomBoard rs x y = Lattice x y $ V.fromList $ take (x * y) rs main = do rs <- newMTGen Nothing >>= randoms let board = randomBoard (map (`mod` 2) rs) 500 500 print $ L.foldl' (\x _ -> updateBoard x) board [1..500]
534 名前:533 mailto:sage [2012/04/25(水) 22:20:37.27 ] instance Show Lattice where show (Lattice m n v) = concat $ snd $ L.mapAccumL (\i x -> if i == n-1 then (0, show x ++ "\n") else (i+1, show x)) 0 $ V.toList v lattice xss = Lattice n m $ V.fromList $ concat xss where n = length xss m = length (concat xss) `div` n > updateBoard $ lattice [[0,1,1,1,0], [0,1,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]] # 出力 01100 01010 00000 00000 00100
535 名前:デフォルトの名無しさん mailto:sage [2012/04/26(木) 20:54:15.37 ] (_, _) (`mod` 2) (\x _ ->
536 名前:デフォルトの名無しさん mailto:sage [2012/04/26(木) 20:56:38.97 ] 最近Lispさんを見かけないけどもう廃れちゃったの?
537 名前:デフォルトの名無しさん mailto:sage [2012/04/26(木) 21:25:38.01 ] 言語仕様を共通にするというトレンドは終わった 個別の実装は始まってなかった
538 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 01:17:14.79 ] Rで life <- function(ary2d) { sum <- rbind(ary2d[ncol(ary2d),], ary2d[-ncol(ary2d),]) + ary2d + rbind(ary2d[-1,], ary2d[1,]) sum <- cbind(sum[,nrow(sum)], sum[,-nrow(sum)]) + sum + cbind(sum[,-1], sum[,1]) ifelse(sum == 3 | (ary2d == 1 & sum == 4), 1, 0) }
539 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 08:45:31.15 ] >>536 2chで世間が判った気になり始めたら色々ヤバイな。
540 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 10:14:19.97 ] >>538 500x500 500世代で測ったら 1.8GHz Core i7 で 68秒だった。けっこう速いね。
541 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 11:00:18.10 ] ライフゲームで関数型とオブジェクト指向の何を比較したいんだろう? >>525 は次世代を返す関数としてるけどオブジェクト指向側は lg = new lifegame(500,500); for(i=0;i<500;i++)lg.life(); console(lg); って感じでいいの? そうしないと関数型 vs 手続き型みたいなことになるよね
542 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 11:37:20.76 ] 例えばF#とC#を比較したら関数型言語と手続き型言語の比較になる 本物のOOは言語に依存しない 関数型言語と対立するようなOOは偽物
543 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 12:00:12.21 ] >>541 ライフゲームは単純だけどパラダイムの特徴をかろうじて出せるくらいの規模はあるんじゃない? お題にあるlifeという関数名(メソッド名)にこだわらなくていいと思うよ。 要は小さな例での正常動作と、500x500セル 500世代(必要なら50世代とかに軽減して) にどのくらいかかるかが示せていればOKかと。
544 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 12:17:25.49 ] >>543 規模の大きさは良いと思うけど、 データの破壊的操作ができると有利な御題のほうが 違いが出て良いと思った Haskellで配列使ったバージョン import Data.Array life ary = array ((1,1),(x,y)) [((i,j), f i j) | i <- [1..x], j <- [1..y]] where (x,y) = snd $ bounds ary f i j = let n = sum [ary ! (g x (i+a), g y (j+b)) | a <- [-1,0,1], b <- [-1,0,1]] in if n == 3 || (n == 4 && ary ! (i,j) == 1) then 1 else 0 g x i = if i < 1 then x else if i > x then 1 else i
545 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 14:36:04.79 ] javascriptで書いてみた。破壊的操作有りで。 ソースの長さ汚さは勘弁してください。 ideone.com/xNY9J ※↑は5秒制限のため500回でなく1回だけ lg.life(500); console.log("life500:" + (new Date()-st) + " msec"); に書き換えてから windows版node.js(pen4 2.6GHz)でやったら30秒くらいだった。 >node.exe life.js 0,1,1,1,0 0,1,0,0,0 0,0,1,0,0 0,0,0,0,0 0,0,0,0,0 --------------- 0,1,1,0,0 0,1,0,1,0 0,0,0,0,0 0,0,0,0,0 0,0,1,0,0 --------------- create :39 msec life500:29794 msec
546 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 20:27:45.31 ] てきとーにCで書いてみた 500回はさすがに秒数制限に引っかかったけど、50回で0.69秒 ideone.com/a7mH5
547 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 22:35:14.09 ] F# 2.6GHz Core2Duo 500世代で2分57秒 let life (field : int[,]) = let height, width = field.GetLength 0, field.GetLength 1 field |> Array2D.mapi (fun y x c -> let s = seq { y - 1 .. y + 1 } |> Seq.sumBy (fun y' -> seq { x - 1 .. x + 1 } |> Seq.sumBy (fun x' -> field.[(y' + height) % height , (x' + width) % width])) match s, field.[y, x] with 4, 1 | 3, _ -> 1 | _ -> 0)
548 名前:デフォルトの名無しさん mailto:sage [2012/04/27(金) 22:37:08.83 ] 手続き型言語F#で書くと>>547 と同じ環境で500世代9秒 let life (field : int[,]) = let height, width = field.GetLength 0, field.GetLength 1 let result = Array2D.zeroCreate height width for y = 0 to height - 1 do for x = 0 to width - 1 do let mutable s = 0 for y' = y - 1 to y + 1 do for x' = x - 1 to x + 1 do s <- s + field.[(y' + height) % height, (x' + width) % width] result.[y, x] <- match s, field.[y, x] with 4, 1 | 3, _ -> 1 | _ -> 0 result
549 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 00:03:43.28 ] OOPならセルごとにオブジェクトで、と思ったが、 仕様が全状態の配列から配列への変換なのね。
550 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 00:54:50.29 ] >>549 べつにこだわらなくてもいいでしょ。組みやすいように組めば。 要は小さな例での動作確認出力結果と、 500x500セル 500世代(必要なら50世代とかに軽減して)の計測結果を示せればOK。
551 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 04:39:34.80 ] まあ出題者が関数的なアタマなんだろう
552 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 06:37:42.91 ] セルごとにオブジェクトとかねぇよww
553 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 07:45:09.18 ] 問題領域がどこかわかれば何処をオブジェクトにしたら良いか分かるよ
554 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 09:32:38.01 ] なかなか面白いじゃないか。 オブジェクト指向で設計されたライフゲーム、頼む。
555 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 09:44:59.90 ] この題じゃ>>541 くらいにしかならんだろ オブジェクト指向をどういうもんだと思ってんだよw
556 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 10:37:13.10 ] セル毎にオブジェクトか、面白そうだしちょっとやってみるかな
557 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 10:51:25.73 ] セル毎にオブジェクトってこんなの?(コードはPython) class Cell(object): def __init__(self, alive): self.neighborhood = [] self.alive = alive def evaluate(self): s = sum(x.alive for x in self.neighborhood) self._alive = 1 if s == 3 or (s == 4 and self.alive == 1) else 0 def update(self): self.alive = self._alive 全部は長いのでこっち ideone.com/3WKkG
558 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 11:05:27.26 ] 8coreのXeonマシンでOpenMP使ってCのコードを並列化したら 500*500の500世代で1秒切ったわw
559 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 12:11:25.24 ] >>557 他スレで遊んでる内に作られてしまった…
560 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 12:13:20.34 ] >>552 ライフゲームは生物が単純だから変に思えるかもしれないけど、 これがゲームのキャラクターと考えればごく普通の考え方。 ライフゲームはどの生物も同じ能力だけど、セルがオブジェクトなら 実際の生物みたく、オブジェクトごとに能力を変えることだって出来る というかそういうゲームがあったね。 マルチプレイヤー・ネットワーク・ゲームTerrarium www.atmarkit.co.jp/fdotnet/wwebserv/wwebserv010/wwebserv010-001.html > プレイヤーは各自プログラミングした動物を持ち寄り、フィールド上で動物同士を戦わせる。
561 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 12:23:40.64 ] やっぱりオブジェクト指向だと規模が大きくなる。 逆に言えば、規模が大きい場合は オブジェクト指向が有利ってことか。
562 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 12:42:19.17 ] 大規模で全貌の把握がしづらいものを 個々人では把握できないままでも比較的扱いやすいのがOOPLだと思ってる
563 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 12:57:03.02 ] 全体を統一しづらい規模になると言語は一つではなくなる Objective-C++/CLIのような状態
564 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 16:19:14.44 ] >セルがオブジェクトなら >実際の生物みたく、オブジェクトごとに能力を変えることだって出来る 大抵のOOPLにはマルチメソッドすらないのに、 良くそんな大口たたけるな。
565 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 16:24:25.86 ] 無いのはマルチメソッドを実現するための言語仕様であって、 マルチメソッド自体は実装できるからね。
566 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 16:25:24.90 ] >>564 突然何言い出してんのこの子(´・ω・`)
567 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 16:28:06.39 ] ホーミングミサイルの話でボコボコにされたやつだ。 気にすんな
568 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 18:10:20.59 ] >>565 関数型言語でも実装できる パラダイムじゃなく言語間の比較スレなんだから そんなこと言っても意味ない
569 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 18:15:28.58 ] >>561 仮に「OOPだと規模が大きくなる」が真だとしても そこから「規模が大きいとOOPは有利」は導けない
570 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 18:53:58.34 ] 静的型付けの割に簡潔に書けて、かつ型チェックも厳しくやってほしい こういうニーズに関数型言語が応えてるから使ってるだけで、 関数型言語使ってる奴が皆OOを嫌ってるわけでも 設計レベルで使わないわけでもないんよ 争いは不毛だ
571 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 19:06:33.77 ] > 静的型付けの割に簡潔に書けて、かつ型チェックも厳しくやってほしい なんとなくC#を思いだしたけどC#で書く人いないね
572 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 19:31:55.12 ] 争わなかったらスレの存在意義がないだろ
573 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 20:25:37.43 ] >>571 C#のジェネリックってダックタイピングできないんでしょ?簡潔かなぁ。
574 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 20:41:49.41 ] >>560 ライフゲームのセルっていう文脈だからねぇよって言ったわけで ゲームのキャラクターのオブジェクト化まで否定はしてねぇよw >>564 またホーミングの子www
575 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 21:39:52.98 ] >>570 Scalaがそう。 静的言語で、簡潔に書けることを 証明した言語。
576 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 21:45:24.53 ] >>575 このスレでまだ一回もScala出て来てないぞ ライフゲームで良いからコードで証明してみてくれ
577 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 23:03:24.87 ] 「Scalaは簡潔に書けると証明した」=>「じゃあチョット書いてみて」=> 逃亡 どんなコントだよwww
578 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 23:11:10.96 ] ん? Scala知らないの?
579 名前:デフォルトの名無しさん mailto:sage [2012/04/28(土) 23:31:57.42 ] Scala待ちの間にw、Squeak Smalltalkでセルがオブジェクト版。(要クラスブラウザ) 細かい違いを無視すれば Python の >>557 とほぼ同じ方針。 Object subclass: #Cell instanceVariableNames: 'neighbors next' Cell >> setBit: int neighbors := OrderedCollection with: int Cell >> collectNeighborsAt: pos in: array2D neighbors addAll: (#(-1 0 1) gather: [:dx | #(-1 0 1) collect: [:dy | (array2D atWrap: (pos y + dy)) atWrap: (pos x + dx)]]); remove: self Cell >> calcNext next := (neighbors inject: 0 into: [:sum :neigh | sum + neigh value]) caseOf: {[3]->[1]. [4]->[self value]} otherwise: [0] Cell >> update neighbors at: 1 put: next Cell >> value ^neighbors first Cell >> printOn: stream self value printOn: stream Cell class >> newWith: bitInt ^self new setBit: bitInt; yourself Cell class >> newLatticeFrom: array2D | lattice | lattice := array2D collect: [:row | row collect: [:bit | Cell newWith: bit]]. ^lattice doWithIndex: [:row :y | row doWithIndex: [:cell :x | cell collectNeighborsAt: x@y in: lattice]]; yourself Cell class >> updateLattice: array2D ^array2D do: [:row | row do: #calcNext]; do: [:row | row do: #update] | lattice | lattice := Cell newLatticeFrom: {{0. 1. 1. 1. 0}. {0. 1. 0. 0. 0}. {0. 0. 1. 0. 0}. {0. 0. 0. 0. 0}. {0. 0. 0. 0. 0}}. Cell updateLattice: lattice. "=> {{0. 1. 1. 0. 0}. {0. 1. 0. 1. 0}. {0. 0. 0. 0. 0}. {0. 0. 0. 0. 0}. {0. 0. 1. 0. 0}} "
580 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 00:22:22.02 ] 純粋な関数型言語って、参照するたびに値が変化する変数みたいなのは作れるの? たとえば乱数とか、参照した時点の現在時刻を値として持ってる変数とか
581 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 00:31:18.37 ] >557をscalaでベタ移植してみた。 case class Cell(var alive:Int) { var neighborhood = List[Cell]() var alive_ = 0 def evaluate() { val s = neighborhood.map(_.alive).sum alive_ = if(s == 3 || s == 4 && alive == 1) 1 else 0 } def update() { alive = alive_ } } case class Board(val lattice:List[List[Int]]) { val cells = lattice.map(_.map(x => Cell(x))) val m = lattice.size; val n = lattice(0).size for(i <- 0 until m; j <- 0 until n; k <- -1 to 1; l <- -1 to 1) cells(i)(j).neighborhood ::= cells((i+k+m)%m)((j+l+n)%n) def life() { cells.foreach(_.foreach(_.evaluate)) cells.foreach(_.foreach(_.update)) } override def toString() = { cells.map(_.map(_.alive.toString).reduce(_ + "," + _)).reduce(_ + "\n" + _) } } val board = Board(List(List(0,1,1,1,0),List(0,1,0,0,0),List(0,0,1,0,0),List(0,0,0,0,0),List(0,0,0,0,0))) board.life print(board) scalaの機能を余り活用できていない感じ。
582 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 01:14:20.15 ] これで静的型付け言語なんだぜ。 val msg = if (true) "true dayo" else "false dayo"
583 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 01:27:13.41 ] せっかくなのですべてのセルが並行に動くように>581を修正 case class Cell(var alive:Int) extends Actor { var neighborhood = List[Cell]() def act() = { neighborhood.foreach(_ ! alive) var count = 0; var s = 0 loopWhile(count < neighborhood.size) { receive { case i:Int => s += i; count += 1 } } andThen { alive = if(s == 3 || s == 4 && alive == 1) 1 else 0 } } } case class Board(val lattice:List[List[Int]]) { val cells = lattice.map(_.map(x => Cell(x))) val m = lattice.size; val n = lattice(0).size for(i <- 0 until m; j <- 0 until n; k <- -1 to 1; l <- -1 to 1) cells(i)(j).neighborhood ::= cells((i+k+m)%m)((j+l+n)%n) def life() { cells.foreach(_.foreach(_.start)) } override def toString() = cells.map(_.map(_.alive.toString).reduce(_ + "," + _)).reduce(_ + "\n" + _) } val board = Board(List(List(0,1,1,1,0),List(0,1,0,0,0),List(0,0,1,0,0),List(0,0,0,0,0),List(0,0,0,0,0))) board.life print(board) evaluate/updateの分割が不要になったので少し短くなったか
584 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 01:30:58.02 ] これで静的型付け言語なのか。 本当に短いコードは動的型付け言語だけの特権じゃないことを 証明してしまったな。
585 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 02:11:32.74 ] ただ静的型にしては遅いよね。 500x500 500世代で動的な >>579 が 112秒なのに、>>581 は 196秒。
586 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 02:18:22.73 ] >>585 それ事前コンパイルしてないだろ?
587 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 02:35:44.97 ] >>583 これって一回のlifeのコール後、 すべてのセルがアップデートを終えるのをどこで待ち合わせているの?
588 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 06:27:13.54 ] >>582 そんなんで感動できるとか何時の時代の人? OCaml : let msg = if true then "true" else "false" Haskell : let msg = if True then "true" else "false"
589 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 06:30:26.82 ] どうせ、RubyとかLLばっかり使ってる人だろw
590 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 07:52:20.17 ] C++,C#にも導入されたね C++11 : auto msg = true ? "true dayo" : "false dayo"; C#(3.0) : var msg = true ? "true dayo" : "false dayo";
591 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 08:14:29.69 ] 最近どんどん動的型付け言語の メリットがなくなっていくね。
592 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 08:47:25.44 ] >>590 …それでmsgの型を推論しろってか。
593 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 09:24:13.53 ] >>591 この戦いが終わったら全ての武器のメリットがなくなるんだ
594 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 09:42:55.39 ] 機械語のメリットがなくなってゆくね、とか言ってる奴の同類だよなぁw
595 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 09:43:05.44 ] でも静的型はコンパイルが必要でREPLももっさり、型推論も万能じゃない スクリプト言語はこれからも残るよ
596 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 10:59:45.94 ] trueって名前の変数を作って、遅延評価によってmsgを参照したときの変数trueの値によりmsgの値も変わるってことでいいんかの 変数trueに再代入できたりしないとあんま意味なくね? いや違ってたらすまんが
597 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 11:11:11.60 ] >>590 は型推論の話じゃないの? "true dayo"も"false dayo"も文字列リテラルなので 三項演算の条件のtrue/falseを問うことなくmsgの型を文字列と確定できる
598 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 11:27:23.87 ] >>597 ああなんだそういうことか、勘違いしてたわ
599 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 11:55:08.69 ] 変数に互換性がない別の型の値を 再代入できる言語はクソです。
600 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 12:10:48.87 ] >>586 Scalaって事前(?)にコンパイルする以外になんか実行方法あったっけ?
601 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 12:18:53.17 ] >>600 >>581 はコンパイルしたらエラーがでます。
602 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 12:21:46.03 ] コンパイルしない場合は、そのまま動きます。
603 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 12:31:37.65 ] >581はscalaスクリプトだから、コンパイルする場合は -Xscript XXX オプションをつける必要があるかと
604 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 12:42:00.90 ] 動くね $ time scala Lifegame.scala 0,1,1,0,0 0,1,0,1,0 0,0,0,0,0 0,0,0,0,0 0,0,1,0,0 scala Lifegame.scala 1.44s user 0.09s system 4% cpu 37.965 total AMD MV-40 1.6GHz シングルコア
605 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 12:42:30.36 ] >>599 それで、代入を禁止するのと共用体を禁止するのは、どっちが良いんですか
606 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 12:48:02.58 ] スクリプト実行 time scala LifeGame.scala 0,1,1,0,0 0,1,0,1,0 0,0,0,0,0 0,0,0,0,0 0,0,1,0,0 real 0m1.819s user 0m0.704s sys 0m0.104s コンパイル実行 time scala LifeGame 0,1,1,0,0 0,1,0,1,0 0,0,0,0,0 0,0,0,0,0 0,0,1,0,0 real 0m0.585s user 0m0.528s sys 0m0.072s コンパイル時間の分、スクリプト実行だと起動に時間がかかるね
607 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 12:48:20.97 ] >>605 両方いいです。
608 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 12:51:30.57 ] >>597 よく見れ。 msgにtrueを代入してる。
609 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 12:53:31.56 ] >>608 どのtrueを代入してるんですか? 全文を引用して、該当のtrueを【】でくくって下さい。
610 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 13:04:26.07 ] >>601 コンパイル通らないのでAppにして通したんだけどこれでも遅いままなのかな? object LifeCell extends App { val board = Board(List(List(0,1,1,1,0),List(0,1,0,0,0),List(0,0,1,0,0),List(0,0,0,0,0),List(0,0,0,0,0))) board.life println(board) val rand = new Random() val b500 = Board(List.fill(500, 500){rand nextInt 2}) val s = new Date().getTime for (i <- 1 to 500) b500.life println(new Date().getTime - s) } >>603 あ、Scalaスクリプトなんてモードがあるんですね。 実行オプションでそんなに差が出るものなんですか?
611 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 13:31:36.87 ] Javaの実行環境に詳しくないとまともにベンチとれないんじゃないかと思う >>608 $ cat hello.cs class Program { public static void Main() { var hoge = true ? "*true*" : "*false*"; System.Console.WriteLine(hoge); } } $ mono hello.exe *true*
612 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 13:56:15.31 ] >>608 お前が良く見た方がいい
613 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 14:10:28.74 ] 括弧を省略する言語は危険 式と文を区別しない言語も危険
614 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 14:12:28.08 ] >>613 蛇の国からようこそおこしやす
615 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 14:22:29.08 ] Lisp系から見るとHaskellも括弧省略言語だな
616 名前:デフォルトの名無しさん mailto:sage [2012/04/29(日) 19:36:04.13 ] λ式に比べたらLispだって
617 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 00:25:42.19 ] >>616 Lispの関数は apply = foldl ($) (((f x) y) z) == (apply f) [x, y, z] 省略ではなく、式を変形している (x, y, zの型が異なる場合、Haskellは上の式が間違っていると主張する)
618 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 01:24:53.48 ] >610 core i5で90s程度だね。 ちなみに def life() { cells.foreach(_.foreach(_.evaluate)) cells.foreach(_.foreach(_.update)) } を def life() { cells.par.foreach(_.foreach(_.evaluate)) cells.par.foreach(_.foreach(_.update)) } にして並列化すると30s。 まだまだ遅いけど。
619 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 01:28:51.62 ] >>587 遅くなって悪い。確かに待ち合わせが抜けてるね。 BoardもActorをextendsしてlifeを以下のactに替えればよさそう。 def act() { cells.foreach(_.foreach((c:Actor) => {link(c); c.start})) var count = 0 loopWhile(count < m * n) { receive { case _ => count += 1 } } andThen { print(this) } }
620 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 01:42:08.34 ] やっぱり手続き型のC言語が こういうのは一番早いね。
621 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 06:36:40.19 ] つまりCの関数を簡単に呼べる言語が優秀
622 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 08:02:32.77 ] なんだ。Rubyが最強ってことか。
623 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 09:21:02.55 ] >>546 のCの関数を呼び出してみた from __future__ import print_function from ctypes import * clife = cdll.LoadLibrary('liblife.so') clife.life.argtypes = [POINTER(POINTER(c_int)), POINTER(POINTER(c_int)), c_int, c_int] x = [[0,1,1,1,0], [0,1,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]] a, b = (POINTER(c_int) * 5)(), (POINTER(c_int) * 5)() for i in xrange(5): a[i], b[i] = (c_int * 5)(*x[i]), (c_int * 5)() clife.life(a, b, 5, 5) print('\n'.join(''.join(str(b[i][j]) for j in xrange(5)) for i in xrange(5)))
624 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 15:16:50.31 ] Haskell(GHC)からC関数を使用 import Foreign.Marshal (newArray, mallocArray, peekArray, free) import Foreign.C.Types (CInt) import Foreign.Ptr (Ptr, plusPtr) import Foreign.Storable (sizeOf, peek) import Data.List (unfoldr) foreign import ccall "life" cLife :: Ptr (Ptr CInt) -> Ptr (Ptr CInt) -> CInt -> CInt -> IO () main = do x' <- newArray $ concat xss :: IO (Ptr (CInt)) y' <- mallocArray (m * n) x <- f x' =<< peek x' y <- f y' =<< peek y' cLife x y (fromIntegral m) (fromIntegral n) z <- peekArray (m * n) y' mapM_ free [x, y] mapM_ free [x',y'] print $ unfoldr (\xs -> if null xs then Nothing else Just $ splitAt n xs) z where xss = [[0,1,1,1,0], [0,1,0,0,0], [0,0,1,0,0], [0,0,0,0,0], [0,0,0,0,0]] m = length xss n = length (concat xss) `div` m f p h = newArray [plusPtr p (sizeOf h * i * n) | i <- [0..m-1]]
625 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 20:00:22.80 ] 速度が必要な極一部の処理だけ 速い言語(C/C++/Java)で書けば良いのに クソ遅い言語で速度競っててワロタwww
626 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 20:14:25.98 ] なんだJava厨か
627 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 20:25:46.03 ] Ruby「実行速度とかそんなの求めてませんから(キリッ」
628 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 21:11:28.94 ] >>546 のコードをJavaにベタ移植したんですが C言語に比べて物凄く遅いです(6.5倍遅い) (出力が遅すぎるので、そこをコメントアウトしてもまだ遅いです) ideone.com/FoYga どうやったら速くなりますか?
629 名前:デフォルトの名無しさん mailto:sage [2012/04/30(月) 21:27:32.39 ] すいません正しく移植したら速くなりました ideone.com/oLyyb
630 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 03:28:55.35 ] 関数型言語で書くとどうしてもボトムアップになる, そこが問題, 小さい処理ならそれでいいが,大きなシステムだとはなしにならん
631 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 03:59:53.53 ] 関数型言語はトップダウンでもボトムアップでも組む事が出来る 出来ないのはそいつが未熟なだけ
632 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 04:44:27.14 ] >>630 自分は逆に関数型言語でトップダウンだが・・・ 入れ子になった関数を変更するときぐらいだな。ボトムアップな感じになるのは
633 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 05:04:37.25 ] マクロな関数(処理)から書き始め、マクロな関数から呼ばれる ミクロな関数は入出力の型だけ決めて実装は後回し なんでこんな簡単なことが>>630 には出来ないの?
634 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 07:57:45.80 ] トップダウンはどうしても車輪の再発明になる 再利用はどうしてもボトムアップになる
635 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 09:19:19.80 ] え?
636 名前: ◆QZaw55cn4c mailto:sage [2012/05/01(火) 12:12:45.49 ] >>634 実感として、トップダウンとボトムアップの出会うところでうんうんうなっています。
637 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 15:17:57.73 ] >>634 ボディを違う色で塗って「ニューモデル」っていうだけだろ
638 名前:デフォルトの名無しさん [2012/05/01(火) 19:35:01.49 ] Excel内臓の関数型言語の普及率はすげぇよな。 窓際に座ってる禿ですら操作できるんだからなぁ。 research.microsoft.com/en-us/um/people/simonpj/Papers/excel/index.htm
639 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 19:48:21.14 ] simonpj先生の勤務先都合仕事だからだまされないで!
640 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 19:53:04.34 ] 騙されるも何も、内容は事実じゃん。
641 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 19:57:17.64 ] スプレッドシート猿によるアホな決定というリスクマネジメントのための学会?
642 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 20:11:03.69 ] 現実には使えないExcelの拡張の話だけどなw
643 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 20:20:54.13 ] 拡張せずとも、普通に計算するだけで関数型だろ? 何言ってんだ?
644 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 20:54:33.43 ] A1=3 A2=A1-32 A3=A2*5/9 これは静的単一代入 (SSA) です。 SSAは関数型に入りますか?
645 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 20:59:05.32 ] y = x + 5 は一次関数。あとは説明要らんよな。
646 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 21:02:58.15 ] そもそも、型に入るとか入らないとかいう型の理論が要らない
647 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 21:47:34.44 ] 型がないと、実行時にしかメソッド名の解決ができない。 これは開発工数が伸びる原因になる。
648 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 21:56:43.18 ] なんという緻密な分析
649 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 22:03:59.52 ] 関数"型"の話してんだろコミュ障
650 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 22:36:11.12 ] >>649 だから、型ですよね?
651 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 22:36:32.17 ] 型だよ型。
652 名前:デフォルトの名無しさん mailto:sage [2012/05/01(火) 22:37:00.05 ] 型の話しようぜ。
653 名前:uy mailto:sage [2012/05/02(水) 01:30:41.35 ] >>67 class Array def my_permu return [self] if size < 1 inject [] do |r , n| reject{|x| x == n } .my_permu.inject r do |r,ary| r << [n] + ary end end end end p (1..3).to_a.my_permu
654 名前:デフォルトの名無しさん mailto:sage [2012/05/02(水) 03:53:50.68 ] ぶっちゃけ関数型もオブジェクト指向もどうでも良くて 自分が使ってる言語以外をdisりたいだけだよね
655 名前:デフォルトの名無しさん mailto:sage [2012/05/02(水) 11:28:46.31 ] >>653 まだpermutationやってんのかよ、こんなもんがそんな面白いか? perm [] = [[]] perm xs = [x:y | x <- xs, y <- perm $ filter (/=x) xs] main = print $ perm [1,2,3]
656 名前:デフォルトの名無しさん mailto:sage [2012/05/02(水) 11:34:39.78 ] こっちは要素の重複を取り除かないバージョン import Data.List perm' [] = [[]] perm' xs = [x:y | x <- xs, y <- perm $ delete x xs]
657 名前:uy mailto:sage [2012/05/02(水) 13:23:15.71 ] >>655 Rubyのpermutationって誰も知らないのか話題にならないから俺が最初に2chにコード投下したやつじゃん(半年前くらいに) 67の冗長ゴミカスRubyソースコードを添削しただけだよ
658 名前:デフォルトの名無しさん mailto:sage [2012/05/02(水) 13:33:49.06 ] へえー、これ良いね。
659 名前:デフォルトの名無しさん mailto:sage [2012/05/02(水) 15:29:43.37 ] >>658 いやHaskellでもRubyでも標準添付や組み込みのライブラリに入ってますし…
660 名前:デフォルトの名無しさん mailto:sage [2012/05/03(木) 10:07:46.90 ] >>655 要素の重複を取り除くところでバグるかもしれない点は面白い
661 名前:デフォルトの名無しさん mailto:sage [2012/05/03(木) 14:24:19.11 ] >>655 を Squeak Smalltalk で書いてみた。バグもそのまま。 perm := [:xs | xs ifEmpty: [#(())] ifNotEmpty: [ xs gather: [:x | (perm value: (xs copyWithout: x)) collect: [:ys | {x}, ys]]]]. perm value: #(1 2 3) "=> #((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1)) "
662 名前:デフォルトの名無しさん mailto:sage [2012/05/03(木) 20:11:32.07 ] >>653 も書いてみた。これも重複要素があるとバグる。 SequenceableCollection >> perm self size < 1 ifTrue: [^Array with: self]. ^self inject: #() into: [:r1 :n | (self reject: [:x | x = n]) perm inject: r1 into: [:r2 :ary | r2 copyWith: (ary copyWithFirst: n)]] #(1 2 3) perm "=> #((1 2 3) (1 3 2) (2 1 3) (2 3 1) (3 1 2) (3 2 1)) " ちなみに、Squeak Smalltalkで組み込みのpermutation相当を見たらこんなふうに 破壊的操作による実装だった。 class Array def perm_each(&block) clone.perm_start_at(0, &block) end def perm_start_at(n, &block) return if n > size-1 return block.call(self) if n == size-1 (n..size-1).each do |i| swap!(n, i) perm_start_at(n+1, &block) swap!(n, i) end end def swap!(a, b); self[a], self[b] = self[b], self[a] end end
663 名前:デフォルトの名無しさん mailto:sage [2012/05/04(金) 12:04:28.46 ] F#で遅延評価 let bind m f = seq {for x in m do yield! (f x)} let ret x = Seq.singleton x let rec perm xs = if Seq.isEmpty xs then ret Seq.empty else bind (seq {0 .. (Seq.length xs - 1)}) (fun n -> bind (perm (Seq.append (Seq.take n xs) (Seq.skip (n+1) xs))) (fun ys -> ret (seq {yield (Seq.nth n xs); yield! ys})))
664 名前:デフォルトの名無しさん mailto:sage [2012/05/05(土) 00:05:09.38 ] ttps://metalab.at/wiki/Lambdaheads こんなひとおる?
665 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 08:01:00.40 ] 未だに関数型言語の機能が欲しいと思ったことがない。 俺みたいな奴は案外多いんじゃないかね。 そんなことよりトランザクショナルメモリはよ。
666 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 09:25:35.24 ] 欲しいと思う機能はそれほど多くない だが変な機能をゴリ押しされるとそれに対抗するものが欲しくなる ゴリ押しを断るために、先約があるとかいって他のを抜擢するみたいな話は案外多い
667 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 11:09:05.44 ] うむ。関数型言語というより コレクションライブラリがあれば 十分だったりするw Guavaおすすめ
668 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 12:23:52.01 ] ム板の関数型言語派の大半は「関数型言語派」ではなく「型推論派」だろ
669 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 12:33:51.12 ] スレタイが無知だな。 手続型 vs 関数型 構造化設計 vs オブジェクト指向設計
670 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 12:34:57.95 ] >666 メタプログラミングなんてどう? LISPのように構文を犠牲にしないMPといえば、OO系が主流だろう。
671 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 12:59:41.15 ] コレクションにもpush型とpull型があって push型は一昔前のOO pull型は遅延評価できるので関数型に近い印象がある 最近はpull型も普及したので、まだ売れ残っている型推論の方が関数型らしく見える メタプログラミングは、共通のVMまたはC言語の上に好きな言語を乗せるのが主流
672 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 13:07:46.75 ] メタオブジェクトプロトコルみたいな話は最近どうなったのか
673 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 16:21:50.38 ] >>671 一昔前がよくわからないのでpull型とpush型の違いがよくわからんです
674 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 17:41:19.49 ] >>673 getterを呼び出したり成功か失敗か調べたりするのがpull型 getter反対派はpush型
675 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 19:43:30.18 ] 言語はなんでもいいので具体例をプリーズ。
676 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 20:31:27.12 ] pushとかpullなんて名前は知らないけどこんな感じなんじゃね? サンプルはJava。上がきっとpushで下がpull www.akirakoyasu.net/2011/01/15/218/ List<B> blist = new ArrayList<B>(alist.size()); for (A a : alist) { blist.add(new B(a)); } Guavaを使う場合は次のように書きます。 List<B> blist = Lists.transform(alist, new Function<A, B>(){ @Override public B apply(A a) { return new B(a); } });
677 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 20:34:08.65 ] いまさらだけど、>>671 の pullとpushの言葉の使い方逆じゃね?
678 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 20:43:49.33 ] >>677 放置したほうがいい人だと思うがどうか? "Push-Pull Functional Reactive Programming"風に、 pull: demand driven push: data driven ってことでいいかと。
679 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 20:45:09.00 ] 言葉のままに捉えればよいんじゃない? pullは引く。 result = hoge( piyo( huga() ) ); pushは押す。 huga( result ); piyo( result ); hoge( result );
680 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 20:59:16.39 ] >>678 遅延評価はdemand drivenだから、671は合ってるだろ
681 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 21:05:42.54 ] 一箇所だけ取り上げてそんな事言われても困りますよ。
682 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 21:16:14.00 ] >>677 は0箇所ですよ 0箇所よりも1箇所の方がいいんじゃないか
683 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 21:18:45.89 ] pullとかpushって>>671 が作った言葉だろ? 手続きタイプと、コールバックタイプとかでいいんじゃね?
684 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 21:23:25.41 ] なんだ、オレオレ用語かよ
685 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 21:44:18.93 ] >>682 まあそりゃそうだねw push/pullは、上に上げたようにFRPでも取り上げられてるし、 他にはWebアプリフレームワークとかXML系APIとか、 いろいろなところでAPIデザインの選択肢として語られてる。 大げさに騒ぐような概念じゃないけど。
686 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 21:51:58.49 ] ja.wikipedia.org/wiki 繊維強化プラスチック 繊維強化プラスチック(せんいきょうかプラスチック、Fiber Reinforced Plastics、FRP)は、 ガラス繊維などの繊維をプラスチックの中に入れて強度を向上させた複合材料のこと。 単に FRP と書いて、ガラス繊維強化プラスチックを指すことも多いが、 ガラス繊維であることを明示したい場合は GFRP または GRP (Glass fiber reinforced plastics, Glass-reinforced plastics) と書かれる。
687 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 22:02:41.17 ] URL貼れってか conal.net/papers/push-pull-frp/push-pull-frp.pdf
688 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 22:14:04.87 ] でも、FRP自体は明らかに関係ない概念だよね? pullとpushの概念引っ張ってくるためだとしても。 それに、Getter/SetterをPull or Pushに分類しようとするのは 独自解釈が過ぎるでしょ
689 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 22:15:07.62 ] なんだF#用語か。pro.art55.jp/?eid=1303925
690 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 22:19:52.64 ] >>671 はオレオレ定義すぎ。 >>676 の下がpush。上はシラネ。 だろ。普通にpull/pushを考えるなら。
691 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 22:23:38.07 ] >>688 > でも、FRP自体は明らかに関係ない概念だよね? ちょっと難しい例でごめんね。
692 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 22:28:26.04 ] >>691 難しい例もなにも、普通にFRP関係ない例しかでてないぞ。 関係あるんなら関係ある例になるコードをださんと。
693 名前:デフォルトの名無しさん mailto:sage [2012/05/06(日) 23:30:20.47 ] >>688 つまり、まず質問をして、独自ではない回答が出るまで待っていればいいんですかね 関数型言語がgetterの使用を制限しない理由は何でしょうか
694 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 06:32:00.39 ] 関数型ってパターンマッチとか、再帰とか、モナドとか、そんな程度のものなの? もっとすごい秘密兵器があるんじゃないかなぁと期待しているんだけど、イマイチ見えてきません。 型クラスのメリットは、クラスを使った不完全な抽象データ型オブジェクト指向より 定式化され優れているとわかるとしても、両者は必ずしも背反するものではないですよね? 参照透明性にしても抽象度やモジュラリティは上げられる反面、直感的でない回りくどい処理や そのための記述を強いられたりする局面も少なからずあるし、そうしたやり難さと引き換えに 関数型でゴリ押しするメリットってどこら辺にあるのでしょうか?
695 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 09:50:54.31 ] 高階プログラミングではないかと昨夜から今朝にかけて思った。 いわゆるメタプログラミングや自己反映計算を実現する方法として、 自己書き換え→テンプレやマクロ→...というように発展してきて、 関数合成とかでプログラミングをするようになった、というか。
696 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 10:34:09.89 ] 関数合成はメタプログラミングに入りますか?
697 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 11:00:16.79 ] >>694 代入を制限する関数型が、get/setの両方を制限するオブジェクト指向よりも回りくどい と言われるのは何故ですか?
698 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 11:08:18.79 ] Smalltalkが普及しなかったようにHaskellは普及しない
699 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 11:19:44.93 ] 「get/setの両方を制限」のところがよくわからないので具体的にお願いします。 あとなんでその「get/setの両方を制限」が関数型の再代入制限に対応すると 思われたのでしょうか?
700 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 11:50:13.94 ] こうかいかんすう
701 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 12:01:35.13 ] 高階関数って関数オブジェクトがファーストクラスなら どうということなく使えますよね。それでもやっぱり 関数型の秘密兵器なんでしょうか? カリー化が自動だったり関数合成演算子が組み込みなのは嬉しいけど、 OOPLであっても関数オブジェクトがそうであればいいだけって気もしますし、 ポイントフリースタイルで書こうとしてパズルみたいになるのも 何だか本末転倒な感も否めません。
702 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 12:15:37.81 ] OOPLでもできるって 頑固なOOPLのスタイルを変えさせることができるなら凄い兵器だ
703 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 12:35:48.84 ] 頑固なOOPLのスタイルってどんなの?
704 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 12:54:07.33 ] >>701 別に秘密兵器でも何でもなく、関数型の思想のうち 手続き型でも適用出来そうな部分は既に受け入れられてるってことさ
705 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 15:35:46.86 ] >>694 「ゴリ押しする」ってのは、あなたの心の問題じゃないの?
706 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 15:47:21.06 ] 関数型の主力は副作用が無いこと 手続き型の主力は副作用が有ること OOPは副作用の局所化を目指すもの 異論は認める
707 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 17:50:02.95 ] 副作用があるのはsetterだけ getterの局所化には副作用以外の目的があるだろう
708 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 18:08:27.94 ] そうかしら?
709 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 18:09:54.21 ] >>707 一体いつからgetterに副作用が無いと錯覚していた? getで内部キャッシュを生成,保持しても良く 副作用は外から分からずとも、仕様(期待)通り動作すればいい
710 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 18:47:24.86 ] しかし実際にはオブジェクトが他のオブジェクトの参照を握ってたりして、 一回のメソッド呼び出しがどんどんたらい回しされてって。 特にオブジェクト指向では多態のためにメソッドのシグネチャを固定化するから、 オブジェクトが他のオブジェクトの参照を握る傾向は強い。 つまり、オブジェクト指向で副作用の局所化はされないし、元々狙っても無い。 オブジェクト指向はオブジェクトに関するコードや変数の依存関係を纏めたってだけ。 これを手続き型で実行すれば、処理がオブジェクトを跨いであちこちに飛び回る。 このとき、副作用は局所化されない。 副作用の局所化するためには、処理がオブジェクトを跨がないように する必要がある。 しかし、それはオブジェクト指向とは関係無く、手続き型一般における、設計のテクニックだ。
711 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 19:01:14.42 ] ・シグネチャを固定化 → 他のオブジェクトの参照を握る ・副作用の局所化するため → 跨がないように この辺前後の関連がよく分からないので詳しくお願いします
712 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 19:09:28.48 ] どう言えばよいんだろうね。 オブジェクト指向はオブジェクト単位で色々纏めるが、これらは変数やコードといった、 静的な要素を分類したに過ぎない。 言い換えれば、「ソースコード」をオブジェクト単位で分類したに過ぎない。 一方で副作用はソースコード上には現れない。 実行時に「処理」にくっ付いて現れる。 だから、副作用を局所化するためには、処理の流れそのものを 局所化する必要があって、これは手続き型一般の設計の問題で、 OOだからどうこうという話ではない。 OOはあくまでソースコードをオブジェクト単位で局所化するだけで、 それ以上は助けてくれない。
713 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 19:26:38.69 ] >>709 それはgetterを作って良いし副作用が有って良いという意見だな そういう自由な考え方が定着すれば、OOに反対する人はいなくなると思う
714 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 19:29:05.25 ] そんでついでに言うと、 オブジェクト指向は処理の流れに関して凄く無頓着な一面がある。 というのも、仮想関数だ多態だといってな。 そんで、むしろソースコードみたいな静的なものは怖くねーよ、 こんなの綺麗に分類するより、 処理の流れとその副作用の方がよほど怖えーよ、そっち整理しろよ、 って考え方もあって、OOは使いどころが難しく、2chなんかで議論もこじれる。 だから皆だんだん嫌になってきて、 処理の流れそのものを気にしなくて良い関数型に白羽の矢が立ったってわけ。
715 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 19:48:12.05 ] 俺にとっての副作用を局所化というのは 「この変数を触るのはこの処理だけ」といった スコープを小さくしたり責任範囲の壁を作ったりすることなんだけど >>712 にとっての副作用の局所化というのは 何かのメソッド呼んだときに変化するN個のオブジェクトのN個の変数とか その辺りに言及してるのかな? メソッドの中で自身(A)が持ってる別のオブジェクト(B)のメソッドを呼んだとして そこから先でファイルアクセスが発生しようと それはBの範疇なのでAの中での局所化には関係無い というスタンスかな、俺はね >処理の流れに関して凄く無頓着 そうかもね 他のオブジェクトは外面(インターフェイスと仕様)しか見ないので 処理の内容は「あとは任せた」って感じだし
716 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 20:17:37.37 ] >>715 これは物凄く悪い例なんだけど、 AがBのメソッドを呼び出して、 そのメソッドの中でBがAのメソッドを呼び出したら、 カプセル化は壊れるんだよね。 そんな設計はするな、と言われそうだが、 これが結構良くあるんよ。 親が子の参照を持ってて、子も親への参照を持ってるとか。
717 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 20:22:02.86 ] 循環参照は注意だが、カプセル化は別に崩れてなくね?
718 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 20:22:28.51 ] カプセル化は言葉が悪かった。 整合性だね。
719 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 20:40:40.96 ] AがcallするならBはreturnすればいいのに、なぜかBもcallしようとするんだな なぜreturnを避ける設計をしてしまうのか
720 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 20:46:15.19 ] >719 てめぇ、CPSさんDisってんのか?
721 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 20:49:59.90 ] >>716 >これが結構良くあるんよ。 わかる・・・ イベントハンドラとかのインターフェイスの実体として子に自身を渡すとか 木構造で高速化のためAが別のA(親)を持つとかは許容出来るけど 一つずつ順にコンパイル出来ないような定義レベルでの循環参照は俺も嫌い
722 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 21:04:21.69 ] >>720 末尾呼出しなら問題なさそうだ 問題は、Aのメソッドの途中でAが参照されること
723 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 21:18:02.26 ] >>718 言葉が悪いんじゃない。関係ないんだよ。
724 名前:デフォルトの名無しさん mailto:sage [2012/05/07(月) 21:29:27.23 ] >>722 ACTORさん(以下略
725 名前:デフォルトの名無しさん mailto:sage [2012/05/11(金) 20:23:27.60 ] それぞれのオブジェクトがメッセージを投げ合い、 その結果でたらめな順序で副作用が起こっても問題が無い 仮に問題あっても例外投げときゃ無問題 そういうイイカゲンなシステム開発にオブジェクト指向は最適
726 名前:デフォルトの名無しさん mailto:sage [2012/05/11(金) 21:46:23.18 ] さすがにそこまでいい加減なシステムは品質を確保できないだろ。バカにし過ぎ。 「そのように組むことができる」ことと「実際にそうする」は別問題。 Haskellでも副作用が発生する処理と、そうでない処理をごちゃ混ぜにすることは可能は可能だし。
727 名前:デフォルトの名無しさん mailto:sage [2012/05/12(土) 18:57:50.97 ] ここの人らなら詳しそうだから教えてくれ。 0 :: Integer 0 = 0 みたいな感じで、数値を関数化できる言語ってないの? 0関数にラムダ与えたら、ラムダの実行を無視して、 0以外の数値関数にラムダ与えたらラムダを実行するようにしたい
728 名前:デフォルトの名無しさん mailto:sage [2012/05/12(土) 19:03:59.81 ] は? 関数なら 'a -> 'b みたいな型を持ってるはずだけど。 Integer という型は整数の型であって、関数じゃないよ。
729 名前:デフォルトの名無しさん mailto:sage [2012/05/12(土) 19:09:46.34 ] 別にそこの式は、数値を関数化したいって例であって 関数を返すとかとは関係ないよ
730 名前:デフォルトの名無しさん mailto:sage [2012/05/12(土) 19:21:16.56 ] 「数値を関数化」ってのが、たとえば「文字列を虚数化」みたいに意味不明。 むしろ、 > 0関数にラムダ与えたら、ラムダの実行を無視して、 > 0以外の数値関数にラムダ与えたらラムダを実行するようにしたい こっちをソースコードで表現できたら、少しはなんとかなるかもしれない。
731 名前:デフォルトの名無しさん mailto:sage [2012/05/12(土) 19:41:40.45 ] あ゛?チャーチ数ディスってんのかメーン
732 名前:デフォルトの名無しさん mailto:sage [2012/05/12(土) 23:05:55.96 ] >>727 「0」というシンボルと、何らかの関数を結び付けたいということ? 関数型ならそもそも、既に何かに結び付けられてるシンボルに 別の値を結び付けるのは再代入そのものだろうし 手続き型関数型問わず、特定リテラルの意味だけを変更するのはちとマズくないかな
733 名前:デフォルトの名無しさん mailto:sage [2012/05/12(土) 23:10:21.88 ] common lispに変数としての値と関数としての値を区別するということなのか
734 名前:デフォルトの名無しさん mailto:sage [2012/05/12(土) 23:11:42.30 ] ごめん、脱字した。 common lisp(のよう)に変数としての値と関数としての値を区別するということなのか
735 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 00:06:48.19 ] >>732 Smalltalkなら実現してたべ value := 0. value message. こんな感じで、数値にメッセージを送ると、 数値に紐付いたメソッドを呼ぶ事ができた。 1にメッセージを送れば、1のメソッド。 2にメッセージを送れば、2のメソッドみたいにね。
736 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 01:07:22.66 ] 本のお題がどういうものだが今一歩ピンとこないが、 チャーチ数を計算する型なしラムダ式処理系なら結構転がってる。 数値や真理値は短形表示できるが。
737 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 02:06:34.64 ] >>735 何が言いたいのか分からん value message と function value は語順が違うだけじゃね?
738 名前:デフォルトの名無しさん mailto:sage [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関数を実行
739 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 02:36:28.73 ] >>738 なるほど分かった 0や1といったリテラルに関数を割り当てたいってことだね どっちかというと関数型 vs. オブジェクト指向じゃなくて 静的型 vs. 動的型になりそうな気配
740 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 02:40:45.66 ] ところで>>727 のいう「ラムダ」の引数は何? それは何時渡すの?
741 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 02:44:08.62 ] >>740 値が関数だって事の説明用だから引数はなんでもいいんですが
742 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 02:49:18.06 ] >>741 意味論的には関数型言語の値は「ゼロ引数関数」という関数
743 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 08:04:27.03 ] いずれにしろ 0 :: Integer では、関数になってないから
744 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 10:20:35.18 ] OO信者の俺ですら数値クラスにメソッド追加するような コードは勘弁して頂きたい オープンクラスではしゃぐのは初心者時代で終わらせてほしい
745 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 11:09:32.18 ] >>735 >>738 シングルディスパッチでは第一引数を特別扱いしてるだけで x.foo y z と foo x y z に本質的な差は無い シングルディスパッチ脳には理解出来ないかもしれんけど
746 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 11:16:35.94 ] 難しい問題だね。 func( o1, o2 ) こういった関数は後からいくらでも追加できるけど、 o1.func( o2 ) との本質的な違いはスコープだけだからな。 多態出来る出来ないの違いは有るけど、それは言語上の制約ってだけだからね。 クラスの外のスコープにいくらでも関数が定義できるのに、 クラスの中のスコープにメソッドを追加することは出来ません、 って制約に一体どれほどの意味があるかって言われると、ねぇ。 特に動的言語では。
747 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 11:37:40.06 ] あんたの恣意的な分類で「本質」とか「言語上の制約ってだけ」とか言われても わかりませんわ。
748 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 12:25:07.97 ] 別に恣意的ではないと思うけど。 本来、どこのスコープに何を追加しようが勝手なものなんじゃないの? 静的言語では実行効率の理由で制限がかかってくるのも分かるけどさ。
749 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 12:32:53.64 ] Haskellでやっつけ お題の真意が掴めてないので、たぶん条件を満たしてない ideone.com/pTYEL
750 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 12:39:04.98 ] 0がどうのこうのの話は、まだ続いてたの? 0と1は同じ型だろうから、同じ関数にディスパッチされるのが当たり前だしさ。
751 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 15:59:42.13 ] >>742 そういう形式化もあるという程度の話。
752 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 18:30:14.35 ] このスレには時代遅れのSmalltalkを使ってる 奇特な人が居るから質問するんだけど、 あのIDEモドキを立ち上げずにプログラム実行する方法無いの? それと動的型付けで実行が遅いから、せめてボトルネックだけでも C/C++で書いて実行できないとトイプログラムでしか 使いモノにならないと思うけど、簡単にC/C++のライブラリとリンクできるの?
753 名前:デフォルトの名無しさん mailto:sage [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という方法が使えます。 www.cincomsmalltalk.com/pdf/DLLandCConnectGuide.pdf PharoやSqueakではVMプラグインを書いてバイトコードを拡張したり、FFIが使えます。 wiki.squeak.org/squeak/1448 wiki.squeak.org/squeak/1414
754 名前:デフォルトの名無しさん mailto:sage [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
755 名前:727 mailto:sage [2012/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を評価しない 数値を関数化できないかというのは、数値を評価したとき、このような 振る舞いをするように数値を定義できなる言語は無いかという事でした。 尤も、言語レベルで最初から数値をチャーチ数と同じように評価できるなら 新たに関数として数値を再定義できる必要は無いんですが。
756 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:00:39.51 ] >>752 時代遅れってアホか、通信・製造・金融・保険・政府。 お前がしらんだけで第一線で新規開発されとるわ。 国内企業なら、東洋ビジネスエンジニアリングとかが導入してんだぞ。
757 名前:デフォルトの名無しさん mailto:sage [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 = ()
758 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:19:29.56 ] >>755 Integer と () -> Bool は違う型なので、 同じ数値(関数)の型が文脈に応じて変化する言語でなければ不可能。
759 名前:727 mailto:sage [2012/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を評価する
760 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:20:46.22 ] >>758 できる言語はあるかと聞いているのですが? あとboolは関係ないですよね
761 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:24:09.03 ] >>760 じゃあ Integer と (() -> a) -> a それはともかく、関数型とか全然関係なくって まともな静的型なら無理って言ってるんだけど、 動的型しか使った事無い馬鹿には分からないかな?
762 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:25:17.06 ] >>761 だから、できない言語の事は聞いてなくて、出来る言語はあるかと聞いてるんですけど。
763 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:29:16.10 ] >>762 スレ違いだし問題としても糞詰まらんから どっか行けって言ってんだけど?
764 名前:デフォルトの名無しさん mailto:sage [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
765 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:32:20.89 ] >>763 NGにしたいんでトリでも付けてもらえます? スレ違い以前に話が通じないので
766 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:42:57.75 ] >>763 まず日本語の通じないお前がどっか行けよ
767 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:44:48.51 ] >>764 オブジェクトで出来てもあんまり嬉しくないんですが・・・
768 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:46:00.83 ] >>765 >>766 型付けの問題だって理解できない自分の低能さを 日本語の問題にすり替えるなよw
769 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:52:46.02 ] >>761 「コンセントの付いている車はありますか?」 「軽トラなら無理です」 お前が言ってるのはこういう事だという自覚は有るのか? 普通は「あります」「ありません」この2択だろ 頭おかしいな
770 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:53:58.75 ] >>767 Int32はラッパークラスとかではなく、プリミティブかつオブジェクトなんだけど。 まぁそれでもダメというならどうしようもない。
771 名前:デフォルトの名無しさん mailto:sage [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")
772 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 20:57:08.31 ] >>770 すいません。 関数と互換性をもってて欲しいんですよ。
773 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 21:06:51.99 ] >>771 >>772 てっきり拡張メソッド的なものを要求してるのかと思ってた。 Scalaなら暗黙型変換あるからできそうな気がする。
774 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 21:08:02.77 ] >>773 なるほど。Scalaですか、調べてみます。
775 名前:デフォルトの名無しさん mailto:sage [2012/05/13(日) 22:46:41.69 ] で、Scalaなら出来たの?
776 名前:デフォルトの名無しさん mailto:sage [2012/05/14(月) 00:37:38.04 ] マイナー言語使い共が 可読性皆無のコード書く御題で 型付けの弱さを競うスレはここですか? 時代に逆行してて笑えるwww
777 名前:デフォルトの名無しさん mailto:sage [2012/05/14(月) 01:46:05.41 ] 誰だって0と1は同じ型だと考えるのに、違った振る舞いをさせたいってのは、 何か前提がおかしいんだろうね。 元々何がしたかったのか聞ければよいんだけど、 彼にそういった振る舞いが出来るとも思えないしなぁ。
778 名前:デフォルトの名無しさん mailto:sage [2012/05/14(月) 07:07:11.76 ] うーん。一番良く分からんのは、>>767 を読むと出題者は>>764 を見て オブジェクトとしてなら「出来ている」認定してるっぽい処だな。
779 名前:デフォルトの名無しさん mailto:sage [2012/05/14(月) 07:40:52.01 ] 出題者がOOP厨だからオブジェクトには甘いだけだろ 別に不思議でもなんでもない もちろん出題者は底なしのアホだけど