Fuzion Logo
flang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.
Fuzion LanguageTutorialData-less Types

Data-less Types

TBW! Data-less types can be used to structure an application similar to Java/C# packages as a means of encapsulation and information hiding. Also, they can be used to avoid overhead since assigning a data-less value type is a NOP. Used as a generic argument, one can use these types to specialize code.

An example, that does not work yet: The data-less features sum and product are used to specialize the generic feature accum to calculate the total sum or the total product of an array if integers.

Demo
{
  monoid<T>
  {
    abstract zero T;
    abstract add (a, b T) T;
  }

  accum<T> (a Array<T>, m monoid<T>) T
  {
    for
      result = m.zero, m.add(result, x);
      x in a;
  }

  sum : monoid<i32>
  {
    zero => 0;
    add (a, b i32) => a + b;
  }

  product : monoid<i32>
  {
    zero => 1;
    add (a, b i32) => a * b;
  }

  i32array := [ 23, 345 , 3, 1, 3 ];
  totalSum     := accum<i32>(i32array, sum)
  totalProduct := accum<i32>(i32array, product)
}

The fuzion compiler will specialize the calls to accum and produce code similar to the following, the data-less instances of sum and product disappear:

Demo
{
  accumSum (a Array<i32>) i32
  {
    for
      result = 0, result + x;
      x in a;
  }

  accumProduct (a Array<i32>) i32
  {
    for
      result = 1, result * x;
      x in a;
  }

  i32array := [ 23, 345 , 3, 1, 3 ];
  totalSum     := accumSum(i32array)
  totalProduct := accumProduct(i32array)

}

Another Application of data-less types are library features. Say you have a set of trigonometry functions:

trigo
{
  sin(a f64) f64 { ... }
  cos(a f64) f64 { ... }
  tan(a f64) f64 { ... }
}

These can now be called using their qualified name

complex (r f64, theta f64)
{
  x => r * trigo.cos(theta);
  y => r * trigo.sin(theta);
}

Alternatively, by making complex inherit from trigo, we can add all of its features to our name space:

complex (r f64, theta f64) : trigo
{
  x => r * cos(theta);
  y => r * sin(theta);
}

In case complex is exported as a public part of a module, we might not want to expose the fact that it inherits from trigo for implementation purposes, so we can inherit privately:

public complex (r f64, theta f64) : private trigo
{
  x => r * cos(theta);
  y => r * sin(theta);
}