プレースホルダ構文 (無名関数の引数省略バージョン?)

下に紹介してあるScalaの本を読んでいると、


def calc(a:Int, b:Int, op:(Int,Int)=>Int)=op(a,b)
val r1 = calc(5,2,_+_)
val r2 = calc(5,2,_-_)
val r3 = calc(5,2,_*_)
val r4 = calc(5,2,_/_)
println(r1, r2, r3,r4)


なんていうのがあった。


_+_ ってなんだ??と思い、いろいろ調べますが、
最終的に30分ほどかかって、プレースホルダ構文というものだとわかりました。
でも、普通、プレースホルダ構文って、
コレクション.map { ここ! }
の、「ここ!」ってところで使うんじゃないの?? と思いました。(コレクション関係の専売特許かと。)


待てよ、「ここ!」ってところは、関数、関数オブジェクト、匿名関数 (どの言葉が適切かわからないが、、)
の部分なので、
(a,b) => hoge(a,b) と書くところ。


もう一度もとの意味不明コードに戻る。

calc(5,2,_+_)は、もともと
calc(5,2,{ _+_ } )
※関数(オブジェクト)は一文の場合、中括弧 { } を省略できるから。
だったに違いない。
そして、プレースホルダ構文のもとは、
calc(5,2,{ (a,b) => a+b} )
だったに違いない。
calc(5,2,(a,b)=>a+b ) でもよいけど。
※もう一度繰り返すが、一文の関数は、中括弧省略できる。


def calc(a:Int, b:Int, op:(Int,Int)=>Int)=op(a,b)
val r1 = calc(5,2, (a,b) => a+b )
val r2 = calc(5,2, (a,b) => a-b )
val r3 = calc(5,2, (a,b) => a*b )
val r4 = calc(5,2, (a,b) => a/b )
println(r1, r2, r3,r4)


確かに、これで同じ結果だ!


つまり、プレースホルダ構文は、無名関数を作るときに、
{ (a,b) => a + b }
あるいは
(a,b) => a + b

_ + _
という風に、=> を書かなくてよくしてくれたものなのですね。


※ この本は、言語経験者のための本ですね。(最後の章が、プログラミング入門みたいになっています。)

オブジェクト指向プログラマが次に読む本 ?Scalaで学ぶ関数脳入門

オブジェクト指向プログラマが次に読む本 ?Scalaで学ぶ関数脳入門