Scala本体に貢献(pull request)してみる話

以前にも増して、普段ずっとgithubしかやっていないわけで、githubでの活動のことに関してはいくらでも書くことがあるというか、逆に全部をblogに書いていたらとても書ききれないわけで、よってあまり特別なことがない限りblog書かないわけですが、なんとなくScala本体にまとまってpull requestするのは自分にとっては多少は珍しいし、特定のプログラミング言語本体にpull requestするのが、どの程度敷居高いのか、どういうpull requestが受け入れられるのか?を少しでも誰かの参考になればと思い、書いてみます。

以下全部、最近1、2ヶ月でpull reqしてmergeされたものです。このblog書いてる時点で38個でしょうか。 (ここ1、2ヶ月という制約をかけなければ、もっと多く送ったことはあります)

一つずつ簡単に解説書きます。

長いので先に結論というか、感想書いておきますが、細かく見ていくとこのように(コンパイラの内部ほぼ知らなくても)いくらでも貢献できる部分あるといえばあるので、みなさんも何か見つけたら、Scala本体だろうがなんだろうがpull reqしてみましょう。

あと、自分の以下のpull reqは大概説明が短いですが、こういう細かい修正ならば説明が短くてもmergeしてくれる可能性は高いですが、もちろん説明丁寧に英語で書けるならそれに越したことはないし、あまりにも急に互換を壊すような変更はpull requestではなく、適切な場所で議論してからのほうがいいでしょう。

delete unused scala.collection.DebugUtils

全く使われてないdebug用のclassを消しただけ。次のものも含め、もともとparallel-collection(かVectorあたり)で使われていたらしいが、parallel-collectionは本体から分離されたし、分離されてなかったとしても、debug用クラス残しておくのは謎なので

delete unused scala.collection.concurrent.Debug

上記と一緒で謎のdebug用クラス削除

fix procedure syntax

Unitの場合だけ戻り値型省略できるというのをprocedure syntaxというのですが、それが非推奨になって将来的に消えるわけですが、本体にその書き方残っているので削除。scalafix 使って自動で書き換えただけ

https://github.com/scalacenter/scalafix

use Iterable instead of Traversable

Scala 2.13からTraversable非推奨になったが、それがまだcompilerやreflect内部で使われている箇所残っていたので書き換え

fix Set#-- deprecated message

完全にtypoしていたので修正。

use foldLeft instead of /:

Scala 2.13からfoldLeftやfoldRightの記号版が非推奨になるが、まだ使われている箇所残ってたので修正

make private[this] if possible

色んな意味で細かい最適化で、どの程度効果あるのかはたしかに謎だが(多少pull req上で議論発生していた)、明らかなデメリットも特にないので

use AbstractIterator instead of Iterator

このほうがjarのサイズが小さくなる。すでに可能なところではやっていた?が、いろんな都合で(?)忘れられててtrait使ったままだったところを修正

Remove deprecated view bounds

procedure syntaxと同じくview boundsという機能も非推奨でそのうち消えるので修正

fix scala.reflect.Manifest scaladoc

scaladocのコード例が古いままでコンパイル通らなかったり、非推奨なメソッド使ったままになっていたのを修正

use collection.Seq instead of scala.Seq in Array scaladoc

これも、2.13からの新しいコレクションの変更にscaladocのコード例がまだ未対応だったので修正

override Stream#take

自分で見つけたStreamのデグレを修正。これだと根本的な解決になってない(takeのみの修正)と言われて、たしかにそうだなーと思ったが、これ自体は悪くもない?ので結局mergeされた

add space after comma

コンパイルエラー時のメッセージで表示されるコードのフォーマットが微妙だとおもったので、スペース一文字だけ入れた

fix procedure syntax

またprocedure syntax修正(以前とは別の部分)。よく覚えてないが、衝突したりするの嫌だった(?)ので別々に出した。もしくは他の人も似たようなpull req出してmergeされていたが、それで修正しきれていなかったものを再び修正、という経緯だったかも

fix some warnings

Scala 2.13からの新しいコレクションの影響で非推奨などの警告が出ている箇所で、明らかに簡単になおせるものだけ修正

fix Array scaladoc. mutable.ArrayOps does not exists

(2.13のコレクションの変更により?) scaladoc内のclass名が単に間違っていた

fix Predef.=:= example code compile error

これもscaladoc内のサンプルコードの微修正。value classは(privateでもいいが)val がついていないとコンパイル通らないが、ついていなかったので付与

Array.fallbackCanBuildFrom no longer exists

Scala 2.13からのコレクションライブラリの変更で、存在しないメソッドに言及する状態になっていたのでコメント自体を削除

simplify Stream.fromIterator implementation

Scala 2.13からLazyListという(Streamに似ているが別の)新しいclassが追加された。(それでStreamは非推奨になった) その影響でStreamとLazyListは現時点では、一部の実装が共有されたり、コピペされたりしている。 が、StreamのfromIteratorがあまり深く考えずにLazyListのほうからコピペされた影響で(?)多少無駄な処理があったので削除した

Make {Stream, LazyList}.Deferrer value class

value classに変更可能だったので変更した、という細かい最適化

remove unnecessary thunk in Stream.Deferrer

これもfromIteratorの件と一緒で、LazyListの実装コピペにより、(LazyListでは意味があるが)Streamの場合は無駄な部分を修正

fix scala.sys.process package object examples

前述の通りStreamは非推奨でLazyListが導入され、sys.processのメソッドもStreamではなくLazyListを返すようなものが追加されたが、scaladocのサンプルがまだそちらに置き換えていなかったので置き換え

fix ProcessBuilder scaladoc. use LazyList instead of Stream

これも上記と完全に一緒(同じpull reqでもよかった感ある)

avoid unnecessary array copy in some immutable.ArraySeq methods.

takeやdropなどのメソッドは、引数の値によっては、(immutableなcollectionなので)同じもの ( = this) を返せばいいが、引数の値に関わらず必ず新しいコレクション再生成していたので、先にそういうチェックをして "必要ない場合は再生成しない" という簡単な?最適化

use AbstractIterator instead of Iterator

以前出したやつと同じ

fix JavaConverters example code

こちらもscaladocのサンプルコードの細かい修正。IteratorのtoStringが微妙に変わっていた

fix NumericRange example code

コレクションライブラリの更新にともなって、scaladocの例がコンパイル通らなくなっていたのを修正

fix IterableOnce#flatMap example code

これもサンプルコード。 仕様的な型推論の限界でコンパイル通らない?ので型アノテーション追加pull reqをした・・・・・と思いきや、なんだかコンパイラのバグが見つかったらしい!? そして、なぜかこれはこれでmergeされた

fix LazyList example code

もともとStreamのsampleコードをLazyList用に書き換えてあったが、そこで一箇所だけ修正漏れがあった

fix some typo in LazyList.scala

以前も書いたが、StreamとLazyListで実装共有していたりコピペしていたりするが、エラーメッセージやscaladocの記述で細かいミスが残っているのを修正

fix LazyList#withFilter comment

コメントが、FilterMonadicという存在しなくなったtraitに言及していて意味不明になっていたのを修正

fix IsIterableLike example code

これもサンプルコードがコンパイル通らなくなっていたのを修正

fix IterableOnce#toMap deprecation message

完全にコピペミスで、 toMap となるべきところが toVector になっていた

use WrappedString.empty instead of new WrappedString("")

無駄にnewしているのを、emptyで置き換えただけの修正(immutableなコレクションのため、valで保持しているempty使えばよい)

override WrappedString#equals for efficiency

WrappedString同士の場合は、内部のStringを比較したほうが速い、という最適化

override ArraySeq#equals for efficiency

WrappedStringの件と完全に同じ最適化

generalize BasicIO.apply parameter type

他のメソッドはそうなっている場合もあるのに、これだけ Appendable ではなく StringBuffer だったので、Appendableに変更

add deprecated DefaultMap in immutable package object

2.12時点では非推奨でもないのに、2.13.0-M4でいきなり消されていたので、非推奨なtype aliasだけ追加