◆ Ruby は関数が第一級オブジェクトじゃない
  ◆ 関数の参照を取得しようとしたら呼び出しされた結果が得られる
◆ オブジェクト形式にする lambda を使う
◆ 呼び出しに call メソッドが必要

この記事で関数呼び出しにカッコ要らない言語っていいなぁと思っていたら そういえば Ruby は要らなかったはず
Ruby だとどういう風に書けるのか気になったので調べてみました

この JavaScript コードと同じことをします

const fn = a => b => a + b
console.log(fn(1)(2))

先に結果を出すと

fn = lambda { |x| lambda { |y| x + y } }
p ((fn.call 1).call 2)

思ってたのと全然違いました

p (fn 1 2)

って書けるのを期待してたのですけどね

一番の驚きは Ruby は関数を値として受け渡しできる言語ではありませんでした

def foo
p 1
end

bar = foo

と書くと foo を実行してるつもりはないのに実行されます
関数名を書くと即実行されます
関数自体を参照できず実行されてその結果を得られます
なので bar に foo と同じ参照は入らず foo を実行した返り値となっています

この仕組みなので 関数を受け渡しするということができないです
やろうとすると関数ではない形に変換が必要です
最初から受け渡しできる形で書けるものもあってそれが lambda です

PHP や C# も関数をそのまま変数として扱えないのでクロージャやラムダ式を使う別のバージョンがあります
Ruby のこれらの仲間だったんですね

Ruby の lambda ですが 得られるものはオブジェクトになっていて .class を見ると Proc という型になっています
関数ではないのでそのままでは呼び出せず call メソッドを呼び出さないといけないです
lambda の処理が lambda を返すと Proc オブジェクトを受け取ります
.call メソッドをチェーンする形になります
そうなると () は避けられず 見づらくなります

p ((fn.call 1).call 2)

call に引数がいらないなら

a = lambda {
p 1
lambda {
p 2
lambda {
p 3
}
}
}

a.call.call.call
# 1
# 2
# 3

と書けるのですけどね