はじめに
みなさん、こんにちは。元気に過ごしていますか? 9月は慌ただしい1か月でした。サイトには多くの新しい改善と機能を追加しました。その多くは、メンタリングとその周辺の流れを改善するものです。その結果、4週間前と比べて2倍の数のメンタリングのリクエストが届くようになりました。これは素晴らしいことです。メンターにコードをレビューしてもらったことがない人は、ぜひ試してみてください。学ぶための素晴らしい方法です。誰かの助けになりたいと思っているなら、キューには助けを待っているリクエストがたくさんあります。ContributeメニューのMentoringリンクから、メンターとして登録できます! また、MySQL 5.6からMySQL 8への大規模なデータベース更新も行いました。その様子は私が録画していて、Insidersセクションで視聴できます。Insiderの方でまだ見ていない方は、ぜひチェックしてみてください!
さて、#12in23の話に移りましょう。9月は、簡潔で無駄のない言語を探求する、興味深い月でした。今月は逆に、もっと大きな言語たちに目を向けます。今回はオブジェクト指向言語、とくにC#、Crystal、Java、Pharo、Ruby、PowerShellに焦点を当てます。PharoとJavaについてはすでに(それぞれ5月と8月に)取り上げているので、この動画ではもう一度扱いません。これらの言語の紹介に興味があれば、過去数か月の動画をチェックしてみてください。この動画では、C#、Crystal、Ruby、PowerShellを掘り下げます。そしていつも通り、Erikがこれらの言語の面白さと独自性を解説してくれます。
バッジ
いつも通り、これらの言語の演習を5つ完了すると、オブジェクト指向の10月バッジを獲得できます。また、多くの方が目指している、年間バッジもあります。そのために、取り組んでほしい注目の演習を5つ用意しました。どれもオブジェクト指向らしい方法で解くのにぴったりのものです。具体的には次のとおりです。
- 二分探索木:二分木に数値を挿入し、検索する
- リングバッファ:端と端がつながったデータ構造を実装する
- 時計:日付なしで時刻を扱う時計を実装する
- 行列:文字列で表された行列の行と列を返す
- 単純暗号:換字暗号を実装する
概要
C#
- 2000年に、MicrosoftのAnders Hejlsbergによって開発されました
- 言語と仮想マシンには公式の仕様があります。2002年にECMA標準、2003年にISO標準になりました
- コンパイラー、.NET Framework(標準ライブラリー)、Visual Studio(エディター)は当初すべてクローズドソースでしたが、2014年にコンパイラーと.NET Frameworkがオープンソース化されました
- Java(数年前にリリースされていました)と多くの構文を共有していますが、C#はJavaの1対1のコピーではありません(たとえば、プロパティや値型のサポート、チェック例外がないことなど)
- バイトコードにコンパイルされ、.NET 7以降では機械語へのコンパイルもサポートされています(現在も改善中)
- ウェブサイトから組み込みシステム、アプリ(Xamarin)からゲーム(Unity)まで、膨大な量のソフトウェアで使われています
Crystal
- Crystalは、Ary Borenszweig(Exercismにアカウントを持っています)、Juan Wajnerman、Brian Cardiffによって開発されました(当初はJoyという名前でしたが、3日後にCrystalに改名されました :))
- Rubyのようなエレガンスと生産性を持ちながら、現代のコンパイル言語の速度、効率、型安全性を備えるように設計されています
- Manasという組織によって開発されているオープンソース言語です
- バージョン1.0は2021年にリリースされました
- Rustと同様にLLVMを使って機械語にコンパイルします
- コンパイラーは当初Rubyで書かれていましたが、後にセルフホスト版に移行しました
- トラックメーカーのNikolaやManasなどで使われており、主にウェブサイト向けですが、クラウドサービス、コマンドラインアプリケーション、スクリプトにも使われています
PowerShell
- MicrosoftのJeffrey Snoverが率いるチームによって作られ、2006年に最初にリリースされました
- 開発のきっかけはIntelでした。IntelはCPUの開発を助けるために、KornShellスクリプトをSun RISCから別のプラットフォームへ移したいと考えていました。最終的にIntelは別のプラットフォームを選びましたが、Microsoftは新しいシェルであるPowerShellの開発を続けました。Windowsのシステム管理(当時はあまり優れておらず、しばしばGUIが必要でした)を改善できる可能性があったからです
- 構文はKornShellに加え、PHPやPerlなどからも影響を受けています
- 最初のバージョンは.NET Framework上でのみ動作していたため、Windowsでしか動きませんでした。しかしPowerShell 6.0(2018年リリース)は、クロスプラットフォームでオープンソースの.NET Core上で動作しました
- 主にシステム管理に使われますが、CLIユーティリティや他のツールのラッパーを提供するのにも使われます。Exercismのリポジトリーをまとめて操作するのに、これをつねに大量に使ってきました
Ruby
- Yukihiro Matsumoto(通称Matz)によって開発され、1995年に最初にリリースされました
- Matzはきちんとしたオブジェクト指向スクリプト言語を求めていましたが、既存の選択肢(PerlやPythonなど)が気に入らず、新しい言語であるRubyを作りました
- MatzはRubyを、核となる部分はシンプルなLispであり、Smalltalkのようなオブジェクトシステム、高階関数に着想を得たブロック、Perlのような実用的な有用性を併せ持つ言語だと説明しています
- 通常はインタプリターによって実行されますが、機械語へジャストインタイムコンパイルすることもできます
- 公式のインタプリター以外にも、JRuby(JVM上で動作)、Rubinius(LLVMを使用)、そして公式インストールパッケージに同梱されているジャストインタイムコンパイラーであるYJITなど、代替実装があります
- 主にウェブサイト(Ruby on Railsを使用)で使われており、たとえばGitHub、Stripe、Shopifyなど多数(ExercismとExercismフォーラムも含みます!)。Rubyは自動化の用途にも使われます
では、プログラミングの観点から見ると、これらはどう違うのでしょうか?
どれもオブジェクト指向言語ですが、同じ方法で実装しているわけではありません(たとえば、CrystalとRubyはメソッドの呼び出しにSmalltalkのメッセージ送信モデルを使っています)。
C#
- 強い静的型付け
- 命令型と宣言型のパラダイムもサポートしており、ますます関数型に近づいています
Crystal
- (Rubyと違い)強い静的型付け
- 関数型プログラミングと命令型プログラミングもサポートしています
PowerShell
- 強い型付け
- 命令型プログラミング、関数型プログラミング、パイプラインベースのプログラミングもサポートしています
Ruby
- 動的型付け
- 関数型プログラミングと命令型プログラミングもサポートしています
とはいえ、これらの言語はどれも何よりオブジェクト指向言語です。
これらの言語の魅力は何でしょうか?
C#
- (ほぼ)どこでも動作し、Xamarin経由でアプリも作れます。当初はWindowsでしか動作せず、そこからMonoが生まれました。MonoはクロスプラットフォームなC#コンパイラーとランタイムの、無料でオープンソースの実装です。2015年には、完全にクロスプラットフォームでオープンソースの.NET Coreが導入されました
- 汎用:アプリ、ウェブサイト、ゲームなど、ほぼあらゆる用途に使えます
- 表現力が高い:比較的少ないC#コードで多くのことができます。とくにLINQは生産性を大きく高めてくれ、扱っていてとても楽しいものです
- 優れたツール群:IDEだけでなく、ビルドシステムなどの他のツールも充実しています。Visual StudioはWindows専用ですが、JetBrains RiderとVS Codeはクロスプラットフォームです
- .NET Compiler Platform(しばしばRoslynと呼ばれます)は、C#コードを解析・変換・生成するための素晴らしい方法です(C#のテストランナー、アナライザー、リプレゼンターで多用しています)
- ドキュメントが豊富で詳細、かつよく書かれています
- 大きなコミュニティ:ブログやフォーラムなど、多くのリソースが利用できます
Crystal
- エレガントで読みやすい構文:Crystalのコードは読み書きしやすいです
- 表現力が高い:Rubyと同様、Crystalは非常に表現力が高く、少ないコードで多くのことができます。これは優れた充実した標準ライブラリーのおかげでもあります
- 高速:静的型付けにより、LLVMを使って効率的な機械語にコンパイルでき、ガベージコレクターによるシンプルなメモリ管理も行えます
- 素晴らしいオブジェクト指向の実装:クラスや、数値・真偽値のようなプリミティブ型も含め、すべてがオブジェクトです
- すぐに使えるものが揃っている:大規模な標準ライブラリー、組み込みのフォーマッター、テンプレートエンジン、テストフレームワークなどが含まれます
- 相互運用:Cライブラリーとの相互運用が簡単です
- クロスプラットフォーム:Linux、macOS、Windowsで動作しますが、Windowsはまだ一級市民とは言えません
PowerShell
- 強力:PowerShellは管理者にとって強力なツールです。Windows OS(コンポーネント、サービス、設定)や、Exchange、SharePoint、Azureといった他のMicrosoft製品など、多くのシステムとよく統合されます。REST API、データベース、ウェブサービスなど、他の多くの技術とも連携できます
- 入手しやすさ:PowerShellは現代のあらゆるWindows OSにプリインストールされており、.NETが動作するあらゆるシステム(macOS、Linux、多くのUnixシステムを含む)にインストールできます
- セキュリティ:PowerShellには、スクリプトを保護し、署名されたスクリプトと実行ポリシーに基づいて実行を制限する機能があります。これは自動化プロセスの安全性を確保するうえで重要です
- GUI:Windows FormsやWindows Presentation Foundationなどの他のフレームワークと組み合わせて、PowerShellスクリプト用のグラフィカルインターフェースを設計・構築し、より使いやすくすることができます
- パイプライン:UnixシステムのBashと同様に、PowerShellではコマンドレットをつなげて、あるコマンドレットの出力を別のコマンドレットの入力として渡すことで、複雑な操作やタスクを実行できます
Ruby
- エレガントで読みやすい構文:Rubyのコードは読み書きしやすいです
- 表現力が高い:Rubyは非常に表現力が高い言語で、少ないコードで多くのことができます。これも優れた充実した標準ライブラリーのおかげです
- 巨大なエコシステム:利用できるライブラリー(gem)が膨大にあります
- 素晴らしいオブジェクト指向の実装:クラスや、数値・真偽値のようなプリミティブ型も含め、すべてがオブジェクトです
- 実用的:Rubyとそのほとんどのライブラリーは非常に実用的で、現実世界の問題を解くことに重点を置いています
- 相互運用:Cライブラリーとの相互運用が簡単で、とくにパフォーマンスが重要な場面でよく使われます。たとえば、Nokogiri gemはCライブラリーをラップして重い処理を任せることで、XMLを非常に高速に扱えます
- 多くの革新が起きています。たとえば、StripeはRubyの型チェッカーであるSorbetを作り、ShopifyはRuby用のジャストインタイムコンパイラーであるYJIT(Ruby 3.1以降に同梱)を開発し、WASMのサポートも進められています
際立った特徴
C#
- 優れたパフォーマンス:とくにマネージド言語としては出色です。言語とランタイムの両方に、パフォーマンスを高める機能が多数あります。たとえばSpan<t>型や、CPUの組み込み命令(AVX命令など)へのアクセスです。CLRは成熟して安定し、高いパフォーマンスを持つ仮想マシンで、今も改善が続いています</t>
- 巨大なエコシステム:利用できるライブラリーが膨大にあります。それらのライブラリーはC#と同様、成熟して安定し、機能も充実しています
- モダンで進化し続ける:言語とランタイムは今も進化しており、言語はよりモダンになるよう、非常に頻繁に更新されています。その例は次のとおりです
- 簡単に並行処理を行うためのasync/await
- メモリを効率的に使うためのspan<t></t>
- Null許容参照型(10億ドルの過ちを修正)
- ランタイムも定期的に更新されています。たとえば、直接機械語にコンパイルする.NET AOTなどです
- 他の多くの言語・エコシステムに比べて選択肢が少なめです。ほとんどの用途では、Microsoftが提供する既定のソリューション(しばしばIDEも含まれます)で十分です。これは欠点だと主張することもできますが、とくに言語を始めたばかりのときには大きな利点になります
Crystal
- いいとこ取り:グローバルな型推論とユニオン型の組み合わせにより、Crystalは動的型付け言語のように感じられ、型をほとんど書く必要がないこともよくありますが、静的型付け言語のパフォーマンスと追加の安全保証(コンパイル時のnilチェックを含む)も備えています
- メタプログラミング:Rubyの動的な実行時メタプログラミングとは違い、Crystalにはコンパイル時に実行されるマクロがあります。マクロはASTノードを操作してコードを生成します。定義も使用もとても簡単です。Embedded Crystal(ECR)は、マクロを使ってCrystalのコードを他のテキストに埋め込む、組み込みのテンプレートエンジンです
- 優れた並行処理:Goに似た並行処理モデルで簡単に扱えます。軽量な実行単位であるファイバーが、チャネルを通じて通信します
- 生産的で楽しい:Rubyは生産性とエンジニアの幸福のために設計されていることで有名で、エレガントで読みやすい構文と優れた使い心地を備えています。Crystalの構文と設計はRubyとよく似ているため、これはCrystalにも当てはまります(豆知識:Rubyのコードのかなりの部分は、有効なCrystalのコードでもあります)
PowerShell
- コマンドレット:PowerShellは、構成要素としてコマンドレット(英語では "command-lets" と発音します)を使います。コマンドレットは、既存の機能をラップする小さなタスク指向のコマンドで、システム管理者にとって一貫性のある(たとえばGet-Helpはどのコマンドレットのヘルプでも表示できます)、管理者に優しいインターフェースを提供します。.NETのすべてのクラス、Windows Management Instrumentation、Azureなど、さまざまな「バックエンド」に対応するコマンドレットがあります。コマンドレットは任意の.NET言語で定義でき、非常に宣言的な方法で定義されます。パラメーター、その検証、要件(必須のtrue/false)、代替名(スイッチ名)などを簡単に定義できます
- オブジェクト指向:PowerShellでは、ほぼすべてが、多くの異なるプロパティを持つオブジェクトです。ファイル、プロセス、レジストリキー、さらには文字列や数値のような単純なデータ型までもがすべてオブジェクトとして扱われ、このアプローチによって、さまざまな種類のデータやサービスを扱い、やり取りする方法がシンプルになります。.NETを触ったことがある人には非常になじみ深いはずです
- リモート管理:Windowsサーバーやシステム、さらにはAzure、AWS、GCPにまたがるクラウドリソースのリモート管理をサポートしており、大規模な自動化やデプロイの管理に欠かせません
- 拡張性:優れた組み込みのモジュールシステムがあり、カスタムのコマンドレット、関数、モジュールを作成できるほか、他のプログラミング言語やライブラリーと組み合わせて、必要に応じて機能をさらに拡張できます
Ruby
- 生産的で楽しい:Rubyは生産性とエンジニアの幸福のために設計されていることで有名です。数値化するのは難しいものの、Rubyを使ったことのある人たちの熱意がすべてを物語っています
- メタプログラミング:Rubyは非常に動的で、実行時のメタプログラミングが可能です。既存のクラスをモンキーパッチすることも、メソッドを動的に追加したり呼び出したりすることも、Rubyなら自在です
- Ruby on Railsは、ウェブサイトを構築するための、機能満載の素晴らしいフレームワークです。すぐに使える形で、テンプレート、キャッシュ、ActiveRecord(オブジェクトを通じてデータベースを操作する仕組み)、マイグレーション、スキャフォールディング、WebSocketなどを含み、ほかにも多くの機能があります
どれを選ぶか
- オブジェクト指向プログラミングに慣れていて、違ったアプローチを見てみたいなら、Pharoを試してみましょう
- JavaやC#を知っていてしばらく触っていないなら、もう一度試してみてください。どちらの言語も大きく進化しているので、新しい魅力的な機能をチェックしてみましょう!
- 仕事を探しているなら、C#とJava(そして程度は劣りますがRuby)も優れた選択肢です。採用側からの需要がとくに高い言語だからです
- Rubyを知っているなら、静的型付けのRubyがどんな見た目でどんな感触かを知るために、Crystalを試してみましょう
- 動的言語が好きだけれど高いパフォーマンスも欲しいなら、Crystalをチェックしてみましょう
- BashやWindowsのバッチファイルを知っているなら、オブジェクト指向という違った切り口のシェルスクリプトを体験するために、PowerShellを試してみましょう
- スクリプト言語全般が好きなら、Ruby、Crystal、PowerShellはどれも良い選択肢です
- メタプログラミングをやってみたいなら、Pharo、Crystal、Rubyがおすすめです(C#にもメタプログラミングの機能が少しずつ入ってきています)
- テキストファイルに支えられていない言語でプログラミングするとはどういうことかを体験したいなら、Pharoとその独自で強力なIDEを試してみましょう
- ウェブサイト作りが好きなら、Ruby on Railsフレームワークを備えたRubyを試す価値があります