3.4. Generic functions

Like C++, Felix supports template style generic functions. The rule for selection of a function in the presence of generics is a generalisation of the rules for generic functions. Note that we use the term 'type variable' instead of 'template type parameter'.

Felix first looks in the current scope to see if an function matches the call. A call matches a generic function if there is a binding to the type variables of the generic function such that the argument of the call matches the function parameter type exactly: this reduces to the exact match rule when there are no type variables.

If there are no matches, Felix proceeds to the next outermost scope and tries again, until there is no such scope.

If there are more than one match, then Felix chooses the most specialised function if there is one, otherwise the call is ambiguous. A function is more specialised than another if every argument it accepts is also accepted by the other, and the other also accepts at least one additional argument. For example:

Start C++ section to tut/examples/mig02.flx[1 /1 ]
     1: include "std";
     2: fun f[t,u] (x:t,y:u)=> 1; //1
     3: fun f[v] (x:v,y:v)=>2; //2: specialises 1
     4: 
     5: print (f (1,2.0)); endl; //calls 1
     6: print (f (1,2)); endl; //calls 2
     7: 
End C++ section to tut/examples/mig02.flx[1]
Note however that the innermost matching function is still called, even if a specialisation is present in an outer scope.

The algorithm which determines whether an argument matches a generic function's parameter, and also whether a function is more specialised than another, is known as the unification algorithm, and the process of matching is known as unification.