The Go Programming Language

Category: Go
The Go Programming Language

Goは何ですか?

Goは、シンプルで信頼性が高く、 効率的なソフトウェアを簡単に構築できるオープンソースのプログラミング言語です。

Goの歴史

Goは2007年9月に、GoogleのRobert Griesemer、Rob Pike、Ken Thompsonによって考案され、2009年11月に発表されました。 この言語とそれに付随するツールの目標は、表現力豊かであること、コンパイルと実行の両方で効率的であること、 そして信頼性が高く堅牢なプログラムを書くのに効果的であることでした。

Go言語の開発者

Goの特徴

Goは表面上Cに似ており、Cと同様にプロのプログラマ向けのツールであり、 最小限の手段で最大限の効果を達成します。 しかし、それは単にCをアップデートしたものではありません。 他の多くの言語から良いアイデアを借用し、適応させる一方で、 複雑さや信頼性の低いコードにつながった機能を避けています。 その並行処理機能は新しく効率的であり、データ抽象化とオブジェクト指向プログラミングへのアプローチは常に柔軟です。 また、自動メモリ管理、つまりガベージコレクションを備えています。

Goの用途

Goは特にネットワークサーバーのようなインフラストラクチャや、 プログラマ向けのツールやシステムの構築に適していますが、 真に汎用的な言語であり、グラフィックス、モバイルアプリケーション、 機械学習といった多様な分野で使用されています。 型付けのないスクリプト言語の代替として人気を博しているのは、 表現力と安全性のバランスが取れているためです。 Goプログラムは通常、 動的言語で書かれたプログラムよりも高速に動作し、 予期しない型エラーによるクラッシュがはるかに少なくなります。

Goのコミュニティ

Goはオープンソースプロジェクトであるため、 そのコンパイラ、ライブラリ、ツールのソースコードは誰でも自由に入手できます。 プロジェクトへの貢献は、活発な世界中のコミュニティから寄せられています。 GoはUnixライクなシステム(Linux、FreeBSD、OpenBSD、Max OS X)や、Plan 9、Microsoft Windowsで動作します。 これらの環境の一つで書かれたプログラムは、通常、他の環境でも修正なしに動作します。

Goの設計に影響を与えた言語

生物種のように、成功した言語は祖先の利点を取り入れた子孫を生み出します。 異種交配は時に驚くべき強みをもたらし、 そしてごく稀に、前例のない革新的な新機能が生まれます。 言語がなぜそのようになっているのか、 そしてどのような環境に適応してきたのかを、 これらの影響を見ることで多くを学ぶことができます。 下の図は、Goの設計に影響を与えた初期のプログラミング言語の最も重要な影響を示しています。

Goの歴史

GoはCから生まれた

Goは時に「Cライクな言語」または「21世紀のC」と評されます。 GoはCから、式構文、制御フローステートメント、基本データ型、値渡しによるパラメータ渡し、 ポインタ、そして何よりも、効率的なマシンコードにコンパイルされ、 現在のオペレーティングシステムの抽象化と自然に連携するプロラグむを重視するCの姿勢を受け継ぎました。

Goの家系図には他にも祖先がいる

しかし、Goの家系図には他にも祖先がいます。 一つの主要な影響の流れは、Pascalに始まるNiklaus Wirthによる言語群から来ています。 Modula-2はパッケージの考えに影響を与えました。 Oberonはモジュールのインターフェースファイルと実装ファイルの区別を無くしました。 Oberon-2はパッケージ、インポート、宣言の構文に影響を与え、 Object Oberonはメソッド宣言の構文を提供しました。

Goの祖先の中でもう一つの系統

Goの祖先の中でもう一つの系統であり、 近年のプログラミング言語の中でGoを際立たせているのは、 ベル研究所で開発された一連のあまり知られていない研究言語です。 これらは全て、Tony Hoareの独創的な1978年の並行処理の基礎に関する論文に登場する「Communicating Sequential Processes(CSP)」の概念に触発されています。 CSPでは、プログラムは共有状態を持たないプロセスの並列合成であり、 プロセスはチャネルを使用して通信し同期します。 しかし、HoareのCSPは並行処理の基本概念を記述するための形式言語であり、 実行可能なプログラムを書くためのプログラミング言語ではありませんでした。 Rob Pikeらは、CSPを実際の言語として実装する実験を始めました。 最初のものはSqueak(「マウスと通信するための言語」)と呼ばれ、 静的に作成されたチャネルでマウスやキーボードのイベントを処理する言語を提供しました。 これに続いたのがNewsqueakで、 Cライクな分と式の構文、Pascalライクな型表記を提供しました。 これはガベージコレクションを備えた純粋関数型言語で、 やはりキーボード、マウス、ウィンドウイベントの管理を目的としていました。 チャネルは第一級の値となり、 動的に作成され変数に格納できるようになりました。 Plan 9オペレーティングシステムは、Alefという言語でこれらのアイデアを推し進めました。 AlefはNewsqueakを実用的なシステムプログラミング言語にしようと試みましたが、 ガベージコレクションを省略したため、並行処理が非常に困難になりました。

Goには祖先以外の遺伝子の影響が随所に見られる

Goの他の構造には、祖先以外の遺伝子の影響が随所に見られます。 例えば、iotaはAPLから大まかに、 ネストされた関数を持つレキシカルスコープはScheme(およびそれ以降のほとんどの言語)から来ています。 ここにも革新的な突然変異が見られます。 Goの革新的なスライスは、 効率的なランダムアクセスを持つ動的配列を提供しつつ、 連結りすとを彷彿とさせる洗練された共有の仕組みも可能にします。 そして、defer文はGoで新たに導入されたものです。

GoはGoogleのソフトウェアが複雑さに苦しんでいたことへの不満から生まれた

すべてのプログラミング言語は、その作成者のプログラミング哲学を反映しており、それにはしばしば、以前の言語の欠点と認識されるものへの反発が大きな要素として含まれます 。 Goプロジェクトは、Googleのいくつかのソフトウェアシステムが複雑さの爆発に苦しんでいたことへの不満から生まれました 。(この問題は決してGoogle特有のものではありません 。)

長期的に見れば簡潔さこそが良いソフトウェアの鍵

Rob Pikeが言うように、「複雑さは乗算的」です。 システムの一部分をより複雑にすることで問題を解決しようとすると、 ゆっくりとしかし確実に他の部分にも複雑さが加わっていきます。 機能やオプション、 設定を追加し、 迅速にコードをリリースするという絶え間ないプレッシャーの中で、 簡潔さを軽視しがちですが、 長期的に見れば簡潔さこそが良いソフトウェアの鍵なのです 。

簡潔さを実現するには

簡潔さを実現するには、 プロジェクトの初期段階でアイデアをその本質にまで落とし込むためのより多くの作業と、 プロジェクトの存続期間を通じて、 良い変更と悪い、 あるいは有害な変更とを区別するためのより多くの規律が必要です。 十分な努力をすれば、 Fred Brooksが「概念的完全性」と呼んだ設計を損なうことなく良い変更を受け入れることができますが、 悪い変更はできず、 有害な変更は簡潔さをその浅薄ないとこである利便性と引き換えてしまいます。 設計の簡潔さを通じてのみ、 システムは成長しても安定し、 安全で、一貫性を保つことができます。

Goプロジェクトには、簡潔さという文化的アジェンダが含まれている

Goプロジェクトには、 言語自体、 そのツールと標準ライブラリ、 そして最後に、 根本的な簡潔さという文化的アジェンダが含まれています。 最近の高級言語として、 Goは過去の経験から恩恵を受けており、 基本がしっかりしています。 ガベージコレクション、 パッケージシステム、 第一級関数、 レキシカルスコープ、 システムコールインターフェース、 そしてテキストが一般的にUTF-8でエンコードされる不変文字列を備えています 。

Goは機能が少ない

しかし、比較的機能が少なく、 これ以上追加される可能性は低いです。 例えば、暗黙的な数値変換、 コンストラクタやデストラクタ、 演算子のオーバーロード、 デフォルトのパラメータ値、 継承、ジェネリクス、例外、マクロ、 関数アノテーション、スレッドローカルストレージがありません。 言語は成熟し安定しており、後方互換性が保証されています。 古いGoプログラムは新しいバージョンのコンパイラと標準ライブラリでコンパイルして実行できます。

Goは型システムがシンプルである

Goには、 動的言語のプログラマを悩ませる不注意なミスのほとんどを回避するのに十分な型システムがありますが、 同等の型付き言語よりもシンプルな型システムを持っています。 このアプローチは、より広範な型のフレームワーク内で「型付けされていない」プログラミングの孤立したポケットを生じさせることがありますが、 Goプログラマは、 C++やHaskellのプログラマが安全性プロパティを型ベースの証明として表現するために行うようなことまではしません。 しかし、実際にはGoは、 複雑な型システムの負担なしに、 比較的強力な型システムの安全性と実行時パフォーマンスの利点の多くをプログラマに提供します 。

Goはメモリ管理がシンプルである

Goは、 現代のコンピュータシステムの設計、 特に局所性の重要性に対する意識を奨励します。 その組み込みデータ型とほとんどのライブラリデータ構造は、 明示的な初期化や暗黙的なコンストラクタなしで自然に動作するように作られているため、 コード内に隠されたメモリアロケーションやメモリ書き込みは比較的少数です。 Goの集合型(構造体と配列)は要素を直接保持するため、 間接的なフィールドを使用する言語よりもストレージが少なく、 アロケーションやポインタの間接参照も少なくて済みます。 そして、現代のコンピュータは並列マシンであるため、 Goには前述のCSPに基づく並行処理機能があります。 Goの軽量スレッド、すなわちゴルーチンの可変サイズスタックは、 最初は十分に小さいため、 1つのゴルーチンを作成するのは安価であり、100万個作成することも実用的です。

Goの標準ライブラリは、しばしば「電池付属」と評される

Goの標準ライブラリは、 しばしば「電池付属」と評され、 I/O、テキスト処理、グラフィックス、 暗号、ネットワーキング、 分散アプリケーションのためのクリーンなビルディングブロックとAPIを提供し、 多くの標準ファイル形式とプロトコルをサポートしています。 ライブラリとツールは、 設定と説明の必要性を減らすために規約を広範に利用しており、 これによりプログラムロジックが簡素化され、 多様なGoプログラムが互いに類似し、 学びやすくなっています。 goツールを使用して構築されたプロジェクトは、 ファイル名、識別子名、そして時折の特別なコメントのみを使用して、 プロジェクトのすべてのライブラリ、 実行可能ファイル、テスト、ベンチマーク、例、 プラットフォーム固有のバリアント、およびドキュメントを決定します。 Goのソース自体がビルド仕様を含んでいるのです。

Goはオブジェクト指向プログラミングに対して独特なアプローチを持っている

Goはオブジェクト指向プログラミングに対して独特なアプローチを持っています。 クラス階層や、そもそもクラスというものが存在しません。 複雑なオブジェクトの振る舞いは、継承ではなく、 より単純なものの組み合わせ(コンポジション)によって作られます。 メソッドは構造体だけでなく、 任意のユーザー定義型に関連付けることができ、 具象型と抽象型(インタフェース)の関係は暗黙的であるため、 具象型は、その型の設計者が意図していなかったインタフェースを満たすことがあります。