Fuzion Logo
fuzion-lang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

Fixed Features

Motivation

Co-variant argument and result type changes using this.type pose problems with inheritance: An implementation of an abstract feature must be generic to work with all possible heirs of this.type, which makes it impossible to, e.g., create return instances of this.type since the actual type of any possible heir cannot be known.

As an example, take numeric that provides co-variant features such as infix + as follows:

numeric is

  ...

  infix +(b numeric.this.type) numeric.this.type => abstract

Now, an heir of numeric such as i32 would like to implement infix + for 32-bit integer values:

i32(val i32) : numeric is

  ...

  infix +(b i32) i32 =>
    add_i32_intrinsic i32.this b

Now imagine we have an heir of i32 as follows

colorful_i32(redef val i32,
                   col color) : i32 val is
  ...

The problem is that an heir colorful_i32 of i32 cannot use this implementation since that heir's version of infix + should have an argument and result type colorful_i32, not i32.

Fixed Features

The idea of a solution is to add a modifier fixed to declare that a given feature would be fixed to a specific outer feature and not be inherited by heirs of that outer feature.

In the previous example, implementations would then be marked as fixed as follows

i32(val i32) : numeric is

  ...

  fixed infix +(b i32) i32 =>
    add_i32_intrinsic i32.this b

Now imagine we have an heir of i32 as follows

colorful_i32(redef val i32,
                    col color) : i32 val is

  ...

  fixed infix +(b colorful_i32) colorful_i32 =>
    colorful_i32 val+b.val (col.additive_mix b.col)

Rules

For this to be useful, it might make sense to enforce the following rules:

  • A feature declared with modifier fixed
    • does not get inherited by heir features of their outer feature
    • does redefine inherited features of ancestors of their outer feature
  • When features a inherits from b and b inherits from c where c declares feature c.f which is redefined in b by fixed b.f, then a ignores b.f and inherits c.f instead.
  • In a fixed feature, this.type for the enclosing feature may be replaced by the actual type of the outer feature.