121 lines
No EOL
11 KiB
Text
121 lines
No EOL
11 KiB
Text
<!DOCTYPE html>
|
|
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Why OCaml</title><meta charset="UTF-8"/><link rel="stylesheet" href="/static/css/style.css"/><link rel="stylesheet" href="/static/css/highlight.css"/><script src="/static/js/highlight.pack.js"></script><script>hljs.initHighlightingOnLoad();</script><link rel="alternate" href="/atom" title="Why OCaml" type="application/atom+xml"/><meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/></head><body><nav class="navbar navbar-default navbar-fixed-top"><div class="container"><div class="navbar-header"><a class="navbar-brand" href="/Posts">full stack engineer</a></div><div class="collapse navbar-collapse collapse"><ul class="nav navbar-nav navbar-right"><li><a href="/About"><span>About</span></a></li><li><a href="/Posts"><span>Posts</span></a></li></ul></div></div></nav><main><div class="flex-container"><div class="post"><h2>Why OCaml</h2><span class="author">Written by hannes</span><br/><div class="tags">Classified under: <a href="/tags/overview" class="tag">overview</a><a href="/tags/background" class="tag">background</a></div><span class="date">Published: 2016-04-17 (last updated: 2024-10-11)</span><article><h2 id="programming">Programming</h2>
|
|
<p>For me, programming is fun. I enjoy doing it, every single second. All the way
|
|
from designing over experimenting to debugging why it does not do what I want.
|
|
In the end, the computer is dumb and executes only what you (or code from
|
|
someone else which you rely on) tell it to do.</p>
|
|
<p>To abstract from assembly code, which is not portable, programming languages were
|
|
developed. Different flavoured languages vary in
|
|
expressive power and static guarantees. Many claim to be general purpose or
|
|
systems languages; depending on the choices of
|
|
the language designer and tooling around the language, it is a language which lets you conveniently develop programs in.</p>
|
|
<p>A language designer decides on the builtin abstraction mechanisms, each of which
|
|
is both a burden and a blessing: it might be interfering (which to use? <code>for</code> or <code>while</code>, <code>trait</code> or <code>object</code>),
|
|
orthogonal (one way to do it), or even synergistic (higher order functions and anonymous functions). Another choice is whether the language includes a type
|
|
system, and if the developer can cheat on it (by allowing arbitrary type casts, a <em>weak</em> type system). A strong static type system
|
|
allows a developer to encode invariants, without the need to defer to runtime
|
|
assertions. Type systems differ in their expressive power (<a href="https://en.wikipedia.org/wiki/Dependent_type">dependent typing</a> are the hot research area at the moment). Tooling depends purely
|
|
on the community size, natural selection will prevail the useful tools
|
|
(community size gives inertia to other factors: demand for libraries, package manager, activity on stack overflow, etc.).</p>
|
|
<h2 id="why-ocaml">Why OCaml?</h2>
|
|
<p>As already mentioned in <a href="/Posts/About">other</a>
|
|
<a href="/Posts/OperatingSystem">articles</a> here, it is a
|
|
combination of sufficiently large community, runtime stability and performance, modularity,
|
|
carefully thought out abstraction mechanisms, maturity (OCaml recently turned 20), and functional features.</p>
|
|
<p>The latter is squishy, I'll try to explain it a bit: you define your concrete
|
|
<em>data types</em> as <em>products</em> (<code>int * int</code>, a tuple of integers), <em>records</em> (<code>{ foo : int ; bar : int }</code> to name fields), sums (<code>type state = Initial | WaitingForKEX | Established</code>, or variants, or tagged union in C).
|
|
These are called <a href="https://en.wikipedia.org/wiki/Algebraic_data_type"><em>algebraic data types</em></a>. Whenever you have a
|
|
state machine, you can encode the state as a variant and use a
|
|
pattern match to handle the different cases. The compiler checks whether your pattern match is complete
|
|
(contains a line for each member of the variant). Another important aspect of
|
|
functional programming is that you can pass functions to other functions
|
|
(<em>higher-order functions</em>). Also, <em>recursion</em> is fundamental for functional
|
|
programming: a function calls itself -- combined with a variant type (such as
|
|
<code>type 'a list = Nil | Cons of 'a * 'a list</code>) it is trivial to show termination.</p>
|
|
<p><em>Side effects</em> make the program interesting, because they
|
|
communicate with other systems or humans. Side effects should be isolated and
|
|
explicitly stated (in the type!). Algorithm and protocol
|
|
implementations should not deal with side effects internally, but leave this to an
|
|
effectful layer on top of it. The internal pure functions
|
|
(which receive arguments and return values, no other way of communication) inside
|
|
preserve <a href="https://en.wikipedia.org/wiki/Referential_transparency_%28computer_science%29"><em>referential
|
|
transparency</em></a>.
|
|
Modularity helps to separate the concerns.</p>
|
|
<p>The holy grail is <a href="https://en.wikipedia.org/wiki/Declarative_programming">declarative programing</a>, write <em>what</em>
|
|
a program should achieve, not <em>how to</em> achieve it (like often done in an imperative language).</p>
|
|
<p>OCaml has a object and class system, which I do not use. OCaml also contains
|
|
exceptions (and annoyingly the standard library (e.g. <code>List.find</code>) is full of
|
|
them), which I avoid as well. Libraries should not expose any exception (apart from out of memory, a really exceptional situation). If your
|
|
code might end up in an error state (common for parsers which process input
|
|
from the network), return a variant type as value (<code>type ('a, 'b) result = Ok of 'a | Error of 'b</code>).
|
|
That way, the caller has to handle
|
|
both the success and failure case explicitly.</p>
|
|
<h2 id="where-to-start">Where to start?</h2>
|
|
<p>The <a href="https://ocaml.org">OCaml website</a> contains a <a href="https://ocaml.org/learn/tutorials/">variety of
|
|
tutorials</a> and examples, including
|
|
<a href="https://ocaml.org/learn/tutorials/get_up_and_running.html">introductionary
|
|
material</a> how to get
|
|
started with a new library. Editor integration (at least for emacs, vim, and
|
|
atom) is via <a href="https://github.com/the-lambda-church/merlin/wiki">merlin</a>
|
|
available.</p>
|
|
<p>A very good starting book is <a href="http://ocaml-book.com/">OCaml from the very
|
|
beginning</a> to learn the functional ideas in OCaml (also
|
|
its successor <a href="http://ocaml-book.com/more-ocaml-algorithms-methods-diversions/">More
|
|
OCaml</a>).
|
|
Another good book is <a href="https://realworldocaml.org">real world OCaml</a>, though it
|
|
is focussed around the "core" library (which I do not recommend due to its
|
|
huge size).</p>
|
|
<p>There are <a href="https://ocaml.org/learn/tutorials/guidelines.html">programming
|
|
guidelines</a>, best to re-read
|
|
on a regular schedule. Daniel wrote <a href="http://erratique.ch/software/rresult/doc/Rresult.html#usage">guidelines</a> how to handle with errors and results.</p>
|
|
<p><a href="https://opam.ocaml.org">Opam</a> is the OCaml package manager.
|
|
The <a href="https://opam.ocaml.org/packages/">opam repository</a> contains over 1000
|
|
libraries. The quality varies, I personally like the small libraries done by
|
|
<a href="http://erratique.ch/software">Daniel Bünzli</a>, as well as our
|
|
not quite so broken libraries (see <a href="https://github.com/mirleft">mirleft org</a>),
|
|
<a href="https://github.com/pqwy/notty">notty</a>.
|
|
A concise library (not much code),
|
|
including tests, documentation, etc. is
|
|
<a href="https://github.com/hannesm/ocaml-hkdf">hkdf</a>. For testing I currently prefer
|
|
<a href="https://github.com/mirage/alcotest">alcotest</a>. For cooperative tasks,
|
|
<a href="https://github.com/ocsigen/lwt">lwt</a> is decent (though it is a bit convoluted by
|
|
integrating too many features).</p>
|
|
<p>I try to stay away from big libraries such as ocamlnet, core, extlib, batteries.
|
|
When I develop a library I do not want to force anyone into using such large
|
|
code bases. Since opam is widely used, distributing libraries became easier,
|
|
thus the trend is towards small libraries (such as
|
|
<a href="http://erratique.ch/software/astring">astring</a>,
|
|
<a href="http://erratique.ch/software/ptime">ptime</a>,
|
|
<a href="https://github.com/abeaumont/ocaml-pbkdf">PBKDF</a>, <a href="https://github.com/abeaumont/ocaml-scrypt-kdf">scrypt</a>).</p>
|
|
<p>What is needed? This depends on your concrete goal. There are lots of
|
|
issues in lots of libraries, the MirageOS project also has a <a href="https://github.com/mirage/mirage-www/wiki/Pioneer-Projects">list of
|
|
Pioneer projects</a> which
|
|
would be useful to have. I personally would like to have a native <a href="https://tools.ietf.org/html/rfc4422">simple
|
|
authentication and security layer (SASL)</a>
|
|
implementation in OCaml soon (amongst other things, such as using an <a href="https://github.com/mirage/mirage/issues/489">ELF section for
|
|
data</a>,
|
|
<a href="https://github.com/mirage/mirage-platform/issues/118">strtod</a>).</p>
|
|
<p>A <a href="https://github.com/rudenoise/mirage-dashboard">dashboard</a> for MirageOS is
|
|
under development, which will hopefully ease tracking of what is being actively
|
|
developed within MirageOS. Because I'm impatient, I setup an <a href="https://github.com/miragebot.private.atom?token=ARh4hnusZ1kC_bQ_Q6_HUzQteEEGTqy8ks61Fm2LwA==">atom
|
|
feed</a>
|
|
which watches lots of MirageOS-related repositories.</p>
|
|
<p>I hope I gave some insight into OCaml, and why I currently enjoy it. A longer read on applicability of OCaml is our Usenix 2015 paper
|
|
<a href="https://www.usenix.org/conference/usenixsecurity15/technical-sessions/presentation/kaloper-mersinjak">Not-quite-so-broken TLS: lessons in re-engineering a security protocol
|
|
specification and
|
|
implementation</a>. I'm interested in feedback, either via
|
|
<a href="https://twitter.com/h4nnes">twitter</a> or via eMail.</p>
|
|
<h2 id="other-updates-in-the-mirageos-ecosystem">Other updates in the MirageOS ecosystem</h2>
|
|
<ul>
|
|
<li>Canopy now sends out appropriate <a href="https://github.com/Engil/Canopy/pull/23">content type</a> HTTP headers
|
|
</li>
|
|
<li><a href="https://github.com/mirage/mirage-http/releases/tag/v2.5.2">mirage-http 2.5.2</a> was released to <a href="https://opam.ocaml.org/packages/mirage-http/mirage-http.2.5.2/">opam</a> which fixes the resource leak
|
|
</li>
|
|
<li>regression in <a href="https://github.com/mirage/mirage-net-xen/issues/39">mirage-net-xen 1.6.0</a>, I'm back on 1.4.1
|
|
</li>
|
|
<li>I stumbled upon <a href="https://github.com/mirage/mirage/issues/396">too large crunch for MirageOS</a>, no solution apart from using a FAT image (<a href="https://github.com/mirage/mirage/issues/489">putting the data into an ELF section</a> would solve the issue, if anyone is interested in MirageOS, that'd be a great project to start with)
|
|
</li>
|
|
<li>unrelated, <a href="https://opam.ocaml.org/packages/x509/x509.0.5.2/">X.509 0.5.2</a> fixes <a href="https://github.com/mirleft/ocaml-x509/commit/1a1476308d24bdcc49d45c4cd9ef539ca57461d2">this bug</a> in certificate chain construction
|
|
</li>
|
|
</ul>
|
|
</article></div></div></main></body></html> |