patch 9.1.1577: Vim9: no generic support yet

Problem:  Vim9: no generic support yet
Solution: Add support for generic functions, funcrefs and object/class
          methods (Yegappan Lakshmanan).

closes: #17313

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan
2025-07-21 21:36:08 +02:00
committed by Christian Brabandt
parent b486ed8266
commit 3416cee36f
35 changed files with 5905 additions and 161 deletions

View File

@ -4615,6 +4615,9 @@ E1425 vim9class.txt /*E1425*
E1426 vim9class.txt /*E1426*
E1429 vim9class.txt /*E1429*
E143 autocmd.txt /*E143*
E1432 vim9.txt /*E1432*
E1433 vim9.txt /*E1433*
E1434 vim9.txt /*E1434*
E144 various.txt /*E144*
E145 starting.txt /*E145*
E146 change.txt /*E146*
@ -4674,7 +4677,17 @@ E1548 wayland.txt /*E1548*
E1549 options.txt /*E1549*
E155 sign.txt /*E155*
E1550 options.txt /*E1550*
E1552 vim9.txt /*E1552*
E1553 vim9.txt /*E1553*
E1554 vim9.txt /*E1554*
E1555 vim9.txt /*E1555*
E1556 vim9.txt /*E1556*
E1557 vim9.txt /*E1557*
E1558 vim9.txt /*E1558*
E1559 vim9.txt /*E1559*
E156 sign.txt /*E156*
E1560 vim9.txt /*E1560*
E1561 vim9.txt /*E1561*
E157 sign.txt /*E157*
E158 sign.txt /*E158*
E159 sign.txt /*E159*
@ -7963,6 +7976,9 @@ gdb debug.txt /*gdb*
gdb-version terminal.txt /*gdb-version*
ge motion.txt /*ge*
gender-neutral helphelp.txt /*gender-neutral*
generic-function-call vim9.txt /*generic-function-call*
generic-function-declaration vim9.txt /*generic-function-declaration*
generic-functions vim9.txt /*generic-functions*
get() builtin.txt /*get()*
get()-blob builtin.txt /*get()-blob*
get()-dict builtin.txt /*get()-dict*
@ -11023,6 +11039,7 @@ type-casting vim9.txt /*type-casting*
type-checking vim9.txt /*type-checking*
type-inference vim9.txt /*type-inference*
type-mistakes tips.txt /*type-mistakes*
type-variable-naming vim9.txt /*type-variable-naming*
typealias vim9class.txt /*typealias*
typename() builtin.txt /*typename()*
typescript.vim syntax.txt /*typescript.vim*

View File

@ -1,4 +1,4 @@
*todo.txt* For Vim version 9.1. Last change: 2025 Jun 12
*todo.txt* For Vim version 9.1. Last change: 2025 Jul 21
VIM REFERENCE MANUAL by Bram Moolenaar
@ -115,7 +115,6 @@ Further Vim9 improvements:
- For chaining, allow using the class name as type for function return
value.
- Implement "specifies" interface
- Implement generics
- Add "assignable" (class or child)?
- More efficient way for interface member index than iterating over list?
- a variant of type() that returns a different type for each class?

View File

@ -41551,6 +41551,8 @@ Add support for internal builtin functions with vim9 objects, see
Enum support for Vim9 script |:enum|
Generic function support for Vim9 script |generic-functions|
Support for protected _new() method
Support for compiling all the methods in a Vim9 class using |:defcompile|.

View File

@ -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<T, A, B>(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<number, string, list<number>>()
<
*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<T>(x: list<list<T>>): list<T>
var result: list<T> = []
for inner in x
result += inner
endfor
return result
enddef
echo Flatten<number>([[1, 2], [3]])
<
Generic class method~
A Vim9 class method can be a generic function: >
class A
def Foo<X, Y>()
enddef
endclass
var a = A.new()
a.Foo<number, string>()
<
*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<T>(): func(T): T
return (x: T): T => x
enddef
var EchoNumber = MakeEcho<number>()
echo EchoNumber(123)
var EchoString = MakeEcho<string>()
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<number, list<number>, dict<string>>
<
The |:disassemble| command can be used to list the instructions generated for
a generic function: >
disassemble MyFunc<string, dict<string>>
disassemble MyFunc<number, list<blob>>
<
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 ~