Creates reaction on a reagents set.

Syntax: react{[x:r1;y:r2..]..}; react[{[x:r1;y:r2..]..}]


  • x,y,.. are arguments of a lambda to be evaluated on reaction triggering;
  • r1;r2.. are reagents involved into reaction.

o)react{[x:r] 0N!x};

Reactions can be redefined. To do this, just create reaction on the set of reagents already defined.

When a reaction is defined, each reagent envolved receives a Descriptor. This means "pinning" that reagent onto the Task that has this reaction.

o)r1:reagent[`async]; r2:reagent[`async]; react {[x:r1;y:r2] println["r1: %; r2: %";x;y]};
o)r1: 1; r2: 2
o)// Now redefine reaction:
o)react {[x:r1;y:r2] println["redefined reaction: r1: %; r2: %";x;y]};
o)redefined reaction: r1: 1; r2: 2

If a reagent is dropped, all reactions defined on this reagent will be dropped too since there is no need in them anymore.

If a task has at least one reaction, it's called an IO task. Such task will wait on IO resources involved into reaction(s) and won't be terminated untill signal or exception is received or all reactions are dropped.

Let's see dynamic creation of reagents/reactions in a wide practical example of a ipc server:

srv: reagent[`listener;"";{0N!"listener dropped}];
react {[x:srv]
    // create new IO task to handle client's session
        client: reagent[`ipc;cli]; // create ipc client on accepted sock
        react {[msg:client] // dynamically define reaction on newly created reagent
            client[msg] // echo back to a client

Thats all! Session-based asynchronuous server is done. Simple, yes? To see which tasks exist and their state, use top:

tid handle        state  created      run          suspend      iowait       total        load
7   TaskHandle<7> IOWait 12:28:14.905 00:07:40.899 00:00:00.000 00:21:02.616 00:28:43.515 0
4   TaskHandle<4> IOWait 12:28:14.552 00:00:00.001 00:00:00.000 00:28:43.869 00:28:43.870 0