Esterel and Synchronous Reactive Programming?

68 views
Skip to first unread message

Bob Paddock

unread,
Jul 28, 2022, 9:35:42 AM7/28/22
to cell-lang
Like most it seems I came across Cell from Hacker News.

I'm mostly interested in the 'Reactive' component and was curios if Cell was influenced by the REALLY obscure and long forgotten computer language Esterel?  If not some of the theoretical papers on its design might be of interest.


https://www.embedded.com/an-introduction-to-esterel/

https://www-sop.inria.fr/meije/esterel/esterel-eng.html





cell-lang

unread,
Aug 1, 2022, 10:12:13 AM8/1/22
to cell-lang
Hi Bob,

thanks for the links. I didn't know about Esterel, and it's interesting to compare the two approaches since they're so different. Do you know if Esterel was actually used in the industry?

So far I've only read the article on embedded.com, and I've tried to rewrite their examples in Cell. This is the first one, the vending machine, in Esterel:

    module VM1:
      input    COIN, TEA, COFFEE;
      output   SERVE_TEA, SERVE_COFFEE;
      relation COIN # TEA # COFFEE;
      loop
          await COIN;
          await
              case TEA    do emit SERVE_TEA;
              case COFFEE do emit SERVE_COFFEE;
          end await;
      end loop;
    .

and this is a slightly more capable version of it in Cell:

    type Beverage = tea, coffee;

    Int beverage_price(Beverage) =
        tea     = 80,
        coffee  = 120;

    reactive VendingMachine {
        input:
            coin*    : Int;
            request* : Beverage;

        output:
            serve*   : Beverage;

        state:
            credit   : Int = 0;

        rules:
            // Whenever a coin is inserted we increase the available credit
            credit = credit + coin;

            // Whenever a beverage is selected, we first check if there's enough credit
            price := beverage_price(request);
            is_paid_for := @credit >= price;

            // We serve the requested beverage if there's enough credit
            serve := request if is_paid_for;

            // Deducting the price of the beverage from the available credit
            credit = credit - price : serve;
    }

And this is their second example, the temperature controller:

    module temp_controller :
        input     TEMP : integer, SAMPLE_TIME, DELTA_T;
        output    B1_ON, B1_OFF, B2_ON, B2_OFF;
        relation  SAMPLE_TIME => TEMP;

        signal HIGH, LOW in
            every SAMPLE_TIME do
                present TEMP else await TEMP end present;
                if (?TEMP >= 250) then emit HIGH else emit LOW end if;
            end every;
            ||
            loop
                await LOW;
                emit B1_ON;
                do
                    await HIGH;
                    emit B1_OFF;
                watching DELTA_T
                timeout
                    present HIGH else
                        emit B2_ON;
                        await HIGH;
                        emit B2_OFF;
                    end present;
                    emit B1_OFF;
                end;
            end loop;
      end;
    .

and a more-or-less equivalent rewrite in Cell:

    Int lower_threshold = 200;
    Int upper_threshold = 250;

    reactive TemperatureController {
      input:
        temperature : Int;

      output:
        boiler_1_on : Bool;
        boiler_2_on : Bool;

      state:
        // At startup the first boiler will be switched on if the temperature is
        // below the lower threshold, and the second boiler will always be off
        boiler_1_on : Bool = temperature < lower_threshold;
        boiler_2_on : Bool = false;

    rules:
        // Switching on the first boiler if the temperature drops below the lower threshold
        boiler_1_on = true when temperature < lower_threshold;

        // Switching on the second boiler if the first boiler has been on for
        // a while (10 minutes) and the temperature still hasn't recovered

        boiler_1_has_been_on_for_a_while = boiler_1_on for 600s;
        boiler_2_on = true when boiler_1_has_been_on_for_a_while and temperature < lower_threshold;

        // Switching off both boilers if the temperature exceeds the upper threshold
        boiler_1_on = false when temperature >= upper_threshold;
        boiler_2_on = false when not boiler_1_on;
    }

It looks like they've more examples on their website, I'll try to rewrite them in Cell hoping to learn something. Unfortunately, I'm probably the wrong person to design a reactive DSL. It looks like examples of interesting reactive systems are pretty uncommon outside of embedded systems, and I've never worked in that field. I wish I had the chance to use Cell to build one of those complex real-world embedded application that need to juggle hundreds or even thousands of signals. Without that, it's hard to test one's ideas and even harder to come up with new ones.

Thanks again for the links.

Regards,
Reply all
Reply to author
Forward
0 new messages