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

Defining global data

There are two aspects here: First, really global data as in Java's static fields or singleton instances, and data that belongs to a given type but cannot be defined within the feature that defines that type because it has to be accessible from the outside as well.

Other languages

static fields

Java, C, etc. provide a modifier static to declare a field that exists only once and becomes accessible globally, causing all sorts of problems since it can be changed from any place, causing all sorts of bugs, in the worst case races conditions.

once functions

Eiffel provides a modifier once for features that are executed only once and return the original result on later calls. They essentially behave like a single static field in its own class in Java that gets initialized when it is first read. Race conditions are controlled a little better since access is read only, but if the result is a reference, we may produce races when modifying the resulting singleton instance.

Global elements via defines section

We need some mechanism to declare inner features that do not depend on instances of the feature they are declared in, but which could very well depend on an outer feature. Examples are the constants zero and one in numeric or the identity element in monoid:

  # identity element
  e T => abstract

It should be possible to use such a global element also via a formal generic argument, i.e., a constrained generic argument T: monoid should allow a call to T.e to get the identity element. If the actual generic argument for T is x.y.z, then T.e should execute x.y.z.e within the outer instance x.y. An open question is if any fields of x and y should be accessible by x.y.z.e since this would require identifying and storing the desired instance of y.

Defining outer elements via defines section

One way to achieve this is by using a specific clause defines (or maybe has, static, outer) that declares features that end up in the outer feature but are accessible through <outer>.monoid.e:

monoid(T monoid.type)

  # identity element
  e T => abstract


  # associative operation
  infix + (other T) T => abstract

Open questions:

  • should state of outer features be accessible from features declared in defines clause?
  • should fields be allowed to be declared in the defines clause?
  • should statements be allowed in defines clause?
  • if fields or statements are allowed, when should they be executed?

Global elements

Outer elements are not global, they are local to the outer instance. As long as this instance is not a singleton, these are elements that are local to the outer feature.

Do we need more? What for?