來分享一下最近貢獻開源專案的小心得,雖然我自己貢獻開源專案的次數跟時間不是很多,不過一個 PR 可以產生不少文字跟討論算是值得紀錄一下的。

我自己在 Julia 的一個統計相關的專案上發了一個 PR,希望補齊在標準化上的一些功能,並且可以支援一維的陣列標準化。

起初,我只想用最簡單、直接的方式可以相容於原本的 API,並且達到我想要的功能。

後來專案的審查者希望我將較為底層的功能一起做調整,在不是很情願的情形下,我提出了我認為比較好的修改方案。畢竟動下去等於是整個架構要重新改掉了。

幾次的來回討論以及確認目標後,我確實需要把這部份的功能全部打掉重做。

其中包含審查者注意到 Julia 是個 column-major 的語言,原本的 row-major 的計算方式要改掉,以讓效能最大化。要如何處理 API 的更動,無非是加入 deprecation warning,然後還得考慮預設值的問題,在這邊審查者一直無法決定預設值該是什麼。

再來是,由 API 將資料收進來之後,該如何有效率而優雅地處理資料是個問題。有效率代表程式碼不能有多餘的動作,包含多餘的記憶體耗用、轉置與否。優雅代表 API 底下設計的函式之間的轉換跟呼叫也需要保持簡潔跟可讀性,如函數式程式設計般簡潔,如物件導向般可讀性,不能有重複的程式碼(Don’t repeat yourself, DRY)。像是在 API 下層還要繼續設計 API 一般,直到最底層演算法都要保持這樣的原則,你不會有機會做骯髒的手腳。

來來回回在 PR 上的討論,一則都會有十行以上的文字。想必工程師最討厭的就是需要不斷地跟別人溝通想法,會不斷有想法拋出去,也不斷地被否決,理由通常都是這麼做不夠簡潔、不夠有可讀性、不夠有效率。

不過我想我們的目標是一致的,希望貢獻開源專案,無非是將好的東西貢獻到專案上。種種的批評跟新想法都是促進彼此的成長,有時候是我的方法不夠有效率,有時候是審查者的想法無法通過自動測試,這時候他會為他的想法道歉。我也曾經誤解了他的英文,讓他需要再重新解釋一遍。

很多時候會遇到一些挫折,像是我覺得他這樣做超級蠢,或是我辛辛苦苦改完一個版本上傳,但是對方卻隔了一個禮拜沒有來看。我想除了技術以外,如何跟別人溝通就在這裡展現出重要性。我講講我自己的心法:

  1. 開源專案是大家一起討論出來的結果,沒有辦法說是誰的 idea,除非你真的貢獻超級多或是是專案的擁有者。

  2. 溝通的時候先溝通目的,將目的說明清楚,別讓別人摸不著頭緒或是不斷猜測浪費時間。

  3. 溝通時請儘量客觀而表達明確,有必要的話,直接寫一個小的例子。

  4. 不斷來回的議題通常會產生一些負面情緒,請耐著性子跟對方解釋清楚。在做的好的地方不吝給個稱讚或是表情符號。

  5. 你認為是對的事情就該明確講出來,將事情說明清楚就好,不需要過於強烈的用字。

到目前為止,PR 都還沒 merge,卻已經歷時了兩個月,累積了 93 次的對話,產生了 15 次的 commit。增加了 339 行程式碼,刪除了 112 程式碼,diff 100%,意味著所有程式碼都被我修改過了。不過我想這不會是最後一次,不過會是一次蠻特別的經驗。