junction

Macro junction 

Source
macro_rules! junction {
    ( $( $channel_name:ident as $mode:ident :: $type:ty),* $(,)+
      $( | $( $args:ident ),* | $function_block:block  ),* $(,)+ ) => { ... };
}
Expand description

Define an entire Junction using a single block.

A Junction is the smallest unit of distribution for the Join Calculus. This syntax allows for an entire junction to be defined as a single block.

§Example

§Standard API

Suppose we use the standard Public API we can define our computation using the following syntax.

let junction = rusty_junctions::Junction::new();
let name = junction.send_channel::<String>();
let value = junction.send_channel::<i32>();
junction.when(&name).and(&value).then_do(|name, value| {
    println!("Standard API: {name} {value}");
});
value.send(0).unwrap();
name.send(String::from("Hello, World!")).unwrap();

§Single Junction Declarative Macro API

However, it is also possible to use this alternative (simpler?) syntax for defining the entire Junction.

let (name, value, mut handle) = junction! {
    name as Send::String,
    value as Send::i32,
    |name, value| {
        println!("Single Junction Declarative Macro API: {name} {value}");
    },
};
value.send(1).unwrap();
name.send(String::from("Hello, World!")).unwrap();
// Explicitly stop the Controller

handle.stop();

§Advantages

  • The main advantage is that we have a convenient and less verbose syntax for defining the Junction.

  • This syntax allows for the entire junction to be defined in a single block. Defining all of the intermediate values in a nested scope, preventing them from being accessed from elsewhere in the client.

§Disadvantages

  • When using the junction macro you are required to bring the when and channel into the name space as well. This is due to a limitation of Declarative Macros, that they are not composed as single units, and are instead executed in a function like manner albeit during compilation and not runtime. A future implementation might utilise a Incremental TT Muncher, and deeper recursion to avoid having calls to other macros (when and channel) which then need to be included in the name space of the client.

  • As you can see in the Example above the Controller explicitly stopped, if we allowed it to be dropped from the inner scope there would be no guarantee it would have time for the pattern to fire.