Finding the good one: mithril

I have just read this insightful statement on this blog article about congitive load in Javascript

jQuery is undoubtedly useful when dealing with browser quirks, but once an application grows over a few thousand lines of code, unstructured jQuery code simply becomes too difficult to maintain, and you start needing the discipline of a framework to organize code. But when you’re at tens of thousands of lines of code, you start to run out of entity types to CRUD, and your application growth starts to build on top of existing concepts. This is when you need the mental shift from being a library consumer to being a reusable component author,

This clever guy is the creator of Mithril, a very small, well crafted javascript library a friend of mine pointed to (via github…):

Mithril is a client-side MVC framework – a tool to organize code in a way that is easy to think about and to maintain.

From my huble point of view Mithril is a all-javascript library, focused on MVC and minimal AJAX. In Mithril even the html part is built in Javascript. It seems a bad route, but I must admit it rocks a lot when you give it a try.

The second generation (jQuery) and third generation javascript library (ReactJS, AngularJS, knockout, etc) all suffers from a big dichotomy between the html template and the event code. It seems all clear on small use cases. Some library also “compile” templates. Sometime I think: “wait a moment, I am fighting with the GUI, or the GUI is part of my code?”.

It easy to think jQuery is unusable when your interface grows: you need some MVC system. So you pass to AngularJS. But The concept below angular a lot, and the reward seems always a bit less. I have no time and re-learning angular or KnockoutJS every time is a big deal.

Mithril is very easy to remember: a recursive, solid, functional-filter based approach.

I cannot stop to suggest you to give it a try.

Recuperare Erlang

Erlang è un linguaggio a mio avviso sottostimato, che ha parecchie cose da insegnare ai vari Scala/Rust/Java(Script) out of there… In particolare ci sono un insieme di feature di Erlang che prese singolarmente non sono difficili da comprendere e implementare, ma è l’insieme delle idee fondanti di Erlang che lo rende assai diverso dagli altri.

Erlang ha:

  1. Una sintassi che prevede che le variabili possano essere assegnate una volta sola. Questo rende side-effect free il suo codice (almeno dal punto di vista formale).
    Però non è ostico come linguaggi che non prevedono variabili oppure le prevedono  mutabilil.
  2. Poiché le strutture dati (e quindi i messaggi tra processi) sono immutabili, l’invio di un messaggio si traduce nel copiare un messaggio dal chiamante al ricevente, tra aree non-condivise (e quindi senza mutex).
  3. Poiché i processi sono side effect-free e state-less, e poiché i messaggi sono tutti asincroni, è molto facile gestire un errore che genera il crash di un processo: cioé è sufficiente far ripartire il processo in crash senza bisogno di ricostruitire il suo stato (perché….non lo ha!).
  4. Ricorsivamente, se un processo che va in crash ne fa morire altri, è facile ricostruirli tutti.
    Poiché i messaggi sono asincroni, un errore di comunicazione si traduce in un semplice “rallentamento”.
    Un errore che si verifica casualmente (per un bug molto subdolo per esempio) si traduce anch’esso in un “rallentamento”.
  5. Erlang minimizza la latenza di risposta, e questo porta automaticamente a massimizzare l’utilizzo dei pool di risorse ed il throughput.
    Per esempio in ErZauker (una applicazione che ho scritto e che ha un numero massimo di connessioni a Redis) Erlang finiva per usare sempre il 100% delle connessioni disponibili, e teneva questo valore sempre al massimo.
  6. Poiché per ogni problema l’approccio è creare processi leggeri, la ErlangVM è facilitata nel minimizzare la latenza poiché può agire su un numero sempre maggiore di message queues per fare il tuning. Se per assurdo tutto fosse fatto da un processo solo, non sarebbe possibile massimizzare la latenza.
  7. E’ banale in Erlang definire le startegie di recovery, tanto che i supervisori “generici” sono codificati e già forniti
  8. Erlang è uno dei pochi linguaggi full-stack production ready. Potete esporre una applicazione Erlang direttamente su internet, con il web server in Erlang, il db in Erlang ecc
    Di converso con Python/Ruby/Java ciò non è possibile/consigliabile.

Ognuno delle due visioni del mondo ha pro e contro, tra i punti di debolezza di Erlang rileviamo:

  1. Erlang per lunghissimo tempo non ha avuto una struttura dati di tipo record “vera” ma tuple indicizzate dal compilatore (l’ultima versione introduce finalmente il tipo “map”).
  2. Benché abbia un compilatore di codice nativo (HiPe), Erlang risulta molto più lento di Java e di altri linguaggi: può compensare girando su più macchine (è banale rilocare un processo!).

 

 

Riferimenti

http://www.erlang.org/doc/efficiency_guide/processes.html

Erlang: a lesson to learn…again!

This entry is part 20 of 19 in the series Programming Languages

Erlang is a great language.

It was just released version 18, so I wanna to come to the party!
On April, Erlang father’s Joe Armstrong give us a very interesting leasson I want to tell about.

There was a long thread titled “Erlang and Akka, The Sequel” on the erlang mailing list, reasoning about the need of some standard pattern on Promises and Furure. A lot of JavaScript libraries deal about that (also jQuery has its implementation).

I want to report the Joe Amstrong reply becuse it give us a very clear understanding on the reason Erlang is different and you should at least try it once.

Form Joe email (code bold by me)
Promises, futures and so on are extremely easy to implement in Erlang.
This is how I explain things when I teach Erlang:

We’ll start with an RPC – we can write this in many ways.
One way might be:

  rpc(Pid, Query) ->
   Ref = make_ref(),
   Pid ! {self(), Ref, Query},
   receive
     {Ref, Response} ->
         Response
   end.

The server that receives this message does something like:

 receive
    ...
    {From, Ref, Query} ->
        Response = ...
           From ! {Ref, Response}
    ...
 end,

This basic pattern is repeated all over the place is with many small
variations.

20140509-091351.jpg
Remember this pattern (repeat 100 times) – this should dance out of your
fingertips and not require conscious thought

For example, all the gen_server does is wrap this pattern
with a few convenience functions.

Now keeping the server code unchanged we can modify the RPC

Start with the original (and stare at the added comment):

 

rpc(Pid, Query) ->
 Ref = make_ref(),
 Pid ! {self(), Ref, Query},
 %% watch this space **************
 receive
 {Ref, Response} ->
 Response
 end.

Now I’ll rename rpc as rpc1 and split it into two functions at the comment:

rpc1(Pid, Query) ->
 Ref = make_ref(),
 Pid ! {self(), Ref, Query},
 Ref.
wait(Ref) ->
 receive
 {Ref, Response} ->
 Response
 end.

So obviously

 

rpc(Pid, Query) ->
 Ref = rpc1(Pid, Query),
 wait(Ref).

 

How about some renaming? I’ll call rpc1 “promise” and wait “yield”

So

promise(Pid, Query) ->
 Ref = make_ref(),
 Pid ! {self(), Ref, Query},
 Ref.
yield(Ref) ->
 receive
 {Ref, Response} ->
 Response
 end.

<aside>we’ve invented futures :-) </aside> Now we can do something in the gap between the promise and the yield:

compute_something(...) ->
 P1 = promise(...)
 Val1 = ... some local computation ...
 Val2 = yield(P1),
 ...

So now Val1 and Val2 are computed in parallel. (We’ve now invented one of the basic mechanisms for parallel programming this might appear as parbegin … parend in some programming language :-)

The reason why Erlang does not have futures/promises/ .. or whatever else you might like to call them is that they are trivially implemented in a few lines of code using just spawn/send/receive. In languages that are basically sequential this is not possible – that’s why it’s a big deal (TM) to have libraries or language features to support this.

And now for the tricky part …. Broken Promises – Remember that scene in Casablanca when Iisa confronts Rick, this is all about broken promises. Fulfilled promises are easy to deal with, but we must ask what happens if the server crashes and never sends back a message? Now life gets difficult, and as Rick found out the consequences of a broken promise lead to all sorts of problems…

In Erlang, dealing with broken promises is possible (though not easy) using links, monitors and by trapping exits.

Giovanni humble note: because Erlang is a functional side effect-free language, dealing with broken promise is a lot easier.

On Ruby/Python/Java/PHP if you get an exception you fail and report the error to the user:  you have an hard time figuring how to redo your work, and you end up rolling back your work. You need to be sure your object are in the right state, your variable are reset and so on: a nightmare-

With Erlang you can relaunch the processes, and the entire business logic can be playback again.
There are some limitations (like dealing with data already commited, system to resync and so on) but is is a lot easier in a functional language.

 

The spawn/send/receive group of primitives are used to program the non error cases where things don’t go wrong. trap_exits/links/monitors deal with error cases where things go wrong.

The gen_servers, supervision trees and so on just wrap these primitives in combinations that we have found useful for  solving “common” problems.

In cases where the library behaviors don’t do exactly what you want it’s often easier to “roll you own” rather than shoehorning your problem into the wrong solution.

The reason there are not a load of design patterns is that we don’t need them.

We do need to teach the basics though. spawn/send/receive are as basic to Erlang as for/if/case are to sequential programming .

This is where we have a problem – in sequential languages nobody bothers to teach what for/if/case/switch/while etc do – it is “implicit knowledge that all programmers have” (I’m excluding total beginners here) – Experienced Erlang programers know the power of spawn/send/receive so rarely bother to explain how to build things with these primitives.

My advice would be to stare hard at spawn/send/receive and memorise the RPC pattern and the basic client/server setup.

Then understand links. Write things without using the libraries – then learn the libraries. Note I said you can write RPC in “many” ways – what did I mean by this? To illustrate, here’s are some variations:

rpc(Pid, Query) ->
 Pid ! {self(), Query},
 receive
 {Pid, Response} ->
 Response
 end.

or

rpc(Pid, Query) ->
 Pid ! {self(), Query},
 receive
 {Pid, Response} ->
 Response
 after 10000 ->
 exit(timout)
 end.

or

rpc(Pid, Query) ->
 Pid ! {self(), Query},
 receive
 {Pid, Response} ->
 {ok, Response}
 after 10000 ->
 {error, timeout}
 end.

You can see how the basic pattern remains – we can add timeouts
etc. but then we have to decide what to do with the variants.

Only the most common patterns are found in the gen_server
so it’s a good idea to understand the basic pattern and
modify it to your specific needs.

/Joe