Generics
A procedure that finds the larger of two values is the same code for integers, floating-point numbers and strings. A generic lets you write it once, with a placeholder for the type, and the compiler builds a separate, fully checked version for each type you use it with.
'' One definition of Larger serves every type that has a '>'.
function Larger( of T )( byval a as T, byval b as T ) as T
if a > b then return a
return b
end function
print Larger( 3, 9 ) '' T is an integer here...
print Larger( 2.5, -1.0 ) '' ...a float64 here...
dim as ustring early = "apple", late = "pear"
print Larger( early, late ) '' ...and a ustring here
Output
9
2.5
pear
( of T ) after the procedure's name declares a type parameter, T, and
from then on T can appear anywhere a type can: in the parameters, the result
and the body. Each call above passes two values of one type, so the compiler
works out T from the arguments and builds Larger for that type.
The result is as fast and as strictly typed as a version you wrote by hand for
each type: there is no conversion to a common type and no check at run time.
What you pay is code size, since each distinct T is a separate copy.
This section covers:
- Generic types: a
Stackthat holds any element type. - Explicit type arguments: writing
( of T )yourself, and naming an instantiation withtype ... as. - What a type parameter asks for: the error you get when a type lacks an operator the generic uses.
- Library demands: Hashable keys: making your own type a
Mapkey. - Generics and lambdas: passing any callable to a generic.
Activities
- Write
Smaller( of T )and call it with three different types. - Call
Largerwith austringvariable and a string literal, and read the error. What does it tell you about howTis chosen?