-
Notifications
You must be signed in to change notification settings - Fork 0
Template Meta Programming
Ergoline features a full suite of template meta-programming features enabling it to manipulate types in sophisticated ways.
Ergoline borrows Scala's upper-bound (<:) and lower-bound (>:) operators.
class birds_only<A <: bird> { ... }
trait bird { ... }
class duck with bird { ... }
class squid ...
...
birds_only<squid> // WILL FAIL
birds_only<duck> // OK!
Like C# and Swift, Ergoline has a where keyword for selectively enabling specializables depending on a specialization's type parameters. This functionality closely relates to C++'s std::enable_if. Note, relational operators are translated to implicit where-clauses.
Like C++, Ergoline can also use "facades" to represent constants as types. For example, a class may have an int as one of its type parameters.
class foo<N : int> where N > 0 { ... }
foo<0> // WILL FAIL
foo<1> // OK!
Ergoline can form tuple types using the .* operator, for example (int) .* 3 corresponds to (int, int, int).
When multiple specializables match a specialization, they are ordered as follows:
- Those without Where-Clauses or Template Args.
- Those with both Template-Args and Where-Clauses.
- Those with Template-Args and without Where-Clauses.
For example, in the following situation:
trait bar { ... }
class foo extends bar { ... }
def baz(f: foo) { ... } // (1)
def baz<A <: bar>(a: A) { ... } // (2)
def baz<A>(a: A) { ... } // (3)
Thus, a call to baz would resolve as (1); calls would resolve to (2) if (1) is removed.
Note, replacing (1) with the following definition would cause an irreconcilable ambiguity:
def baz<A>(a: A) where a == foo { ... }
In the future, this could be resolved if a mechanism for simplifying function definitions is added (rewriting the above to (1)).