静的型付けと動的型付けに関するポエム
静的型付けと動的型付けに関する議論は尽きなくて、どっちが良いかというのはたびたび話題になったりします。私個人としては業務経験では静的型付け言語を使うほうが圧倒的に多いですが、個人の開発では動的型付けの言語もけっこう使ったりします。ので、一応は両方触ってきたという観点から、今回はこの型付けに関するポエムを書いてみたいと思います。
最近はgolangやTypeScriptといった、静的型付けの言語が人気が出てる傾向にあると感じます。それでもRuby、Python、JavaScript(あるいはJava)を使う方々への記事にある通り、静的型付けでは型が定義されるので、コンパイル時にエラーで落としてくれたり、型自体がドキュメントのような役割を果たせるので、秩序が保ちやすいという点が利点として挙げられています。最近静的型付けの言語が取り上げられるようになったのは、おそらく無秩序状態になってしまった動的型付け言語で作成されたアプリケーションの反省からではないかと感じます。
では、なぜ動的型付け言語が無秩序になってしまうのでしょうか。それは動的型付け言語自体が悪いというよりは、その特性を理解した開発を行ってこなかったからだと私は考えます。
静的オブジェクト指向は設計者が苦労を背負込むシステムの記事が、静的と動的の適所を考える上で参考になります。動的型付け言語ではクラスの設計を省略できるので、ソースの記述量が少なくて開発できる分、個々の開発者のスキルや知識に依存するような形になります。もちろん、個人や少数であったりスキルが高いメンバーがそろったチームであれば効果的に機能するでしょう。
適所を鑑みずにエンジニアとしてまだ初級レベルのメンバーがいる中で、動的型付け言語を選択してしまうと無秩序になりやすい状態になると考えられます。にもかかわらず、型という概念を使わずに実装できる動的言語を、初級者でも分かりやすいという理由だけで採用してしまったという点に、問題があると私は感じます。
本来的には、開発の進め方やチームメンバーの構成や、スキルを考慮して言語を選ぶべきと私は考えます。メンバーが使ったことある言語とか、触ってみたい言語を採用したいという気持ちはメチャメチャ分かります。ただ、チームで言語選定の基準を明確にしつつ、そのチームの特性に沿った言語で開発を行うのが継続的に機能追加などを行う上では大事で、それが秩序を保つことにもつながると思います。
Discussion
その記事の筆者です。感情のあまり書き散らかした文で、いまさら恥ずかしくなって消してしまいましたが。記事を拝見して少々思うところがありましたのでこちらもポエムで反論させていただきたいと思います。
スキルの高いメンバーが動的型付け言語(JavaScript)でもりもりとプロダクトを作っていったのを見ましたが、後に残ったのは地獄でした。その方のスキルは非常に高く、ORM やサーバーなどを含めたフレームワークまで作っていらっしゃる方でした。しかし、その方はまともなドキュメントも残さず育休に入り、残されたのは型のない継承が繰り返されどんなメンバがあるのかわからないオブジェクトが生成され中身はソースコードを辿らなければわからない、動かして
console.log()
で確認しようにも巨大なモノリス過ぎてできない、そしてバグがあちこちで頻発するという自体になりました。これはいささか極端な例でしたが、スキルがあるからと言って動的型付け言語内で秩序を保てるとは限らないという例でした。いや、多分秩序を保てることを含めてスキルなのでしょう。もちろんこれが静的型付け言語で書かれていたからといって全てが解決するとは言いません。しかし多くのエラーはコンパイル前に弾かれていたでしょうし、オブジェクトのメンバは型情報から入手することもできたでしょう。後から開発に携わる人はそれだけでずいぶんと楽になったと思います。
動的型付け言語の中で秩序を保ち続けるためには、特に組織で開発するにおいて、強い「規約」が必要になります。規約を守り続けるというのはそれ相応のコストを払い続けるのと同等であります。(型推論付きの)静的型付け言語は秩序を守る行為を型に限り全て型理論に裏付けされたコンパイラに任せてしまうことにより規約を守るためのコストを払わなくて済むようにしたのです。ソフトウェアエンジニアであれば自動化できるものは自動化したい、そのための静的片付け言語である。わたしはそう思っています。その自動化したいという思いにはおそらくスキルレベルは関係ないでしょう。
静的オブジェクト指向は設計者が苦労を背負込むシステムを参考に「動的型付け言語ではクラスの設計を省略できるので、ソースの記述量が少なくて開発できる」とおっしゃっているようですが、Java と比較するならばそうでしょう。しかし強い型推論を持った静的型付け言語であれば型の宣言もほぼしなくても済みます。ソースコードの記述量は動的型付け言語とそう変わらないのではないのでしょうか(JavaScript と TypeScript を比較するとどうしても長くなってしまいますが……)。また、わたしは直接は知りませんが Java もソースコードの記述量を減らす試みをしているようです。ですので少なくとも 2008 年の記事だけを引き合いに出して「動的型付け言語の方がソースコードの記述量が少ない」というのは間違いであると言えます。
「適材適所」、確かにそういう言葉もあります。機械学習ではデータ型を変えながら試したいという欲求がありますし、さっと書くスクリプトにいちいち型を書きたくないというのもわかります。どんなデータが飛んでくるかわからないという状況に静的型付け言語は相性が悪いということも知られています。しかし、できることなら決まりきっている部分は静的型付け言語で「秩序の自動化」を行い規約を守るコストを払い続けることから脱したい。そう思ってできる限り新しいシステムは静的型付け言語で作っていきたいと考えています。
コメントありがとうございます。
私もJavaScriptでは苦労させられているので、メチャメチャ気持ちは分かります。。
チームでの「規約」に重きをおくと静的型付けが現時点ではベターであると私も思います。
周りをながめるとあまりこういうことを議論せずに、ただ流行りだからという理由で言語選定されてしまう風潮があるので、今回このような記事を書いてみました。
「流行りだから」を危惧する気持ちはわかります。かつての動的型付け言語もそうでした。「流行りだから」使った結果今揺り戻しが来ているのだと思います。いつになってもそういった流行りに惑わされてしまう人たちは一定数存在するものです。
しかし静的型付け言語についての議論を Java でのみ終わらせてほしくなかったので長々とコメントさせていただいた次第です。Java 以外の型推論付き静的型付け言語を経験済みなのかもしれませんが、もしそうでしたら 2008 年の Java の記事を引き合いに出してくることは無いと思いまして。記事の大筋としておっしゃることはわかりますが、やはりその点は指摘させていただきます。
また本筋とは関係ありませんが 2020 年現在、静的型付け言語で多分最近そこそこ聞くと思うかもしれない(ちょっと自信ない)言語として Go と Rust が挙げられると思いますが、どちらも完全な class 相当の機能はありません。フロントエンドでも React のコンポーネントが class ベースの書き方をやめて関数コンポーネントを使用するようになって久しいです。class に相当する機能自体が扱いが難しすぎて廃れているのかもしれませんね。