type content = [ `ocaml | `erlang | `haskell | `random ]

Recently I’ve been messing around with a new and exciting web framework in
erlang called N2O. This framework appeals to me for a few reasons. These
include:

It’s lean. Clocking in around 4.5k lines, it’s small enough for me to read
the source whenever I don’t understand something, and modify it to my liking if
I ever find it inadequate. Just imagine doing any of that with something like
Rails.

It’s powerful. Quite a bit can be accomplished with comparatively little
code. The rest of my post will provide some evidence for that.

It’s “realtime” (in the web 2.0 sense). Bidrectional streaming is a core
tenant of the framework and Web Sockets are exceptionally easy to use.

It’s full stack. I’m not interested in a so called framework that just lets
you dump some static html and leaves you to the JS sharks. Unless I’m making an
API. N2O has an erlang to js compiler (shen), nice integration with a
templating engine (erlydtl), and lots of other utilities for making front end
work much easier.

To demonstrate all of the properties above, I’ve implemented a tiny omegle
clone in N2O. The aim being to showcase how n2o gets out of your way and lets
you solve such problems in a concise and natural manner.

Implementation

The full implementation is available at my github repo. Which also contains instructions
how to run the project. It should serve as a good project template as well,
since there isn’t an official one for rebar. Most of the code is one file -
omegle.erl. There’s certainly other code but it’s mostly scaffolding for
setting up an n2o app on top of cowboy. The heart of the code is short enough
to include here:

-module(omegle).-compile(export_all).-include_lib("n2o/include/wf.hrl").%% The main function is the entrance point to your n2o handlermain()->#dtl{file="index",app=nitroshell,bindings=[{body,body()}]}.body()->%% spawn a background process responsible for pairing users{ok,Pid}=wf:async("matcher",fun()->matcher()end),[#span{id=status,body="Welcome"},#br{},#span{id=ui,body=ui(seek,Pid)}].%% helper functions for constructing the domui(seek,Pid)->[#button{id=seekButton,body="Seek",postback={seek,Pid}}];ui(chat,Pid)->[#textbox{id=message},#button{id=sendButton,body="Send",postback={chat,Pid},source=[message]},#span{id=history}].message_ui(From,Msg)->#pre{body=(From++": "++Msg)}.set_status(S)->wf:update(status,#span{id=status,body=S}).append_history(Msg)->wf:insert_bottom(history,Msg).%% Event handler function called on dom/chat eventsevent({seek,Pid})->%% user starts to seekPid!{seek,self()},set_status("Seeking..."),wf:update(ui,#span{id=ui});event({chat,Pid})->%% user sends chat messageMessage=wf:q(message),append_history(message_ui("You",Message)),Pid!{direct,{inbox,Message}};%% incoming message from userevent({inbox,Message})->append_history(message_ui("Anonymous",Message));%% signal a user that he's been paired upevent({connected,To})->wf:update(ui,ui(chat,To)),set_status("Connected. Say Hi.").%% Pairing up users has 2 responsibilities, hence another process is neededmatcher()->{ok,Q}=ebqueue:start_link(),_Pid=spawn_link(fun()->matcherQ(Q)end),matcherRcv(Q).%% first responsibility is to add willing users to the queuematcherRcv(Q)->receive{seek,Pid}->ebqueue:in(Pid,Q)end,matcherRcv(Q).%% second is to consume the queue 2 items a time and pair up the usersmatcherQ(Q)->{ok,Pid1}=ebqueue:out(Q),{ok,Pid2}=ebqueue:out(Q),Pid1!{direct,{connected,Pid2}},Pid2!{direct,{connected,Pid1}},matcherQ(Q).

I do have to confess that I’ve cheated a little bit. I needed a very simple
implementation of a blocking queue. I’ve made a quick and dirty version and
called it ebqueue.

Hopefully the code above inspires you to checkout n2o and mess around with it.
Especially if you’re coming from the world of big heavy frameworks, in erlang
or otherwise.

Type safe routing means different things to different people. So let’s start by
clarifying the intended meaning in this post. There are 2 widely used
definitions:

The first refers to the case where the type system is used to maintain hyper
links in your web app so that there are no dangling links. This static checking
also extends to the parameters accepted by the hyper links.

The second definition is processing URL’s in a way that assigns types to the
values extracted.

The first definition is much stronger and is mostly useful for complete web
apps. The second definition pertains to API’s exposed over HTTP and will be the
subject of this blog post. I am not an expert on this subject and this post
only documents my first steps as to how to solve this problem. The end solution
that I propose is not quite satisfying but is elegant in its own right. Let’s
begin.

The Problem

There is something very unsatisfying in the code above. We are attaching a
function to a URL that contains 2 parameters x and y. We know in the body
of the function that the parameters are always there (otherwise our handler
would not be executed) and yet we don’t express this deduction statically.

Can we do better? Yes, and I’ll show you how. Let’s start by pretending that a
solution exists:

This is much better. The function that we are binding to the route is now
typed. The combinators used to specify the routes should be familiar, but a
brief explanation is in order. s x will consume a portion of the url defined
by x. </> concatenates 2 routes sequentially. str specifies a string
parameter that ends with a "/".

The advantages of this approach include:

We don’t have to extract the parameters manually out of the request or even
name the parameters. Although, we can imagine adding support for that if it proves useful.

The compiler will warn us if we haven’t used an argument.

We can now specify the types of the parameters we accept. We can imagine
using int to specify a numerical parameter. In fact, we can probably think of
a host of combinators to add various functionality.

The advantages are obvious, but how can we implement it?

Aspiring OCaml hackers might want give this a problem a crack themselves. To
specify the problem a little better, and perhaps give a hint to the solution
this is interface which we will be implementing:

The Solution

If you have a hard problem related to static typing, a good rule of thumb is to
check if Oleg has already solved it. Indeed, the problem above falls under that
category but under a different context. Typed Formatting attempts to define an EDSL
for specifying a type safe printf/scanf. Our problem of type safe routes
is just a subset of that since we only need scanf. Oleg’s solution in Haskell
involves GADT’s, which have almost have worn off the novelty for me in OCaml.

We will also need a generic parser type ('a Parser.t is a parser that yields
a value of type 'a). A simple monadic parser will do. Since it’s not
particularly interesting, I will link my own implementation in the end. Here’s
the signature for the parser (Although I don’t think we will need all of these
operations).

123456789101112131415161718

openCore.Std(* A Substring.t is analgous to a string * int * int The parser return None on failure. Some with the result and the rest of the substring on success. *)type'at=Substring.t->('a*Substring.t)optionvalreturn:'a->'atval(>>=):'at->('a->'bt)->'bt(* validate/map input with f. If f returns none then the parser fails. If f return Some x then x is the result returned *)valfilter_map:'at->f:('a->'boption)->'bt(* run the parser against the string and return None if parsing fails. On success Some (x, rest) where x is the result and rest is the remaining string that needs to be parsed *)valrun:'at->Substring.t->('a*Substring.t)option(* little helpers *)valdrop_prefix:string->unittvaldrop_while:(char->bool)->unittvaltake_while:(char->bool)->stringt

This function takes a typed route and a function corresponding to a handler and
returns a parser that returns the result of our handler on success.

We just need a bit more massaging to fit our proposed interface:

123456789

letmatch_urltscb=lets=Substring.of_stringsinmatchintstcbswith|None->None|Some(x,subs)->ifsubs|>Substring.to_string|>String.is_emptythenSomexelse(* we did not consume the whole string so no match *)None

The rest is a small matter of programming the combinators:

12345678910111213141516171819

(* a little helper to make sure our params are not empty *)letnon_empty=Parser.filter_map~f:(funx->ifString.is_emptyxthenNoneelseSomex)letint=Parse(funx->(Char.is_digit|>Parser.take_while|>non_empty|>Parser.map~f:Int.of_string)x)letsx=Try_parse(Parser.drop_prefixx)let(</>)x1x2=letlead_slashx=Concat(s"/",x)inConcat(x1,lead_slashx2)letstr=Parse(funx->(Parser.take_while((<>)'/')|>non_empty)x)

Conclusion

I have a prototype of Opium using these routes but it’s not for public
consumption. I’d like to totally revamp routes from a scalability standpoint
first before I improve the API for routing. There are also many other
approaches to this problem (mostly from the land of Haskell). Here’s some great
resources:

The most recent and promising servant. However, it covers a whole lot more than just routing.

Spock is a tiny Haskell web framework that is most similar to my approach, although it uses type families under the hood.

At the end, I’m not sure which approach is the best for OCaml so I’m not ready
to commit to anything in Opium yet. However, one thing is for certain: I
definitely intend to the have the current untyped approach as an option.

Here’s a gist of a working version of my library. You’re welcome to fork
and experiment, please let me know if you find any bugs.

One last thing. My implementation above can be called an “initial encoding” of
the EDSL. You can actually implement the EDSL as a “final encoding” without
GADT’s. I don’t see the advantage in either approach so I went with the initial
encoding. I reached for it first and it gives me an excuse to play with GADT’s.
A solution that uses a final encoding will be left as an exercise to the
reader. (Who else has fond memories of this phrase from back in college?)

There is an old and great schism in the OCaml community. The schism is between
two concurrency libraries - Async and Lwt. As usual for these things, the two
are very similar, and outsiders would wonder what the big deal is about. The
fundamental problem of course is that they’re mutually incompatible. The result
of this is a split OCaml world with almost no interoperability, and duplication
of efforts.

The purpose of this post is not to compare the two from a technical perspective,
but rather to describe my own experiences and the sentiment of the community.
In the end, my conclusion is that disputes like this are rarely resolved on the
basis of technical merits.

Splitting Hairs

Since I know (wish) there’s an influx of newcomers in the OCaml community.
This is partly due to the great book Real World OCaml. I’ll spend a brief
moment describing the fundamental differences between the 2 libraries. I assume
that an informed beginner has read RWO. A basic understanding of Async and
monadic concurrency will be needed to follow along.

The most noticeable between Async and Lwt is the approach towards error
handling. Lwt’s analog to Async’s Deferred.t - Lwt.t, allows for an
exception to be raised that would prevent an asynchronous value from being
computed. Modelling this in Async we could get:

123456

(* This is core's Result.t *)type('ok,'error)result=|Okof'ok|Errorof'errortypeLwt.t=('a,exn)Result.tDeferred.t

Another way of stating that is Lwt.t “inlines” the Either monad. How
does Async deal with errors then? Two ways:

You can copy Lwt’s approach. But you must opt in to do it. See:
Deferred.Or_error.t.

Construct monitor hierarchies that are responsible for handling exceptions
raised in their context. Monitors either bubble exceptions up the monitor
tree or swallow them, possibly handling them along the way.

Both of these approaches are covered in RWO.

At a first glance, Async’s approach is more elegant. When we look at the
Haskell parallel universe we are reminded of the monad’s “fail” epic failure. A
similar case of grafting unnecessary “features” where it does not belong in the
name of error handling. Users of Lwt will quickly remind you that there are
syntax extensions (both camlp4 and ppx!) to make up for this defficiency.
Personally, I don’t find that satisfactory.

The second important difference between Async and Lwt that I’d like to
highlight is the behavior of the most essential and primitive operation in any
monadic concurrency library. The bind - >>=. async >>= f schedules the
computation f using the value of async once it’s determined. However,
there’s a slight twist in each library.

Lwt - if async is already determined when binding then f will run
instantly. In effect, Lwt is always “eager” to execute as much as it can.

Async - attempts to help reasoning about code using the invariant “code
between binds cannot be interrupted”. For example:

123

m>>=funx->...>>=funy->

You are guaranteed not to have scheduler context switch to another job in the
.... The supposed benefits of this is the easier reasoning about race
conditions. YMMV.

That will be it for technical details from me. There are more differences
between Async and Lwt that I urge you to explore in more depth. Two great
sources are:

Although I’ve tried to make the comparison above “fair and balanced”. It’s
probably obvious from a purely technical perspective that I prefer Async. In
fact, almost all of my concurrent programming in OCaml has been done in Async.
Isn’t the decision obvious then?

A Bucket of Cold Water

First let’s quickly survey the community’s stance on Async vs. Lwt:

Lwt had at least 1700 downloads this month and 117 direct reverse
dependencies.

Async had at least 400 downloads this month and 31 direct reverse
dependencies. This includes Jane Street’s stuff, which is a huge chunk of
it.

From the figures above and my own personal experience as a member in the
community, clearly the OCaml community vastly prefers Lwt over Async. That
means that if you’re an OCaml programmer that’s starting a potential project
and thinking of using either concurrency library, Lwt is by far the most
community friendly choice. Potential users will usually be more familiar with
it and if your project is a library it will be far more interoperable. If you
have any interest in being an active participant in the community then
justifying using only Async will be very difficult.

What about supporting both? You have a choice between:

The problem space your code is trying to solve is simple enough that you can
write a small core that is independent of any particular concurrency library.
Daniel Bunzli’s Jsonm comes to mind.

You will have to functorize your library over an async monad.

As usual for these things, you cannot have your cake and eat it too.

The first option is great and is fully recommended in the odd case when it’s
available. It’s certainly not free as I believe it adds complexity to the
implementation. However, the cost is justified since your attempt to support
both async/lwt also supports users of neither library and keeps your dependency
profile low.

The second option is at first very natural. Deferred.t and Lwt.t are both
monads aren’t they? Don’t we have some operations that are generic over those
things? Unfortunately, this eureka moment is spoiled by a death by a thousand
cuts. Be prepared to spend considerable time:

Learning the ins and outs of Async’s and Lwt’s idioms if you are to expose a
good interface to either backend.

Using only the common subset of features of Async and Lwt. A painful waste of
time as you end up slowly having to reimplement a concurrency library of your
own as part of your software.

The amount of libraries available to you is much smaller. You are limited to
libraries that support both Async and Lwt.

Tackling the considerable complexity added by supporting multiple backends in
your build systems, messing around with a plethora of module signatures and
sharing constraints, and worst of all - testing both backends.

Worst of all, consumers of your library will have to do all of this shit as
well if they are to support both Async and Lwt.

All in all, it’s not same as doing 2x the work; it’s even worse! I’ve witnessed
(and even participated) in seeing this churn unfold in cohttp and I can say the
only reason it has been worth it is because we ended up having JS backend as
well. In any case, I cannot in clear conscience recommend this path to anybody
enthusiastic about using OCaml. It’s an unreasonable amount of work. The
conclusion here is that it’s very unlikely that we’ll ever have an Async and
Lwt compatible kumbaya in the OCaml world.

The Case for Lwt

I’ve already hinted at Lwt’s massive advantage over Async: the fact that the
community has pretty much settled on using it. However, suppose that you’re
some sort counter cultural hipster that writes software in a vacuum. Is there
anything else Lwt offers you? Three words. Portability, portability,
portability. More seriously, OCaml actually has AT LEAST 3 more platforms that
Lwt supports and Async doesn’t.

js_of_ocaml - A very mature and
downright awesome OCaml bytecode to JS compiler. While you’re at it check out
the ocsigen project as well. A mature and complete (client + server) web
framework for OCaml that is Lwt only.

mirage - Who wants to compile their server into a
unikernel? I do. What’s stopping me? Async’s C dependencies. Also at this
point, a considerable amount of software under mirage’s umbrella is using
Lwt. Even if Async ever ends up working on mirage, it would be unwelcome as
it would introduce its fragmentation there as well

Windows - People still use it I kid you not. In all honesty I don’t care
about this one but I’m sure some of you will. Take note.

OCaml-Java - I’ve said at least 3 because I’m
not sure if Lwt runs on this new and exciting target for OCaml. At least I’m
sure of what doesn’t run on OCaml-Java. [1]

Suppose that portability is not so important. Let’s compare Async and Lwt
purely as open source projects. On one hand we have a healthy active community. On the other, we have
crickets. I cannot pretend to to
understand why this is so, as I’ve never attempted to contribute to either
project. I can tell you that only one of these projects gives me confidence
that it serves the needs of its users (at least those who aren’t paid to use
it).

Finally, the icing on the cake. Despite the excellent introduction to
Async in RWO. Lwt remains vastly better documented than Async. Whether it’s the
automatically generated reference, the numerous blog posts, or the mountains of
examples everywhere. It remains that it’s much easier to get your Lwt questions
answered faster.

What Now?

Naturally, I can only answer this question for myself. I will port all of my
software from Async to Lwt. My minimalistic web framework
Opium for one. With an eye towards
running it on mirage. I will recommend everyone else who is looking to program
in OCaml to use Lwt as well.

What about Core? (Or core_kernel rather)

My bearishness on Async luckily doesn’t translate to core. The core of core -
core_kernel, is far more interoperable and portable. Its problems of slow
compilation times and bloated executables are either solvable in the future,
irrelevant, or far less severe than Async’s.

Regular Expressions in OCaml

OCaml is my favorite language, but one area where it (its tools rather)
often falls short in practice is common string handling tasks where
regular expressions are often involved. The kind of stuff that Awk
and and scripting languages often get praised for. In other words,
not getting in the way and allowing to get the job done with minimal
boilerplate.

The story for trying to accomplish the same thing in OCaml is not
nearly as short. First, one usually looks at the String module and
after a quick scroll realizes that there’s no solution there. Second,
the Str
library is checked out. Realize that the interface is not user friendly
nor thread safe. If you’re a beginner, then you also start wandering
what kind of a functional language OCaml really is.

Luckily, now that we have OPAM, it’s much easier to look for solutions
beyond. If your string handling needs are simple enough then
core’s or
batteries’String module. If you’re lucky, your search ends
there. Even if you’re not, you still have plenty of good options:

pcre-ocaml Markus Mottl
has written excellent bindings to the most popular flavor of regular
expressions. In fact, I’d recommend these to anyone first if they’re
writing an application or an internal library.

re2
Janestreet’s bindings to Google’s re2. The interface is quite nice but
there’s a gajillion dependencies. Nevertheless, this is probably your
best option if you’re looking for speed. As always, profile your code
first.

ocaml-re This is the most
interesting regex library because it’s written in OCaml. Its coolest
feature is that it supports various regex syntaxes. Including: pcre,
str, posix, glob, etc. In fact, it even has a drop in replacement for
the builtin Str. Unfortunately, re’s interface is rather prickly,
especially for beginners. Fixing that problem is going to be the meat of
this blog post. Nevertheless, this is what I’d recommend if you’re going
to publish a library for others to use. It doesn’t force any non-ocaml
dependencies on users.

Humane-re

Realizing that it’s too hard for users to do the right thing
and use ocaml-re, I’ve created a little wrapper called
Humane-re around ocaml-re that
makes it easier to accomplish the common tasks. The goal is to cover 90%
of the use cases with minimal incidental complexity.

For now, Humane-re is still an experiment so the interface isn’t stable
yet. I haven’t fleshed out the interface for replacement either, and
currently I’m only supporting the Str flavor of regular expressions.
Even with these limitations it’s already been useful for me. I’ll do a
few brief examples of how to do some common tasks.

Parsing HTTP Header Like Value

I’ll admit, for these simple (but not contrived!) examples there’s no
great improvement in readibility over Str. At least we’re not relying
on any global variables. However, humane-re pulls ahead of Str in
readability when groups are involved. I’ll show how to use groups in the
next example.

Extracting Links Matching a Predicate

Where the predicate here is links to a certain website (e.g. imgur).
Don’t ever use regular expressions to parse HTML in practice. This is
only for demonstration purposes:

The whole interface is contained in
S.mli. I could
reproduce it here but it will just go out of date. The ocamldoc isn’t there yet
but the interface should be straight forward enough. Once again, send me
suggestions, questions, critique, etc.

What’s next?

At this point I’m trying to collect as much feedback as possible about
the interface because providing a nice interface is the first goal of
this library. In particular, an interface for substitution would be very
welcome.

The second goal is to support the different ways ocaml-re allows you to
construct regular expressions. I’m not very fond of Str’s regex syntax,
but it does have the practical purpose of allowing me to port old Str
code. The third and lofty goal is to implement humane-re’s interface
with other backends. There’s probably some value in not having to commit
to code to any particular regex implementation (aside from benchmarking
purposes ;D).

In my previous post
I’ve introduced opium in a beginner friendly way, while in this post I’ll try
to show something that’s a little more interesting to experienced OCaml
programmers or those are well versed with protocols such as Rack, WSGI, Ring,
from Ruby, Python, Clojure respectively.

Traditional Middleware

First, let’s start with some history. I’ll be recounting from memory so I
apologize for any inaccuracies. Back in the stone ages of web application
development, a big problem was (still is) creating reusable stand alone
components. For example, caching, authentication, static pages. One solution to
this problem was invented by the python community, (WSGI) and popularized by
the Ruby community (Rack). Since then, it caught on like wild fire and has been
ported to almost every other langauge. I attribute Rack’s success to its
extreme simplicity. In Rack, an application is an object that takes an
environment, an all-encompassing dictionary that includes the http request
among other things, usually called env and returns a tuple of three elements,
the status code, the headers, and the body of the response. Translating this
to OCaml, a rack application is just:

12345678910

typeenv=(string,string)Hashtbl.t(* In ruby, the env hash is not restricted to string values course. They can beany values. Ignore this restriction for now. Or pretend that we're doing somegross Obj.magic hack. Ruby does the same anyway ;) *)typebody=stringtypeheader=(string,string)Hashtbl.ttypeapplication=env->status*header*body(* Actually I'm simplfiying. In reality, body in Rack is more similar to: *)typebody=(string->unit)->unit

Accepting Rack’s proposition that applications are simply functions that return
that 3 element tuple, how do we create reusable components? In Rack the
solution was to create so called “middleware”. Middleware is an object with a
call method (of type application) and is constructed by passing the next
application down the middleware chain. A very literal translation of a typical
rack middleware to OCaml gives:

One can imagine chaining multiple middleware to provide various functionality.
For example checking credentials in the header of the request (found in env) to
decide whether to authenticate the user to proceed with the next step or to
return a not authorized status.

Middleware in Opium

Of course, nobody sane writes code like that in OCaml. So if we get rid of the
classes and store state using closures instead of instance variables (if
necessary) we’d get just a function of type:

123

typemiddleware=application->env->status*header*body(* which can be simplified to *)typemiddleware=application->application

In this viewpoint, middleware is simply a higher order function that
transforms an application to another.

OK, so is this good enough for OCaml? No. Putting back my statically
typed functional programming hat on I can poke a couple of holes in this
approach.

env is mutable. In fact, middleware is encouraged to treat it
as request local storage and pass information between middleware.
This means that env may not be the same before and after calling a
middleware.

env offers no encapsulation. Middleware can easily pry at each other’s
internals. Sometimes this is necessary, but many times it’s not. Ring in
clojure offers namespaced keywords as the keys to the env hash, but this
is only a gentleman’s agreement.

env offers no type safety. In rack, doing env[‘xxx’] is like trying to
pull a rabbit out of hat. There’s no guarantee that the value obtained
will of a certain type.

Universal Maps

All of this points us towards using something other than an untyped hash table
for the environment hash. But what do we use in OCaml if we want, an openly
extensible, heteregoneus, immutable map? We use core’s Univ_map. I won’t go
into the details of how it works but I’ll say that a univ map supports the
following two operations:

In addition to the creation of new Univ_map.Key.t that are associated
with the types a key would extract.

1

valcreate:name:string->('a->Sexp.t)->'aUniv_map.Key.t

If you’d like to know more I recommend the following resource [2], [3], [4].

In Opium, we throw away Rack’s env and simply put everything under the
same umbrella and call it a Request. Similarly, an opium response will
subsume the 3 element response tuple. env will then be the extensible
part of a request/response. Which gives us:

store stuff in env and always know the type of a value pulled out of
env.

middleware can encapsulate its private data by not exposing its env
keys in the public interface

And of course, there’s no sight of side effects anywhere.

Examples

Enough theory crafting, let’s build some middleware. Let’s start with a trivial
example. First of all, our middleware need not even use env at all. For
example here’s a middleware that uppercases the body:

12345678910111213141516171819202122

openCore.StdopenAsync.StdopenOpium.Stdletuppercase=letfilterhandlerreq=handlerreq>>|funresponse->response|>Response.body(* this trick is only available with the latest cohttp. you can manually unpack to a string and then repack however *)|>Cohttp_async.Body.map~f:String.uppercase|>Field.fsetResponse.Fields.bodyresponseinRock.Middleware.create~name:(Info.of_string"uppercaser")~filterlet_=App.empty|>middlewareuppercase|>get"/hello"(funreq->`String("Hello World")|>respond')|>App.cmd_name"Uppercaser"|>App.command|>Command.run

In our example, the middleware runs the handler and returns a response with the
uppercased body. But of course a general middleware doesn’t have to run handler
at all, it can change the request before feeding the handler, or it can simple
add a logging message and let the handler proceeed with the request.

You can tell that middleware is flexible, but to make it do something more
interesting, you must be able to store stuff along the request/response. As
I’ve mentioned before, the env bag is the perfect place for that.

Here’s another common use case. Suppose we’d like our webapp to
automatically authenticate users that provide their credentials using the
HTTP Basic scheme.
For example, we can export a export function like:

openCore.StdopenAsync.StdopenOpium.Stdtypeuser={username:string;(* ... *)}withsexp(* My convention is to stick the keys inside an Env sub module. By not exposing this module in the mli we are preventing the user or other middleware from meddling with our values by not using our interface *)moduleEnv=structletkey:userUniv_map.Key.t=Univ_map.Key.create"user"<:sexp_of<user>>end(* Usually middleware gets its own module so the middleware constructor function is usually shortened to m. For example, [Auth.m] is obvious enough. The auth param (auth : username:string -> password:string -> user option) would represent our database model. E.g. it would do some lookup in the db and fetch the user.*)letmauth=letfilterhandlerreq=matchreq|>Request.headers|>Cohttp.Header.get_authorizationwith|None->(* could redirect here, but we return user as an option type *)handlerreq|Some(Cohttp.Auth.Basic(username,password))->matchauth~username~passwordwith|None->failwith"TODO: bad username/password pair"|Someuser->(* we have a user. let's add him to req *)letenv=Univ_map.add_exn(Request.envreq)Env.keyuserinletreq=Field.fsetRequest.Fields.envreqenvinhandlerreqinRock.Middleware.create~name:(Info.of_string"http basic auth")~filterletuserreq=Univ_map.find(Request.envreq)Env.key

The middleware above might be basic as well but it should give you an idea on
how to create a wide variety of middleware. For example, serving static pages,
caching, throttling, routing, etc.

There are of course downsides however that I’ve yet to solve in Opium.
The main downside is that middleware does not commute. This means that
it must be executed in serial for every request. Much more worse however
is that middleware order will affect application behaviour. In fact,
a common source of bugs in Rack is executing middleware in the wrong
order. One obvious solution to this is to explictly specify dependencies
between middleware. Unfortunately it’s pretty ugly and heavyweight and
it makes middleware less composable.

Final Note: After writing the first version of Opium I realized I was copying
the core of twitter’s finnagle/finatra. I don’t mention them here however since
finnagle is a lot more general and I don’t know much about it other than this
excellent paper. I did end up borrowing
their terminology for the lower level plumbing though.

[2] Ring Spec. A huge
improvement of Rack in my opinion. Rock could be thought of as a typed Ring.

[3] If you’re coming from the haskell WAI world I believe env would be
called the vault. In fact, the way Rock is designed should be very
similar to the old WAI (< 3.0). Except that WAI use IO instead of Deferred.t.

[4] mixtbl An implementation without core.
It’s also a hashtable instead of a map.

One itch that I usually need to scratch is setting up quick and dirty
REST API’s - preferably in OCaml. OCaml does have a few options for
web development but I found them to be not so great fits for my needs.
To summarize:

Ocsigen - Is an innovative web framework but
it’s too heavyweight for my common and simple use case; all of the
client side stuff is immediately useless when all I want is just to
throw some json over a POST request. Plus, I also prefer Async to Lwt
and Ocsigen is much too big to port.

Ocamlnet - Mature and stable and from the sounds of
it, pretty fast as well. However, by the looks of it,
it’s too low level. Also it does not use cooperative threads for
concurrency (Async or Lwt), and that’s a deal breaker for me.

To OCaml programmers coming from other languages, I’ll
re-iterate all of the above very briefly: What I want is a
Sinatra clone written in OCaml.

Without further ado, I’d like to introduce
Opium, my own stab at this problem
and I’m ready to declare it at a state where it’s not embarassing
to show around. The project’s readme already contains high level
documentation and a few examples. Instead of repeating that here I’ll
quickly describe the project and do a little tutorial that’s a little
more beginner friendly.

Getting Started

Opium has been available on OPAM for a while now and can be installed
with:

1

$ opam install opium

From the dependencies that opium we can immediately see that opium is
written on top of the async backend of cohttp, a pure OCaml http
library for Lwt + Async. Cohttp is a great library but it’s a little
too low level for the kind of code I’d like to write.

If you’ve installed everything correctly, the following simple example:

What do we get out of this? Run ./hello_opium.native -h and see.
Opium generates a convenient executable for you with a few common
options. For example to run a specific port and print debug
information to stdout we can:

1

$./hello_opium.native-p9000-d

Now we can test our little server with:

1

$curl127.0.0.1:9000

Basics

Routing

The most basic functionality that opium provides is a simple interface
for binding http requests to functions. It uses a simple glob like
routing for url paths and normally binds one function to an http
method. Parameters can also be specified. Here’s a couple examples:

Going deeper

Opium is an extremely simple toolkit (I’m careful not to call it a
framework on purpose). At its heart there are only 4 basic types:

{Request,Response} - Wrappers around cohttp’s {request,response}

Handler - Request.t -> Response.t Deferred.t

Middleware - Handler.t -> Handler.t

A handler is a full blown opium on its own (even though we usually
have multiple handlers we dispatch to with routing). For example if we
expand out the type signature for the familiar get function we get:

1

valget:string->Handler.t->builder

We see that the function parameter we pass to get is nothing more than a
simple handler.

Middleware on the ojther hand is the main building block of reusable
components. In fact all of opium is built in terms of such middleware,
Router, Debugging, Static pages, etc. The low level layer that knows
what to do with them is called Rock (Kind of like Rack in ruby, or
WSGI in python). For something that’s pretty flexible, middleware is
extremely simple, all it does is transform handlers. To give you a small
taste, here’s a simple middleware that will randomly reject based on
their user agent. Also available in the readme.

Actually I’ve lied a little bit as you can tell from the example above.
A middleware is not just a Handler.t -> Handler.t. That is only it’s
filter component. Middleware is also named, it is mainly useful for
debugging.

The Future

Until 1.0.0 is mostly suitable for me and brave beta testers. This means
that opium still has some potentially embarrassing bugs, and interface
breakges are to be expected But I still invite all users and potential
contributors to help me improve Opium.

At this moment I’m most interested in bug reports and suggestions to the
interface. More features are of course to be expected, such as support
for sessions, whether cookie based or in memory. One big feature that
will probably not make it into 1.0 is Lwt support. I’d love to have it
but 2 backends would be a little much for me to maintain on my own.

Python ranks fairly high when it comes getting things done without too
much ceremony in the programming community. I briefly had some doubts
of this assertion of until I finally found
Flask-Sockets. This
small library makes it very natural to serve WebSockets in
Flask/gevent. You can consider this blog post as an advertisement for
this small but extremely useful library.

In this post, I will show how to create an extremely simple omegle POC
using the Gevent/Flask/Flask-Sockets combo. The end result is that the
javascript client is comparable in code size to the server. Here’s the
code for the server (the client is ugly and uninteresting but you can
see it in the repo):

OCaml & Json

At the time of writing, Yojson is actually the 6th most popular OCaml
library overall!

All things being equal we’d like to use the fastest json
library. Unfortunately for us, things aren’t equal. In fact, Jsonm
strives to be extremely minimalist and low level and the API that it
provides non-blocking encoding and decoding.

Therefore, we will instead be benchmarking Yojson against
Ezjsonm. Ezjsonm is a wrapper library designed provide a user
friendly API on top of Jsonm. With this wrapper,
serialization/deserialization code looks almost identical with both
libraries. In my benchmarks I test the speed in which I read/write the
following datatype:

The verdict is: Yojson is at least twice as fast as Ezjsonm in
both benchmarks.

Of course, recall that benchmarks often lie (on behalf of their
author) and it’s entirely possible that this difference can be
attributed to my code. Therefore, I welcome you to go over my code
here and draw
your own conclusions.

Even in the case where I did not make a mistake in benchmarking, don’t
let me turn you off from using Jsonm, which allows you to write json
parsers at a very low level. I’m certain that a specialized
reader/writer in Jsonm will easily beat Yojson.

Future work

This set of tests is not enough to draw any conclusions just
yet. Here’s what I’d like to do in the future:

OCaml has more implementations of the json serialization
format. They are uncommonly used, however it would still be nice to
include them: yajl, tiny_json.

Reading OCharles’ excellent series about 24 days of hackage, in
particular the post about Linear, I’ve been inspired to revisit some old code I wrote. The code is a document search engine that uses cosine similarity to rank matches. I like the following two
articles if you’re not familiar with this technique:

Linear allows me to shave off all the code defining norms/inner
products for Map String Float and condense a proof of concept of the
technique in very little code (More than half is imports!). The
snippet is obviously not as efficient as it could be (toVector is slow
for example) but we can get the n most similar documents for “free”
thanks to laziness even if we write code the naive way.

Lately, I’ve been messing around with Janestreet’s core and async
libraries by reimplementing an old interview question that has been
posed to me before. The problem statement itself is from my memory
alone so this isn’t 100% what I’ve been asked but it should be
extremely close.

Problem

Implement a simple memcache like TCP interface to an Lru cache. All commands
in the server are of the form:

123

QUIT\r\n
GET key\r\n
SET key value\r\n

where key, value must not contain spaces.

Responses are of the form:

123

INSERTED\r\n
OK\r\nvalue\r\n
NOT_FOUND\r\n

It should be obvious enough to see the request-response correspondence.

Solution

First we’d like to separate the protocol from any particular server implementation
by defining a Protocol module encapsulating the definitions above.

the particular of the cache itself is immaterial so there’s no reason
why our server should depend on it. The only real restrictions we’d
like to have is that the cache must have have a bounded number of
elements so that our server doesn’t run out of memory (Note that to
achieve this we’d need restrict the size of the keys and values as
well but we’ll skip it). We could functorize our server over the
protocol as well if we include quitting as a return type for
of_string for example. The following interface is satisfactory:

Of course, I’m aware that original intent of the interview question was not to test
how well you put together ready made lego blocks to solve the problem but more of
designing the data structure for the Lru cache. The aim of this blogpost is more to
show how well the lego blocks in core/async fit together.

Finally we can start writing our Cache server module functorized over
the cache signature. We will start with the function process which simply
processes a request into a response in the context of the server’s state - the
cache in our case. We’d expect a type signature such as:

The server runs by simply binding to an address and passing
input to the function above in the main loop. The only special handling
we need is for the quit message and bad input (which we just ignore).