8.12

3.4 Binding and Annotation Macros🔗ℹ

Macros can extend binding-position syntax, too, via bind.macro. In the simplest case, a binding operator is implemented by expanding to other binding operators, like this definition of $$$ as a prefix operator to constrain a pattern to number inputs:

import:

  rhombus/meta open

bind.macro '$$$ $n':

  '$n :: Number'

> def $$$salary = 100.0

> salary

100.0

More expressive binding operators can use a lower-level protocol where a binding is represented by transformers that generate checking and binding code. It gets complicated, and it’s tied up with the propagation of static information, so the details are in Binding Low-Level Protocol. After an expressive set of binding forms are implemented with the low-level interface, however, many others can be implemented though simple expansion.

The annot.macro form is similar to bind.macro, but for annotations.

use_static

 

annot.macro 'PosnList': 'List.of(Posn)'

 

fun nth_x(ps :~ PosnList, n):

  ps[n].x

For details on the low-level annotation protocol, see Annotations and Static Information.