Patterns may be parameterized by listing the types to paraeterize after the name in angle brackets as:
public class List<τ>
{
public abstract operator..<ρ, α
..., ε
...>(v :ListVisitor<τ, ρ, α
..., ε
...>, α
...) -> ρ throws ε
...;
}
public interface ListVisitor<τ, ρ, α
..., ε
...>
{
public whenNull(host :NullList, α
...) -> ρ throws ε
...;
public whenNonNull(host :NonNullList<τ>, α
...) -> ρ throws ε
...;
}
public class NonNullList<τ> :List<τ>
{
_first :τ;
_rest :List<τ>;
public operator..<ρ, α
..., ε
...>(v :ListVisitor<τ, ρ, α
..., ε
...>, α
...) -> ρ throws ε
...
{
return v.whenNonNull(this, α
...);
}
public get rest() -> List<τ>
{
return _rest;
}
public get first() -> τ
{
return _first;
}
}
public NullList :List<Any>
{
public operator..<ρ, α
..., ε
...>(v :ListVisitor<τ, ρ, α
..., ε
...>, α
...) -> ρ throws ε
...
{
return v.whenNull(this, α
...);
}
}
public class SumVisitor ::ListVisitor<int, int, void, void>
{
public whenNull(host :NullList) -> int
{
return 0;
}
public whenMonNull(host :NonNullList<int>) -> int
{
return host.first+host.rest..this();
}
}
public class DemoVisitor ::ListVisitor<InStream, void, (int, Object), (EOFException, IOException)>
{
public whenNull(host :NullList, bufferSize :int, data :Object) -> void throws EOFException, IOException
{
return;
}
public whenNonNull(host :NonNullList<InStream>, bufferSize :int, data :Object) -> void throws EOFException, IOException
{
// do whatever
}
}
This operates very much like java generics. One key difference is that you have the full runtime support of the parametric type, so you may do anything you might with any other type, including reflect upon it. Void may be used as a type parameter to indicate the absence of some entity. This makes the most sense for return types but is also allowed in other cases in which case it causes the ommison of a type. In additon the type 'Any
' may be used once in a super type to indicate that this is a subclasses of any such entities not just the specific one. Taking parameters of type any is like taking parameters of type object. It is not possible to return something of the type any unless it was passed to you. Properties of type any are problematic. Another feature is type lists, these are idicated by the triple dots '...
' after the type name. Any such thing forms a type list. Type lists then may be used where other type lists were expected or in parameters. If a method takes a type list then that name may be used within a method to mean passing all those parameters to the object. This must be safe at compile time. Type lists may be specfied by inheriting patterns or overiding patterns by listing the types in parens as a tuple type.