12/04/20 22:55:07.28
・コンソール上で動く、カード(つーてもただの数字を表示するだけだが)を使ったミニゲーム
・1~9のカードを各4枚ずつ用意、それをシャッフルして「ストック」とする
・ストックから7枚のカードを引く
・引いたカードの中から、プレイヤーは合計が15になるように数枚を選んで捨てる
(選ばせ方はプログラマが考える、ギブアップ手段も用意)
・捨てなかったカードと合わせて再び7枚になるか、もしくはストックが空になるまでストックからカードを引く
・また15になるように捨てる
・引いては捨ててを繰り返し、ストックと手札が共に空になったらおめでとう的な言葉を吐いて終了
513:デフォルトの名無しさん
12/04/20 23:16:37.51
つまらない。
514:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/21 02:46:31.71
>>514
なぜこの人は今どきSmalltalkの末裔を使っているのか理由をうかがいたいので
おしえてくださいです
516:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/22 12:27:13.72
Squeakは入れたことあるが(てか今も入ってるけど)何をどうしたらいいのか判らん
>>514 のコードをどこに入力して、どう実行したら動くんだ?
519:デフォルトの名無しさん
12/04/22 17:54:43.65
>>518
1. URLリンク(sourceforge.jp) から 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:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/23 00:28:55.28
>>519
ありがと。何か前に入れたバージョンでやってみたら「[ | input |」の行の左に「Period or right bracket expected ->」とか出たけど、実行の仕方自体は判ったから色々試してみる。
522:デフォルトの名無しさん
12/04/23 00:33:02.59
ああ、インデントを一旦削って入れ直したら動いたわ。thx
523:デフォルトの名無しさん
12/04/23 07:26:59.30
あ、動的にいたスモールトーカーだ。よろしく!
524:デフォルトの名無しさん
12/04/24 12:35:28.99
日本語でおk
525:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/25 13:54:49.01
くだらん
527:デフォルトの名無しさん
12/04/25 14:03:57.26
Java8でラムダ式が言語仕様に入るようだね
javaもマルチパラダイム化が進むな
OOPLが関数型言語の特徴の一部を取り込む中
スレタイの通り言語比較した場合
「副作用の有無」が一番重要なんじゃないかと思ったけどどうだろう?
機能を取り込むことはあっても無くすことはしないだろうから
副作用の有無が、開発速度や可読性、保守性にどのように影響してくるか・・・
と考えても良いお題は思いつかないんだけどね
528:デフォルトの名無しさん
12/04/25 15:26:58.18
Javaって今でも組み込み型以外は参照型でしか扱えないの?
関数型言語使うようになってから、nullを持たない参照型とか、イミュータブルな値型がいかに重要か思い知った。
しかも、イミュータブルな値型を基本として、nullを持った参照オブジェクト型、nullを持たない参照オブジェクト型って形で扱えないと厳しい。
これは言語仕様として取り込まれていないとどうしようもない。
そういう意味では、C++は結構惜しいところまで行ってたと思う。
529:デフォルトの名無しさん
12/04/25 16:37:33.03
C++にはpure virtual function callというのがあって、仮想関数がnullを持つ。
値型でも仮想関数があったら元も子もない。
仮想関数をやめてswitchを使う覚悟がないと厳しい。
関数型言語のパターンマッチはswitchと同じ方式だ。
530:デフォルトの名無しさん
12/04/25 16:43:26.43
>>528 関数型言語はむしろ全てが参照型とも言えるんだが
531:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/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
12/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:デフォルトの名無しさん
12/04/26 20:54:15.37
(_, _) (`mod` 2) (\x _ ->
536:デフォルトの名無しさん
12/04/26 20:56:38.97
最近Lispさんを見かけないけどもう廃れちゃったの?
537:デフォルトの名無しさん
12/04/26 21:25:38.01
言語仕様を共通にするというトレンドは終わった
個別の実装は始まってなかった
538:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/27 08:45:31.15
>>536
2chで世間が判った気になり始めたら色々ヤバイな。
540:デフォルトの名無しさん
12/04/27 10:14:19.97
>>538
500x500 500世代で測ったら 1.8GHz Core i7 で 68秒だった。けっこう速いね。
541:デフォルトの名無しさん
12/04/27 11:00:18.10
ライフゲームで関数型とオブジェクト指向の何を比較したいんだろう?
>>525は次世代を返す関数としてるけどオブジェクト指向側は
lg = new lifegame(500,500);
for(i=0;i<500;i++)lg.life();
console(lg);
って感じでいいの?
そうしないと関数型 vs 手続き型みたいなことになるよね
542:デフォルトの名無しさん
12/04/27 11:37:20.76
例えばF#とC#を比較したら関数型言語と手続き型言語の比較になる
本物のOOは言語に依存しない
関数型言語と対立するようなOOは偽物
543:デフォルトの名無しさん
12/04/27 12:00:12.21
>>541
ライフゲームは単純だけどパラダイムの特徴をかろうじて出せるくらいの規模はあるんじゃない?
お題にあるlifeという関数名(メソッド名)にこだわらなくていいと思うよ。
要は小さな例での正常動作と、500x500セル 500世代(必要なら50世代とかに軽減して)
にどのくらいかかるかが示せていればOKかと。
544:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/27 14:36:04.79
javascriptで書いてみた。破壊的操作有りで。
ソースの長さ汚さは勘弁してください。
URLリンク(ideone.com)
※↑は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:デフォルトの名無しさん
12/04/27 20:27:45.31
てきとーにCで書いてみた
500回はさすがに秒数制限に引っかかったけど、50回で0.69秒
URLリンク(ideone.com)
547:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/28 00:03:43.28
OOPならセルごとにオブジェクトで、と思ったが、
仕様が全状態の配列から配列への変換なのね。
550:デフォルトの名無しさん
12/04/28 00:54:50.29
>>549
べつにこだわらなくてもいいでしょ。組みやすいように組めば。
要は小さな例での動作確認出力結果と、
500x500セル 500世代(必要なら50世代とかに軽減して)の計測結果を示せればOK。
551:デフォルトの名無しさん
12/04/28 04:39:34.80
まあ出題者が関数的なアタマなんだろう
552:デフォルトの名無しさん
12/04/28 06:37:42.91
セルごとにオブジェクトとかねぇよww
553:デフォルトの名無しさん
12/04/28 07:45:09.18
問題領域がどこかわかれば何処をオブジェクトにしたら良いか分かるよ
554:デフォルトの名無しさん
12/04/28 09:32:38.01
なかなか面白いじゃないか。
オブジェクト指向で設計されたライフゲーム、頼む。
555:デフォルトの名無しさん
12/04/28 09:44:59.90
この題じゃ>>541くらいにしかならんだろ
オブジェクト指向をどういうもんだと思ってんだよw
556:デフォルトの名無しさん
12/04/28 10:37:13.10
セル毎にオブジェクトか、面白そうだしちょっとやってみるかな
557:デフォルトの名無しさん
12/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
全部は長いのでこっち
URLリンク(ideone.com)
558:デフォルトの名無しさん
12/04/28 11:05:27.26
8coreのXeonマシンでOpenMP使ってCのコードを並列化したら
500*500の500世代で1秒切ったわw
559:デフォルトの名無しさん
12/04/28 12:11:25.24
>>557
他スレで遊んでる内に作られてしまった…
560:デフォルトの名無しさん
12/04/28 12:13:20.34
>>552
ライフゲームは生物が単純だから変に思えるかもしれないけど、
これがゲームのキャラクターと考えればごく普通の考え方。
ライフゲームはどの生物も同じ能力だけど、セルがオブジェクトなら
実際の生物みたく、オブジェクトごとに能力を変えることだって出来る
というかそういうゲームがあったね。
マルチプレイヤー・ネットワーク・ゲームTerrarium
URLリンク(www.atmarkit.co.jp)
> プレイヤーは各自プログラミングした動物を持ち寄り、フィールド上で動物同士を戦わせる。
561:デフォルトの名無しさん
12/04/28 12:23:40.64
やっぱりオブジェクト指向だと規模が大きくなる。
逆に言えば、規模が大きい場合は
オブジェクト指向が有利ってことか。
562:デフォルトの名無しさん
12/04/28 12:42:19.17
大規模で全貌の把握がしづらいものを
個々人では把握できないままでも比較的扱いやすいのがOOPLだと思ってる
563:デフォルトの名無しさん
12/04/28 12:57:03.02
全体を統一しづらい規模になると言語は一つではなくなる
Objective-C++/CLIのような状態
564:デフォルトの名無しさん
12/04/28 16:19:14.44
>セルがオブジェクトなら
>実際の生物みたく、オブジェクトごとに能力を変えることだって出来る
大抵のOOPLにはマルチメソッドすらないのに、
良くそんな大口たたけるな。
565:デフォルトの名無しさん
12/04/28 16:24:25.86
無いのはマルチメソッドを実現するための言語仕様であって、
マルチメソッド自体は実装できるからね。
566:デフォルトの名無しさん
12/04/28 16:25:24.90
>>564
突然何言い出してんのこの子(´・ω・`)
567:デフォルトの名無しさん
12/04/28 16:28:06.39
ホーミングミサイルの話でボコボコにされたやつだ。
気にすんな
568:デフォルトの名無しさん
12/04/28 18:10:20.59
>>565
関数型言語でも実装できる
パラダイムじゃなく言語間の比較スレなんだから
そんなこと言っても意味ない
569:デフォルトの名無しさん
12/04/28 18:15:28.58
>>561
仮に「OOPだと規模が大きくなる」が真だとしても
そこから「規模が大きいとOOPは有利」は導けない
570:デフォルトの名無しさん
12/04/28 18:53:58.34
静的型付けの割に簡潔に書けて、かつ型チェックも厳しくやってほしい
こういうニーズに関数型言語が応えてるから使ってるだけで、
関数型言語使ってる奴が皆OOを嫌ってるわけでも
設計レベルで使わないわけでもないんよ
争いは不毛だ
571:デフォルトの名無しさん
12/04/28 19:06:33.77
> 静的型付けの割に簡潔に書けて、かつ型チェックも厳しくやってほしい
なんとなくC#を思いだしたけどC#で書く人いないね
572:デフォルトの名無しさん
12/04/28 19:31:55.12
争わなかったらスレの存在意義がないだろ
573:デフォルトの名無しさん
12/04/28 20:25:37.43
>>571
C#のジェネリックってダックタイピングできないんでしょ?簡潔かなぁ。
574:デフォルトの名無しさん
12/04/28 20:41:49.41
>>560
ライフゲームのセルっていう文脈だからねぇよって言ったわけで
ゲームのキャラクターのオブジェクト化まで否定はしてねぇよw
>>564
またホーミングの子www
575:デフォルトの名無しさん
12/04/28 21:39:52.98
>>570
Scalaがそう。
静的言語で、簡潔に書けることを
証明した言語。
576:デフォルトの名無しさん
12/04/28 21:45:24.53
>>575
このスレでまだ一回もScala出て来てないぞ
ライフゲームで良いからコードで証明してみてくれ
577:デフォルトの名無しさん
12/04/28 23:03:24.87
「Scalaは簡潔に書けると証明した」=>「じゃあチョット書いてみて」=> 逃亡
どんなコントだよwww
578:デフォルトの名無しさん
12/04/28 23:11:10.96
ん? Scala知らないの?
579:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/29 00:22:22.02
純粋な関数型言語って、参照するたびに値が変化する変数みたいなのは作れるの?
たとえば乱数とか、参照した時点の現在時刻を値として持ってる変数とか
581:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/29 01:14:20.15
これで静的型付け言語なんだぜ。
val msg = if (true) "true dayo" else "false dayo"
583:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/29 01:30:58.02
これで静的型付け言語なのか。
本当に短いコードは動的型付け言語だけの特権じゃないことを
証明してしまったな。
585:デフォルトの名無しさん
12/04/29 02:11:32.74
ただ静的型にしては遅いよね。
500x500 500世代で動的な >>579 が 112秒なのに、>>581 は 196秒。
586:デフォルトの名無しさん
12/04/29 02:18:22.73
>>585
それ事前コンパイルしてないだろ?
587:デフォルトの名無しさん
12/04/29 02:35:44.97
>>583
これって一回のlifeのコール後、
すべてのセルがアップデートを終えるのをどこで待ち合わせているの?
588:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/29 06:30:26.82
どうせ、RubyとかLLばっかり使ってる人だろw
590:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/29 08:14:29.69
最近どんどん動的型付け言語の
メリットがなくなっていくね。
592:デフォルトの名無しさん
12/04/29 08:47:25.44
>>590
…それでmsgの型を推論しろってか。
593:デフォルトの名無しさん
12/04/29 09:24:13.53
>>591
この戦いが終わったら全ての武器のメリットがなくなるんだ
594:デフォルトの名無しさん
12/04/29 09:42:55.39
機械語のメリットがなくなってゆくね、とか言ってる奴の同類だよなぁw
595:デフォルトの名無しさん
12/04/29 09:43:05.44
でも静的型はコンパイルが必要でREPLももっさり、型推論も万能じゃない
スクリプト言語はこれからも残るよ
596:デフォルトの名無しさん
12/04/29 10:59:45.94
trueって名前の変数を作って、遅延評価によってmsgを参照したときの変数trueの値によりmsgの値も変わるってことでいいんかの
変数trueに再代入できたりしないとあんま意味なくね?
いや違ってたらすまんが
597:デフォルトの名無しさん
12/04/29 11:11:11.60
>>590は型推論の話じゃないの?
"true dayo"も"false dayo"も文字列リテラルなので
三項演算の条件のtrue/falseを問うことなくmsgの型を文字列と確定できる
598:デフォルトの名無しさん
12/04/29 11:27:23.87
>>597
ああなんだそういうことか、勘違いしてたわ
599:デフォルトの名無しさん
12/04/29 11:55:08.69
変数に互換性がない別の型の値を
再代入できる言語はクソです。
600:デフォルトの名無しさん
12/04/29 12:10:48.87
>>586
Scalaって事前(?)にコンパイルする以外になんか実行方法あったっけ?
601:デフォルトの名無しさん
12/04/29 12:18:53.17
>>600
>>581はコンパイルしたらエラーがでます。
602:デフォルトの名無しさん
12/04/29 12:21:46.03
コンパイルしない場合は、そのまま動きます。
603:デフォルトの名無しさん
12/04/29 12:31:37.65
>581はscalaスクリプトだから、コンパイルする場合は
-Xscript XXX オプションをつける必要があるかと
604:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/29 12:42:30.36
>>599
それで、代入を禁止するのと共用体を禁止するのは、どっちが良いんですか
606:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/29 12:48:20.97
>>605
両方いいです。
608:デフォルトの名無しさん
12/04/29 12:51:30.57
>>597
よく見れ。
msgにtrueを代入してる。
609:デフォルトの名無しさん
12/04/29 12:53:31.56
>>608
どのtrueを代入してるんですか?
全文を引用して、該当のtrueを【】でくくって下さい。
610:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/29 13:56:15.31
>>608
お前が良く見た方がいい
613:デフォルトの名無しさん
12/04/29 14:10:28.74
括弧を省略する言語は危険
式と文を区別しない言語も危険
614:デフォルトの名無しさん
12/04/29 14:12:28.08
>>613
蛇の国からようこそおこしやす
615:デフォルトの名無しさん
12/04/29 14:22:29.08
Lisp系から見るとHaskellも括弧省略言語だな
616:デフォルトの名無しさん
12/04/29 19:36:04.13
λ式に比べたらLispだって
617:デフォルトの名無しさん
12/04/30 00:25:42.19
>>616
Lispの関数は
apply = foldl ($)
(((f x) y) z) == (apply f) [x, y, z]
省略ではなく、式を変形している
(x, y, zの型が異なる場合、Haskellは上の式が間違っていると主張する)
618:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/30 01:42:08.34
やっぱり手続き型のC言語が
こういうのは一番早いね。
621:デフォルトの名無しさん
12/04/30 06:36:40.19
つまりCの関数を簡単に呼べる言語が優秀
622:デフォルトの名無しさん
12/04/30 08:02:32.77
なんだ。Rubyが最強ってことか。
623:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/04/30 20:00:22.80
速度が必要な極一部の処理だけ
速い言語(C/C++/Java)で書けば良いのに
クソ遅い言語で速度競っててワロタwww
626:デフォルトの名無しさん
12/04/30 20:14:25.98
なんだJava厨か
627:デフォルトの名無しさん
12/04/30 20:25:46.03
Ruby「実行速度とかそんなの求めてませんから(キリッ」
628:デフォルトの名無しさん
12/04/30 21:11:28.94
>>546のコードをJavaにベタ移植したんですが
C言語に比べて物凄く遅いです(6.5倍遅い)
(出力が遅すぎるので、そこをコメントアウトしてもまだ遅いです)
URLリンク(ideone.com)
どうやったら速くなりますか?
629:デフォルトの名無しさん
12/04/30 21:27:32.39
すいません正しく移植したら速くなりました
URLリンク(ideone.com)
630:デフォルトの名無しさん
12/05/01 03:28:55.35
関数型言語で書くとどうしてもボトムアップになる,
そこが問題,
小さい処理ならそれでいいが,大きなシステムだとはなしにならん
631:デフォルトの名無しさん
12/05/01 03:59:53.53
関数型言語はトップダウンでもボトムアップでも組む事が出来る
出来ないのはそいつが未熟なだけ
632:デフォルトの名無しさん
12/05/01 04:44:27.14
>>630
自分は逆に関数型言語でトップダウンだが・・・
入れ子になった関数を変更するときぐらいだな。ボトムアップな感じになるのは
633:デフォルトの名無しさん
12/05/01 05:04:37.25
マクロな関数(処理)から書き始め、マクロな関数から呼ばれる
ミクロな関数は入出力の型だけ決めて実装は後回し
なんでこんな簡単なことが>>630には出来ないの?
634:デフォルトの名無しさん
12/05/01 07:57:45.80
トップダウンはどうしても車輪の再発明になる
再利用はどうしてもボトムアップになる
635:デフォルトの名無しさん
12/05/01 09:19:19.80
え?
636: ◆QZaw55cn4c
12/05/01 12:12:45.49
>>634
実感として、トップダウンとボトムアップの出会うところでうんうんうなっています。
637:デフォルトの名無しさん
12/05/01 15:17:57.73
>>634
ボディを違う色で塗って「ニューモデル」っていうだけだろ
638:デフォルトの名無しさん
12/05/01 19:35:01.49
Excel内臓の関数型言語の普及率はすげぇよな。
窓際に座ってる禿ですら操作できるんだからなぁ。
URLリンク(research.microsoft.com)
639:デフォルトの名無しさん
12/05/01 19:48:21.14
simonpj先生の勤務先都合仕事だからだまされないで!
640:デフォルトの名無しさん
12/05/01 19:53:04.34
騙されるも何も、内容は事実じゃん。
641:デフォルトの名無しさん
12/05/01 19:57:17.64
スプレッドシート猿によるアホな決定というリスクマネジメントのための学会?
642:デフォルトの名無しさん
12/05/01 20:11:03.69
現実には使えないExcelの拡張の話だけどなw
643:デフォルトの名無しさん
12/05/01 20:20:54.13
拡張せずとも、普通に計算するだけで関数型だろ?
何言ってんだ?
644:デフォルトの名無しさん
12/05/01 20:54:33.43
A1=3
A2=A1-32
A3=A2*5/9
これは静的単一代入 (SSA) です。
SSAは関数型に入りますか?
645:デフォルトの名無しさん
12/05/01 20:59:05.32
y = x + 5 は一次関数。あとは説明要らんよな。
646:デフォルトの名無しさん
12/05/01 21:02:58.15
そもそも、型に入るとか入らないとかいう型の理論が要らない
647:デフォルトの名無しさん
12/05/01 21:47:34.44
型がないと、実行時にしかメソッド名の解決ができない。
これは開発工数が伸びる原因になる。
648:デフォルトの名無しさん
12/05/01 21:56:43.18
なんという緻密な分析
649:デフォルトの名無しさん
12/05/01 22:03:59.52
関数"型"の話してんだろコミュ障
650:デフォルトの名無しさん
12/05/01 22:36:11.12
>>649
だから、型ですよね?
651:デフォルトの名無しさん
12/05/01 22:36:32.17
型だよ型。
652:デフォルトの名無しさん
12/05/01 22:37:00.05
型の話しようぜ。
653:uy
12/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:デフォルトの名無しさん
12/05/02 03:53:50.68
ぶっちゃけ関数型もオブジェクト指向もどうでも良くて
自分が使ってる言語以外をdisりたいだけだよね
655:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/05/02 11:34:39.78
こっちは要素の重複を取り除かないバージョン
import Data.List
perm' [] = [[]]
perm' xs = [x:y | x <- xs, y <- perm $ delete x xs]
657:uy
12/05/02 13:23:15.71
>>655
Rubyのpermutationって誰も知らないのか話題にならないから俺が最初に2chにコード投下したやつじゃん(半年前くらいに)
67の冗長ゴミカスRubyソースコードを添削しただけだよ
658:デフォルトの名無しさん
12/05/02 13:33:49.06
へえー、これ良いね。
659:デフォルトの名無しさん
12/05/02 15:29:43.37
>>658
いやHaskellでもRubyでも標準添付や組み込みのライブラリに入ってますし…
660:デフォルトの名無しさん
12/05/03 10:07:46.90
>>655
要素の重複を取り除くところでバグるかもしれない点は面白い
661:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/05/05 00:05:09.38
URLリンク(metalab.at)
こんなひとおる?
665:デフォルトの名無しさん
12/05/06 08:01:00.40
未だに関数型言語の機能が欲しいと思ったことがない。
俺みたいな奴は案外多いんじゃないかね。
そんなことよりトランザクショナルメモリはよ。
666:デフォルトの名無しさん
12/05/06 09:25:35.24
欲しいと思う機能はそれほど多くない
だが変な機能をゴリ押しされるとそれに対抗するものが欲しくなる
ゴリ押しを断るために、先約があるとかいって他のを抜擢するみたいな話は案外多い
667:デフォルトの名無しさん
12/05/06 11:09:05.44
うむ。関数型言語というより
コレクションライブラリがあれば
十分だったりするw
Guavaおすすめ
668:デフォルトの名無しさん
12/05/06 12:23:52.01
ム板の関数型言語派の大半は「関数型言語派」ではなく「型推論派」だろ
669:デフォルトの名無しさん
12/05/06 12:33:51.12
スレタイが無知だな。
手続型 vs 関数型
構造化設計 vs オブジェクト指向設計
670:デフォルトの名無しさん
12/05/06 12:34:57.95
>666
メタプログラミングなんてどう?
LISPのように構文を犠牲にしないMPといえば、OO系が主流だろう。
671:デフォルトの名無しさん
12/05/06 12:59:41.15
コレクションにもpush型とpull型があって
push型は一昔前のOO
pull型は遅延評価できるので関数型に近い印象がある
最近はpull型も普及したので、まだ売れ残っている型推論の方が関数型らしく見える
メタプログラミングは、共通のVMまたはC言語の上に好きな言語を乗せるのが主流
672:デフォルトの名無しさん
12/05/06 13:07:46.75
メタオブジェクトプロトコルみたいな話は最近どうなったのか
673:デフォルトの名無しさん
12/05/06 16:21:50.38
>>671
一昔前がよくわからないのでpull型とpush型の違いがよくわからんです
674:デフォルトの名無しさん
12/05/06 17:41:19.49
>>673
getterを呼び出したり成功か失敗か調べたりするのがpull型
getter反対派はpush型
675:デフォルトの名無しさん
12/05/06 19:43:30.18
言語はなんでもいいので具体例をプリーズ。
676:デフォルトの名無しさん
12/05/06 20:31:27.12
pushとかpullなんて名前は知らないけどこんな感じなんじゃね?
サンプルはJava。上がきっとpushで下がpull
URLリンク(www.akirakoyasu.net)
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:デフォルトの名無しさん
12/05/06 20:34:08.65
いまさらだけど、>>671の
pullとpushの言葉の使い方逆じゃね?
678:デフォルトの名無しさん
12/05/06 20:43:49.33
>>677
放置したほうがいい人だと思うがどうか?
"Push-Pull Functional Reactive Programming"風に、
pull: demand driven
push: data driven
ってことでいいかと。
679:デフォルトの名無しさん
12/05/06 20:45:09.00
言葉のままに捉えればよいんじゃない?
pullは引く。
result = hoge( piyo( huga() ) );
pushは押す。
huga( result );
piyo( result );
hoge( result );
680:デフォルトの名無しさん
12/05/06 20:59:16.39
>>678
遅延評価はdemand drivenだから、671は合ってるだろ
681:デフォルトの名無しさん
12/05/06 21:05:42.54
一箇所だけ取り上げてそんな事言われても困りますよ。
682:デフォルトの名無しさん
12/05/06 21:16:14.00
>>677は0箇所ですよ
0箇所よりも1箇所の方がいいんじゃないか
683:デフォルトの名無しさん
12/05/06 21:18:45.89
pullとかpushって>>671が作った言葉だろ?
手続きタイプと、コールバックタイプとかでいいんじゃね?
684:デフォルトの名無しさん
12/05/06 21:23:25.41
なんだ、オレオレ用語かよ
685:デフォルトの名無しさん
12/05/06 21:44:18.93
>>682
まあそりゃそうだねw
push/pullは、上に上げたようにFRPでも取り上げられてるし、
他にはWebアプリフレームワークとかXML系APIとか、
いろいろなところでAPIデザインの選択肢として語られてる。
大げさに騒ぐような概念じゃないけど。
686:デフォルトの名無しさん
12/05/06 21:51:58.49
URLリンク(ja.wikipedia.org)繊維強化プラスチック
繊維強化プラスチック(せんいきょうかプラスチック、Fiber Reinforced Plastics、FRP)は、
ガラス繊維などの繊維をプラスチックの中に入れて強度を向上させた複合材料のこと。
単に FRP と書いて、ガラス繊維強化プラスチックを指すことも多いが、
ガラス繊維であることを明示したい場合は GFRP または
GRP (Glass fiber reinforced plastics, Glass-reinforced plastics) と書かれる。
687:デフォルトの名無しさん
12/05/06 22:02:41.17
URL貼れってか
URLリンク(conal.net)
688:デフォルトの名無しさん
12/05/06 22:14:04.87
でも、FRP自体は明らかに関係ない概念だよね?
pullとpushの概念引っ張ってくるためだとしても。
それに、Getter/SetterをPull or Pushに分類しようとするのは
独自解釈が過ぎるでしょ
689:デフォルトの名無しさん
12/05/06 22:15:07.62
なんだF#用語か。URLリンク(pro.art55.jp)
690:デフォルトの名無しさん
12/05/06 22:19:52.64
>>671 はオレオレ定義すぎ。
>>676 の下がpush。上はシラネ。
だろ。普通にpull/pushを考えるなら。
691:デフォルトの名無しさん
12/05/06 22:23:38.07
>>688
> でも、FRP自体は明らかに関係ない概念だよね?
ちょっと難しい例でごめんね。
692:デフォルトの名無しさん
12/05/06 22:28:26.04
>>691
難しい例もなにも、普通にFRP関係ない例しかでてないぞ。
関係あるんなら関係ある例になるコードをださんと。
693:デフォルトの名無しさん
12/05/06 23:30:20.47
>>688
つまり、まず質問をして、独自ではない回答が出るまで待っていればいいんですかね
関数型言語がgetterの使用を制限しない理由は何でしょうか
694:デフォルトの名無しさん
12/05/07 06:32:00.39
関数型ってパターンマッチとか、再帰とか、モナドとか、そんな程度のものなの?
もっとすごい秘密兵器があるんじゃないかなぁと期待しているんだけど、イマイチ見えてきません。
型クラスのメリットは、クラスを使った不完全な抽象データ型オブジェクト指向より
定式化され優れているとわかるとしても、両者は必ずしも背反するものではないですよね?
参照透明性にしても抽象度やモジュラリティは上げられる反面、直感的でない回りくどい処理や
そのための記述を強いられたりする局面も少なからずあるし、そうしたやり難さと引き換えに
関数型でゴリ押しするメリットってどこら辺にあるのでしょうか?
695:デフォルトの名無しさん
12/05/07 09:50:54.31
高階プログラミングではないかと昨夜から今朝にかけて思った。
いわゆるメタプログラミングや自己反映計算を実現する方法として、
自己書き換え→テンプレやマクロ→...というように発展してきて、
関数合成とかでプログラミングをするようになった、というか。
696:デフォルトの名無しさん
12/05/07 10:34:09.89
関数合成はメタプログラミングに入りますか?
697:デフォルトの名無しさん
12/05/07 11:00:16.79
>>694
代入を制限する関数型が、get/setの両方を制限するオブジェクト指向よりも回りくどい
と言われるのは何故ですか?
698:デフォルトの名無しさん
12/05/07 11:08:18.79
Smalltalkが普及しなかったようにHaskellは普及しない
699:デフォルトの名無しさん
12/05/07 11:19:44.93
「get/setの両方を制限」のところがよくわからないので具体的にお願いします。
あとなんでその「get/setの両方を制限」が関数型の再代入制限に対応すると
思われたのでしょうか?
700:デフォルトの名無しさん
12/05/07 11:50:13.94
こうかいかんすう
701:デフォルトの名無しさん
12/05/07 12:01:35.13
高階関数って関数オブジェクトがファーストクラスなら
どうということなく使えますよね。それでもやっぱり
関数型の秘密兵器なんでしょうか?
カリー化が自動だったり関数合成演算子が組み込みなのは嬉しいけど、
OOPLであっても関数オブジェクトがそうであればいいだけって気もしますし、
ポイントフリースタイルで書こうとしてパズルみたいになるのも
何だか本末転倒な感も否めません。
702:デフォルトの名無しさん
12/05/07 12:15:37.81
OOPLでもできるって
頑固なOOPLのスタイルを変えさせることができるなら凄い兵器だ
703:デフォルトの名無しさん
12/05/07 12:35:48.84
頑固なOOPLのスタイルってどんなの?
704:デフォルトの名無しさん
12/05/07 12:54:07.33
>>701
別に秘密兵器でも何でもなく、関数型の思想のうち
手続き型でも適用出来そうな部分は既に受け入れられてるってことさ
705:デフォルトの名無しさん
12/05/07 15:35:46.86
>>694
「ゴリ押しする」ってのは、あなたの心の問題じゃないの?
706:デフォルトの名無しさん
12/05/07 15:47:21.06
関数型の主力は副作用が無いこと
手続き型の主力は副作用が有ること
OOPは副作用の局所化を目指すもの
異論は認める
707:デフォルトの名無しさん
12/05/07 17:50:02.95
副作用があるのはsetterだけ
getterの局所化には副作用以外の目的があるだろう
708:デフォルトの名無しさん
12/05/07 18:08:27.94
そうかしら?
709:デフォルトの名無しさん
12/05/07 18:09:54.21
>>707
一体いつからgetterに副作用が無いと錯覚していた?
getで内部キャッシュを生成,保持しても良く
副作用は外から分からずとも、仕様(期待)通り動作すればいい
710:デフォルトの名無しさん
12/05/07 18:47:24.86
しかし実際にはオブジェクトが他のオブジェクトの参照を握ってたりして、
一回のメソッド呼び出しがどんどんたらい回しされてって。
特にオブジェクト指向では多態のためにメソッドのシグネチャを固定化するから、
オブジェクトが他のオブジェクトの参照を握る傾向は強い。
つまり、オブジェクト指向で副作用の局所化はされないし、元々狙っても無い。
オブジェクト指向はオブジェクトに関するコードや変数の依存関係を纏めたってだけ。
これを手続き型で実行すれば、処理がオブジェクトを跨いであちこちに飛び回る。
このとき、副作用は局所化されない。
副作用の局所化するためには、処理がオブジェクトを跨がないように
する必要がある。
しかし、それはオブジェクト指向とは関係無く、手続き型一般における、設計のテクニックだ。
711:デフォルトの名無しさん
12/05/07 19:01:14.42
・シグネチャを固定化 → 他のオブジェクトの参照を握る
・副作用の局所化するため → 跨がないように
この辺前後の関連がよく分からないので詳しくお願いします
712:デフォルトの名無しさん
12/05/07 19:09:28.48
どう言えばよいんだろうね。
オブジェクト指向はオブジェクト単位で色々纏めるが、これらは変数やコードといった、
静的な要素を分類したに過ぎない。
言い換えれば、「ソースコード」をオブジェクト単位で分類したに過ぎない。
一方で副作用はソースコード上には現れない。
実行時に「処理」にくっ付いて現れる。
だから、副作用を局所化するためには、処理の流れそのものを
局所化する必要があって、これは手続き型一般の設計の問題で、
OOだからどうこうという話ではない。
OOはあくまでソースコードをオブジェクト単位で局所化するだけで、
それ以上は助けてくれない。
713:デフォルトの名無しさん
12/05/07 19:26:38.69
>>709
それはgetterを作って良いし副作用が有って良いという意見だな
そういう自由な考え方が定着すれば、OOに反対する人はいなくなると思う
714:デフォルトの名無しさん
12/05/07 19:29:05.25
そんでついでに言うと、
オブジェクト指向は処理の流れに関して凄く無頓着な一面がある。
というのも、仮想関数だ多態だといってな。
そんで、むしろソースコードみたいな静的なものは怖くねーよ、
こんなの綺麗に分類するより、
処理の流れとその副作用の方がよほど怖えーよ、そっち整理しろよ、
って考え方もあって、OOは使いどころが難しく、2chなんかで議論もこじれる。
だから皆だんだん嫌になってきて、
処理の流れそのものを気にしなくて良い関数型に白羽の矢が立ったってわけ。
715:デフォルトの名無しさん
12/05/07 19:48:12.05
俺にとっての副作用を局所化というのは
「この変数を触るのはこの処理だけ」といった
スコープを小さくしたり責任範囲の壁を作ったりすることなんだけど
>>712にとっての副作用の局所化というのは
何かのメソッド呼んだときに変化するN個のオブジェクトのN個の変数とか
その辺りに言及してるのかな?
メソッドの中で自身(A)が持ってる別のオブジェクト(B)のメソッドを呼んだとして
そこから先でファイルアクセスが発生しようと
それはBの範疇なのでAの中での局所化には関係無い
というスタンスかな、俺はね
>処理の流れに関して凄く無頓着
そうかもね
他のオブジェクトは外面(インターフェイスと仕様)しか見ないので
処理の内容は「あとは任せた」って感じだし
716:デフォルトの名無しさん
12/05/07 20:17:37.37
>>715
これは物凄く悪い例なんだけど、
AがBのメソッドを呼び出して、
そのメソッドの中でBがAのメソッドを呼び出したら、
カプセル化は壊れるんだよね。
そんな設計はするな、と言われそうだが、
これが結構良くあるんよ。
親が子の参照を持ってて、子も親への参照を持ってるとか。
717:デフォルトの名無しさん
12/05/07 20:22:02.86
循環参照は注意だが、カプセル化は別に崩れてなくね?
718:デフォルトの名無しさん
12/05/07 20:22:28.51
カプセル化は言葉が悪かった。
整合性だね。
719:デフォルトの名無しさん
12/05/07 20:40:40.96
AがcallするならBはreturnすればいいのに、なぜかBもcallしようとするんだな
なぜreturnを避ける設計をしてしまうのか
720:デフォルトの名無しさん
12/05/07 20:46:15.19
>719 てめぇ、CPSさんDisってんのか?
721:デフォルトの名無しさん
12/05/07 20:49:59.90
>>716
>これが結構良くあるんよ。
わかる・・・
イベントハンドラとかのインターフェイスの実体として子に自身を渡すとか
木構造で高速化のためAが別のA(親)を持つとかは許容出来るけど
一つずつ順にコンパイル出来ないような定義レベルでの循環参照は俺も嫌い
722:デフォルトの名無しさん
12/05/07 21:04:21.69
>>720
末尾呼出しなら問題なさそうだ
問題は、Aのメソッドの途中でAが参照されること
723:デフォルトの名無しさん
12/05/07 21:18:02.26
>>718
言葉が悪いんじゃない。関係ないんだよ。
724:デフォルトの名無しさん
12/05/07 21:29:27.23
>>722
ACTORさん(以下略
725:デフォルトの名無しさん
12/05/11 20:23:27.60
それぞれのオブジェクトがメッセージを投げ合い、
その結果でたらめな順序で副作用が起こっても問題が無い
仮に問題あっても例外投げときゃ無問題
そういうイイカゲンなシステム開発にオブジェクト指向は最適
726:デフォルトの名無しさん
12/05/11 21:46:23.18
さすがにそこまでいい加減なシステムは品質を確保できないだろ。バカにし過ぎ。
「そのように組むことができる」ことと「実際にそうする」は別問題。
Haskellでも副作用が発生する処理と、そうでない処理をごちゃ混ぜにすることは可能は可能だし。
727:デフォルトの名無しさん
12/05/12 18:57:50.97
ここの人らなら詳しそうだから教えてくれ。
0 :: Integer
0 = 0
みたいな感じで、数値を関数化できる言語ってないの?
0関数にラムダ与えたら、ラムダの実行を無視して、
0以外の数値関数にラムダ与えたらラムダを実行するようにしたい
728:デフォルトの名無しさん
12/05/12 19:03:59.81
は?
関数なら 'a -> 'b みたいな型を持ってるはずだけど。
Integer という型は整数の型であって、関数じゃないよ。
729:デフォルトの名無しさん
12/05/12 19:09:46.34
別にそこの式は、数値を関数化したいって例であって
関数を返すとかとは関係ないよ
730:デフォルトの名無しさん
12/05/12 19:21:16.56
「数値を関数化」ってのが、たとえば「文字列を虚数化」みたいに意味不明。
むしろ、
> 0関数にラムダ与えたら、ラムダの実行を無視して、
> 0以外の数値関数にラムダ与えたらラムダを実行するようにしたい
こっちをソースコードで表現できたら、少しはなんとかなるかもしれない。
731:デフォルトの名無しさん
12/05/12 19:41:40.45
あ゛?チャーチ数ディスってんのかメーン
732:デフォルトの名無しさん
12/05/12 23:05:55.96
>>727
「0」というシンボルと、何らかの関数を結び付けたいということ?
関数型ならそもそも、既に何かに結び付けられてるシンボルに
別の値を結び付けるのは再代入そのものだろうし
手続き型関数型問わず、特定リテラルの意味だけを変更するのはちとマズくないかな
733:デフォルトの名無しさん
12/05/12 23:10:21.88
common lispに変数としての値と関数としての値を区別するということなのか
734:デフォルトの名無しさん
12/05/12 23:11:42.30
ごめん、脱字した。
common lisp(のよう)に変数としての値と関数としての値を区別するということなのか
735:デフォルトの名無しさん
12/05/13 00:06:48.19
>>732
Smalltalkなら実現してたべ
value := 0.
value message.
こんな感じで、数値にメッセージを送ると、
数値に紐付いたメソッドを呼ぶ事ができた。
1にメッセージを送れば、1のメソッド。
2にメッセージを送れば、2のメソッドみたいにね。
736:デフォルトの名無しさん
12/05/13 01:07:22.66
本のお題がどういうものだが今一歩ピンとこないが、
チャーチ数を計算する型なしラムダ式処理系なら結構転がってる。
数値や真理値は短形表示できるが。
737:デフォルトの名無しさん
12/05/13 02:06:34.64
>>735
何が言いたいのか分からん
value message と function value は語順が違うだけじゃね?
738:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/05/13 02:36:28.73
>>738
なるほど分かった
0や1といったリテラルに関数を割り当てたいってことだね
どっちかというと関数型 vs. オブジェクト指向じゃなくて
静的型 vs. 動的型になりそうな気配
740:デフォルトの名無しさん
12/05/13 02:40:45.66
ところで>>727のいう「ラムダ」の引数は何?
それは何時渡すの?
741:デフォルトの名無しさん
12/05/13 02:44:08.62
>>740
値が関数だって事の説明用だから引数はなんでもいいんですが
742:デフォルトの名無しさん
12/05/13 02:49:18.06
>>741
意味論的には関数型言語の値は「ゼロ引数関数」という関数
743:デフォルトの名無しさん
12/05/13 08:04:27.03
いずれにしろ 0 :: Integer では、関数になってないから
744:デフォルトの名無しさん
12/05/13 10:20:35.18
OO信者の俺ですら数値クラスにメソッド追加するような
コードは勘弁して頂きたい
オープンクラスではしゃぐのは初心者時代で終わらせてほしい
745:デフォルトの名無しさん
12/05/13 11:09:32.18
>>735>>738
シングルディスパッチでは第一引数を特別扱いしてるだけで
x.foo y z と foo x y z に本質的な差は無い
シングルディスパッチ脳には理解出来ないかもしれんけど
746:デフォルトの名無しさん
12/05/13 11:16:35.94
難しい問題だね。
func( o1, o2 )
こういった関数は後からいくらでも追加できるけど、
o1.func( o2 )
との本質的な違いはスコープだけだからな。
多態出来る出来ないの違いは有るけど、それは言語上の制約ってだけだからね。
クラスの外のスコープにいくらでも関数が定義できるのに、
クラスの中のスコープにメソッドを追加することは出来ません、
って制約に一体どれほどの意味があるかって言われると、ねぇ。
特に動的言語では。
747:デフォルトの名無しさん
12/05/13 11:37:40.06
あんたの恣意的な分類で「本質」とか「言語上の制約ってだけ」とか言われても
わかりませんわ。
748:デフォルトの名無しさん
12/05/13 12:25:07.97
別に恣意的ではないと思うけど。
本来、どこのスコープに何を追加しようが勝手なものなんじゃないの?
静的言語では実行効率の理由で制限がかかってくるのも分かるけどさ。
749:デフォルトの名無しさん
12/05/13 12:32:53.64
Haskellでやっつけ
お題の真意が掴めてないので、たぶん条件を満たしてない
URLリンク(ideone.com)
750:デフォルトの名無しさん
12/05/13 12:39:04.98
0がどうのこうのの話は、まだ続いてたの?
0と1は同じ型だろうから、同じ関数にディスパッチされるのが当たり前だしさ。
751:デフォルトの名無しさん
12/05/13 15:59:42.13
>>742
そういう形式化もあるという程度の話。
752:デフォルトの名無しさん
12/05/13 18:30:14.35
このスレには時代遅れのSmalltalkを使ってる
奇特な人が居るから質問するんだけど、
あのIDEモドキを立ち上げずにプログラム実行する方法無いの?
それと動的型付けで実行が遅いから、せめてボトルネックだけでも
C/C++で書いて実行できないとトイプログラムでしか
使いモノにならないと思うけど、簡単にC/C++のライブラリとリンクできるの?
753:デフォルトの名無しさん
12/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という方法が使えます。
URLリンク(www.cincomsmalltalk.com)
PharoやSqueakではVMプラグインを書いてバイトコードを拡張したり、FFIが使えます。
URLリンク(wiki.squeak.org)
URLリンク(wiki.squeak.org)
754:デフォルトの名無しさん
12/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
12/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:デフォルトの名無しさん
12/05/13 20:00:39.51
>>752
時代遅れってアホか、通信・製造・金融・保険・政府。
お前がしらんだけで第一線で新規開発されとるわ。
国内企業なら、東洋ビジネスエンジニアリングとかが導入してんだぞ。
757:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/05/13 20:19:29.56
>>755
Integer と () -> Bool は違う型なので、
同じ数値(関数)の型が文脈に応じて変化する言語でなければ不可能。
759:727
12/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:デフォルトの名無しさん
12/05/13 20:20:46.22
>>758
できる言語はあるかと聞いているのですが?
あとboolは関係ないですよね
761:デフォルトの名無しさん
12/05/13 20:24:09.03
>>760
じゃあ Integer と (() -> a) -> a
それはともかく、関数型とか全然関係なくって
まともな静的型なら無理って言ってるんだけど、
動的型しか使った事無い馬鹿には分からないかな?
762:デフォルトの名無しさん
12/05/13 20:25:17.06
>>761
だから、できない言語の事は聞いてなくて、出来る言語はあるかと聞いてるんですけど。
763:デフォルトの名無しさん
12/05/13 20:29:16.10
>>762
スレ違いだし問題としても糞詰まらんから
どっか行けって言ってんだけど?
764:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/05/13 20:32:20.89
>>763
NGにしたいんでトリでも付けてもらえます?
スレ違い以前に話が通じないので
766:デフォルトの名無しさん
12/05/13 20:42:57.75
>>763
まず日本語の通じないお前がどっか行けよ
767:デフォルトの名無しさん
12/05/13 20:44:48.51
>>764
オブジェクトで出来てもあんまり嬉しくないんですが・・・
768:デフォルトの名無しさん
12/05/13 20:46:00.83
>>765>>766
型付けの問題だって理解できない自分の低能さを
日本語の問題にすり替えるなよw
769:デフォルトの名無しさん
12/05/13 20:52:46.02
>>761
「コンセントの付いている車はありますか?」
「軽トラなら無理です」
お前が言ってるのはこういう事だという自覚は有るのか?
普通は「あります」「ありません」この2択だろ
頭おかしいな
770:デフォルトの名無しさん
12/05/13 20:53:58.75
>>767
Int32はラッパークラスとかではなく、プリミティブかつオブジェクトなんだけど。
まぁそれでもダメというならどうしようもない。
771:デフォルトの名無しさん
12/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:デフォルトの名無しさん
12/05/13 20:57:08.31
>>770
すいません。
関数と互換性をもってて欲しいんですよ。
773:デフォルトの名無しさん
12/05/13 21:06:51.99
>>771 >>772
てっきり拡張メソッド的なものを要求してるのかと思ってた。
Scalaなら暗黙型変換あるからできそうな気がする。
774:デフォルトの名無しさん
12/05/13 21:08:02.77
>>773
なるほど。Scalaですか、調べてみます。
775:デフォルトの名無しさん
12/05/13 22:46:41.69
で、Scalaなら出来たの?
776:デフォルトの名無しさん
12/05/14 00:37:38.04
マイナー言語使い共が
可読性皆無のコード書く御題で
型付けの弱さを競うスレはここですか?
時代に逆行してて笑えるwww
777:デフォルトの名無しさん
12/05/14 01:46:05.41
誰だって0と1は同じ型だと考えるのに、違った振る舞いをさせたいってのは、
何か前提がおかしいんだろうね。
元々何がしたかったのか聞ければよいんだけど、
彼にそういった振る舞いが出来るとも思えないしなぁ。
778:デフォルトの名無しさん
12/05/14 07:07:11.76
うーん。一番良く分からんのは、>>767を読むと出題者は>>764を見て
オブジェクトとしてなら「出来ている」認定してるっぽい処だな。
779:デフォルトの名無しさん
12/05/14 07:40:52.01
出題者がOOP厨だからオブジェクトには甘いだけだろ
別に不思議でもなんでもない
もちろん出題者は底なしのアホだけど