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

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

このコミットは、Go言語の初期の仕様書である doc/go_spec.txt に対する変更です。主な内容は、内部的なTODOリストの整理と、配列の代入互換性に関する記述の明確化です。Go言語の設計が進行中であった時期の、言語仕様の進化とドキュメント管理の様子を垣間見ることができます。

コミット

commit 1593ab6bb4d5bf59bed1d66f292992572555b999
Author: Robert Griesemer <gri@golang.org>
Date:   Fri Jan 16 15:36:46 2009 -0800

    - cleanup todo list
    - fixed language for arrays slightly
    
    R=r
    DELTA=81  (39 added, 25 deleted, 17 changed)
    OCL=23000
    CL=23000

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

https://github.com/golang/go/commit/1593ab6bb4d5bf59bed1d66f292992572555b999

元コミット内容

このコミットは、Go言語の公式リポジトリにおける、Robert Griesemer氏による doc/go_spec.txt の更新です。具体的には、以下の2点が行われました。

  1. TODOリストの整理: 仕様書内に埋め込まれていた開発中のTODOリスト、決定事項、要望リスト、クローズされた項目などが整理されました。これにより、Go言語の設計プロセスにおける課題管理の状況が更新されています。
  2. 配列に関する記述の修正: 配列の代入互換性に関する記述が修正され、より正確かつ明確な表現になりました。特に、配列からスライスへの代入時の挙動が詳細に説明されています。

変更の背景

このコミットが行われた2009年1月は、Go言語がまだ一般に公開される前の、活発な開発と設計が行われていた時期です。doc/go_spec.txt は、Go言語のセマンティクスと構文を定義する中心的なドキュメントであり、言語の設計変更や決定が頻繁に反映されていました。

変更の背景には、以下の点が挙げられます。

  • 言語仕様の成熟: Go言語の設計が進むにつれて、初期の仕様書に記載されていたTODOや未解決の課題が解決されたり、新たな課題が浮上したりしていました。これらを最新の状態に保つために、定期的なドキュメントの整理が必要でした。
  • 配列のセマンティクスの明確化: 配列はGo言語の基本的なデータ構造の一つですが、その代入互換性に関する初期の記述には曖昧さや不正確な点がありました。特に、配列からスライスへの変換や、配列変数間の代入に関する挙動は、言語の型システムとメモリモデルの理解において重要です。このコミットは、これらの点を明確にし、開発者がGo言語の配列を正しく理解し、利用できるようにすることを目的としています。
  • 内部開発プロセスの反映: go_spec.txt 内のTODOリストや決定事項のセクションは、Go言語開発チームの内部的な議論や進捗を反映するものでした。これらの整理は、開発プロセスの透明性を保ち、設計の方向性を共有するためにも重要でした。

前提知識の解説

このコミットを理解するためには、以下のGo言語の基本的な概念と、当時の開発状況に関する知識が役立ちます。

  • Go言語の仕様書 (go_spec.txt): Go言語の公式な言語仕様を定義するドキュメントです。Go言語の構文、セマンティクス、組み込み型、制御構造など、言語のあらゆる側面が記述されています。開発の初期段階では、このドキュメントが言語設計の「真実の源」として機能していました。
  • 配列 (Arrays): Go言語における配列は、同じ型の要素を固定長で連続して格納するデータ構造です。配列の長さは型の一部であり、コンパイル時に決定されます。
  • スライス (Slices): スライスは、配列のセグメントを参照する動的なデータ構造です。スライスは、基になる配列へのポインタ、長さ、容量の3つの要素で構成されます。スライスはGo言語で最も頻繁に使用されるシーケンス型であり、配列よりも柔軟性があります。
  • 代入互換性 (Assignment Compatibility): ある型の値を別の型の変数に代入できるかどうかを定義するルールです。Go言語では厳格な型システムを採用しており、代入互換性のルールは言語の安全性と予測可能性を保証するために重要です。
  • Go言語の初期開発: Go言語は2007年にGoogleで設計が始まり、2009年後半にオープンソースとして公開されました。このコミットが行われた2009年1月は、まさに公開前の最終調整と設計の固めが行われていた時期にあたります。そのため、仕様書にはまだ「TODO」や「Open issues」といった開発中のメモが多数含まれていました。

技術的詳細

このコミットの技術的詳細は、主に doc/go_spec.txt の内容変更に集約されます。

TODOリストの整理

コミットの差分を見ると、doc/go_spec.txt の冒頭部分に記載されていた開発中のメモが大幅に整理されています。

  • Timeline の移動: 以前は冒頭にあった Timeline (9/5/08) セクション(スレッド、リフレクション、プロトコルバッファサポート、GC、デバッガなどの開発予定期間が記載されていた)が、ドキュメントの末尾の Closed セクションに移動されました。これは、これらの項目がもはや進行中のTODOではなく、過去の計画や完了した項目として扱われるようになったことを示唆しています。
  • 新しいセクションの導入:
    • Decisions in need of integration into the doc:: ドキュメントにまだ統合されていない決定事項をリストアップするセクションが新設されました。例えば、「ペア代入はマップと受信のOK値を取得するために必要である」といった具体的な言語設計の決定がここに記載されています。
    • Wish list:: 将来的にGo言語に導入したい機能の要望リストが新設されました。例えば、「組み込みの assert() 関数」や「enum機能」などが挙げられています。これは、言語の進化に対する長期的なビジョンを示しています。
  • 既存項目の移動と更新:
    • Todo'sOpen issuesClosed の各セクション間で、多くの項目が移動または更新されています。例えば、「convert() は廃止されるべきか?」や「if 文の else 構文の修正」といった具体的な言語設計の課題が、その解決状況に応じて適切なセクションに再分類されています。
    • 特に Closed セクションでは、[x] マークとともに、その項目がどのように解決されたか(例:「assert() はwish listに追加された」)が簡潔に記述されています。これは、設計上の決定がどのように下され、ドキュメントに反映されていったかの記録として機能します。

配列の代入互換性の修正

最も重要な技術的変更は、配列の代入互換性に関する記述の修正です。

変更前:

Assignment compatibility: Arrays can be assigned to slice variables of
equal element type; arrays cannot be assigned to other array variables
or passed to functions (by value).
TODO rethink this restriction. Causes irregularities.

この記述は、配列が他の配列変数に代入できない、または関数に値渡しできないという制限を課しており、さらに「この制限を再考する必要がある。不規則性を引き起こす」というTODOコメントが付いていました。これは、当時のGo言語の配列のセマンティクスがまだ完全に固まっていなかったことを示しています。

変更後:

Assignment compatibility: Arrays can be assigned to variables of equal type
and to slice variables with equal element type. When assigning to a slice
variable, the array is not copied but a slice comprising the entire array
is created.

この修正により、以下の点が明確になりました。

  1. 同型配列への代入: 「arrays cannot be assigned to other array variables」という制限が削除され、「Arrays can be assigned to variables of equal type」と明記されました。これは、同じ型(要素の型と長さが同じ)の配列変数間では、値の代入が可能であることを意味します。Go言語の配列は値型であるため、代入時には要素がコピーされます。
  2. 配列からスライスへの代入: 「When assigning to a slice variable, the array is not copied but a slice comprising the entire array is created.」という記述が追加されました。これは、配列をスライス変数に代入する際に、配列の内容がコピーされるのではなく、その配列全体を参照する新しいスライスが作成されることを明確にしています。これは、Go言語における配列とスライスの関係、特にスライスが配列の「ビュー」であるという概念を強調する重要な点です。
  3. TODOコメントの削除: 以前の記述にあった「TODO rethink this restriction. Causes irregularities.」というコメントが削除されました。これは、この修正によって配列の代入互換性に関する不規則性が解消され、セマンティクスが明確になったことを示しています。

この変更は、Go言語の型システムにおける配列とスライスの相互作用をより正確に定義し、開発者がこれらのデータ構造をより直感的に扱えるようにするための重要な一歩でした。

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

このコミットにおけるコアとなるコードの変更箇所は、doc/go_spec.txt ファイル内の以下の部分です。

--- a/doc/go_spec.txt
+++ b/doc/go_spec.txt
@@ -18,18 +18,21 @@ Any part may change substantially as design progresses.
 ----
 
 <!--
-Timeline (9/5/08):
-- threads: 1 month
-- reflection code: 2 months
-- proto buf support: 3 months
-- GC: 6 months
-- debugger
-- Jan 1, 2009: enough support to write interesting programs
+Decisions in need of integration into the doc:\n+[ ] pair assignment is required to get map, and receive ok.\n+[ ] len() returns an int, new(array_type, n) n must be an int
 \n \n Missing:\n-[ ] Helper syntax for composite types: allow names/indices for maps/arrays,\n-    remove need for type in elements of composites
+[ ] onreturn/undo statement\n+[ ] Helper syntax for composite types: allow names/keys/indices for\n+\tstructs/maps/arrays, remove need for type in elements of composites
+\n+\n+Wish list:\n+[ ] built-in assert() - alternatively: allow entire expressions as statements\n+\tso we can write: some_condition || panic(); (along these lines)\n+[ ] enum facility (enum symbols are not mixable with ints)\n \n \n Todo\'s:\n@@ -39,34 +42,20 @@ Todo\'s:\n [ ] need to talk about precise int/floats clearly\n [ ] iant suggests to use abstract/precise int for len(), cap() - good idea\n     (issue: what happens in len() + const - what is the type?)\n+[ ] cleanup convert() vs T() vs x.(T) - convert() should go away?\n [ ] what are the permissible ranges for the indices in slices? The spec\n \tdoesn\'t correspond to the implementation. The spec is wrong when it\n \tcomes to the first index i: it should allow (at least) the range 0 <= i <= len(a).\n \talso: document different semantics for strings and arrays (strings cannot be grown).\n+[ ] fix \"else\" part of if statement\n+[ ] cleanup: 6g allows: interface { f F } where F is a function type.\n+\tfine, but then we should also allow: func f F {}, where F is a function type.\n \n \n Open issues:\n-[ ] semantics of type decl and where methods are attached\n-\twhat about: type MyInt int (does it produce a new (incompatible) int)?\n-[ ] convert should not be used for composite literals anymore,\n-\tin fact, convert() should go away\n-[ ] if statement: else syntax must be fixed\n-[ ] old-style export decls (still needed, but ideally should go away)\n-[ ] like to have assert() in the language, w/ option to disable code gen for it\n-[ ] composite types should uniformly create an instance instead of a pointer\n-[ ] need for type switch? (or use type guard with ok in tuple assignment?)\n-[ ] do we need anything on package vs file names?\n-[ ] type switch or some form of type test needed\n-[ ] what is the meaning of typeof()\n+[ ] semantics of type decl: creating a new type or only a new type name?\n [ ] at the moment: type T S; strips any methods of S. It probably shouldn\'t.\n-[ ] 6g allows: interface { f F } where F is a function type. fine, but then we should\n-    also allow: func f F {}, where F is a function type.\n-[ ] provide composite literal notation to address array indices: []int{ 0: x1, 1: x2, ... }\n-    and struct field names (both seem easy to do).\n-[ ] reopening & and func issue: Seems inconsistent as both &func(){} and func(){} are\n-    permitted. Suggestion: func literals are pointers. We need to use & for all other\n-\tfunctions. This would be in consistency with the declaration of function pointer\n-\tvariables and the use of \'&\' to convert methods into function pointers.\n+[ ] need for type switch? (or use type guard with ok in tuple assignment?)\n [ ] Conversions: can we say: \"type T int; T(3.0)\" ?\n \tWe could allow converting structurally equivalent types into each other this way.\n \tMay play together with \"type T1 T2\" where we give another type name to T2.\n@@ -78,18 +67,35 @@ Open issues:\n \twhat about maps (require ==, copy and hash)\n \tmaybe: no maps with non-basic type keys, and no interface comparison unless\n \twith nil\n-[ ] consider syntactic notation for composite literals to make them parseable w/o type information\n-\t(require ()\'s in control clauses)\n-\n-\n-Decisions in need of integration into the doc:\n-[ ] pair assignment is required to get map, and receive ok.\n-[ ] len() returns an int, new(array_type, n) n must be an int\n-[ ] passing a \"...\" arg to another \"...\" parameter doesn\'t wrap the argument again\n-\t(so \"...\" args can be passed down easily)\n+[ ] Russ: If we use x.(T) for all conversions, we could use T() for \"construction\"\n+    and type literals - would resolve the parsing ambiguity of T{} in if\'s\n+[ ] Russ: consider re-introducing \"func\" for function type. Make function literals\n+\tbehave like slices, etc. Require no &\'s to get a function value (solves issue\n+\tof func{} vs &func{} vs &func_name).\n+\t\n \n \n Closed:\n+[x] reopening & and func issue: Seems inconsistent as both &func(){} and func(){} are\n+    permitted. Suggestion: func literals are pointers. We need to use & for all other\n+\tfunctions. This would be in consistency with the declaration of function pointer\n+\tvariables and the use of \'&\' to convert methods into function pointers.\n+\t- covered by other entry\n+[x] composite types should uniformly create an instance instead of a pointer - fixed\n+[x] like to have assert() in the language, w/ option to disable code gen for it\n+\t- added to wish list\n+[x] convert should not be used for composite literals anymore,\n+\tin fact, convert() should go away - made a todo\n+[x] type switch or some form of type test needed - duplicate entry\n+[x] provide composite literal notation to address array indices: []int{ 0: x1, 1: x2, ... }\n+    and struct field names (both seem easy to do). - under \"Missing\" list\n+[x] passing a \"...\" arg to another \"...\" parameter doesn\'t wrap the argument again\n+\t(so \"...\" args can be passed down easily) - this is documented\n+[x] consider syntactic notation for composite literals to make them parseable w/o type information\n+\t(require ()\'s in control clauses) - use heuristics for now\n+[x] do we need anything on package vs file names? - current package scheme workable for now\n+[x] what is the meaning of typeof() - we don\'t have it\n+[x] old-style export decls (still needed, but ideally should go away)\n [x] packages of multiple files - we have a working approach\n [x] partial export of structs, methods\n [x] new as it is now is weird - need to go back to previous semantics and introduce\n@@ -125,6 +131,14 @@ Closed:\n [x] should binary <- be at lowest precedence level? when is a send/receive non-blocking? (NO - 9/19/08)\n [x] func literal like a composite type - should probably require the \'&\' to get address (NO)\n [x] & needed to get a function pointer from a function? (NO - there is the \"func\" keyword - 9/19/08)\n+\n+Timeline (9/5/08):\n+- threads: 1 month\n+- reflection code: 2 months\n+- proto buf support: 3 months\n+- GC: 6 months\n+- debugger\n+- Jan 1, 2009: enough support to write interesting programs\n -->\n \n \n@@ -1173,10 +1187,10 @@ The length of arrays is known at compile-time, and the result of a call to\n \t[2*N] struct { x, y int32 }\n \t[1000]*float64\n \n-Assignment compatibility: Arrays can be assigned to slice variables of\n-equal element type; arrays cannot be assigned to other array variables\n-or passed to functions (by value).\n-TODO rethink this restriction. Causes irregularities.\n+Assignment compatibility: Arrays can be assigned to variables of equal type\n+and to slice variables with equal element type. When assigning to a slice\n+variable, the array is not copied but a slice comprising the entire array\n+is created.\n \n \n Struct types\n```

## コアとなるコードの解説

### TODOリストの整理部分

この部分の変更は、Go言語の設計と開発プロセスにおける内部的な進捗を反映しています。

*   **コメントアウトされたセクションの移動と再構成**: `<!-- ... -->` で囲まれたHTMLコメント内のセクションが大幅に再構成されています。これは、Go言語の仕様書が単なる言語定義だけでなく、開発チームの設計上の決定、未解決の課題、将来の計画などを追跡するための内部ツールとしても機能していたことを示しています。
*   **`Timeline` の移動**: 開発初期のロードマップであった `Timeline` が `Closed` セクションに移動されたことは、そこに記載されていた項目が完了したか、あるいはその計画が古くなったことを意味します。
*   **新しいカテゴリの導入**: `Decisions in need of integration into the doc:` や `Wish list:` といった新しいカテゴリが導入されたことで、設計上の決定事項と将来の要望が明確に区別され、より構造化された形で管理されるようになりました。これは、言語設計の成熟度が増し、より体系的なアプローチが取られるようになったことを示唆しています。
*   **具体的な課題の追跡**: `Todo's` や `Open issues` の項目が更新されたことで、当時のGo言語が直面していた具体的な設計上の課題(例: `convert()` 関数の扱い、`if` 文の `else` 構文、型宣言のセマンティクスなど)が明確になります。これらの課題は、Go言語の現在の姿を形成する上で重要な議論の対象となりました。

### 配列の代入互換性の修正部分

この部分の変更は、Go言語の型システムにおける配列とスライスのセマンティクスを明確にする上で非常に重要です。

*   **旧記述の課題**: 変更前の記述「`arrays cannot be assigned to other array variables or passed to functions (by value). TODO rethink this restriction. Causes irregularities.`」は、配列の代入に関する不自然な制限と、それが引き起こす「不規則性」を認めていました。これは、Go言語の設計者が配列のセマンティクスについてまだ試行錯誤していた段階であったことを示しています。特に、配列が値型であるにもかかわらず、他の配列変数への代入が制限されていた点は、直感的ではありませんでした。
*   **新記述の明確化**:
    *   「`Arrays can be assigned to variables of equal type`」という記述により、同じ型の配列変数間での代入が可能であることが明確になりました。これにより、配列が他の値型(例: `int`, `string`)と同様に扱われるという一貫性が保たれます。代入時には、ソース配列の全要素がデスティネーション配列にコピーされます。
    *   「`When assigning to a slice variable, the array is not copied but a slice comprising the entire array is created.`」という記述は、配列からスライスへの変換のメカニズムを正確に説明しています。これは、Go言語におけるスライスの本質(基になる配列への参照)を強調するものです。この挙動は、パフォーマンスの観点からも重要であり、不要なデータコピーを避けることができます。
*   **`TODO` コメントの削除**: `TODO rethink this restriction. Causes irregularities.` というコメントが削除されたことは、この修正によって配列の代入互換性に関する設計上の課題が解決され、セマンティクスが安定したことを意味します。

このコミットは、Go言語がその初期段階でどのように言語仕様を洗練させ、開発者の使いやすさと内部的な一貫性を追求していったかを示す良い例です。特に、配列とスライスの関係はGo言語の重要な特徴の一つであり、このコミットはその基礎を固める上で貢献しました。

## 関連リンク

*   Go言語公式ウェブサイト: [https://go.dev/](https://go.dev/)
*   Go言語の歴史: [https://go.dev/doc/history](https://go.dev/doc/history)
*   Go言語の仕様書 (現在のバージョン): [https://go.dev/ref/spec](https://go.dev/ref/spec)

## 参考にした情報源リンク

*   GitHub: golang/go commit 1593ab6bb4d5bf59bed1d66f292992572555b999: [https://github.com/golang/go/commit/1593ab6bb4d5bf59bed1d66f292992572555b999](https://github.com/golang/go/commit/1593ab6bb4d5bf59bed1d66f292992572555b999)
*   Go言語の配列とスライスに関するドキュメント (現在のバージョン): [https://go.dev/blog/go-slices-usage-and-internals](https://go.dev/blog/go-slices-usage-and-internals)