On this page:
annot
annot_  meta.space
annot.macro
annot_  meta.is_  predicate
annot_  meta.pack_  predicate
annot_  meta.unpack_  predicate
annot_  meta.is_  converter
annot_  meta.pack_  converter
annot_  meta.unpack_  converter
annot_  meta.parse_  to_  packed_  statinfo
annot.delayed_  declare
annot.delayed_  complete
annot_  meta.Parsed
annot_  meta.After  Prefix  Parsed
annot_  meta.After  Infix  Parsed
annot_  meta.Name  Start
annot_  meta.relative_  precedence
annot_  meta.ends_  parse
annot_  meta.Context
annot_  meta.Dependencies
8.17.0.1

3.7 Annotation Macros🔗ℹ

space

annot

The space for bindings of identifiers and operators that can be used in annotation, such as after ::.

Provided as meta.

A compile-time value that identifies the same space as annot. See also SpaceMeta.

definition

annot.macro macro_patterns

 

more_options

 = 

~context id

 | 

~context: id

Like expr.macro, but defines an identifier or operator as an annotation form in the annot space. The result of the macro expansion can be a result created with annot_meta.pack_predicate.

In addition to the option forms supported by expr.macro, annot.macro supports a ~context option, which declares an identifier be bound to context information. Context is represented by a annot_meta.Context object, which records argument names that can be referenced by Any.like, for example. Normally, when nested annotations are parsed directly via annot_meta.Parsed and similar, the same context object should be passed along.

> annot.macro 'two_of($ann)':

    'matching(List(_ :: $ann, _ :: $ann))'

> [1, 2] :: two_of(Number)

[1, 2]

> [1, 2, 3] :: two_of(Number)

::: value does not satisfy annotation

  value: [1, 2, 3]

  annotation: two_of(Number)

> [1, "x"] :: two_of(Number)

::: value does not satisfy annotation

  value: [1, "x"]

  annotation: two_of(Number)

function

fun annot_meta.is_predicate(stx :: Syntax) :: Boolean

 

function

fun annot_meta.pack_predicate(fun_stx :: Syntax,

                              statinfo_stx :: Syntax = '()')

  :: Syntax

 

function

fun annot_meta.unpack_predicate(stx :: Syntax)

  :: (Syntax, Syntax)

Provided as meta.

The annot_meta.is_predicate function determines whether a syntax object represents a parsed predicate annotation. This function and annot_meta.unpack_predicate are potentially useful on the result of matching annot_meta.Parsed.

The annot_meta.pack_predicate function packs an expression for a predicate with static information into an annotation form as a syntax object. When the resulting annotation is applied to a value, it checks the value using the predicate, and it also associates the static information in statinfo_stx with the value. The given statinfo_stx is in unpacked form (i.e., statinfo_meta.pack is applied automatically).

The annot_meta.unpack_predicate function is the inverse of annot_meta.pack_predicate, returning two values: an expression and unpacked static information.

See Annotations as Converters for more explanation and for examples.

function

fun annot_meta.is_converter(stx :: Syntax) :: Boolean

 

function

fun annot_meta.pack_converter(bind_stx :: Syntax,

                              body_stx :: Syntax,

                              statinfo_stx :: Syntax = '()')

  :: Syntax

 

function

fun annot_meta.unpack_converter(stx :: Syntax)

  :: (Syntax, Syntax, Syntax)

Provided as meta.

The annot_meta.is_converter function determines whether a syntax object represents a parsed converter annotation. This function and annot_meta.unpack_converter are potentially useful on the result of matching annot_meta.Parsed.

The annot_meta.pack_converter function packs a binding, a body expression (that can refer to bindings), and static information into a converter annotation form as a syntax object. When the resulting annotation is applied to a value, it uses the binding to determine whether the value satisfies the predicate, and if so (and if the converted result is needed), the body expression is evaluated to obtain the converted value. It also associates the static information in statinfo_stx with the converted value. The given statinfo_stx is in unpacked form (i.e., statinfo_meta.pack is applied automatically).

The annot_meta.unpack_converter function is the inverse of annot_meta.pack_converter, returning three values: a binding, an expression, and unpacked static information. The annot_meta.unpack_converter function will also unpack a predicate annotation, automatically generalizing it to a converter annotation.

See Annotations as Converters for more explanation.

Provided as meta.

A convenience function that parses stx as an annotation and returns just its static-information component in packed form.

Last-resort forms for solving mutual-dependency problems among annotations. The annot.delayed_declare form declares an annotation, and the annot.delayed_complete form mutates a declaration to make it equivalent to as_annot.

A completed delayed annotation need not be declared in the same module or definition context, which is why annot.delayed_complete allows an id_name. See Namespaces form more information on id_name.

If a value is tested against a delayed annotation id before it is completed via annot.delayed_complete at run time, then an exception is reported. At compile time, attempting to use the static information associated id throws a syntax error until it is completed via annot.delayed_complete.

These forms should be used as last resort, because they inherently involve a side effect, and because that effect is potentially across module boundaries. When a module uses an imported delayed annotation, the run-time component of that delayed annotation might be initialized as a side effect of requiring some other module, which potentially makes the reference fragile. Delayed annotations are suitable for use inside a library that is implemented by multiple private modules that are aggregated into a single library as the public interface.

> annot.delayed_declare Forward

> class Posn(x, y)

> Posn(1, 2) :: Forward

Forward: delayed annotation is not yet completed

> block:

    use_static

    fun (p :: Forward): p.x

Forward: annotation static information needed before completed

> annot.delayed_complete Forward: Posn

> Posn(1, 2) :: Forward

Posn(1, 2)

> block:

    use_static

    fun (p :: Forward): p.x

#<function:fun>

syntax class

syntax_class annot_meta.Parsed(ctx = annot_meta.Context.empty):

  kind: ~group

  fields:

    group

 

syntax class

syntax_class annot_meta.AfterPrefixParsed(op_name,

                                          ctx = annot_meta.Context.empty):

  kind: ~group

  fields:

    group

    [tail, ...]

 

syntax class

syntax_class annot_meta.AfterInfixParsed(op_name,

                                         ctx = annot_meta.Context.empty):

  kind: ~group

  fields:

    group

    [tail, ...]

 

syntax class

syntax_class annot_meta.NameStart:

  kind: ~group

  fields:

    name

    [head, ...]

    [tail, ...]

Provided as meta.

Analogous to expr_meta.Parsed, etc., but for annotations.

Unlike expr_meta.Parsed, an optional annot_meta.Context argument can supply context information—including argument names that can be referenced by Any.like, for example.

function

fun annot_meta.relative_precedence(left_mode :: matching(#'prefix || #'infix),

                                   left_op :: Name,

                                   right_infix_op :: Name)

  :: matching(#'weaker || #'stronger || #false)

 

function

fun annot_meta.ends_parse(left_mode :: matching(#'prefix || #'infix),

                          left_op :: Name,

                          tail :: Group) :: Boolean

Provided as meta.

Like expr_meta.relative_precedence and expr_meta.ends_parse, but for annotation operators.

Provided as meta.

An annot_meta.Context object represents the syntactic context of an annotation form. The argument_names map is empty and this_position is #false in the default context annot_meta.Context.empty.

The keys of the argument_names map are identifiers. An identifier received by an annotation macro typically must be “unintroduced” by syntax_meta.flip_introduce to find it in the map.

Each value in the map or in the this_position field is a positions, one of the following:

Note that a function form’s argument may not all have names that can be referenced, so annot_meta.Context object does not necessarily represent all arguments to a function.

Provided as meta.

An annot_meta.Context object represents static information for actual arguments of a function call as passed to a bridge function encoded in a statinfo_meta.dependent_result_key value by statinfo_meta.pack_dependent_result.

The arguments list holds static information for the by-position arguments—at least, up to the point that an argument repetition or splice (of an unknown length) is encountered.

The keyword_arguments list holds static information for the by-keyword arguments, not including any keywords supplied through a keyword-argument splice.

The has_more_arguments and has_more_keyword_arguments fields effectively report whether arguments and keyword_arguments are an incomplete enumeration of actual argument due to repetitions and splices.