Generics
Generics are a way of defining functions and data structures that can operate on any data type. This allows you to create more generic code that can be reused for different data types.
In V at the moment, generics are pretty limited and do not have such important things as type constraints.
Unlike many languages, V uses the [T]
syntax instead of <T>
to specify generics.
Initially V used the
<T>
syntax, but it was changed to[T]
to simplify the parser.
Generic names use single letters such as T
or U
, any other names are currently prohibited.
Functions
Generic functions are defined using square brackets after the function name containing the parameter types:
Such a function can be called with any data type that supports the <
and >
operators.
When calling a function, the parameter types must optionally be specified in square brackets:
In the first case compare
will be generated for type int
and called with int
and int
parameters.
If you try to pass 'b'
instead of 0
, you will get a compilation error:
The V compiler is smart enough to be able to determine the types of the parameters if they are not explicitly specified:
Structs
Generic structures are defined using square brackets after the name of the structure containing the parameter types:
This structure can be used with any data type; when creating an object, the parameter types must be specified after the structure name and before the curly brace:
Unlike functions, when creating a generic structure object, the parameter types must always be specified explicitly:
Methods of generic structs
To describe methods of generic structures, the receiver must be of
type Type[<generic parameters>]
:
Generic struct methods can use struct parameter types as method parameter types or as return value types.
Such methods can define their own parameter types:
You may notice that when the map()
method is called, the parameter type U
is not explicitly
specified.
The V compiler itself inferred the type of the U
parameter from the function passed to it.
Interfaces
Generic interfaces are defined using square brackets after the interface name containing the parameter types:
This interface can be implemented by any data type that implements the has_next()
and next()
methods.
A struct can also be generic:
Or not:
Note that in this case the compiler will not be able to calculate the type when calling each()
and must be specified explicitly.
At the moment, methods declared in the interface cannot have their own parameter types:
Compile-time conditions
Due to the fact that V has compile-time if
, in the body of
generic functions, you can separate the code depending on the type passed:
Under the hood
In V, generics are implemented using compile-time code generation for each parameter type. This means that generics do not add any execution time to your program.