A major design goal of Fuzion is to unify different concepts into the single concept of a Fuzion feature. This makes a Fuzion feature a very powerful mechanism. Nevertheless, Fuzion features are not all the same, there are different kinds of features and what can be done with one feature might not be possible with a different kind of feature. The following table gives an overview of what is can be done with features of different kinds.
But first, let's see what all features have in common
What all features have in common
All features declared in Fuzion have a feature name. The name is typically
just an identifier such as
execute, or an operand such
All features are declared within the context of an outer feature. This outer
feature might is the feature that syntactically surrounds the feature
declaration. In case there is no explicit feature surrounding a feature
declaration, the outer feature is the implicit feature called
Differences between Feature Kinds
Fuzion Features are of one of several kinds and not all features can be used in every context. This gives an overview of the feature kinds and what they can do.
|Defines Type||✅ Yes||✅ Yes1||❌ No||❌ No||❌ No||✅ Yes||✅ Yes|
|May contain code||✅ Yes||✅ Yes||❌ No||❌ No||❌ No||❌ No||✅ Yes|
|May contain declarations||✅ Yes||✅ Yes||❌ No||❌ No||❌ No||✅ Yes2||✅ Yes|
|May be redefined||❌ No3||✅ Yes||✅ Yes||✅ Yes||✅ Yes||❌ No||❌ No3|
|May redefine||✅ Yes4||✅ Yes||✅ Yes||✅ Yes||✅ Yes||❌ No||✅ Yes4|
|May have formal arguments||✅ Yes||✅ Yes||❌ No||✅ Yes||✅ Yes||❌ No||✅ Yes|
|Has explicit result type||❌ No||✅ Yes5||✅ Yes5||✅ Yes||✅ Yes||❌ No||❌ No|
|May have formal type arguments||✅ Yes||✅ Yes||❌ No||✅ Yes||✅ Yes||✅ Yes||✅ Yes|
|May be called||✅ Yes||✅ Yes||✅ Yes||✅ Yes||❌ No||❌ No||✅ Yes6|
|May be assigned to||❌ No||❌ No||✅ Yes||❌ No||❌ No||❌ No||❌ No|
|May be called in inheritance clause||✅ Yes||❌ No||❌ No||❌ No||❌ No||❌ No||✅ Yes|
|May inherit||✅ Yes||✅ Yes||❌ No||❌ No||❌ No||❌ No||✅ Yes|
1The inner type of a routine is anonymous, so it cannot be used in declarations.
2Inner features may be constructors or routines, not fields.
3Redefinition would require dynamic binding in inherits call which results in trouble since different targets in that call would result in different features inherited.
4Requires type defined by constructor to be compatible to result type of redefined feature.
5Result type may be inferred from returned or assigned expression.
6There are even two ways to call a function: Calling its constructor and calling its inner feature
Defining a Type
One restriction, however, is that typ names must not be ambiguous, i.e., overloading for constructors results in the corresponding types to be no longer usable since Fuzion does not permit a means to disambiguate overloaded types:
A routine does define a type, but this type is anonymous, i.e., it does not have a name that we could use in a declaration. However, type inference can be used to create features using a routine's type:
An instance of a routine's implicit type can even exist longer than the routine's call itself. Here is an example that shows a routine in a closure that extends the life span of the routine's instance until after the call to the routine has returned:
Negative example: using a routine's name explicitly as a type does not work since a routine does not define a name for its type:
Positive example declarations:
Negative example declaring a field:
Positive example with compatible types:
Negative example with incompatible types: