Static Typing

Felix uses a static typing system which features:

  • anonymous variants (sums), tuples (products), and function (exponential) types
  • structurally typed records with labeled fields
  • nominally typed structs (products) and unions (sums) and classes
  • first order extensional parametric polymorphism
  • multi-parameter type classes for ad-hoc polymorphism
  • C++ style overloading for ad-hoc polymorphism
  • bottom up type deduction but no inference

Add C++ Types as Primitives

Felix provides a unique method for introducing new primitive types: they're defined inline in terms of C++ types. For example:

type complex = "std::complex<double>" requires header "#include <complex>";
fun _ctor_complex: double * double -> complex = "std::complex($1,$2)";
fun abs: complex -> double = "abs($1)";
fun arg: complex -> double = "arg($1)";
//
val z = complex(1.0,2.0);
print "abs="; print (abs z); print "arg="; print (arg z); endl;

introduces a new abstract type and methods to access it. The requires clause specifies that the code generator must emit a #include for the C++ complex library functions if the Felix type complex is used in your program. The special function name _ctor_complex indicates a constructor invoked by using the type name as a function.

Create an Abstract Type in Felix

Abstract types can also be defined in Felix like:

module X {
  type ii = new int;
  fun mkii(x:int):ii=> _make_ii x;
  fun get(x:ii):int=>_repr_ x;
}

where the _make_* and _repr_ functions are private to the current module.