Scalaのメソッドと関数は違うもの?

Scalaのメソッドと関数(と関数オブジェクト)の違いについて。
12
Kaz (Jugyo) 🇺🇦 @jugyo

Link: メソッド != オブジェクト - プログラミング言語Scala 日本語情報サイト http://t.co/JhI5XoJ

2011-06-26 06:06:49
kmizu @kmizu

@sumim JVMレベルでのJavaメソッドとのバイナリ互換性とか、多相型が絡んだときの問題があるからかなと思います。ファーストクラスにする方法も考えられなくはないですが、影響範囲がどのくらいになるかイマイチ予測がつかないですね。 #scala

2011-06-26 15:31:36
sumim @sumim

@kmizu 個人的には、メソッドがファーストクラスなSmalltalkとの比較も兼ねて、ファーストクラスにした場合(そもそもJVMの制約の上でも可能だとしてですが)、ルールのシンプルさを今のままキープできるのか、より複雑怪奇なものになってしまうのかちょっとみてみたかったです。

2011-06-26 17:48:26
kmizu @kmizu

@sumim JVMの制約、とは別の点で問題が発生する可能性はあります。特に多相的なメソッドの場合が危ないです。

2011-06-26 21:23:44
kmizu @kmizu

@sumim たとえば、List#map[A, B](f: A =>B): B というメソッドがファーストクラスオブジェクトとして扱えなければいけないなら、"[A, B](A => B) B" のような多相型が「ファーストクラスな型」として必要になります。(続く) #scala

2011-06-26 21:25:56
kmizu @kmizu

@sumim 「ファーストクラスな型」というのは俺用語ですが(別の用語があった気もします)、通常の型としてプログラム上で扱えることを意味しています。具体的には、 変数や引数、返り値の型などとして使うことができる必要があります。(続く) #scala

2011-06-26 21:30:05
kmizu @kmizu

@sumim 問題は[A, B](A => B): A という、「多相的な関数オブジェクトの型」をどう表現するかということにあります。今までのScalaでは、 A => B は Function2[A, B] の構文糖、ということでシンプルだったのですが、

2011-06-26 21:34:10
kmizu @kmizu

@sumim 「多相的な関数オブジェクト」はFunctionN(N = 0 ~22) にマッピングすることができませんから、FPolymorphicFunction1, FPolymorphicFunction2, ... のように、対応する新たなクラスが必要になります。

2011-06-26 21:36:05
kmizu @kmizu

@sumim この時点でルールがかなり複雑化して大変になりますが、まだ問題があります。たとえば、val ref = Ref[[A] A]() という式を考えてみます。ここで、Refはポインタ型のようなもので、中に型パラメタで指定した型の要素を格納することができます。 #scala

2011-06-26 21:54:58
kmizu @kmizu

@sumim refは ref.set(1) ref.get() のようにすることで、値を設定/取得できます。問題は、refには何でも入れられるため、ref.set(1); val y: String = ref.get などの不正な式が型チェックを通ってしまう点にあります。

2011-06-26 21:58:20
kmizu @kmizu

@sumim これは、型システムと副作用を絡めたときに発生する古典的な問題で、これを回避するために値多相という制限がMLにはあります(間違ってたら誰かツッコんでください)。いずれにせよ、メソッドを完全な「ファーストクラスの値」するのはJVMの制限抜きでも難しいです。 #scala

2011-06-26 22:02:31
kmizu @kmizu

@sumim 「多相的なメソッド」は値として持ち運べなくすればこの問題は回避できますが、するとさらに追加ルールが必要になります。てな感じで、「不可能ではないけど、現状の仕様をかなり複雑化することになるだろうなあ」というのが今の自分の見解です。 #scala

2011-06-26 22:05:03
kmizu @kmizu

@sumim 以上、長々と説明してすいませんでした。参考になれば幸いです。 #scala

2011-06-26 22:06:11
sumim @sumim

@kmizu ご丁寧に痛み入ります。単純に、ランタイム時(コンパイル後)の型が決定済みのメソッドオブジェクトを想定していたので、なるほど多相をそのままファーストクラスにする考え方もあるのかなと気付かされました。(そして、それはかなりやっかい、というか早々に破綻しそうだな―とも)

2011-06-26 22:17:45