29 agosto 2018
A reactive programming example

As part of our guild, we spent a few hours to explore reactive programming and we would like to share with you a simple example we developed as an exercise.

Reactive programming is a paradigm focused on simplifying asincronicity through the observer pattern with some functional flavour. By representing data as streams, it can process in a convenient and uniform way both plain data structures and streams of asynchronous events.

In this example we will build a simple REPL in reactive style, in Kotlin with RxKotlin library (which in turn works on top of RxJava, providing convenient extension functions). You can find the full code on github: https://github.com/intresrl/RxKotlin-REPL

The REPL is an Observable object implemented as a simple loop that waits for commands to be issued and then notifies them to every observer subscribed.

private val emitterFunction = { emitter: Emitter<String> ->
    var shouldAskForCommand = true
    while (shouldAskForCommand) {
        print(PROMPT_STRING)
        val command = readLine()!!
        when (command) {
            "exit" -> shouldAskForCommand = false
            else -> emitter.onNext(command)
        }
    }
    emitter.onComplete()
}

This snippet is wrapped into a function that has the emitter as parameter: the emitter is a Rx object used to notify every observer of a new event through the onNext method.

The observers are wrapped into an Interpreter class, registered to the observable with its observe method

fun main(args: Array<String>) {
    val observable = Observable.create(emitterFunction).publish()
    Interpreter().observe(observable)
}

The Interpreter registers some command handlers that will observe the command stream and react when needed.

class Interpreter {
    fun observe(observable: ConnectableObservable<String>) {
       
       // register observers here

        observable.connect()
    }
}

The command stream can be modified and filtered in a functional way for each subscription so that only the relevant messages are dispatched to the subscriber.

The first handler just echoes back every non blank command issued

// echo everything
observable
        .filter { it.isNotBlank() }
        .subscribe(::echo, ::error, ::end)

The subscribe method accepts functions to be executed on every event, on error and when the stream ends.

private fun echo(it: String?) {
    println(" & $it")
}

private fun error(it: Throwable) {
    it.printStackTrace()
}

private fun end() {
    println("Done!")
}

The second handler keeps an history of issued commands, filtering some of them and removing duplicates

// censored history (everything ending with "ck" is a bad word)
observable
        .filter { !it.toLowerCase().endsWith("ck") }
        .distinctUntilChanged()
        .subscribe(historian(), ::error)
private fun historian(): (String) -> Unit {
    val history = mutableListOf<String>()
    return {
        when (it) {
            "history", "hist" -> println(" Previous commands: $history")
            else -> history.add(it)
        }
    }
}

The last observer filters arithmetic operations and prints out the result.

// execute arithmetic operations
val jsEngine = ScriptEngineManager().getEngineByName("js")
observable
        .filter { it.matches(Regex("(\\s*[-+]?\\d+\\s*[-+*/])*\\s*[-+]?\\d+\\s*")) }
        .map { jsEngine.eval(it) }
        .subscribe { println(" = $it") }

Here is a simple demo of the REPL in action

We think that one advantage of this approach is that it decouples how and when data is provided from how it should be elaborated. In this way we could reuse our business logic, i.e. the Interpreter, in another context, for example while reading a list of commands to be executed from a script file as in the FileRunner example:

fun main(args: Array<String>) {
    File("commands.txt").useLines {
        sequence -> Interpreter().observe(sequence.toObservable().publish())
    }
}

In conclusion I believe it would be hard to rewrite this code without using the reactive approach and still managing both synchronous and asynchronous scenarios in such a simple way. And I must say that I find very expressive yet concise the functional stream manipulation syntax.

Tag
Milan Kotlin Community Conf

The first Kotlin related Italian conference made from the community to the community!

Let's see how was it...

DroidCon IT, Turin, 19 & 20 April 2018: our report
Milan Kotlin Community Conference

How, why and what has lead us to the Milan Kotlin Community Conference.

Intré Camp – 13 Febbraio 2018

Racconto del camp aziendale svoltosi a Pontida, agriturimo Polisena

Vert.x – 4o articolo su Mokabyte!

4o articolo sul mondo Vert.x a cura di Marco

Vert.x – 3o articolo su Mokabyte!

3o articolo sul mondo Vert.x a cura di Marco

NoSlidesConf 2017

NoSlidesConf: una conferenza diversa dal solito

Vert.x – 2o articolo su Mokabyte!

2o articolo sul mondo Vert.x a cura di Marco

Vert.x – 1o articolo su Mokabyte!
IAD Urbino 2017 – Conferenza 18 Novembre

Racconto della conferenza presso l'università degli studi Carlo Bo di Urbino

IAD Urbino 2017 – Unconference 17 Novembre

#IAD17: Racconto della giornata di unconference presso l'Università degli Studi Carlo Bo di Urbino

Intré Camp – 5 Ottobre 2017

Racconto del camp aziendale svoltosi all'agriturismo La Camilla

Intré Camp – 18 Maggio 2017

Resoconto del camp aziendale svoltosi all'Oasi di Galbusera Bianca

CloudConf Torino 2017

CloudConf 2017 a Torino. Come è andata?

Mini IAD Vimercate 2017

Il racconto della giornata al Mini Italian Agile Day tenutasi a Vimercate.

Codemotion Milano 2016

Nel week-end del 25-26 novembre 2016 si è svolto il Codemotion Milano 2016.
Francesco Sacchi e Ferdinando Santacroce ci raccontano com'è andata.

Angular Conf 2016

Il racconto della nostra giornata alla Angular Conf 2016 a Torino, sia come spettatori e soprattutto come sponsor.

Intré Camp – 3 Novembre 2016

Un racconto di come è andata la nostra giornata di team building, tra sorrisi e battaglie ;)

Node.Js Italian conference – V edition

Cronistoria sulla nostra partecipazione alla 5^ edizione della Node.Js Italian Conference, con tante belle foto, stickers e...leggete :)

Business24 TV: Fabio Ghislandi presenta Intré

In questo breve intervista viene presentata Intré e il suo innovativo approccio allo sviluppo di software.

Come cambia il mondo dei linguaggi
WebRTC – #1 Video-Chat in javascript

Con la tecnologia WebRTC (Real Time Communication www.webrtc.org) è possibile integrare, all’interno di applicazioni che comprendono javascript, funzionalità di audio e video-chat, registrazione chat, condivisione schermo e signaling.

Future e Promise in Scala

Primo post sulla programmazione in Scala dedicato a future e promise, due costrutti fondamentali per la programmazione concorrente.

Come inviare dati live da un’applicazione C# Desktop al web usando le WebSocket

Questa è una guida passo passo su come esporre dati live da un'applicazione C# console ad un web browser usando le WebSocket. L'esempio è stato testato su Windows 7.

IOS Push notifications iOS 6 con Sencha Touch 2.2

Se state cercando di inviare una Push Notification al vostro iOS6 iPhone/iPad usando Sencha Touch 2.2 probabilmente avrete incontrato diversi problemi. In questo articolo vedremo passo passo come configurare i certificati, impostare il file Sencha package.json ed inviare una push notification con uno script PHP o C#.

Creare una issue in Jira con i sub-task predefiniti

E' possibile programmare script in Atlassian Jira usando Groovy. Questi script possono essere eseguiti allo scattare di un evento come alla creazione di una issue o al suo aggiornamento. Sfruttando questo principio vediamo come creare uno script che crea i sub-task in automatico alla creazione di una Issue.

Lego controllato con Cloudfoundy via WebSockets

Questo è un breve test di come è possibile controllare Lego Mindstorm con Cloudfoundry usando HTML5 e WebSockets.

Beaglebone how-to. Come cambiare lo stato di una pagina web premendo un pulsante con node.js

Questo articolo descrive come intercettare l'interrupt GPIO di una beagle bone e aggiornare, via web sockets, una pagina web usando node.js.

youSCADA presentato al Graphical Web 2012

Come controllare e monitorare i device usando una piattaforma Cloud? La soluzione è stata presentata al Graphical Web 2012 a Zurigo.

Chiamare una REST API con node.js

Node.js sta rivoluzionando il modo di programmare le piattaforme software. Basato sul Google V8 JavaScript Engine permette di scrivere codice lato server in JavaScript.

Top
Ogni nostro Sprint ha l'obiettivo di massimizzare il Valore per l'utente finale
Il tuo browser non è aggiornato!
Aggiornalo per vedere questo sito correttamente.Aggiorna ora

×