[インデックス 18163] ファイルの概要
このコミットは、Go言語の公式仕様書 doc/go_spec.html における記述の修正に関するものです。具体的には、nil スライスとチャネルの容量に関する記述で使われていた接続詞「and」を「or」に修正し、より正確で並列的な表現に改善しています。これは意味の変更を伴わない、記述の明確化を目的とした修正です。
コミット
- コミットハッシュ:
82e2db70f6a08f55dc7c9d216af9642336390eff - 作者: Rob Pike r@golang.org
- 日付: 2014年1月4日 土曜日 10:52:59 -0800
- コミットメッセージ:
spec: s/and/or/ for correctness and parallelism No change to the meaning, just bad writing found by Doug McIlroy. Let's start the new year off with a bang. R=golang-codereviews, bradfitz, dave CC=golang-codereviews https://golang.org/cl/47110044
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/82e2db70f6a08f55dc7c9d216af9642336390eff
元コミット内容
Go言語の仕様書 doc/go_spec.html において、nil スライス、マップ、チャネルの length および capacity に関する記述で、「The capacity of a nil slice and channel is 0.」となっていた箇所を、「The capacity of a nil slice or channel is 0.」に修正しました。また、仕様書のバージョン日付も更新されています。
変更の背景
この変更は、Go言語の仕様書における表現の正確性を向上させることを目的としています。コミットメッセージによると、著名なコンピュータ科学者であるダグラス・マキルロイ(Doug McIlroy)氏がこの「悪い記述(bad writing)」を発見し、その指摘を受けて修正が行われました。
「slice and channel」という表現は、あたかも「slice」と「channel」の両方が同時に nil である場合にのみ容量が0になるかのような誤解を与える可能性があります。しかし、Go言語のセマンティクスでは、nil スライス単独でも、nil チャネル単独でも、それぞれの容量は0です。したがって、「slice or channel」という表現の方が、それぞれの型が nil である場合に独立して容量が0であるという事実を正確に伝えます。
これは機能的な変更ではなく、あくまで仕様書の記述をより明確で誤解の余地のないものにするための、文法的な修正です。
前提知識の解説
Go言語の仕様書 (The Go Programming Language Specification)
Go言語の仕様書は、Go言語の構文、セマンティクス、標準ライブラリの動作などを厳密に定義した公式文書です。Go言語の挙動に関する最終的な権威であり、コンパイラやランタイムの実装、そしてGoプログラマがコードを書く際の指針となります。この文書はHTML形式で提供され、Goのソースコードリポジトリの一部として管理されています。
nil とは
Go言語における nil は、ポインタ、インターフェース、マップ、スライス、チャネル、関数といった参照型の「ゼロ値」を表します。これは、それらの変数がまだ有効な値やメモリを指していない状態を示します。nil は他の言語における null に似ていますが、Goでは型によって nil の意味合いや挙動が異なります。
スライス (Slice)
スライスはGo言語における可変長シーケンス型です。内部的には、基盤となる配列へのポインタ、長さ(len)、容量(cap)の3つの要素で構成されます。
- 長さ (Length): スライスに含まれる要素の数。
len(s)で取得。 - 容量 (Capacity): スライスの基盤となる配列の、スライスが拡張できる最大要素数。
cap(s)で取得。nilスライスは、基盤となる配列へのポインタがnilであり、長さも容量も0です。
マップ (Map)
マップはキーと値のペアを格納するハッシュテーブルです。
nil マップは、初期化されていないマップであり、要素を追加しようとするとランタイムパニックが発生します。nil マップの長さは0です。マップには容量の概念はありません。
チャネル (Channel)
チャネルはGoルーチン間で値を送受信するための通信メカニズムです。
nil チャネルは、初期化されていないチャネルであり、送受信操作を行うとGoルーチンが永久にブロックされます。nil チャネルの容量は0です。
length と capacity の関係
Go言語では、スライスとチャネルに対して len() と cap() という組み込み関数が提供されています。
len(s): スライスsの現在の要素数、またはチャネルcのバッファ内の要素数。cap(s): スライスsの基盤となる配列の容量、またはチャネルcのバッファの総容量。
このコミットで修正された箇所は、nil のスライスとチャネルの capacity が0であるという仕様を明確にするものです。
技術的詳細
このコミットの技術的な核心は、Go言語の仕様書における論理的な接続詞の選択にあります。
元の記述: The capacity of a nil slice **and** channel is 0.
修正後の記述: The capacity of a nil slice **or** channel is 0.
「and」を使用した場合、これは論理積(AND)を意味し、「スライスが nil であり、かつチャネルが nil である場合に、その容量が0である」という解釈を招く可能性があります。しかし、Go言語のセマンティクスでは、nil スライス単体でその容量は0であり、nil チャネル単体でその容量は0です。これらは独立した事実であり、両方が同時に nil である必要はありません。
「or」を使用した場合、これは論理和(OR)を意味し、「スライスが nil であるか、またはチャネルが nil である場合に、その容量が0である」という解釈になります。これは、それぞれの型が nil である場合に独立して容量が0であるというGo言語の仕様を正確に反映しています。
この修正は、仕様書の記述がGo言語の実際の挙動と完全に一致するようにするためのものであり、読者が誤解する可能性を排除します。特に、並列処理の文脈で「and」と「or」の区別は重要であり、この修正は仕様書の厳密性と正確性を高めることに貢献しています。
また、仕様書のバージョン日付が「Nov 13, 2013」から「Jan 2, 2014」に更新されているのは、この修正が2014年の初めに行われたことを示しており、仕様書が継続的にメンテナンスされている証拠でもあります。
コアとなるコードの変更箇所
変更は doc/go_spec.html ファイル内で行われました。
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
- "Subtitle": "Version of Nov 13, 2013",
+ "Subtitle": "Version of Jan 2, 2014",
"Path": "/ref/spec"
}-->
@@ -5263,7 +5263,7 @@ At any time the following relationship holds:
<p>
The length of a <code>nil</code> slice, map or channel is 0.
-The capacity of a <code>nil</code> slice and channel is 0.
+The capacity of a <code>nil</code> slice or channel is 0.
</p>
<p>
具体的には、以下の2箇所が変更されました。
-
仕様書のバージョン日付の更新:
- "Subtitle": "Version of Nov 13, 2013",+ "Subtitle": "Version of Jan 2, 2014", -
nilの容量に関する記述の修正:- The capacity of a <code>nil</code> slice and channel is 0.+ The capacity of a <code>nil</code> slice or channel is 0.
コアとなるコードの解説
このコミットの主要な変更は、Go言語の仕様書 doc/go_spec.html の特定の段落における単語の置き換えです。
変更前の行:
The capacity of a <code>nil</code> slice and channel is 0.
この行は、nil のスライスとチャネルの容量が0であることを述べています。しかし、ここで使われている接続詞「and」は、文法的には「スライスとチャネルの両方が nil である場合に」という解釈を招く可能性があります。Go言語では、nil スライス単独で cap(nil_slice) は0を返し、nil チャネル単独で cap(nil_channel) は0を返します。これらは独立した事実であり、両方が同時に nil である必要はありません。
変更後の行:
The capacity of a <code>nil</code> slice or channel is 0.
「or」に置き換えることで、この文は「nil スライスの場合、または nil チャネルの場合、その容量は0である」という、より正確な意味合いになります。これにより、読者がGo言語の nil 型の挙動について誤解する可能性がなくなります。これは、仕様書がGo言語のセマンティクスを正確かつ厳密に記述するという目的を果たす上で重要な修正です。
また、仕様書のバージョン日付が更新されたのは、この修正が適用された日付を反映するためであり、仕様書の履歴管理の一環です。
関連リンク
- Go Code Review (CL) へのリンク: https://golang.org/cl/47110044
参考にした情報源リンク
- Go言語の公式ドキュメント (The Go Programming Language Specification): https://go.dev/ref/spec
- Go言語における
nilの概念に関する一般的な情報源 (例: Go by Example - Nil): https://gobyexample.com/nil - Go言語におけるスライス、マップ、チャネルの
lenとcapに関する情報源 (例: Go Slices: usage and internals): https://go.dev/blog/slices - ダグラス・マキルロイ (Doug McIlroy) に関する情報 (例: Wikipedia): https://en.wikipedia.org/wiki/Douglas_McIlroy
- Go言語のコミット履歴 (GitHub): https://github.com/golang/go/commits/master
- Go言語のコードレビューシステム (Gerrit): https://go-review.googlesource.com/
- Go言語のコミットメッセージの慣習に関する情報 (例: Go Contribution Guidelines): https://go.dev/doc/contribute
- Go言語の仕様書における
nilの定義に関する情報 (Go言語の仕様書内): https://go.dev/ref/spec#The_zero_value - Go言語の仕様書におけるスライス、マップ、チャネルの定義に関する情報 (Go言語の仕様書内): https://go.dev/ref/spec#Slice_types, https://go.dev/ref/spec#Map_types, https://go.dev/ref/spec#Channel_types
- Go言語の仕様書における組み込み関数
lenとcapの定義に関する情報 (Go言語の仕様書内): https://go.dev/ref/spec#Length_and_capacity - Go言語の仕様書における
nilの長さと容量に関する記述の周辺コンテキスト (Go言語の仕様書内): https://go.dev/ref/spec#The_zero_value (このコミットで変更された具体的なセクションは、The zero valueの章のAt any time the following relationship holds:の下にあるnilの長さと容量に関する記述です。)