It is well-known that closures and objects are equivalent. So are actors. Which one is the most fundamental?
よく知られたように、クロージャとオブジェクトは等価です。アクターも同様です。どの概念が最も基本的なのでしょうか?
Closures vs Objects
2024/02/19(月) 20:39:15.91ID:VT95BnI9
2024/02/19(月) 20:49:06.93ID:VT95BnI9
A closure is a function with state in the local scope.
An object also has methods and state which belong to its instance.
These are compatible with each other.
クロージャはローカル・スコープに状態をもつ関数です。
オブジェクトもまたそのインスタンスに属するメソッドと状態を持ちます。
これらは互いに互換性があります。
An object also has methods and state which belong to its instance.
These are compatible with each other.
クロージャはローカル・スコープに状態をもつ関数です。
オブジェクトもまたそのインスタンスに属するメソッドと状態を持ちます。
これらは互いに互換性があります。
2024/02/20(火) 09:36:12.34ID:fQy0X2aE
オブジェクトは複数のメソッドを持てる
クロージャは関数をひとつしか返せない
オブジェクトの勝ち
クロージャは関数をひとつしか返せない
オブジェクトの勝ち
2024/02/20(火) 11:01:18.21ID:BFMbzAij
>>3
ハッシュテーブルに関数を追加して返すことで、複数のメソッドを返すことが可能
より柔軟に、オブジェクトとそれを操作する関数の組を返すこともできるし、無限個のメソッドをもったオブジェクトだって作れる
これらは書く対象によって使い分ければよいのであって、オブジェクトにメソッドが属しているのが常に最適とは限らない
たとえばイベントハンドラにコールバック関数として渡すような場合は、ひとつの関数として取得できたほうが便利
ハッシュテーブルに関数を追加して返すことで、複数のメソッドを返すことが可能
より柔軟に、オブジェクトとそれを操作する関数の組を返すこともできるし、無限個のメソッドをもったオブジェクトだって作れる
これらは書く対象によって使い分ければよいのであって、オブジェクトにメソッドが属しているのが常に最適とは限らない
たとえばイベントハンドラにコールバック関数として渡すような場合は、ひとつの関数として取得できたほうが便利
2024/02/20(火) 23:29:16.13ID:0cXn/136
クロージャのほうがprimitive
今時、高階関数やイテレータを書くのにわざわざデザインパターンとか使いたいかって話
クラスは、レキシカル環境つきオブジェクトだけが欲しくても必ず新しい名前空間が作られるし、単品で購入できない福袋みたいなもん
今時、高階関数やイテレータを書くのにわざわざデザインパターンとか使いたいかって話
クラスは、レキシカル環境つきオブジェクトだけが欲しくても必ず新しい名前空間が作られるし、単品で購入できない福袋みたいなもん
2024/02/21(水) 05:55:14.17ID:j79lZ4PO
二変数以上の関数のほとんどは、どの引数のオブジェクトに属しているともアプリオリには言えないし、オブジェクト指向は不自然
オブジェクトと引数は別物だし、もし関数を特定のオブジェクトに属するようにしたいなら、クロージャでラップすれば簡単にできる
オブジェクトと引数は別物だし、もし関数を特定のオブジェクトに属するようにしたいなら、クロージャでラップすれば簡単にできる
2024/02/21(水) 05:56:37.93ID:j79lZ4PO
二変数以上の関数のほとんどは、どの引数のオブジェクトに属しているともアプリオリには言えないし、オブジェクト指向は不自然
オブジェクトと関数は別物だし、もし関数を特定のオブジェクトに属するようにしたいなら、クロージャでラップすれば簡単にできる
オブジェクトと関数は別物だし、もし関数を特定のオブジェクトに属するようにしたいなら、クロージャでラップすれば簡単にできる
2024/02/21(水) 10:09:33.92ID:HBySQ9lj
2変数関数をクロージャにラップして1変数関数にしても、メソッドチェーンはできないよね
2024/02/21(水) 10:29:18.43ID:Cg6r5DK9
[1, 2, 3, 4, 5]にメソッドが属してれば
[1, 2, 3, 4, 5]
.filter(hoge) # ←戻り値もオブジェクト
.map(piyo) # ←これも
.sum()
みたいにできるけど、配列がオブジェクトじゃなかったら
map([1, 2, 3, 4, 5], hoge)
の戻り値はただの配列なので、繰り返し関数適用するには、Lispみたいな醜い入れ子にするしかない
sum(
map(
filter([1, 2, 3, 4, 5], hoge),
piyo))
[1, 2, 3, 4, 5]
.filter(hoge) # ←戻り値もオブジェクト
.map(piyo) # ←これも
.sum()
みたいにできるけど、配列がオブジェクトじゃなかったら
map([1, 2, 3, 4, 5], hoge)
の戻り値はただの配列なので、繰り返し関数適用するには、Lispみたいな醜い入れ子にするしかない
sum(
map(
filter([1, 2, 3, 4, 5], hoge),
piyo))
2024/02/21(水) 12:32:59.23ID:pWazjr0Z
>>8-9
これでどうよ
chain = (obj) => {
return (f, ...args) => {
if (!f) return obj
return chain(f(obj, ...args))
}
}
chain([1, 2, 3, 4, 5])(
filter, (x) => x % 2)(
map, (x) =>x * x)(
sum)()
// => 35
これでどうよ
chain = (obj) => {
return (f, ...args) => {
if (!f) return obj
return chain(f(obj, ...args))
}
}
chain([1, 2, 3, 4, 5])(
filter, (x) => x % 2)(
map, (x) =>x * x)(
sum)()
// => 35
2024/02/21(水) 15:43:45.17ID:im/wtuEl
一時期メタプログラミングとかいって、動的にクラスやメソッドを作れるのがすごいって言われてたけど、クロージャをデータ構造として使うならそれは自明にできることでは
2024/02/21(水) 16:28:56.20ID:4iB0jwLo
やり方が複数ある場合は、一番綺麗に書けるコードを採用するのが基本
2024/02/21(水) 22:54:29.50ID:DX/jvS2m
入れ子にしなくても関数合成でいいのでは?
メソッドチェーンっぽく書くには
Reverse-application operatorってのもあるけど
個人的には関数合成のほうがスッキリしててすこ
https://ideone.com/gCWxLP
let hoge n = n mod 2 = 1
let piyo = ( * ) 2
let () = print_int (List.fold_left (+) 0 (List.map piyo (List.filter hoge [1;2;3;4;5])))
(* function composition *)
let (<<) f g x = f (g x)
let f = print_int << List.fold_left (+) 0 << List.map piyo << List.filter hoge
let () = f [1;2;3;4;5]
let (>>) f g x = g (f x)
let f = List.filter hoge >> List.map piyo >> List.fold_left (+) 0 >> print_int
let () = f [1;2;3;4;5]
(* @@ Application operator *)
let () = print_int @@ List.fold_left (+) 0 @@ List.map piyo @@ List.filter hoge [1;2;3;4;5]
(* |> Reverse-application operator *)
let () = [1;2;3;4;5] |> List.filter hoge |> List.map piyo |> List.fold_left (+) 0 |> print_int
メソッドチェーンっぽく書くには
Reverse-application operatorってのもあるけど
個人的には関数合成のほうがスッキリしててすこ
https://ideone.com/gCWxLP
let hoge n = n mod 2 = 1
let piyo = ( * ) 2
let () = print_int (List.fold_left (+) 0 (List.map piyo (List.filter hoge [1;2;3;4;5])))
(* function composition *)
let (<<) f g x = f (g x)
let f = print_int << List.fold_left (+) 0 << List.map piyo << List.filter hoge
let () = f [1;2;3;4;5]
let (>>) f g x = g (f x)
let f = List.filter hoge >> List.map piyo >> List.fold_left (+) 0 >> print_int
let () = f [1;2;3;4;5]
(* @@ Application operator *)
let () = print_int @@ List.fold_left (+) 0 @@ List.map piyo @@ List.filter hoge [1;2;3;4;5]
(* |> Reverse-application operator *)
let () = [1;2;3;4;5] |> List.filter hoge |> List.map piyo |> List.fold_left (+) 0 |> print_int
14デフォルトの名無しさん
2024/02/22(木) 01:30:07.21ID:seCGgTJE Forth で書いてよ
2024/02/22(木) 08:01:15.94ID:5dknMZXg
>>13
カリー化のなせる技やね
カリー化のなせる技やね
2024/02/22(木) 08:40:34.15ID:GWomKHpC
chainl = (obj) => {
return (f, arg) => {
if (!f) return obj
return chainl(f(arg, obj))
}
}
cons = (x, xs) => [x, xs]
foreach = (lst, f) => {
if(!lst) return
[x, xs] = lst
f(x)
foreach(f, xs)
}
linkedList =
chainl(null)(
cons, 1)(
cons, 2)(
cons, 3)()
chainl(linkedList)(foreach, console.log)()
// 3
// 2
// 1
いろいろ書けるんだな
return (f, arg) => {
if (!f) return obj
return chainl(f(arg, obj))
}
}
cons = (x, xs) => [x, xs]
foreach = (lst, f) => {
if(!lst) return
[x, xs] = lst
f(x)
foreach(f, xs)
}
linkedList =
chainl(null)(
cons, 1)(
cons, 2)(
cons, 3)()
chainl(linkedList)(foreach, console.log)()
// 3
// 2
// 1
いろいろ書けるんだな
レスを投稿する
ニュース
- 国内ホテル、既にキャンセルも 訪日客関連業界、事態見守る ★3 [蚤の市★]
- 習政権、高市首相への態度硬化 台湾有事発言で連日非難 中国 ★11 [ぐれ★]
- 橋下徹氏 外務省幹部の訪中受け「口だけ番長」へ痛烈指摘 「喧嘩は日本の完敗…なんとかっこ悪い日本か」 [冬月記者★]
- 【外国人問題】小野田紀美担当相「不法就労や不法滞在は許さない」 [シャチ★]
- 【野球】井端監督 大谷翔平、山本由伸らのWBCへの参加 「1日も早く返事ほしい」「待っててといっても、国内組が遅くなってしまう」★3 [冬月記者★]
- 【青森・はぐれ子グマがラーメン店襲撃】「笑えないです」ボコボコにしてクマを返り討ち レジェンド男性はまぶたが腫れあがり骨折 ★2 [ぐれ★]
- 中国「高市許さん😡」ジャップメディア「熊!🐻!」 [809488867]
- 中国「高市が頭を下げて謝罪しない限り、絶対に許さない」 [329329848]
- 🏡
- 女子高校生におちんちを見せる 、 頭髪薄めが発生 [485983549]
- 今季最強寒気襲来!!!!
- 【高市早苗】習近平激怒か [115996789]
