Annotations

Annotations can be attached to any declarations, and purpose to be used as directive or metadata by target compiler or runtime library.

Each annotation starts with an @ character, and its name follows, e.g., @foo. Annotation names have the same rule to other Nirum identifiers, but there’s no separation of facial and behind names.

There are annotations defined and used by a target compiler, or more than one targets. If an annotation that no target defined is used, they are merely no-op (i.e., ignored and even not errored).

Nirum annotations are similar to Java’s one or C#’s attributes.

Declarations

All declarations in Nirum can attach annotations. Declarations in Nirum mean things that have their own name, e.g., imports, records, fields, union tags, service methods, method parameters. In other words, any things that can have docs comments also can have annotations.

Each declaration is allowed to have multiple annotations, but their name cannot be duplicated.

For example, the following code is allowed:

@foo
@bar(baz = "qux")
unboxed filename (text);

Whereas the following code is disallowed:

@foo
@foo(baz = "qux")  // `foo` is duplicated
unboxed filename (text);

Arguments

Annotations have zero or more arguments. Every parameter is named, and names cannot be duplicated in an annotation. Annotation arguments follow an annotation name and are wrapped by parentheses. An = operator is placed between each parameter name and its argument value. Arguments are separated by a comma, and an optional trailing comma is also allowed. E.g.:

@foo()
@bar(baz = "qux")
@quux(corge = "grault", garply = "waldo", fred = "plugh",)
unboxed filename (text);

Currently, argument values are only allowed to be a text (which is wrapped by double quotes), but they could be extended to other types (e.g., integer). Note that C-style escape sequences work between double quotes, e.g.:

@foo(bar = "Escape double quotes (\") with backslashes (\\).")
unboxed filename (text);

Common annotations

The following annotations are common among more than one target languages. For target-specific annotations, read each target’s docs.

@docs (docs)

@docs annotations represent docs comments (# ...). The following two examples are equivalent, and the former is internally transformed to the latter:

# Docs comments are transformed to `@docs` annotations.
unboxed filename (text);
@docs(docs = "Docs comments are transformed to `@docs` annotations.\n")
unboxed filename (text);

It is primarily for simplifying internal syntax tree, but can be used at runtime for other purposes.

Since all docs comments become transformed to @docs annotations, a declaration cannot have both a docs comment and a @docs annotation at a time.

docs : A docs text.

@error

Many object-oriented languages (e.g., Java, Python) require exception classes to inherit a specific base class (e.g., Exception) to be thrown. @error annotation is a hint for such languages to make a record or a union to inherit that.

For example, the following first Nirum code is compiled to the second Python code:

@error
union file-error = file-not-found
                 | file-not-readable
                 ;
class FileError(Exception):
    ...

class FileNotFound(FileError):
    ...

class FileNotReadable(FileError):
    ...