Templates

The basic “new idea” is, to define templates (classes and functions) mostly the same as they are used.
Similar as in Java, C#, Swift and Rust.

Class Templates

The template parameters (<...>) are given after the class name, so that the definition is similar to the usage (in a variable declaration).

class MyArray<Number T> {
    T* numbers = NullPtr
    Int size = 0
}

Function Templates

Requires

Further restrict the type with requires (as in C++):

func sq<Number T>(T x) -> T
requires (T x) { x * x }
{
    return x * x
}
class SlidingAverage<type T, type TSum = T>
requires (T x, TSum sum) {
    sum = 0   // requires assignment of 0
    sum += x  // requires addition of type T to type TSum
    sum -= x  // requires subtraction of type T from type TSum
    sum / 1   // requires to divide sum by 1 (i.e. an Int)
} {
    T+ numbers
    Int size = 0
    Int sizeMax = 0
    Int index = 0
    TSum sum = 0
public:
    SlidingAverage(Int size) {
        sizeMax = size
        numbers = new T[sizeMax]
    }
    func append(T value) { ... }
    func average() -> TSum { ... }
    func reset() { ... }
    func reset(Int newSize) { ... }
}

Extension Templates

Template type alias with using (not typedef):

extension<type T> T {
    using InParameterType = const T&
}

Template static constants as type traits:

extension<type T>          T { Bool IsFloatingPoint = False }
extension            Float32 { Bool IsFloatingPoint = True }
extension            Float64 { Bool IsFloatingPoint = True }
extension<type T> Complex<T> { Bool IsFloatingPoint = T::IsFloatingPoint }

Same Rules for ADL & PTS as in C++

Cilia follows the same rules for ADL and PTS as C++. While they are complex, their problems are “well known and understood”, and matching C++ semantics is important for interop with existing C++ APIs and libraries. I try to avoid having different rules for Cilia and C++ classes.

Argument Dependent Lookup (ADL)

ADL (Koenig Lookup) lets generic code find overloads in the namespace of the argument types, so helps to customize operator<<, unqualified begin()/end(), swap(), etc.

Problems:

The problems with ADL are reduced a bit, as

Partial Template Specialization (PTS)

PTS is a practical way to customize behavior for families of types (for example traits and container-like wrappers) without rewriting full implementations.

Problems: