[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [MirageOS-devel] Cohttp Design -- LWT, Async, JS, Mirage Compatibility
Indeed, these are very good approaches too. There's a distinct tradeoff in all three examples though:
- ocaml-tls is a very complex state machine, and so the pure core dominates the Lwt driver. After that though, there's no abstraction across (e.g.) Async or Lwt. I'm not sure how well this would translate to HTTP, which is dominated by I/O logic (after all, there's a pure protocol core already).
- Despite being a heavy user of Daniel's libraries, I don't find them to have the most usable interfaces for quick usage, although they are the best documented and thought through from the libraries I select from (hence the existence of ezxmlm, ezjsonm, and so on as wrapper libraries). A monadic interface is quite intuitive to pick up and use.
The compelling argument against functors for I/O is the greatest common divisor argument, although even this is (somewhat) mitigated by careful signature inclusion rather than massive interface types. This does create a burden on maintaining fine-grained interface types.
One aspect that really needs more investigation are the performance tradeoffs. It used to be that functors always introduced an extra indirection, but with Pierre Chambart's new inliner this is greatly mitigated. The pressure now goes onto the GC for the purely functional code that will do a lot more allocation...
-anil
Hi,
While I do not have any particular criticism of cohttp, there is another approach to this problem that I personally find far more elegant and flexible. I will talk mostly of how to handle IO, but the same approach works with any type of "layering". Let us call it the "functor-less" approach.
The main difference is that, while functors are used to parametrise the IO operations used *in* the code (often by way of defining an enclosing monad), the functor-less approach takes the IO completely *out* of the code. Instead IO actions are returned as values that guide the actions of particular backends. This involves formulating the sequencing of IO actions as a state machine. Rather than trying to explain the general setup, let me point to some well-known examples, which I hope will convey the essence of this approach:
- ocaml-tls (purely functional style)
- D Buenzli's codecs (imperative signature), eg
Some advantages of this approach:
- using functors require following a greatest common divisor design - the argument signature has to account for all relevant features of each backend, whether they are relevant or not for a particular one. Similarly, adding a new feature to a backend in the functorised approach often means giving an interpretation of this feature to all other backends, even if it does not make much sense.
- by construction it completely decouples IO and the program logic. The advantages of this with respect to clarity, error handling, safety, testing, are hard to overestimate.
- do not have to write code in monadic style
Best wishes, Nicolas
|
_______________________________________________
MirageOS-devel mailing list
MirageOS-devel@xxxxxxxxxxxxxxxxxxxx
http://lists.xenproject.org/cgi-bin/mailman/listinfo/mirageos-devel
|