diff --git a/doc/vim9.jax b/doc/vim9.jax index 49663ce9f..6e0546175 100644 --- a/doc/vim9.jax +++ b/doc/vim9.jax @@ -1,4 +1,4 @@ -*vim9.txt* For Vim バージョン 9.1. Last change: 2025 Apr 27 +*vim9.txt* For Vim バージョン 9.1. Last change: 2025 Jul 21 VIMリファレンスマニュアル by Bram Moolenaar @@ -14,10 +14,11 @@ script の新しい文法と機能について書かれています。 2. 変更点 |vim9-differences| 3. 新しいスタイルの関数 |fast-functions| 4. 型 |vim9-types| -5. 名前空間、Import と Export |vim9script| -6. クラスとインターフェイス |vim9-classes| +5. ジェネリック関数 |generic-functions| +6. 名前空間、Import と Export |vim9script| +7. クラスとインターフェイス |vim9-classes| -9. 理論的根拠 |vim9-rationale| +8. 理論的根拠 |vim9-rationale| ============================================================================== @@ -1895,7 +1896,140 @@ NOTE: ジョブなどの特殊な変数はデフォルトで null 値になり ============================================================================== -5. 名前空間、Import と Export + *generic-functions* +5. ジェネリック関数 + +ジェネリック関数は、引数と戻り値の型チェックを維持しながら、同じ関数を異なる型 +の引数で使用できる。これにより、型安全性とコードの再利用性が確保される。 + +宣言~ + *generic-function-declaration* + *E1553* *E1554* *E1559* +ジェネリック関数の型パラメータは、関数名の直後に山括弧 "<" と ">" で宣言され +る。複数の型名はコンマで区切られる: > + + def[!] {funcname}<{type} [, {types}]>([arguments])[: {return-type}] + {function body} + enddef +< +これらの型パラメータは、関数のシグネチャと本体内の他の型と同じように使用でき +る。例: > + + def MyFunc(param1: T): T + var f: A + var x = param1 + return x + enddef +< + *type-variable-naming* *E1552* +型変数には大文字 1 文字を使用するのが慣例である (例: T、A、X)。ただし、より長 +い名前も使用できる。名前は必ず大文字で始まる必要がある。 + + *E1558* *E1560* +関数は、ジェネリック関数または通常の関数のいずれかとして宣言および使用する必要 +がある。両方としてはできない。 + + *E1561* +型変数名は、クラス名、型エイリアス、列挙名、関数名、他の型変数名など、他の定義 +済みの名前と競合してはならない。 + +ジェネリック関数の呼び出し~ + *generic-function-call* +ジェネリック関数を呼び出すには、関数名と引数リストの間に "<" と ">" で具体的な +型を指定する: > + + MyFunc>() +< + *E1555* *E1556* *E1557* +ジェネリック関数を呼び出す際に指定する具体的な型の数は、関数内の型変数の数と一 +致する必要がある。空の型リストは許可されない。Vim9 の任意の型 (|vim9-types|) +は、ジェネリック関数内の具体的な型として使用できる。 + +関数名と "<" の間、または ">" と開始の "(" の間には空白を入れることはできない。 + +ジェネリック関数は通常の関数と同様に export および import できる。|:export| お +よび |:import| を参照。 + +ジェネリック関数は、別の通常関数またはジェネリック関数内で定義できる。 + +ジェネリック型における型変数の参照~ + +ジェネリック型では、具体的な型の代わりに型変数を使用できる。これは、辞書のリス +トやリストの辞書のような複雑なデータ構造に便利である。例: > + + vim9script + + def Flatten(x: list>): list + var result: list = [] + for inner in x + result += inner + endfor + return result + enddef + + echo Flatten([[1, 2], [3]]) +< + +ジェネリッククラスメソッド~ + +Vim9 クラスメソッドはジェネリック関数にすることができる: > + + class A + def Foo() + enddef + endclass + var a = A.new() + a.Foo() +< + *E1432* *E1433* *E1434* +基底クラスのジェネリッククラスメソッドは、子クラスのジェネリックメソッドでオー +バーライドできる。型変数の数は両方のメソッド間で一致している必要がある。具象ク +ラスメソッドをジェネリックメソッドでオーバーライドすることはできない。逆もまた +同様である。 + +ジェネリック関数参照~ + +関数参照 (|Funcref|) はジェネリック関数として使用できる。これにより、特定の型 +を操作する関数のファクトリーを作成できる: > + + vim9script + + def MakeEcho(): func(T): T + return (x: T): T => x + enddef + + var EchoNumber = MakeEcho() + echo EchoNumber(123) + + var EchoString = MakeEcho() + echo EchoString('abc') +< +ジェネリック関数のコンパイルと逆アセンブル~ + +|:defcompile| コマンドは、具体的な型の特定のリストを持つジェネリック関数をコン +パイルするために使用できる: > + + defcompile MyFunc, dict> +< +|:disassemble| コマンドを使用すると、ジェネリック関数に対して生成された命令を +一覧表示できる: > + + disassemble MyFunc> + disassemble MyFunc> +< +制限事項と今後の課題~ + +現在、Vim は以下をサポートしていない: + - 型変数の型推論: ジェネリック関数を呼び出す際は、すべての型を明示的に指定 + する必要がある。 + - 型制約: 型変数を特定のクラスまたはインターフェイスに制限することはできな + い (例: `T extends SomeInterface`)。 + - デフォルト型引数: 型パラメータが明示的に指定されていない場合に、デフォル + トの型を提供する。 + +============================================================================== + +6. 名前空間、Import と Export *vim9script* *vim9-export* *vim9-import* Vim9 script は、import されるように書くことができます。これは、いくつかの項目 @@ -2178,7 +2312,7 @@ import したオートロードスクリプトを使用するマッピングを ============================================================================== -6. クラスとインターフェイス *vim9-classes* +7. クラスとインターフェイス *vim9-classes* 旧来のスクリプトでは、関数であるメンバーを追加することで、辞書を一種のオブジェ クトとして使用することができます。しかし、これは非常に非効率的で、すべてのオブ @@ -2192,7 +2326,7 @@ import したオートロードスクリプトを使用するマッピングを ============================================================================== -9. 理論的根拠 *vim9-rationale* +8. 理論的根拠 *vim9-rationale* :def コマンド ~ diff --git a/en/vim9.txt b/en/vim9.txt index 0dae57deb..063c17936 100644 --- a/en/vim9.txt +++ b/en/vim9.txt @@ -1,4 +1,4 @@ -*vim9.txt* For Vim version 9.1. Last change: 2025 Apr 27 +*vim9.txt* For Vim version 9.1. Last change: 2025 Jul 21 VIM REFERENCE MANUAL by Bram Moolenaar @@ -15,10 +15,11 @@ features in Vim9 script. 2. Differences |vim9-differences| 3. New style functions |fast-functions| 4. Types |vim9-types| -5. Namespace, Import and Export |vim9script| -6. Classes and interfaces |vim9-classes| +5. Generic functions |generic-functions| +6. Namespace, Import and Export |vim9script| +7. Classes and interfaces |vim9-classes| -9. Rationale |vim9-rationale| +8. Rationale |vim9-rationale| ============================================================================== @@ -1895,7 +1896,146 @@ corresponding empty value. ============================================================================== -5. Namespace, Import and Export + *generic-functions* +5. Generic functions + +A generic function allows using the same function with different type +arguments, while retaining type checking for arguments and the return value. +This provides type safety and code reusability. + +Declaration~ + *generic-function-declaration* + *E1553* *E1554* *E1559* +The type parameters for a generic function are declared in angle brackets "<" +and ">" directly after the function name. Multiple type names are separated +by commas: > + + def[!] {funcname}<{type} [, {types}]>([arguments])[: {return-type}] + {function body} + enddef +< +These type parameters can then be used like any other type within the function +signature and body. Example: > + + def MyFunc(param1: T): T + var f: A + var x = param1 + return x + enddef +< + *type-variable-naming* *E1552* +The convention is to use a single uppercase letter for a type variable (e.g., +T, A, X), although longer names are allowed. The name must start with an +uppercase letter. + + *E1558* *E1560* +A function must be declared and used either as generic or as a regular +function - but not both. + + *E1561* +A type variable name must not conflict with other defined names, such as class +names, type aliases, enum names, function names or other type variable names. + +Calling a generic function~ + *generic-function-call* +To call a generic function, specify the concrete types in "<" and ">" +between the function name and the argument list: > + + MyFunc>() +< + *E1555* *E1556* *E1557* +The number of concrete types provided when calling a generic function must +match the number of type variables in the function. An empty type list is not +allowed. Any Vim9 type (|vim9-types|) can be used as a concrete type in a +generic function. + +Spaces are not allowed between the function name and "<", or between ">" and +the opening "(". + +A generic function can be exported and imported like a regular function. +See |:export| and |:import|. + +A generic function can be defined inside another regular or generic function. + +Referencing type variables in generic types~ + +Instead of concrete types, type variables can be used with generic types. +This is useful for complex data structures like lists of dictionaries or +dictionaries of lists. Example: > + + vim9script + + def Flatten(x: list>): list + var result: list = [] + for inner in x + result += inner + endfor + return result + enddef + + echo Flatten([[1, 2], [3]]) +< + +Generic class method~ + +A Vim9 class method can be a generic function: > + + class A + def Foo() + enddef + endclass + var a = A.new() + a.Foo() +< + *E1432* *E1433* *E1434* +A generic class method in a base class can be overridden by a generic method +in a child class. The number of type variables must match between both +methods. A concrete class method cannot be overridden by a generic method, +and vice versa. + +Generic function reference~ + +A function reference (|Funcref|) can be a generic function. This allows for +creating factories of functions that operate on specific types: > + + vim9script + + def MakeEcho(): func(T): T + return (x: T): T => x + enddef + + var EchoNumber = MakeEcho() + echo EchoNumber(123) + + var EchoString = MakeEcho() + echo EchoString('abc') +< +Compiling and Disassembling Generic functions~ + +The |:defcompile| command can be used to compile a generic function with a +specific list of concrete types: > + + defcompile MyFunc, dict> +< +The |:disassemble| command can be used to list the instructions generated for +a generic function: > + + disassemble MyFunc> + disassemble MyFunc> +< +Limitations and Future Work~ + +Currently, Vim does not support: + - Type inference for type variables: All types must be explicitly specified + when calling a generic function. + - Type constraints: It's not possible to restrict a type variable to a + specific class or interface (e.g., `T extends SomeInterface`). + - Default type arguments: Providing a default type for a type parameter + when not explicitly specified. + +============================================================================== + +6. Namespace, Import and Export *vim9script* *vim9-export* *vim9-import* A Vim9 script can be written to be imported. This means that some items are @@ -2174,7 +2314,7 @@ Or: > ============================================================================== -6. Classes and interfaces *vim9-classes* +7. Classes and interfaces *vim9-classes* In legacy script a Dictionary could be used as a kind-of object, by adding members that are functions. However, this is quite inefficient and requires @@ -2188,7 +2328,7 @@ functionality it is located in a separate help file: |vim9class.txt|. ============================================================================== -9. Rationale *vim9-rationale* +8. Rationale *vim9-rationale* The :def command ~