Robert Harperの型クラス批判
Robert Harperのブログに(10年くらい前に)載っていたHaskellの型クラスに対する批判について@elpin1alさんに教えていただいたのでメモ。@elpin1al ありがとうございます!
型クラスとモジュール
言語の抽象化機構の中心的存在は何かと考えると、Haskellなら型クラス、MLならモジュールが挙がる。
Typeclasses vs Modules
Haskell has typeclasses, which are simply awesome. OCaml has a superb module system which can play some of the same roles, but typeclasses are simply more useful, more often. Some specific patterns—like monads—are nicer and easier to use thank to typeclasses. People using OCaml in the real world do still use particular monads like option or async, but they're more awkward than in Haskell, especially when you want to use multiple ones in related parts of your code. Additionally, it's much harder to write generic code against monads in OCaml.
のようなことが書かれたりする。
これを踏まえてこんなジョークを飛ばした:
who needs functors when you can have type classes? https://t.co/3wwlw3gV9R
— zehnpaard (@zehnpaard) February 24, 2021
そうしたらこういうツッコミ(?)をもらった:
Still waiting for an answer to this question
— Daniピー (@kidviddy) February 25, 2021
私も個人的にはまだ型クラスによる制御されたアドホック多相を放棄するほどの価値がモジュールシステムにあるのかは判断できない・・・
Modules Matter Most
こういう時に思い出すのがThe Definition of Standard MLの作者の一人Robert HarperのこのModules Matter Mostというブログ記事である:
(ちなみにHarperは共著で「Modularity Matters Most」という論文も出している)
全体的にHarper節炸裂な感のある記事だが:
In Haskell you have type classes, which are unaccountably popular (perhaps because it’s the first thing many people learn). There are two fundamental problems with type classes. The first is that they insist that a type can implement a type class in exactly one way. For example, according to the philosophy of type classes, the integers can be ordered in precisely one way (the usual ordering), but obviously there are many orderings (say, by divisibility) of interest. The second is that they confound two separate issues: specifying how a type implements a type class and specifying when such a specification should be used during type inference. As a consequence, using type classes is, in Greg Morrisett’s term, like steering the Queen Mary: you have to get this hulking mass pointed in the right direction so that the inference mechanism resolves things the way you want it to.
挙げられている二点の批判のうちの最初のものはよく聞くもの(例えばIntがモノイドとしては(Int, +, 0)として定義されていてそのままだと(Int, *, 1)と使い分けられない)だが、二点目がなかなか理解できないでいた。
Modular Type Classes
その旨呟いたら@elpin1alさんに
instance宣言をした瞬間に、そのinstanceがoverload解決に使われうることを指しています
— El Pin Al (@elpin1al) March 20, 2021
https://t.co/eKDmTsA7Gz の2.2節 "Separating the definition of an instance from its use"を見ると良いです
— El Pin Al (@elpin1al) March 20, 2021
なるほど、ありがとうございます!
— zehnpaard (@zehnpaard) March 20, 2021
とするとやはり「there can only ever be a single instance of a class at a certain type in one program」という点が問題だという話になるんですね
いえ、そちらの問題はnamed instanceなどで解決できるのでそうではなく、「複数instanceが存在する(特に別々のモジュールで定義された)場合にどのinstanceが選択されるかの予測・制御が難しい」という点について言っているのだと思います
— El Pin Al (@elpin1al) March 20, 2021
ブログだと”in Greg Morrisett’s term, ... the way you want it to.”の部分、論文だと”thus facilitating modular decomposition and constraining inference to make use only of a clearly specified set of instances.”の部分です
— El Pin Al (@elpin1al) March 20, 2021
と教えていただいた。
Modular Type Classesという論文で、Modular Implicits関連で話は聞いていたものの読んだことがなかったのだが大変面白かった。
つまりHarperの批判というのは
- 型クラスはHaskellで実装されているものだと一つの型が同じ型クラスの複数インスタンスになり得ない、がこれはダメだ
- Haskell界でもこの問題は認識されているけど、それに対する提案(named instancesなど)だと(Moduleから始めていないので?)特定の箇所での型推論時に期待されるインスタンスを使うようにするのが非常に大変(それに対してモジュールを中心としたデザインに型クラスを上乗せするような実装だと上手くいくよ)
ということか。最初のポイントはHaskellにおける型クラスに対する批判、第二のポイントは(複数インスタンスを可能とさせるような)Haskell界で提案されている型クラス拡張(そしてその思想的背景(=モジュールの軽視?))に対する批判、という感じだろうか?