Reading recently great Philip K Dick novel The Man in the High Castle I learned about I Ching – ancient Chinese philosophical, cosmological, but mainly divination text. I’m no big fan of divination, so in case of I Ching I would generally agree with this critical review. However the procedure of divination used within I Ching is quite interesting – hexagrams actually represent one of oldest binary codes. Idea that one’s fortune could be represented by 6 bits (actually it’s 12 bits, because for practical divination purpose we use 6 x 4 states) is quite amusing. So I decided to create online I Ching application as an exercise to learn bit more about Ocsigen web framework. You can check result of my effort here.
I have been playing with OCaml for some time and I was wondering what web frameworks are available there. Ocsigen is probably most popular, it’s fairly stable, with reasonable documentation, so I decided to give it a try. Ocsigen is actually a set of projects – the application server is called Eliom (this is a core for writing web apps), web server is Ocsigenserver, library for generating HTML is TyXML, etc.
Ocsigen/Eliom has several quite unique features – the most notable one is that even client (browser) side of application is written in OCaml. Thanks to sub-project Js_of_Ocaml, which provides compiler and runtime to compile and run Ocaml bytecode in browser JS engine. That sounds freaky enough to bring my attention.
How does it feel?
Ocsigen/Eliom is definitely not very easy framework to start with. Especially for me, while I’m still OCaml beginner, it was notable effort. Comparing it, for instance, with python Flask, which I used recently for some other project (PDF Checker), Eliom required much more time to learn. With Flask I just read quickly through docs for an hour and was ready to start and during project never hit an issue, which could not be resolve quickly (provided that I have Django background from several other projects). Eliom I started with few official tutorials and initially I did not have much idea what I was doing. I slso had to read thoroughly through docs to grasp key concepts.
Eliom is approaching web development from little bit different perspective, but when I finally got most of it, I have to say it make very much sense and it’s well and carefully designed.
Key surprises for me were:
Sometime it was bit struggle to get something right – for instance this JS code
document.getElementById("hexa_"+no).value = value
Has this equivalent in OCaml:
let input = Js.coerce_opt (Dom_html.document##getElementById(Js.string(Printf.sprintf "hexa_%d" no))) Dom_html.CoerceTo.input (fun _ -> assert false) in input##value <- (Js.string (string_of_int value));
- No HTML templates – Eliom does not have HTML templates. At first I could not believe that there could be a web framework without templates, but then I learned that Eliom has other ways – functional constructors and syntax extension. When I got used to it, it was not so bad :-).
- Mixing server and client code together – Eliom provides some syntax extensions to mix together code for server and client – initially I was bit confusing and syntax felt bit messy, but it was easy to get used to it.
- Cooperative multitasking programming – actually it was not so big surprise, because I used OCaml Async library in my other learning project and Eliom is using Lwt library, which is quite similar in concept (monadic interface to asynch programming). As you probably know OCaml executes in one physical thread, because there is a global lock for garbage collector (similar to python GIL). Eliom in order to enable efficient concurrency uses Lwt library for cooperative multitasking (similar concept to gevent or asyncio in python). This requires special programming style, which has to be used in all application and usage of blocking IO operations or some other libraries that potentially block calls for significant time should be generally prevented.
- No I18N support – that was really missed. Ocaml provides a gettext library, but it’ll require additional effort to use it together with Eliom (I rather hacked some small custom I18N functionality for my app).
Apart of some initial troubles, described above, I found some Eliom features that are really great and unique in world of web programming ( at least to me):
- Functional Reactive Programming – Eliom implements FRP on client side – where signals can be connected to content of HTML elements and also provides means to send signals and events between client and server. For instance you can have a signal updated on server and it’s value is displayed as text in a HTML element in client. It feels so right and elegant! In my I Ching application FRP and signals are used for Yin-Yang counter and progress bar.
- Client-server communication – Eliom provides several sophisticated ways for client – sever communication, like buses, channels and before mentioned reactive signals. It enables to create highly interactive web application ( check tutorial for cooperative drawing web application).
- Continuations based web programming – I’m not big expert in this area, so just my two cents. Technically spoken Eliom is not working with continuations, but it provides similar functionality by enabling dynamic creation of new web services/handlers from within running web service/handler, where new dynamic service is provided a closure to running environment. This enables easy creation of different types of wizard- like interactions. I did not have time to play with it yet, but I think it can have great potential.
My I Ching application
There are tons of I Ching applications around (especially for mobiles), so this one probably will not be any break-through. However it stands solid in comparison with others (I made some small research). Notable features are:
- Full I Ching oracle – provides both current and future hexagrams and moving lines. Text is based on most popular Richard Wilhelm translation of I Ching.
- PRNG used for coins throws is seeded from data generated by user actions (mouse moves) – to best simulate real throwing of coins ( shake, then throw).
- Responsible interface design – works well on desktop browsers or mobiles.
- Can be easily localized. (Now English and Czech, volunteers for translations are welcomed).