Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 1135] ファイルの概要

このコミットは、Go言語の仕様書ドラフトである doc/go_spec.txt に加えられた変更を記録しています。doc/go_spec.txt は、Go言語の設計初期段階における言語仕様の定義を目的とした文書であり、言語の構文、セマンティクス、標準ライブラリの振る舞いなどが記述されています。このファイルは、Go言語の進化の過程で、言語設計者たちがどのような議論を行い、どのような変更を検討していたかを示す貴重な資料となります。

コミット

  • コミットハッシュ: a1c85ed83ef0c9e11374caf14ec7aff6b716329d
  • 作者: Robert Griesemer gri@golang.org
  • コミット日時: Mon Nov 17 09:51:56 2008 -0800

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/a1c85ed83ef0c9e11374caf14ec7aff6b716329d

元コミット内容

Package-export proposal:
- syntax change
- missing: corresponding language

DELTA=5  (2 added, 0 deleted, 3 changed)
OCL=19221
CL=19352

変更の背景

このコミットは、Go言語の初期開発段階における「パッケージエクスポート」メカニズムに関する提案の一部として行われました。Go言語では現在、識別子(変数、関数、型など)の最初の文字が大文字であるか小文字であるかによって、その識別子がパッケージ外に公開される(エクスポートされる)かどうかが決定されます。しかし、言語の初期段階では、この暗黙的なルールに加えて、明示的な export キーワードや、さらに package キーワードを用いたエクスポートの構文が検討されていました。

このコミットは、その検討の一環として、仕様書ドラフトに新たな構文の可能性を追記したものです。コミットメッセージにある「missing: corresponding language」は、この構文変更に対応する言語仕様の記述がまだ不足していることを示唆しており、当時の議論が進行中であったことを物語っています。最終的に、Go言語は現在の「大文字で始まる識別子はエクスポートされる」というシンプルなルールを採用しましたが、このコミットは、その決定に至るまでの言語設計の試行錯誤の一端を垣間見ることができます。

前提知識の解説

Go言語における「パッケージエクスポート」とは、あるパッケージ内で定義された識別子(変数、関数、型、メソッドなど)が、そのパッケージの外部から参照可能であるかどうかの可視性(visibility)を制御するメカニズムです。

  • 現在のGo言語のエクスポートルール: Go言語では、識別子の名前の最初の文字が大文字である場合、その識別子はエクスポートされ、他のパッケージからアクセス可能になります。小文字で始まる識別子はエクスポートされず、そのパッケージ内でのみ使用可能です。このルールは非常にシンプルで、明示的なキーワード(例: public, private)を必要としないため、コードの記述量を減らし、可読性を高めるというGoの設計思想に合致しています。

  • 他のプログラミング言語におけるエクスポート/アクセス修飾子: 多くのプログラミング言語では、識別子の可視性を制御するために明示的なキーワード(アクセス修飾子)を使用します。

    • Java/C#: public, private, protected, internal (C#), package-private (Javaのデフォルト)
    • Python: アンダーバー(_)で始まる識別子は慣習的にプライベートとされるが、強制力はない。
    • JavaScript (ES Modules): export キーワードを用いて明示的にエクスポートする。

Go言語の初期段階では、JavaScriptのES Modulesのように export キーワードを導入する案や、さらに package キーワードを組み合わせる案が検討されていました。これは、より明示的な可視性制御を求める声や、他の言語との整合性を考慮した結果と考えられます。しかし、最終的には現在のシンプルな大文字/小文字ルールが採用され、Go言語の大きな特徴の一つとなっています。

技術的詳細

このコミットは、Go言語の仕様書ドラフト doc/go_spec.txt 内の構文定義に、package キーワードの選択肢を追加しています。具体的には、Declaration(宣言)と ExportDecl(エクスポート宣言)の構文規則が変更されています。

変更前は、宣言はオプションで "export" キーワードを伴う形でした。

Declaration =
		[ "export" ]
		( ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl ) .

変更後は、"export" に加えて "package" も選択肢として追加されています。

Declaration =
		[ "export" | "package" ]
		( ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl ) .

同様に、ExportDecl の構文も変更されています。 変更前:

ExportDecl = "export" ExportIdentifier { "," ExportIdentifier } .

変更後:

ExportDecl = [ "package" ] "export" ExportIdentifier { "," ExportIdentifier } .

この変更は、Go言語の初期設計において、識別子のエクスポート方法について複数のアプローチが検討されていたことを示しています。特に package キーワードが export と並列に、あるいは export の前に置かれる形で検討されていたことは、パッケージレベルでの可視性制御をより細かく、あるいは異なるセマンティクスで表現しようとしていた可能性を示唆しています。

しかし、この構文は最終的なGo言語の仕様には採用されませんでした。Go言語は、識別子の最初の文字が大文字であるか小文字であるかによってエクスポートを制御するという、より簡潔なルールを採用しています。このコミットは、Go言語の設計過程における試行錯誤の一例として、その歴史的背景を理解する上で重要です。

コアとなるコードの変更箇所

--- a/doc/go_spec.txt
+++ b/doc/go_spec.txt
@@ -4,7 +4,7 @@ The Go Programming Language Specification (DRAFT)
 Robert Griesemer, Rob Pike, Ken Thompson
 
 ----
-(November 7, 2008)
+(November 13, 2008)
 
 
 This document is a semi-formal specification of the Go systems
@@ -85,6 +85,8 @@ Open issues:
 	with nil
 [ ] consider syntactic notation for composite literals to make them parseable w/o type information
 	(require ()'s in control clauses)
+[ ] global var decls: "var a, b, c int = 0, 0, 0" is ok, but "var a, b, c = 0, 0, 0" is not
+	(seems inconsistent with "var a = 0", and ":=" notation)
 
 
 Decisions in need of integration into the doc:
@@ -542,7 +544,7 @@ a package, constant, type, struct field, variable, parameter, result,
 function, method) and specifies properties of that entity such as its type.\n \tDeclaration =\n-\t\t[ "export" ]\n+\t\t[ "export" | "package" ]\n \t\t( ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl ) .\n \t\t\n Except for function, method and abbreviated variable declarations (using ":="),\n@@ -822,7 +824,7 @@ source than the export directive itself, but it is an error to specify\n an identifier not declared anywhere in the source file containing the\n export directive.\n \n-\tExportDecl = "export" ExportIdentifier { "," ExportIdentifier } .\n+\tExportDecl = [ "package" ] "export" ExportIdentifier { "," ExportIdentifier } .
 \tExportIdentifier = QualifiedIdent .\n \n \texport sin, cos

コアとなるコードの解説

このコミットにおける主要な変更は、Go言語の仕様書ドラフト doc/go_spec.txt 内の2つの構文規則の定義にあります。

  1. Declaration 規則の変更:

    • 変更前: [ "export" ]
    • 変更後: [ "export" | "package" ] これは、Go言語におけるあらゆる宣言(定数、型、変数、関数、メソッド)の前に、オプションで export または package というキーワードを置くことが可能になるという提案を示しています。これにより、宣言されたエンティティの可視性を明示的に制御しようとしていたことが伺えます。
  2. ExportDecl 規則の変更:

    • 変更前: "export" ExportIdentifier { "," ExportIdentifier }
    • 変更後: [ "package" ] "export" ExportIdentifier { "," ExportIdentifier } これは、複数の識別子をまとめてエクスポートする ExportDecl においても、オプションで package キーワードを export の前に置くことが可能になるという提案です。これにより、パッケージ全体のエクスポート設定や、特定の識別子群のパッケージレベルでの可視性制御を意図していた可能性があります。

これらの変更は、Go言語が現在のシンプルなエクスポートルール(大文字/小文字による制御)に落ち着くまでの過程で、より明示的なキーワードを用いたエクスポートメカニズムが検討されていたことを明確に示しています。特に package キーワードの導入は、パッケージという概念とエクスポートの関連性をより強く表現しようとする試みであったと考えられます。

また、コミットの差分には、仕様書のドラフト日付が「(November 7, 2008)」から「(November 13, 2008)」に更新されている点や、Open issues セクションにグローバル変数宣言に関する不整合の指摘が追加されている点も含まれています。これらは、当時のGo言語の設計が活発に議論され、仕様書が頻繁に更新されていた状況を反映しています。

関連リンク

  • Go言語の明示的なエクスポートに関する議論 (GitHub Issue #30572): https://github.com/golang/go/issues/30572 (このコミットの直接的な関連ではないが、Goのエクスポートメカニズムに関する後年の議論の文脈として参考になる)

参考にした情報源リンク