[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 2chのread.cgiへ]
Update time : 05/14 13:02 / Filesize : 255 KB / Number-of Response : 780
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

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



1 名前:営利利用に関するLR審議中@詳細は自治スレへ mailto:sage [2012/04/07(土) 21:26:47.61 ]
一般的には、オブジェクト指向型言語が優勢でが
一部には関数型言語を崇拝している人もいます

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

前スレ toro.2ch.net/test/read.cgi/tech/1331328955/

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厨だからオブジェクトには甘いだけだろ
別に不思議でもなんでもない

もちろん出題者は底なしのアホだけど






[ 新着レスの取得/表示 (agate) ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<255KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef