Table of Contents

Signals enable HipHop components to communicate with one another. They also implement outside world communications. A signal is identified by its name. It can be local, i.e., defined locally inside a module and invisible outside this module, or global, that is defined as an input or as an output of the main module. Signals have a direction. A signal may be an input from the outside world, an output to the outside world, or used in both directions.

A signal can also carry a value. The value is specified by the emitter and transmitted to the receiver. A same signal can be emitted several times during a reaction but it that signal is valued, a combination used to accumulate all the values must be specified when the signal is declared. The combination function is an arbitrary JavaScript but it must be associative and commutative.

Signal Declarations

Signals are declared in module signatures, possibly via an interface declaration or inside an HipHop statement, with the signal construct.

signal [direction] ident [= value], ..., interface, ...

Formal syntax

Variable Declarations

let ident [= value], ...,

Formal syntax

Along with signals, HipHop supports local Hop variables. They are local variable carrying Hop values. These variable can be used in all the Hop expressions HipHop might used, for instance, for computing a delay, for producing an emission value, or for running asynchronous computation.

Using Signals in Expressions

Signals presence (has a signal been emitted or not during the reaction) and signal values can be used in HipHop JavaScript expressions. For that, HipHop analyses Hop expressions and detect signal accesses. It recognizes four syntactic constructs that correspond to signal access. Notice that these detections are only executed within the syntactic context of an HipHop expression:

signal.now

A predicate that is true if and only if signal has been emitted during the reaction.

signal.pre

A predicate that is true if and only if signal has been emitted during the previous reaction.

signal.nowval

The current value of the signal. Note that values are preserved from reaction to reaction so if a signal is emitted during reaction r1 and not at reaction i1 + 1, getting the value at reaction i1 + 1 will return the same value as reaction i1, although signal.now at reaction i1 + 1 will be false.

signal.preval

The previous value of the signal. The previous value corresponds to the value of the previous signal emission. Notice that the previous emission is not supposed to have happened during the previous reaction.

The following example illustrates the various values of now, pre, nowval, and preval along instants.

"use hopscript"

hiphop machine prg( in A = "_", in B ) {
   loop {
      hop {
         console.log( "A.now=" + A.now, "A.pre=" + A.pre, 
            "A.nowval=" + A.nowval, "A.preval=" + A.preval );
         console.log( "B.now=" + B.now, "B.pre=" + B.pre, 
            "B.nowval=" + B.nowval, "B.preval=" + B.preval );
      }
      yield;
   }
}

exports.prg = prg;

When executed with the following input signals:

;
A(1) B(1);
A(2) B(2);
B(3);
B(4);
A(5);
A(6);

It generates the following output:

undefined> ;
A.now=false A.pre=false A.nowval=_ A.preval=_
B.now=false B.pre=false B.nowval=undefined B.preval=undefined
--- Output:
undefined> A(1) B(1);
A.now=true A.pre=false A.nowval=1 A.preval=_
B.now=true B.pre=false B.nowval=1 B.preval=undefined
--- Output:
undefined> A(2) B(2);
A.now=true A.pre=true A.nowval=2 A.preval=1
B.now=true B.pre=true B.nowval=2 B.preval=1
--- Output:
undefined> B(3);
A.now=false A.pre=true A.nowval=2 A.preval=2
B.now=true B.pre=true B.nowval=3 B.preval=2
--- Output:
undefined> B(4);
A.now=false A.pre=false A.nowval=2 A.preval=2
B.now=true B.pre=true B.nowval=4 B.preval=3
--- Output:
undefined> A(5);
A.now=true A.pre=false A.nowval=5 A.preval=2
B.now=false B.pre=true B.nowval=4 B.preval=4
--- Output:
undefined> A(6);
A.now=true A.pre=true A.nowval=6 A.preval=5
B.now=false B.pre=false B.nowval=4 B.preval=4
--- Output:

Test, Await, and Emit

if( expr ) { ... } [else { ... }]

Formal syntax

The presence or absence of a signal can be checked with the if conditional construct. The value of a signal can be checked too. The expr argument is any Hop expression agumented with the signal API. For instance, the presence of a signal can be checked with:

if( !SIG.now ) { hop { console.log( "signal not emitted in reaction" ) } }

A particular value of a signal can be checked. For instance:

if( SIG.nowval > 10 && SIG.nowval < 100 ) { hop { console.log( "signal in range" ) } }

await delay

Formal syntax

It is frequent for a program to wait for one or several signals to be emitted. This can be acheived with the await construct, which waits for a condition to be true. The delay expression can be:

emit signal( [ value ] )

Formal syntax

The emit form emit the value in the instant. The form emit sig1() emits a signal without value. The form emit sig2( val ) emits a signal with a value.

Note: If a valued signal is to be emitted several times within a single reaction it must be declared with a combinaison function that is a Hop function that must be commutative and associative. It is up to the Hop program to check and satisfy this requirement.

sustain signal( [ value ] )

Formal syntax

Similar to emit but the emission is repeated at each instant. The statement

sustain sig( expr )

is equivalent to

loop {
   sustain sig( expr );
   yield;
}

Examples

A module waiting sequentially for A and B to be emitted during distinct reactions and that emits O right after B is received.

await-seq.hh.js

"use hiphop";
"use hopscript";

var hh = require( "hiphop" );

hiphop module prg( in A, in B, out O ) {
   await( A.now );
   await( B.now );
   emit O();
}

exports.prg = new hh.ReactiveMachine( prg, "awaitseq" );

A module that waits the event I to be present in three distinctive instants.

await-count.hh.js

"use hiphop"
"use hopscript"

const hh = require( "hiphop" );

hiphop module prg( in I, out O ) {
   loop {
      await count( 3, I.now );
      emit O();
   }
}

exports.prg = new hh.ReactiveMachine( prg, "await3" );

A module using Hop variable inside HipHop statements.

variable.hh.js

"use hiphop"
"use hopscript"

var hh = require( "hiphop" );

hiphop module prg( in sig ) {
   let v = 1;

   every( sig.now ) {
      if( sig.nowval > v ) hop { v = sig.nowval + 1 };

      hop { console.log( "v=", v ) }
      yield;
   }
}

const m = new hh.ReactiveMachine( prg, "variable" );
exports.prg = prg;

m.react()
m.inputAndReact( "sig", 0 );
m.inputAndReact( "sig", 10 );