312 | 312 |
in practice, software usually _does something_ over and above calculating
|
313 | 313 |
the result of an expression. Users click buttons, shapes get displayed,
|
314 | 314 |
files get written to filesystems.
|
|
315 |
|
|
316 |
Some languages resolve this by having function take a representation of
|
|
317 |
the outside world on their input, and producing a (possibly modified)
|
|
318 |
representation of the outside world on their output.
|
|
319 |
|
|
320 |
Robin's approach is not this. Robin's approach is rather more like
|
|
321 |
JavaScript, in that it is _event-oriented_.
|
|
322 |
|
|
323 |
A Robin program may define a _reactor_ by giving some configuration, an
|
|
324 |
initial state, and an operator (a function or macro) called the _transducer_.
|
|
325 |
|
|
326 |
The transducer will be evaluated any time an event comes in. The event could
|
|
327 |
come in from the outside world (for example, the user clicks a button,)
|
|
328 |
or it could be generated by the Robin program itself.
|
|
329 |
|
|
330 |
When the transducer is evaluated, it is also passed the current state.
|
|
331 |
The return value of the transducer consists of two parts: a new value to
|
|
332 |
use as the new current state, and a list of events to cause.
|
|
333 |
|
|
334 |
This is very similar to "The Elm Architecture" used in the language Elm.
|
|
335 |
|
|
336 |
Here is an example reactor.
|
|
337 |
|
|
338 |
(reactor (line-terminal) 0
|
|
339 |
(macro (args env)
|
|
340 |
(bind event (head args)
|
|
341 |
(bind event-type (head event)
|
|
342 |
(if (equal? event-type (literal init))
|
|
343 |
(list 0
|
|
344 |
(list (literal writeln) (literal ''Hello, world!''))
|
|
345 |
(list (literal stop) 0))
|
|
346 |
(list 0))))))
|
|
347 |
|
|
348 |
The `(line-terminal)` part at the top is the configuration referred to above;
|
|
349 |
in this case it indicates that the reactor wishes to subscribe to a facility
|
|
350 |
called `line-terminal` (similar to "standard I/O" in most other languages.)
|
|
351 |
|
|
352 |
The `0` at the top is the initial state. In fact this example is so simple
|
|
353 |
that the state does not change, but it still must be given.
|
|
354 |
|
|
355 |
After that is a macro, which is the transducer. It receives, as its
|
|
356 |
arguments, an event, which consists of an event type; it exracts this and
|
|
357 |
compares it against `init` to see if it is the initialization event.
|
|
358 |
|
|
359 |
If it is, it produces a new state (0) and two events to return: an event to
|
|
360 |
write `Hello, world!` as a line of output, and an event to `stop` the program.
|
|
361 |
|
|
362 |
If it's not, it just produces and returns a new state. The reactor will
|
|
363 |
wait for the next event and process it.
|
315 | 364 |
|
316 | 365 |
(To be continued).
|
317 | 366 |
|