image/svg+xml

HipHop.js

version 1.1.2 15 April 2021

.keep

HipHop.js: Synchronous Multitier JavaScript Reactive Programming

HipHop.js is an Hop.js DLS for orchestrating web applications. HipHop.js helps programming and maintaining Web applications where the orchestration of asynchronous tasks is complex.

HipHop.js adds synchronous concurrency and preemption to JavaScript. Inspired from Esterel, it simplifies the programming of non-trivial temporal behaviors as found in complex web interfaces or IoT controllers and the cooperation between synchronous and asynchronous activities. HipHop.js is compiled into plain sequential JavaScript and executes on unmodified runtime environments.

Important: Since version 1.1.0 HipHop programs can be executed in Hop.js, all web browsers, and Node.js.

Example 1

Here is a seminal example of synchronous programming languages. This program simulates a machine that has three input buttons. It waits for buttons A and B to be clicked before emitting the signal O. The machine is reset when button R is pressed, whatever its current state.

"use hiphop";

service abro() {
   return <html>
     <head>
       <script src="hiphop" lang="hopscript"/>
       <script defer>
          hiphop machine prg( in A, in B, in R, out O ) {
             do {
                fork {
                   await( A.now );
                } par {
                   await( B.now );
                }
                emit O();
             } every( R.now )
          }
   
          prg.addEventListener( "O", v => alert( "got O: " + v ) );
       </script>
     </head>
     <body>
       <button onclick=~{prg.react( "A" )}>A</button>
       <button onclick=~{prg.react( "B" )}>B</button>
       <button onclick=~{prg.react( "R" )}>R</button>
     </body>
   </html>
}   

Example 2, Android

HipHop.js can be used on fullfledged computers such as desktops and laptops. It can also be used on Android devices. The second example binds on-device events inside a HipHop.js reactive machine to automatically answer SMS messages still answered after a user defined delay has expired.

"use hiphop"
"use hopscript"

const hopdroid = require( hop.hopdroid );

const phone = new hopdroid.phone();

hiphop module Alarm( alarm, var minutes ) {
   weakabort( alarm.now ) {
      async alarm {
         this.intv = 
            setTimeout( () => this.notify( true ),
               1000 * 60 * minutes );
      }
   }
}

hiphop machine autoReply( in smsdelivered, smsreceived, autoreply = 0 ) {
   every( smsreceived.now && autoreply.nowval > 0 ) {
      let no = smsreceived.nowval[ 0 ];
      signal alarm;
      abort( smsdelivered.now && smsdelivered.nowval[ 0 ] === no ||
             autoreply.now && autoreply.nowval === 0 ) {
         run Alarm( minutes = autoreply.nowval );
         hop { 
            phone.sendSms( no, "I'm busy. I will answer as soon as I can" );
            hop.broadcast( "autoreply", "delivered " + no );
         }
      }
   }
}

autoReply.bindEvent( "smsreceived", phone );
autoReply.bindEvent( "smsdelivered", phone );

service hhdroid() {
   const con = <div/>;
   const del = <span>0</span>;
   return <html>
     <script>
       server.addEventListener( "autoreply", e => ${con}.innerHTML = e.value );
     </script>
     <h2>Phone: ${phone.model}</h2>
     ${del}
     <input id="delay" type="range" value=0 min=0 max=9 
            onchange=~{${service (v) { autoReply.react( { autoreply: v } ); }}( this.value ).post();
                       ${del}.innerHTML = this.value}/> 
     <label for="delay">auto reply delay</label>
     ${con}
   </html>
}