Custom Annotations & Scope Injection
Flame empowers systems engineers to declare custom annotations using the annotation keyword. Annotations in Flame are first-class runtime and compile-time constructs: they accept typed parameters, execute initialization logic, and return data that is automatically injected directly into the decorated function’s local scope.
1. Defining Custom Annotations
Section titled “1. Defining Custom Annotations”[!IMPORTANT] Naming Convention: Custom annotations must begin with an uppercase letter (e.g.,
Logger, notlogger). The compiler enforces this via a mandatory lint rule to ensure annotations remain easily distinguishable from standard functions.
You define custom annotations using the annotation keyword, specifying parameters and an explicit return type:
// Declare an annotation that returns a formatted logger prefix stringexport annotation Logger(prefix: String) -> String { return $"[{prefix}] "}
// Declare an annotation that initializes a route configuration formulaexport annotation Route(method: String, path: String) -> Formula { return formula { method: method, path: path, timestamp: 1785940000 }}2. Automatic Value Injection into Functions
Section titled “2. Automatic Value Injection into Functions”When you decorate a function with a custom annotation, Flame evaluates the annotation at runtime and automatically injects the returned value directly into the function’s local scope as a mutable variable named after the annotation (accessible via lowercase or PascalCase):
@Logger("AUTH_SERVICE")fn authenticate_user(username: String) { // 'logger' (or 'Logger') is automatically available in local scope from @Logger! print(logger + "Authenticating user: " + username)
// The injected variable is mutable and can be dynamically modified in scope logger = logger + "[SECURE] " print(logger + "Access granted.")}
authenticate_user("admin")Output:
Section titled “Output:”[AUTH_SERVICE] Authenticating user: admin[AUTH_SERVICE] [SECURE] Access granted.3. Mutable State & Complex Formula Injection
Section titled “3. Mutable State & Complex Formula Injection”Custom annotations can return complex formulas, structs, or state containers, making them invaluable for middleware pipelines and contextual dependency injection:
export annotation Context(service_name: String) -> Formula { return formula { service: service_name, request_count: 0 }}
@Context("PAYMENT_GATEWAY")fn process_transaction(amount: Float) { // Access formula properties directly from the injected 'context' variable context.request_count += 1 print($"Service: {context.service}, Requests: {context.request_count}, Amount: ${amount}")}
process_transaction(99.95)4. Built-in Annotations & CLI Synthesis
Section titled “4. Built-in Annotations & CLI Synthesis”Flame also comes packed with native annotations for testing (@Test, @Setup, @Cleanup) and declarative CLI building (@Cli, @Command).
To learn how to use @Cli and @Command to assemble powerful interactive system utilities and subcommands with zero boilerplate, visit the comprehensive reference on Built-in Annotations & CLI Builder.
