Skip to content

Template Meta Programming

Justin Szaday edited this page Jul 5, 2021 · 4 revisions

Ergoline features a full suite of template meta-programming features enabling it to manipulate types in sophisticated ways.

Relational Constraints

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!

Where-Clauses

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.

Constants

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!

Tuple Multiplication

Ergoline can form tuple types using the .* operator, for example (int) .* 3 corresponds to (int, int, int).

Disambiguation

When multiple specializables match a specialization, they are ordered as follows:

  1. Those without Where-Clauses or Template Args.
  2. Those with both Template-Args and Where-Clauses.
  3. 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)).

Clone this wiki locally