9.4. Named augmentations

It is possible for augmentations to have a name. A named augmentation is a set of functions that can be applied to some classes or structures.

This can be seen as a kind of lightweight traits [1] , or mixin [2], as found in Rust, Groovy or Scala.

Named augmentations are defined with the augmentation keyword.

As an example:

augmentation FooBar = {
  function foo = |this| -> "foo"
  function bar = |this, a| -> this: length() + a
}

augmentation Spamable = {
  function spam = |this| -> "spam"
}

A named augmentation is applied using the augment ... with construct, as in

augment java.util.Collection with FooBar

augment MyStruct with Spamable

augment java.lang.String with FooBar, Spamable

When applying several named augmentations, they are used in the application order. For instance, if AugmentA and AugmentB define both the method meth, and we augment augment java.lang.String with AugmentA, AugmentB, then calling "": meth() will call AugmentA::meth.

Augmentation rules about scopes and reusability apply. So, if we create a module

module MyAugmentations

augmentation Searchable = {
  function search = |this, value| -> ...
}

augment java.util.Collection with Searchable

and import it, we can use the applied augmentation

import MyAugmentations

#...
list[1, 2, 3, 4]: search(2)

The augmentations defined in an other module can also be applied, provided they are fully qualified or the module is imported:

augment java.lang.String with MyAugmentations.Searchable

or

import MyAugmentations

augment java.lang.String with Searchable

Note

If several imported modules define augmentations with the same name, the first imported one will be used.

The validity of the application is not checked at compile time. Thus augmenting without importing the coresponding module, as in:

augment java.lang.String with Searchable

will not raise an error, but trying to call search on a String will throw a java.lang.NoSuchMethodError: class java.lang.String::search at runtime.

Important

As for every augmentation, no checks are made that the augmentation can be applied to the augmented class. For instance, augmenting java.lang.Number with the previous FooBar augmentation will raise java.lang.NoSuchMethodError: class java.lang.Integer::length at runtime when trying to call 1:bar(1). Calling 1:foo() will be OK however.