Previous Up

1.11  Non reactive higher-order features

Besides this functional facility, we can also define recursive functions, such as the celebrated Eratosthenes sieve:

let node first x = v
  where rec v = x fby v

let rec node sieve x =
  let clock filter = (x mod (first x))<> 0
  in  merge filter
            (sieve (x when filter))
            (true fby false)

let node from n = o where rec o = n fby (o + 1)

let clock sieve = sieve (from 2)

let node primes () = (from 2) when sieve

val first :  ’a => ’a
val first :: ’a -> ’a
val sieve :  int => bool
val sieve :: ’a -> ’a
val from :  int => int
val from :: ’a -> ’a
val sieve :  bool
val sieve :: ’a
val primes :  unit => int
val primes :: ’a -> ’b on sieve

This program is no more real-time since the time and memory to answer at every instant grows.

A compilation option -realtime is provided for restricting the language to define only real-time programs.

Here is another way of writing the same program using the implicit filtering of streams done by the pattern matching construct:

let rec node sieve x =
  let filter = (x mod (first x))<> 0 in
  match filter with
    true -> sieve x
  | false -> true fby false
  end

let node primes () =
  let nat = from 2 in
  let clock ok = sieve n in
  let emit o = n when ok in
  o


val sieve :  int => bool
val sieve :: ’a -> ’a
val primes :  unit => int sig
val primes :: ’a -> ’b sig

Note that in these two versions, the absence of unbounded instantaneous recursion is somehow hidden: the program is reactive because the very first value of filter is false. Here is a guarded version where no instantaneous recursion can occur.

let rec node sieve x =
  automaton
    Await -> true then Once(x)
  | Once(i) ->
      match not_divides_l i x with
        true -> sieve x
      | false -> false
      end
  end

Previous Up