4.6 Binding and Annotation
When a constructor clause creates a constructor that is different enough from the default one, then the binding and annotation forms associated with the class name also should be updated. The binding and annotation clause forms support that customization. Binding and annotation are customized by macros, and similar to constructor customization, they work by relying on an underlying binding or annotation form. But instead of having a super that is mapped to the underlying forms, binding and annotation customization rely on an internal clause to give a name to the more primitive form, and then that name can be used in an example.
For example, suppose we customize the constructor for a Sandwich class to accept any number of arguments, instead of having the user put those arguments into a list. That is, we want users to write Sandwich("pb", "j") instead of Sandwich(["pb", "j"]). To make pattern-matching binding consistent with that choice, we should also customize the binding, so that Sandwich(top, bottom) would match instead of Sandwich([top, bottom]). Similarly, Sandwich.of(String) would be preferable to Sandwich.of(List.of(String)), which requires adding an of annotation form that is exported from Sandwich as a namespace.
The customization shown below defines _Sandwich with internal so that it can be used in the binding and annotation expansion:
class Sandwich(ingredients):
internal _Sandwich
constructor (ingredient, ...):
annotation 'Sandwich':
'_Sandwich'
annot.macro 'of($ingredient)':
export:
of
> top
"bacon"
> blt is_a Sandwich
#true
#false
When a class has a superclass, the super constructor function
is curried for customizing a subclass constructor. The name bound by
internal can be used as a constructor, and it is
curried in the same way as super—
An internal name for a subclass is not curried as a binding or annotation form. Instead, it always refers to just the immediate fields of the class. A superclass binding or annotation can be combined with an internal binding or annotation using the && binding operator or && annotation operator.
class Sub(inches):
extends Sandwich
internal _Sub
constructor (~inches: inches, ingredient, ...):
annotation 'Sub':
'_Sub'
annot.macro 'of($ingredient)':
export:
of