Function Attributes & Metaprogramming
Relevant source files
The following files were used as context for generating this wiki page:
Sploosh utilizes a declarative attribute system as its primary surface for metaprogramming and compiler directives. In alignment with the project's design philosophy of "One way to do everything," arbitrary metaprogramming, macros, and reflection are explicitly excluded from the language. Instead, attributes serve as the sole mechanism for modifying the behavior of functions, actors, and modules, particularly for specialized targets like Web3 environments.
Attributes in Sploosh are prefixed with the @ symbol and can be applied to various item forms, including functions, actor handlers, and modules. They provide critical metadata for the compiler to handle concerns such as on-chain reentrancy guards, payment handling, and actor mailbox configurations. This structural approach ensures that even complex behaviors remain explicit and prompt-loadable for AI agents.
Sources: VISION.md:126-131, crates/sploosh-parser/src/lib.rs:115-139, README.md:10-20
Attribute Syntax and Parsing
The Sploosh parser implements a robust mechanism for capturing attributes during the recursive-descent parsing process. Attributes are defined by the @ token followed by an identifier and optional arguments. The parser preserves these attributes in the Abstract Syntax Tree (AST) to ensure they are available for later semantic analysis and code generation phases.
Data Structures for Attributes
The internal representation of attributes consists of the attribute name, a list of arguments, and the source span for diagnostic reporting. Arguments can be positional identifiers, named assignments, or complex expressions.
The diagram shows the relationship between an attribute and its various argument types as defined in the parser logic.
Sources: crates/sploosh-parser/src/lib.rs:115-139, crates/sploosh-parser/src/lib.rs:1126-1165
Parsing Logic Flow
When the parser encounters a TokenKind::At, it triggers the attrs() method. This method loops to consume all consecutive attributes attached to a specific item, such as a function or struct.
This flowchart illustrates the recursive-descent logic used to extract attributes and their arguments.
Sources: crates/sploosh-parser/src/lib.rs:115-139, crates/sploosh-parser/src/lib.rs:142-155
Specialized Function Attributes
Sploosh defines several reserved attributes that dictate specific execution semantics, particularly for actor concurrency and on-chain (Web3) targets.
Web3 and On-chain Attributes
For onchain mod components, attributes are used to manage blockchain-specific constraints. The reentrancy guard is active by default for all public on-chain functions; however, developers can explicitly opt-out using specific attributes.
| Attribute | Scope | Description |
|---|---|---|
@payable | pub fn | Opts a function into receiving native value (e.g., ETH or SOL). |
@reentrant | pub fn | Opts a function out of the default per-contract reentrancy guard. |
@indexed | Event Fields | Marks a field for indexing in blockchain logs/events. |
| Sources: VISION.md:86-90, README.md:46-50 |
Actor and Concurrency Attributes
Actors use attributes to configure their internal message-passing infrastructure. A primary example is the mailbox configuration for actor handlers.
@mailbox: Used on actor handlers to define mailbox properties such as capacity.@supervisor: Can be applied to actor definitions to specify restart strategies (e.g.,one_for_one) and maximum restart counts.
Sources: crates/sploosh-parser/src/lib.rs:1255-1279, crates/sploosh-parser/src/lib.rs:1208-1225
Metaprogramming Constraints
Metaprogramming in Sploosh is intentionally limited to ensure the language remains "AI-native" and predictable. The following features found in other languages are explicitly excluded:
- No Macros: Arbitrary code generation via macros (like Rust's
macro_rules!or procedural macros) is not supported. - No Reflection: There is no runtime type information (RTTI) or reflection beyond basic
dyn Traitrequirements. - No Implicit Behavior: Attributes must be explicit. There are no implicit conversions or hidden control flows triggered by naming conventions.
- No Novel Tokens: All attributes and metaprogramming surfaces use familiar vocabulary from the top 12 most-trained languages.
Sources: VISION.md:126-135, crates/AGENTS.md:35-45
Attribute Argument Classification
The parser employs a canonicalization strategy for attribute arguments. Since bare identifiers, assignments, and calls are also valid expressions, the parser first parses the arguments as expressions and then classifies them into specific AttrArg variants.
| Argument Form | Example | Classification |
|---|---|---|
| Bare Identifier | @derive(Debug) | AttrArg::Ident |
| Named Assignment | @mailbox(capacity: 2048) | AttrArg::Named |
| Value Assignment | @cfg(target = evm) | AttrArg::Assigned |
| Parameterized Call | @feature(fast) | AttrArg::Call |
| Complex Expression | @check(CAP + 1) | AttrArg::Expr |
Sources: crates/sploosh-parser/src/lib.rs:161-170, crates/sploosh-parser/src/lib.rs:1126-1165
Implementation Status
As of the current compiler bootstrap phase, the lexer and parser are capable of recognizing the @ token and the basic attribute grammar. However, semantic enforcement of these attributes is deferred to later stages of the compiler pipeline.
- Lexer: Tokenizes
@asTokenKind::At. - Parser: Preserves
Vec<Attribute>onItemandHandlernodes. - Directives: Compiler directives using the
#[...]syntax (e.g.,#[cfg(test)]) are currently reserved in the grammar but listed as "Not yet implemented" in the bootstrap crates.
Sources: crates/sploosh-lexer/src/lib.rs:65, crates/AGENTS.md:38-40, crates/sploosh-parser/src/lib.rs:90-105
In summary, Function Attributes and Metaprogramming in Sploosh provide a constrained but powerful declarative interface. By leveraging attributes for critical safety and target-specific behaviors while rejecting complex macro systems, Sploosh maintains the simplicity required for high-accuracy AI code generation.