[インデックス 1804] ファイルの概要
このコミットは、Go言語の初期段階におけるprint
の構文変更、具体的にはprint
がステートメントから組み込み関数へと移行する過程で、既存のコードベース内の古いスタイルのprint
呼び出しを修正したものです。src/lib/fmt/format.go
ファイル内のコメント行の例が更新されています。
コミット
fix old-style print call in constant
R=rsc OCL=26093 CL=26093
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/5559ff6ece381c8ee1b27779708bc821f609eafb
元コミット内容
fix old-style print call in constant
R=rsc
OCL=26093
CL=26093
変更の背景
このコミットは、Go言語の初期開発段階における重要な言語仕様の変更、特にprint
およびprintln
が組み込みのステートメント(キーワードのように振る舞う)から、通常の組み込み関数へと移行したことに関連しています。
Go言語の初期バージョンでは、print
とprintln
は特殊なステートメントとして扱われていました。これは、C言語のprintf
のような関数とは異なり、引数を括弧で囲む必要がないなど、通常の関数呼び出しとは異なる構文を持っていました。しかし、言語の設計が進むにつれて、このような特殊なステートメントは言語の統一性を損ない、パーサーの実装を複雑にするという問題が浮上しました。
そのため、Go言語の設計者たちは、print
とprintln
を通常の関数呼び出し構文(引数を括弧で囲む)に統一することを決定しました。この変更により、言語の構文がより一貫性のあるものになり、コンパイラの処理も簡素化されました。
このコミットは、その構文変更に伴い、Goの標準ライブラリであるfmt
パッケージ内のformat.go
ファイルにあるコメント内の古いprint
ステートメントの例を、新しい関数呼び出し構文に修正するものです。これは、言語仕様の変更がコードベース全体に波及し、既存のコードやドキュメント、例もそれに合わせて更新する必要があったことを示しています。
前提知識の解説
Go言語の初期開発
Go言語は、GoogleでRob Pike、Ken Thompson、Robert Griesemerによって設計され、2009年にオープンソースとして公開されました。このコミットが行われた2009年3月は、Go言語がまだ活発に開発され、言語仕様が固まりつつある非常に初期の段階でした。この時期には、現在では当たり前となっているGoの構文やセマンティクスが頻繁に変更されていました。
print
とprintln
の歴史
Go言語には、デバッグや簡単な出力のためにprint
とprintln
という組み込み関数(または初期にはステートメント)が存在します。これらはfmt
パッケージのfmt.Print
やfmt.Println
とは異なり、インポートなしで利用できます。しかし、これらは主にデバッグ用途であり、本番コードでの使用は推奨されません(通常はfmt
パッケージを使用します)。
このコミットの時点では、print
は以下のような構文で使われていました(古いスタイル):
print expression
例: print "Hello, World!"
変更後(新しいスタイル):
print(expression)
例: print("Hello, World!")
この変更は、Go言語の構文解析器の簡素化と、言語全体の一貫性を高めるためのものでした。
fmt
パッケージ
fmt
パッケージは、Go言語におけるフォーマットされたI/O(入出力)を実装するための標準ライブラリです。C言語のprintf
やscanf
に似た機能を提供し、文字列、数値、構造体などの様々なデータ型を整形して出力したり、入力から解析したりすることができます。
このコミットで変更されたsrc/lib/fmt/format.go
は、fmt
パッケージの内部実装の一部であり、特にフォーマット処理のコアロジックや、その使用例が記述されているファイルと考えられます。
技術的詳細
このコミットの技術的詳細は、Go言語のパーサーとコンパイラの設計、そして言語の進化における構文の安定化に焦点を当てています。
-
構文解析の簡素化:
print
がステートメントであった場合、コンパイラはprint
キーワードの後に続くトークンが式であると特別に認識し、その式を評価して出力するという特殊なルールを適用する必要がありました。これは、言語の文法規則(BNFなど)に特別なプロダクションを追加することを意味します。print
が関数になった場合、コンパイラはprint
を通常の関数名として扱い、その後に続く括弧内の引数を評価して関数に渡すという、一般的な関数呼び出しのルールを適用できます。これにより、パーサーのロジックが簡素化され、言語の文法がより規則的になります。
-
言語の一貫性:
- Go言語は、シンプルさと一貫性を重視する設計思想を持っています。
print
が特殊なステートメントであることは、他のすべての関数が括弧を使って呼び出されるという一般的なルールからの逸脱でした。この不一致は、学習コストを増やし、コードの可読性を低下させる可能性がありました。 print
を関数にすることで、Go言語内のすべての「アクション」が関数呼び出しという統一されたメカニズムを通じて行われるようになり、言語全体の一貫性が向上しました。
- Go言語は、シンプルさと一貫性を重視する設計思想を持っています。
-
後方互換性への配慮:
- このような言語仕様の変更は、既存のコードベースに大きな影響を与えます。Go言語の開発チームは、初期段階でこのような変更を積極的に行い、言語が広く採用される前に安定した構文を確立しようとしました。このコミットは、その過程で発生した、既存のコード(この場合はコメント内の例)を新しい構文に適合させるための典型的な作業です。
-
fmt
パッケージの例:- 変更された行は、
fmt
パッケージのformat.go
ファイル内のコメントブロックにあります。このコメントは、fmt
パッケージのFmt
型(おそらくフォーマッタのインスタンス)の使用方法を示す例です。 f.Fmt_d(1234).Fmt_s("\n").Str()
は、Fmt
インスタンスのメソッドチェーンを使って数値をフォーマットし、改行を追加し、最終的に文字列として取得する操作を示しています。この結果の文字列をprint
で出力するという例でした。- この例が更新されたのは、単に古い構文の例を新しい構文に合わせるためであり、
fmt
パッケージ自体の機能が変更されたわけではありません。
- 変更された行は、
コアとなるコードの変更箇所
変更はsrc/lib/fmt/format.go
ファイルの一箇所のみです。
--- a/src/lib/fmt/format.go
+++ b/src/lib/fmt/format.go
@@ -34,7 +34,7 @@ func init() {
methods return ``self'' so the operations can be chained.
f := fmt.New();
-print f.Fmt_d(1234).Fmt_s("\n").Str(); // create string, print it
+print(f.Fmt_d(1234).Fmt_s("\n").Str()); // create string, print it
f.Fmt_d(-1234).Fmt_s("\n").Put(); // print string
f.Fmt_ud(1<<63).Putnl(); // print string with automatic newline
*/
具体的には、36行目のprint
呼び出しが変更されています。
コアとなるコードの解説
変更された行は、src/lib/fmt/format.go
ファイル内のコメントブロックの一部です。このコメントブロックは、fmt
パッケージのFmt
型(おそらくフォーマット操作を行うための内部的な型)の使用方法を示すコード例を含んでいます。
元の行:
print f.Fmt_d(1234).Fmt_s("\n").Str(); // create string, print it
変更後の行:
print(f.Fmt_d(1234).Fmt_s("\n").Str()); // create string, print it
この変更は、print
ステートメントがprint
関数に変わったことに対応するものです。
f := fmt.New();
:fmt
パッケージから新しいフォーマッタインスタンスを作成しています。f.Fmt_d(1234)
:Fmt
インスタンスのFmt_d
メソッドを呼び出し、整数1234
をフォーマットしています。Fmt_d
はおそらく"format decimal"(10進数をフォーマット)を意味します。.Fmt_s("\n")
: チェーンされた呼び出しで、Fmt_s
メソッドを使って改行文字列"\n"
を追加しています。Fmt_s
はおそらく"format string"(文字列をフォーマット)を意味します。.Str()
: フォーマットされた結果を文字列として取得しています。print(...)
: 取得した文字列を標準出力に出力しています。
この行は、fmt
パッケージの内部的なフォーマット機能がどのように連鎖的に使用され、最終的に文字列として取得されるかを示す例であり、その結果をprint
で出力するというデモンストレーションです。このコミットは、このデモンストレーションのprint
構文を、当時のGo言語の最新の仕様に合わせるために行われました。これは機能的な変更ではなく、構文的な修正であり、コードの動作には影響を与えません。
関連リンク
- Go言語の公式ドキュメント: https://go.dev/doc/
- Go言語のリリース履歴(初期の変更点に関する情報が見つかる可能性があります): https://go.dev/doc/devel/release
- Go言語の
fmt
パッケージのドキュメント: https://pkg.go.dev/fmt
参考にした情報源リンク
- Go言語の公式リポジトリのコミット履歴: https://github.com/golang/go
- Go言語の初期の設計に関する議論やメーリングリストのアーカイブ(Go言語の
print
ステートメントから関数への変更に関する詳細な議論が見つかる可能性があります)- Go Nutsメーリングリスト: https://groups.google.com/g/golang-nuts
- Go開発者向けメーリングリスト: https://groups.google.com/g/golang-dev
- Go言語の歴史に関する記事やブログポスト(非公式なものも含む)
- 例: "A brief history of Go" by Russ Cox (Go言語の歴史に関する公式ブログ記事など)
- Go言語の初期の変更に関する情報源は、当時のメーリングリストの議論や、Go言語の設計に関する論文やブログ記事に散見されます。