https://d226lax1qjow5r.cloudfront.net/blog/blogposts/working-on-a-multi-language-team/multi-language-team-1-.png

多言語チームで働く

最終更新日 March 17, 2022

所要時間:1 分

多くの場合、チームの一員として働く開発者は、チームのメンバー全員が同じ言語、技術スタック、ツールのセットを使いこなすことに慣れている。文脈によっては、複数のプログラミング言語を使って仕事をすることになるかもしれない。

フロントエンドに携わるのであれば、HTML、CSS、JavaScriptを「話す」必要があるだろう。フルスタックの文脈では、バックエンドのプログラミング言語をいくつでも追加することができる。スタックの特定の部分に特化したり集中したりすることはさておき、このようなチームの開発者は、共通の技術用語と、使用している技術スタックによって定義される参照枠を共有することになります。しかし、Vonageのデベロッパー・リレーション・チームに入ってから、私は今述べたのとは全く異なる現実に慣れなければならなくなった。

ここで少し背景を説明しますと、私たちのチームの主な目的の一つは、Vonageの多くの通信APIを使用する開発者を支援し、サポートすることです。私たちがそれを行う方法の一つは、アプリケーションにAPIをより簡単に統合するために、APIを使用するための低レベルの複雑さの一部を抽象化するSDKを提供することです。もちろん、VonageのAPIを使用する開発者は、さまざまなプログラミング言語や技術スタックを使用しています。Ruby、PHP、Python、Java、Node、.net用のサーバSDK、JavaScript、iOS、Android用のクライアントSDKなどです。

チームのRubyデベロッパー・アドボケイトとして、私の役割の一つはRuby SDKの保守と改善です。バグを修正したり機能を追加したりする必要があるときは、Rubyのコードを書いてそれを行います。しかし、私のチームメイトはRubyを書いていません。代わりにPHPやPython、C#を書いている。同じ機能の実装に取り組んでいても、実際にはまったく違う言語でやっているのだ。

JavaScriptの腕前はそこそこだと思いたいが、私の主要言語ではない。過去にPHPを書いたこともあるし(PHPの提唱者であるジムは、当時とは言語がかなり変わっていると断言しているが!)、Pythonも少し知っているが、どちらの言語の専門家でもないと思っている。

しかし、もし私が良いチームメンバーであり、同僚の仕事をサポートできるようになりたいのであれば、時折、ルビーのコンフォートゾーンから自分を押し出す必要がある。

チームに加わってから7ヶ月あまりの間、(Ruby以外の)SDKのバグや機能に取り組んでいる同僚たちの相談相手や第二の目として、自分自身が機能していることに気づきました。PHP、Python、.netライブラリのプルリクエストのレビューも手伝ってきました。Pythonのリポジトリに小さなコミットをプッシュしたこともあります。

居心地が悪い(こともある)ことは、実はいいことだ

多言語チームで働くことは、確かにいくつかの困難を伴うかもしれない。しかし、多くのメリットもあることを提案したい。

開発者として、私たちは技術の習得に努める。私たちは、特定の知識領域で快適に感じられるレベルまで専門知識を高めます。知識のコンフォートゾーン」を構築することは、多くの利点をもたらします。私たちは、常に物事を再確認したり調べたりすることなく、自信を持って、素早く、効率的に仕事をすることができます。その反面、怠け者になったり、思い込みが激しくなったりすることもある。新しい問題や状況に遭遇したとき、私たちは時として慣れ親しんだパターンに戻ってしまい、問題について明確に考えることなく、解決策をすでに知っていると思い込んでしまうことがある。

禅宗には 初心これは「初心」と訳される。あるトピックを学んだり、新しい問題に取り組んだりするときに、先入観を持たず、可能性に対してオープンであることを意味します。専門知識を身につけると「初心」は失われてしまいますが、時には自分の言語のコンフォートゾーンを離れることで、「初心」を取り戻すことができます。

例えば、私がRubyライブラリの1つの機能に取り組んでいて、純粋にRubyの文脈でそれについて考えている場合、私は解決策だけに集中し、問題について明確に考えないという悪い習慣に陥るかもしれない。しかし、同じ機能をPHPやPythonの文脈で同僚と議論していると、解決策についてRuby特有の思い込みを捨て、代わりに問題に集中することを強いられる。

先入観を取り払うだけでなく、他の言語背景を持つ開発者と日々仕事をすることで、別の意味で視野を広げることができる。異なるアプローチややり方、ひいては異なる考え方に触れることができるのだ。

言語学には次のような理論がある。 言語相対論あるいはサピア=ウォーフ仮説と呼ばれる言語理論がある。この理論は、言語の構造が私たちの考え方や世界の見方に影響を与えることを示唆している。この理論は、プログラミング言語ではなく、人間の言語を念頭に置いて開発された。しかし、プログラミング言語は人間が設計したものなので、同じ理論を適用することができる。

プログラミング言語の設計は、ソフトウェアがどのように書かれるべきかについて、ある種の正統性を生み出すことがある。言語は強く型付けされることもあれば、弱く型付けされることもある。ある言語は命令型アプローチに適しているし、ある言語は宣言型アプローチに適している。このような言語の特徴は、コードを書くときに特定の方法で考えさせる可能性がある。

ある考え方しか経験したことがないと、その考え方が正しいと思い込んでしまう。異なる言語やアプローチを経験することで、その言語の設計が示唆するさまざまな考え方に触れることができる。必ずしもひとつの「正しい」方法があるわけではなく、それぞれがトレードオフの関係にある、さまざまな「方法」があることを教えてくれるのだ。

例えば、Rubyは常に(そして今もデフォルトで)動的型付け言語であったが、Rubyプログラムに静的型チェックを導入するオプションができた。Sorbetのようなライブラリは数年前から存在し、最近ではRuby 3でこのオプションがネイティブに導入された。 考えるC#のような静的型付け言語のコードを見ることで、多くのことを学ぶことができる。

private static void ValidSmsResponse(SendSmsResponse smsResponse)

このように見慣れない言語のメソッドシグネチャを見るとき、私たちはその言語についての先入観を持っていない。コードが何をしているのかを理解するためには、次のように自問しなければならない。 と自問しなければならない。シグネチャの各要素は何のためにあるのか? なぜなぜこのように書かれたのか?私たちはこのプロセスから学び、その学びをRubyのコードに持ち帰ることができる。

学習のポイントとヒント

この数ヶ月の間に、多言語チームで仕事をするために役立つアプローチをいくつか学んだので、そのいくつかをここで紹介したいと思う。

ズームアウトしてコンテクストを確立する

数ヶ月前、JimはPHPライブラリの一つから様々なTraitを非推奨にし、削除する作業をしていました。会話を始めている間、私はPHP特有の構文の雑草の中で迷っていました。そのような状況で本当に役に立ったのは、ズームアウトして、より抽象度の高い変更について話し合うことだった。特定のコード行が何をしているのかを考えるよりも、「このTraitの目的は何か」「これらのクラスの関係は何か」などを尋ねることで、変更の文脈を理解しやすくなった。見慣れないコードが何をしているのか、明確なコンテキストを確立すれば、実装の詳細にズームバックするのはずっと簡単になる。

メンタル・モデルの再利用

不慣れな土地に足を踏み入れるときに役立つのは、既存のメンタル・モデルを再利用したり、再目的化したりすることだ。プログラマーとしての学習の旅において、私たちは皆、自分が扱う数多くの技術的概念について、しっかりとしたメンタル・モデルを確立するために多くの時間を費やしてきた。良いニュースは、これらの多くは他のプログラミング言語の文脈でも再利用や再利用が可能だということだ。

例えば、Rubyのブロックのようなものを、Ruby以外の開発者に説明するような場合だ。構文的にはブロックはRuby言語特有のものだが、例えばJavaScriptの開発者にブロックが何であるかを説明する必要がある場合、「ブロックはコールバック関数のようなものだ」と言うことができる。確かに、言語実装の詳細を掘り下げれば、それらは同じものではないが、ブロックが何をするのか、どのように使われるのかを説明するための一般的なメンタルモデルとしては、十分に近いものだろう。

概念的には、ブロックを mapを渡す:

[1, 2, 3].map do |num|
  num + 1
end

にコールバック関数を渡すのと大差はない。 mapにコールバック関数を渡すのと大差ない:

[1, 2, 3].map(function(num) {
  return num + 1;
});

両言語の構文の選択によっては、このように見えるかもしれない。 にも見えるかもしれない。かなり似ているかもしれない:

# Ruby
[1, 2, 3].map { |num| num + 1 }
// JavaScript
[1, 2, 3].map(num => num + 1)

違いを理解するために類似点を見極める

このテーマを続けると、もうひとつやるべきことは、異なる言語や技術スタック間の共通点を探し出すことだ。先ほど、プログラミング言語が取りうるさまざまなアプローチを探求し、それを受け入れることで得られる利点について述べた。しかし結局のところ、これらの言語とその周辺に構築されたツールは、一般的に同じ問題を解決することを目的としている。

例えば、ほとんどのプログラミング言語で利用可能なテスト・ライブラリがある。RSpecのように、独自のDSLを使うものもある。しかし結局のところ、テスティング・ライブラリはどれも同じ問題を解決している。一般的なレベルでは、どれも何らかの形でアサーションを使用します。

Minitest と PyTest はどちらもテストライブラリで、一方は Ruby 用、もう一方は Python 用です。両者の類似点を明らかにすることで、ベースレベルのコンテキストを提供することができ、その結果、両者の動作や実装方法における興味深い違いを浮き彫りにすることができます。

Rubyを超えた世界

私が言いたいのは、Ruby以外の言語にも、活気に満ちた面白い世界があるということだ。私はRubyが大好きだし、主要言語としてRubyから離れるつもりはない。

シェア:

https://a.storyblok.com/f/270183/373x376/e8d3211236/karl-lingiah.png
Karl LingiahRuby開発者支援

KarlはVonageのDeveloper Advocateで、RubyサーバSDKのメンテナンスとコミュニティの開発者エクスペリエンスの向上に注力しています。彼は学ぶこと、ものを作ること、知識を共有すること、そして一般的にウェブ技術に関連することが大好きです。