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

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

このコミットは、Go言語の公式仕様ドキュメント doc/go_spec.html における、関数リテラル(FunctionLit)の文法定義の修正に関するものです。具体的には、関数リテラルの生成規則において、SignatureFunctionType に置き換えることで、言語仕様の記述をより正確かつ一貫性のあるものにしています。

コミット

commit 62fd90ab7673f060634df6ce032d2b360334ac57
Author: Robert Griesemer <gri@golang.org>
Date:   Wed Mar 25 13:58:44 2009 -0700

    use FunctionType in FunctionLit production
    
    R=r
    DELTA=1  (0 added, 0 deleted, 1 changed)
    OCL=26738
    CL=26753

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

https://github.com/golang/go/commit/62fd90ab7673f060634df6ce032d2b360334ac57

元コミット内容

    use FunctionType in FunctionLit production
    
    R=r
    DELTA=1  (0 added, 0 deleted, 1 changed)
    OCL=26738
    CL=26753

変更の背景

このコミットは、Go言語がまだ開発の初期段階にあった2009年に行われたものです。当時のGo言語仕様は、言語の進化とともに継続的に洗練されていました。この変更は、関数リテラル(匿名関数)の文法定義をより厳密かつ整合性の取れたものにするための修正です。

以前の定義では、関数リテラルはキーワード "func"Signature(関数の引数と戻り値の型)、そして Block(関数本体)から構成されるとされていました。しかし、Go言語の型システムにおいて、関数のシグネチャは FunctionType という明確な型として扱われます。このコミットは、言語仕様の記述を実際の言語設計とより密接に一致させるため、FunctionLit の定義において SignatureFunctionType に置き換えることで、文法定義の正確性と一貫性を向上させています。これにより、言語の形式的な定義がより明確になり、コンパイラの実装や言語の厳密な理解に役立ちます。

前提知識の解説

  • 関数リテラル (Function Literal): Go言語における関数リテラルは、名前を持たない匿名関数をその場で定義し、変数に代入したり、他の関数の引数として渡したり、即座に実行したりできる構文です。クロージャとして利用されることが多く、コードの簡潔性や柔軟性を高めます。

    例:

    sum := func(a, b int) int {
        return a + b
    }
    result := sum(1, 2) // result は 3
    
  • 関数型 (Function Type): Goでは、関数の型を定義できます。これは、関数の引数の型と戻り値の型によって決まります。同じ引数と戻り値の型を持つ関数は、同じ関数型を持つとみなされます。

    例:

    type BinaryOperation func(int, int) int
    
    func add(a, b int) int { return a + b }
    func subtract(a, b int) int { return a - b }
    
    var op BinaryOperation
    op = add       // add は BinaryOperation 型に代入可能
    result := op(5, 3) // result は 8
    
  • 生成規則 (Production Rule): プログラミング言語の構文は、通常、BNF (Backus-Naur Form) や EBNF (Extended Backus-Naur Form) といった形式文法で定義されます。この文法は「生成規則 (production rule)」の集合から成り立っており、各規則は非終端記号(構文要素、例: FunctionLit, Block)がどのように終端記号(実際のコードのトークン、例: "func", "{", "}")や他の非終端記号に展開されるかを示します。これにより、言語の構文が厳密に定義されます。

  • Go言語仕様 (Go Language Specification): Go言語の公式な定義文書であり、言語の構文、セマンティクス、標準ライブラリの動作などが詳細に記述されています。Go言語の「真実の源」であり、コンパイラの実装者や言語の厳密な理解を求める開発者にとって不可欠なドキュメントです。

技術的詳細

このコミットは、Go言語仕様の doc/go_spec.html ファイル内の、関数リテラル (FunctionLit) の生成規則の定義を修正しています。

変更前:

FunctionLit = "func" Signature Block .

変更後:

FunctionLit = FunctionType Block .

この修正の技術的なポイントは以下の通りです。

  1. "func" キーワードの削除: 変更前の定義では、FunctionLit の一部として明示的にキーワード "func" が含まれていました。しかし、Go言語の文法において FunctionType 自体が func キーワードを含む形で定義されている場合(例えば、FunctionType = "func" Parameters Result のような定義がある場合)、FunctionLit の定義から "func" を削除することで冗長性が排除されます。これにより、文法定義がより簡潔で、かつ各非終端記号の役割が明確になります。

  2. Signature から FunctionType への置き換え: これは最も重要な変更点です。

    • Signature は、関数の引数と戻り値の型を記述する構文要素を指します。
    • FunctionType は、Goの型システムにおける「関数型」そのものを表す非終端記号です。

    この置き換えにより、関数リテラルのシグネチャ部分が、単なる構文要素としてではなく、Goの型システムにおける正式な「関数型」として扱われることが明確になります。これは、言語の設計において型システムの一貫性を保ち、構文解析の曖昧さを減らす上で非常に重要です。例えば、コンパイラが関数リテラルを解析する際、そのシグネチャ部分を直接関数型として解釈できるようになり、型チェックのプロセスがより直接的になります。

この修正は、Go言語の初期段階において、言語の形式的な定義をより正確で、一貫性があり、かつ簡潔にするための重要なステップであり、言語の安定性と将来の拡張性にも寄与しています。

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

--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1991,7 +1991,7 @@ It consists of a specification of the function type and a function body.
 </p>
 
 <pre class=\"grammar\">\n-FunctionLit   = \"func\" Signature Block .\n+FunctionLit   = FunctionType Block .\n Block         = \"{\" StatementList \"}\" .\n </pre>\n \n```

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

上記の差分は、`doc/go_spec.html` ファイル内のGo言語の文法定義(`<pre class="grammar">` タグで囲まれた部分)における `FunctionLit` の生成規則の変更を示しています。

*   `-FunctionLit = "func" Signature Block .`: これは変更前の定義です。関数リテラルが、リテラル文字列 `"func"`、`Signature`(関数の引数と戻り値の型を記述する部分)、そして `Block`(関数本体、つまり `{}` で囲まれたステートメントのリスト)から構成されることを示していました。

*   `+FunctionLit = FunctionType Block .`: これは変更後の定義です。
    *   キーワード `"func"` が削除されています。これは、`FunctionType` 自体が `func` キーワードを含む形で定義されているため、`FunctionLit` の定義で再度 `"func"` を記述する必要がなくなったことを意味します。これにより、文法定義がより簡潔になります。
    *   `Signature` が `FunctionType` に置き換えられています。これは、関数リテラルのシグネチャ部分が、単なる構文要素としての `Signature` ではなく、Go言語の型システムにおける正式な「関数型」として扱われることを明確にしています。この変更により、言語仕様全体での型の一貫性が向上し、コンパイラの実装においてもより明確な指針が与えられます。

この修正は、Go言語の文法定義における抽象化レベルの向上と一貫性の強化を目的としており、言語の設計思想である「シンプルさと明確さ」を反映したものです。

## 関連リンク

*   Go言語の公式ドキュメント: [https://go.dev/doc/](https://go.dev/doc/)
*   Go言語仕様 (Go Language Specification): [https://go.dev/ref/spec](https://go.dev/ref/spec) (このコミットで修正された `doc/go_spec.html` は、現在のGo言語仕様の基盤となるドキュメントの一部です。)

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

*   Go言語のコミット履歴 (GitHub): [https://github.com/golang/go/commits/master](https://github.com/golang/go/commits/master)
*   Go言語の関数リテラルに関する解説記事 (Web検索結果より):
    *   [https://boldlygo.tech/posts/2023/07/20/go-function-literals/](https://boldlygo.tech/posts/2023/07/20/go-function-literals/)
    *   [https://www.syntaxdb.com/go/function-literal](https://www.syntaxdb.com/go/function-literal)
    *   [https://www.bogotobogo.com/GoLang/GoLang_Functions_Literals_Closures.php](https://www.bogotobogo.com/GoLang/GoLang_Functions_Literals_Closures.php)
    *   [https://yourbasic.org/go/function-literal/](https://yourbasic.org/go/function-literal/)
    *   [https://dev.to/hackmamba/go-function-literals-and-closures-301c](https://dev.to/hackmamba/go-function-literals-and-closures-301c)