はじめに
無事、SymPy 1.13.0 がリリースされた (Release Notes)。
私は、SymPy 1.12 の途中からコントリビュートしてきたが、大部分が1.13に含まれる修正である。1.12のリリースから1年以上も空いたため、やはり感慨深いものがある。その間に色々あった。いくつものプルリクエストを投げつけた代償にメンバーに推され、他人のコードをレビューするというのもやったりした。
ちょうどいい区切りだから、SymPyにどのようにして関わったのか、まとめてみようと思う。
きっかけはtypoから
ある日、SymPyのコードを読んでいると、コメントに"paramater"という単語を見つけた。「パラメータってそう綴るんだっけ?」と思って調べてみると"parameter"が正しく、typoだった。typoを見つけたものの、指摘してみるかという思い以上に、放置してもいいのではないかという思いが沸き起こった。実行に影響するわけでもドキュメントに関係するわけでもなく、単なるコメント1行の些細なtypoだ。しかも、私の英語力は中学生にも劣るという現実が、更に報告をためらわせた。
最終的に、「無言でも修正内容を見れば分かるやろ」の精神でプルリクエストを送り付けた、人生初プルリクエスト! それが、これ。
なるべく文章にはせず、単語で済まそうという気持ちがあふれている。SymPyのルールとして、"Release Notes"を書く必要があるのを指摘されて修正し、ほどなくしてマージされた。
で、調子乗った
しょうもないプルリクエストであろうと、マージされたことは嬉しい。そうすると、もう一度プルリスクエストを送りたくなってくる。完全にヤク中のそれである。SymPyの粗探しが始まった。それまで、「OSSって凄い人たちが取り組んでいる、凄いコード」という先入観があったので、自分が貢献できるなんて考えていなかったのだが、あに図らんやそんなことはなかった。英語も、deeplやChatGPTを使うことでなんとかなった(幻想かもしれない)。
例えば、これ。
for q in sieve.primerange(r + 2, r + 2*D + 1):
delta = (q - r) // 2
f = (R.x_cord - S[d].x_cord)*(R.z_cord + S[d].z_cord) -\
alpha + beta[delta]
じーっと眺めているとバグが見えてくる――d
って何者だ?
ということで、修正すると、こんなかんじ。
f = (R.x_cord - S[delta].x_cord)*\
(R.z_cord + S[delta].z_cord) - alpha + beta[delta]
こういう小さなバグから大幅なリファクタリングまで、色々と手を入れた。リファクタリングなどユーザーに特に恩恵がなく、自己満足の域は出ない。それでも、コードはこんなに減ることがあるんだな、という例がこちら。
+19/-91 という大減量。うち、+13はdocstringの追加なので、実質は+6。1つの関数がここまで簡潔に書けるのである。レビュワーからは"beautiful edits"と言われ、満更でもなかった。
その他、今思い返してもクソみたいなプルリクエストを送り続けたわけだが、それらを逐一レビューしていただき感謝の念に堪えない。いちおう釈明をさせていただくと、幾ばくかの新機能実装もしている。
- 位数nの群の個数を計算する関数
sympy.combinatorics.group_numbers.groups_count
(#25947) -
クロネッカー記号
sympy.functions.combinatorial.numbers.kronecker_symbol
-
プロステスト
sympy.ntheory.primetest.proth_test
#25898
なんと実用性のないコードたち!
お前もマージしたくはないか?
さすがにレビューばかり受けるのでは申し訳が立たないので、自分が分かる範囲のプルリクエストにはコメントを入れるようにしていた。するとある日、"invited you to join the sympy organization" というメールが届いた。要は「お前にマージ権限あげるから、もっと励め」というお達しで、あわあわしながらメールを英語で作成して(ChatGPTさんマジ天使)メンテナとやり取りした。
マージ権限を貰ったものの、そんな難しいことはしていない。プロジェクトとしてレビューを誰かに割り当てるようなことをしていないため、自分の分かる範囲でレビューしてマージするという感じだからだ。まあ、どんなイシューやプルリクエストでも捌けるほど知識も経験もないので、さもありなん。
さいごに
英語がへなちょこなのでこれまでハードルが高かったが、ChatGPTのおかげでなんか話せる気がする(気のせい)し、プログラムも直したいことが山ほどある。例えば、素数列挙のアルゴリズムは素朴なエラトステネスの篩だったので、それはあんまりだろうということで偶数をスキップするようにした。これで1.13.0からは、かかる時間がおよそ半分になった。一方で、素因数分解をする関数factorint
の実装もどうにかしたいと思いつつ、どこから手を付けようかという感じで大きくは変えられていない。
どんどんコードの内容に話が流れていってしまったが、結論「当たって砕けろ」「為せば成る」ということだ。今でさえイシューやプルリクエストは玉石混淆なので、そこに石が1つや2つ増えてもなんてことはない。そういう心持ちで臨んだ方が結果的に良いこともある。
そういうわけで、
俺たちの戦いはこれからだ!