The `ascetic!` family of Rust macros ==================================== Invocations of any macro from `ascetic!` family of macros are _clean_: symbols are strictly separated from the enclosing Rust scope. All symbols occurring in a plain `ascetic!` or `ascetic_nodes!` macro invocation are interpreted as literal `Gnid`s. All symbols used in the body of `ascetic_rules!` invocation have to be first declared in its signature. There are two forms of a c-e structure definition: - plain `ascetic!` macro, without suffix, is the immediate definition of a `CES` object; - the generic form, `ascetic_rules!`, defines a parameterized `CES` template by introducing a new Rust macro, so that each invocation of this new macro instantiates a c-e structure based on the template. For instance, an immediate form ```rust let arrow = ascetic! { x => y }; ``` defines the same object as the result of the `arrow!` template instantiation below: ```rust ascetic_rules! arrow(source: Node, sink: Node) { source => sink } let (x, y) = ascetic_nodes![x, y]; let arrow = arrow!(x, y); ``` Macro `ascetic_nodes!` accepts a list of literal `Gnid`s and returns a tuple of `Gnid` objects, which may then be used for template instantiation and for accessing state, capacities, etc. ```rust let mut arrow = ascetic! { x => y }; let (x, y) = ascetic_nodes![x, y]; arrow[y].capacity(3); arrow[x] = 3; while arrow.shoot() { println!("x = {}, y = {}", arrow[x], arrow[y]); } println!("deadlock!"); ```