No subject


Tue Dec 8 03:07:43 PST 2020


<code>Error</code> constructor were
treated specially such that values it produced always carried a stack trace=
 (as exceptions do/are), so
that programmers would not need to opt into it as above. However, that woul=
d not come without costs,
including a maybe-significant runtime penalty that might render <code>Resul=
t</code> a less useful way to <span class=3D"underline">cheaply</span>
signal recoverable error conditions (something that other exception-dominan=
t languages/runtimes
struggle to do given that stacktrace generation is far from free).
</p>
</div>
</div>

<div id=3D"outline-container-org7b2dacf" class=3D"outline-4">
<h4 id=3D"org7b2dacf">Correctness</h4>
<div class=3D"outline-text-4" id=3D"text-org7b2dacf">
<p>
Bikal's final topic was re: correctness, and to what extent using one or an=
other error-handling
mechanism tangibly affects his work. What he says is short enough to reprod=
uce in full:
</p>

<blockquote>
<p>
I thought this would be the biggest advantage of using <code>result</code> =
type and a net benefit. However, my
experience of <b>NOT</b> using it didn't result in any noticeable reduction=
 of <b>correct by construction</b>
OCaml software. Conversely, I didn't notice any noticeable improvement on t=
his metric when <b>using</b>
it. What I have noticed over time is that abstraction/encapsulation mechani=
sms and type system in
particular play by far the most significant role in creating <b>correct by =
construction</b> OCaml
software.
</p>
</blockquote>

<p>
There's a lot left undefined here: what "correct by construction" might mea=
n generally, what it means
in the context of OCaml software development, how it could be measured (_is=
_ there a metric, or are we
just reckoning here?), and so on.
</p>

<p>
While reminding myself of exactly what "correct by construction" meant, I c=
ame across a fantastic
lecture by Martyn Thomas[1] that neatly defines it (and goes into some deta=
il of how to go about
achieving it); from the accompanying lecture notes[2]:
</p>

<blockquote>
<p>
=E2=80=A6you start by writing a requirements specification in a way that ma=
kes it possible to analyse whether
it contains logical omissions or contradictions. Then you develop the softw=
are in a way that provides
very strong evidence that the program implements the specification (and doe=
s nothing else) and that
it will not fail at runtime. We call this making software =E2=80=9Ccorrect =
by construction=E2=80=9D, because the way
in which the software is constructed guarantees that it has these propertie=
s.
</p>
</blockquote>

<p>
While we aren't working with anything as formal as a theorem prover when we=
 are programming in OCaml,
it does provide us with a tremendous degree of certainty about how our prog=
rams will behave. One of the
greatest sources of that certainty is its default of requiring functions an=
d pattern matches to be
exhaustive with regard to the domain of values of the type(s) they accept; =
i.e. a function that accepts
a <code>result</code> must provide cases for all of its known constructors:
</p>

<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><span style=3D"color: #000000; font-weight: bo=
ld;">let</span> <span style=3D"color: #0000ff;">get</span> =3D <span style=
=3D"color: #a020f0;">function</span> <span style=3D"color: #000000; backgro=
und-color: #ffffff;">Ok</span> v -&gt; v
</pre>
</div>
<pre class=3D"example">
$ ocamlc -g -o demo.exe src/demo.ml
File "src/demo.ml", line 15, characters 10-28:
15 | let get =3D function Ok v -&gt; v
               ^^^^^^^^^^^^^^^^^^
Warning 8: this pattern-matching is not exhaustive.
Here is an example of a case that is not matched:
Error _
</pre>

<p>
This one way we "provide evidence" to the OCaml compiler that our code does=
 not not contain "logical
omissions", to use Prof. Thomas' nomenclature.
</p>

<p>
There are ways to relax this requirement, though. Aside from simply telling=
 the compiler to not bother
us with its concerns via an attribute:
</p>

<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><span style=3D"color: #000000; font-weight: bo=
ld;">let</span> <span style=3D"color: #0000ff;">get</span> =3D <span style=
=3D"color: #a020f0;">function</span> <span style=3D"color: #000000; backgro=
und-color: #ffffff;">Ok</span> v -&gt; v <span style=3D"color: #483d8b;">[@=
@warning </span><span style=3D"color: #8b2252;">"-8"</span><span style=3D"c=
olor: #483d8b;">]</span>
</pre>
</div>

<p>
=E2=80=A6we could simply use exceptions instead. For example, an exception-=
based variant of the program I
started with earlier:
</p>

<div class=3D"org-src-container">
<pre class=3D"src src-ocaml"><span style=3D"color: #a020f0;">exception</spa=
n> <span style=3D"color: #000000; background-color: #ffffff;">Unimplemented=
</span>

<span style=3D"color: #000000; font-weight: bold;">let</span> <span style=
=3D"color: #0000ff;">a</span> <span style=3D"color: #a0522d;">x</span> =3D
  <span style=3D"color: #a020f0;">if</span> x &gt; 0
  <span style=3D"color: #a020f0;">then</span> 0
  <span style=3D"color: #a020f0;">else</span> <span style=3D"color: #483d8b=
;">raise</span> <span style=3D"color: #000000; background-color: #ffffff;">=
Unimplemented</span>

<span style=3D"color: #000000; font-weight: bold;">let</span> <span style=
=3D"color: #a0522d;">_</span> =3D <span style=3D"color: #228b22;">Format.</=
span>printf <span style=3D"color: #8b2252;">"%d at ."</span> <span style=3D"co=
lor: #a52a2a;">@@</span> a (int_of_string <span style=3D"color: #a52a2a;">@=
@</span> <span style=3D"color: #228b22;">Sys.</span>argv.(1))
</pre>
</div>

<p>
This approach is less correct by any measure: the <code>Unimplemented</code=
> exception is not indicated in the
signature of <code>a</code>, making it easy to call <code>a</code> without =
handling the exception, or being aware of its
possibility at all. Insofar as the exceptions in question are not intended =
to be fatal,
program-terminating errors, this approach absolutely increases the potentia=
l for "logical omissions",
increases the potential for programs to fail at runtime, and hobbles the ex=
haustivity guarantees that
the OCaml compiler provides for us otherwise.
</p>

<p>
Later in the reparse announcement thread, @rixed said (presumably in respon=
se to this tension):
</p>

<blockquote>
<p>
If only we had a way to know statically which exceptions can escape any fun=
ctions that would be the
best of both worlds!
</p>
</blockquote>

<p>
And indeed, this approach of incorporating known thrown exception types int=
o function signatures is a
known technique, (in)famously included in Java from the beginning (called <=
b>checked exceptions</b>), but
widely disdained. I suspect that disdain was more due to Java's other weakn=
esses in exception handling
than the principal notion of propagating exception types in function/method=
 signatures. It would be
interesting to see something like checked exceptions experimented with in O=
Caml, though it may be that
doing so would nullify one of the primary benefits that those preferring ex=
ceptions enjoy (perceived
improved aesthetics/clarity), and/or the work needed to achieve this might =
approximate the typed effect
handling approaches that @lpw25 et al. have been pursuing for some time.
</p>

<p>
[1]: <b>Making Software 'Correct by Construction'</b>
<a href=3D"https://www.gresham.ac.uk/lectures-and-events/making-software-co=
rrect-by-construction">https://www.gresham.ac.uk/lectures-and-events/making=
-software-correct-by-construction</a> <br />
[2]: <a href=3D"https://www.gresham.ac.uk/lecture/transcript/download/makin=
g-software-correct-by-construction/">https://www.gresham.ac.uk/lecture/tran=
script/download/making-software-correct-by-construction/</a>
</p>
</div>
</div>
</div>


<div id=3D"outline-container-org5511f23" class=3D"outline-3">
<h3 id=3D"org5511f23">bnguyenvanyen said</h3>
<div class=3D"outline-text-3" id=3D"text-org5511f23">
<p>
Just chiming in to note that there has been an interesting discussion on th=
is topic two years ago:
<a href=3D"https://discuss.ocaml.org/t/specific-reason-for-not-embracing-th=
e-use-of-exceptions-for-error-propagation/1666/40">https://discuss.ocaml.or=
g/t/specific-reason-for-not-embracing-the-use-of-exceptions-for-error-propa=
gation/1666/40</a>
</p>

<p>
It's also interesting to note that that discussion also ended up talking ab=
out typed effects.
As I understand it, they would indeed subsume checked exceptions, and I'm q=
uite excited about them.
</p>
</div>
</div>


<div id=3D"outline-container-org36883ce" class=3D"outline-3">
<h3 id=3D"org36883ce">Yawar Amin also said</h3>
<div class=3D"outline-text-3" id=3D"text-org36883ce">
<p>
Cristiano Calcagno has been doing some pretty interesting work on this:
<a href=3D"https://github.com/reason-association/reanalyze/blob/72712393459=
d7e132c78e0700abffc5fc4cd09b8/EXCEPTION.md">https://github.com/reason-assoc=
iation/reanalyze/blob/72712393459d7e132c78e0700abffc5fc4cd09b8/EXCEPTION.md=
</a>
</p>

<p>
Let me quote the central concept from there:
</p>

<blockquote>
<p>
The exception analysis is designed to keep track statically of the exceptio=
ns that might be raised at
runtime. It works by issuing warnings and recognizing annotations. Warnings=
 are issued whenever an
exception is raised and not immediately caught. Annotations are used to pus=
h warnings from he local
point where the exception is raised, to the outside context: callers of the=
 current function. Nested
functions need to be annotated separately.
</p>
</blockquote>
</div>
</div>


<div id=3D"outline-container-orgad1703b" class=3D"outline-3">
<h3 id=3D"orgad1703b">Later in the thread, Chet Murthy said</h3>
<div class=3D"outline-text-3" id=3D"text-orgad1703b">
<p>
I'm going to address the general issue of "programming with monads", and no=
t specifically the result
monad, b/c I think it's just an instance of the general phenomenon.
</p>

<p>
TL;DR In 1992, when someone told me about "programming with monads", I repl=
ied that I <b>already</b>
programmed with monads: I used the "SML Monad".  And this LtU post seems to=
 me to be pithily succinct (<a href=3D"http://lambda-the-ultimate.org/node/=
5504">http://lambda-the-ultimate.org/node/5504</a> )
</p>

<p>
(1) when we talk about program correctness, we mean two things: reasoning a=
bout programs, and
type-safety.  I'll address each in turn below.
</p>

<p>
(2) All monadic transformations of which I am aware (exceptions, state, con=
trol, I/O) are direct
equivalents to the "standard semantics" for such language-features, e.g. as=
 described in Michael J.C.
Gordon's book <i>The Denotational Description of Programming Languages</i>.=
  <b>Programming with monads is
programming with some combinators and macros, on the right-hand-side of the=
 denotational interpreters</b>
in that book.
</p>

<p>
(3) "reasoning about programs" has historically meant "equational reasoning=
", and IIUC,
Felleisen&amp;Sabry's work (and follow-on works) proved pretty conclusively=
 that anything you can prove
about the right-hand-side of the denotational semantics interpeter defiitio=
n, you can "pull back" to
equational reasoning with extra rules, on the left-hand-side of the DS inte=
rpreter.
</p>

<p>
(4) "type safety":
</p>

<blockquote>
<p>
If only we had a way to know statically which exceptions can escape any fun=
ctions
</p>
</blockquote>

<p>
There was a cottage industry of "effect type systems" to capture/reason-abo=
ut exceptions, state, maybe
other things, decades ago.  They were judged too cumbersome for programmers=
 to use, and hence died-out.
&gt;10yr ago there was a caml-light (OCaml?) variant that checked exception=
s in function-types; it didn't
catch on.  Look at Java, where some exceptions are "checked" and others are=
 not: some exceptions, it's
just too cumbersome to track in the type system.  And so either your "resul=
t" monad only captures some
of the exceptions, or it's going to be wildly cumbersome.
</p>

<p>
(5) Monads are less-efficient than direct-style, memory-wise.  For me, the =
moment in 1992 when I (an
avowed SML/NJ bigot) became convinced of the superiority of caml-light (not=
withstanding 2.5x slower on
average) was when I realized that it was -so- much less memory-intensive.  =
Because it didn't allocate
stack-frames on the heap, and closures started out on the stack and only mo=
ved to the heap on-demand.
Henry Baker made the observation &gt;20yr ago that the stack is a form of n=
ursery.  Writing in monadic
style is sacrificing this obviously performance advantage.  In the era of m=
ulticore, arguments made
back then about memory, can be recast as arguments about the cache today, s=
ince (as hardware designers
put it) "memory is at infinity" today.
</p>

<p>
P.S. And yet, I use monads sometimes, too.  Rarely.  But for instance, it's=
 a good model for (e.g.)
writing a type-checker that wants to type-check a list of expressions (no u=
nification, hence no
side-effects) and not stop at the firs type-error, but rather gather togeth=
er errors from all the
expressions in the list, and produce an error with all of them combined.  S=
o the type-checker at the
top of each member of the list catches any raised exception, stores it in a=
n accumulator, and goes on
to the rest of the list; at the end of the list, if the accumulator is empt=
y, it returns the list of
result-types; otherwise it raises an exception containing list of errors st=
ored in the accumulator.
</p>

<p>
It's rare, and if the Result monad didn't exist, I'd hack something togethe=
r, but &#x2026;. it's literally
the only use I can think of, that wasn't driven by a library (e.g. <code>bo=
s</code>) using the Result monad itself
(and my needing to use that library).
</p>

<p>
And this <b>efficiency</b> is the real reason that exception-based backtrac=
es are better: IIUC, OCaml
exceptions are <b>really</b> cheap because they don't materialize that back=
trace until demanded.  It means
that you have to be careful what code you put between the "try-with" and th=
e demand for the backtrace,
but it's <b>efficient</b>.  Materializing the backtrace for every exception=
 raised would be &#x2026;.. pretty
horrendously inefficient, and yet that's what you have to do if you use the=
 result monad.
</p>
</div>
</div>


<div id=3D"outline-container-orgf179027" class=3D"outline-3">
<h3 id=3D"orgf179027">Malcolm also said</h3>
<div class=3D"outline-text-3" id=3D"text-orgf179027">
<p>
I wrote two blog posts on my experience using <code>result</code> awhile ag=
o, linked below.  Much of it still
holds.  Many of the pain points others have mentioned do exist, but in my j=
udgement, <b>given the current
state of Ocaml</b>, results are strictly better (at the very least at the A=
PI boundary, assuming you can
convince yourself no exceptions escape it) than exceptions.  I also believe=
 that the reasonable error
values are necessary.  For example, I know some APIs like some variation of=
 <code>('a, string) result</code>
which, IMO, is not a great API as I end up comparing strings and hoping the=
 string value is actually
part of the API and not some rando value tossed in there.  Double for when =
meaningful aspects of the
error are encoded in the string and I have to decode it to decide what to d=
o.
</p>

<p>
For my own things I do require that all errors are convertible to a string =
so I can just show them to
the user, this is especially important for development and debugging, IME. =
 This is one of the few
places where I do wish we had something like type classes so I could do som=
ething like:
</p>

<div class=3D"org-src-container">
<pre class=3D"src src-ocaml">foo ()
&gt;&gt;=3D <span style=3D"color: #a020f0;">function</span>
| <span style=3D"color: #000000; background-color: #ffffff;">Ok</span> () -=
&gt; yadda
| <span style=3D"color: #000000; background-color: #ffffff;">Error</span> e=
rr -&gt; show err
</pre>
</div>

<p>
YMMV
</p>

<p>
<a href=3D"http://functional-orbitz.blogspot.com/2013/01/experiences-using-=
resultt-vs-exceptions.html">http://functional-orbitz.blogspot.com/2013/01/e=
xperiences-using-resultt-vs-exceptions.html</a>
</p>

<p>
<a href=3D"http://functional-orbitz.blogspot.com/2013/01/introduction-to-re=
sultt-vs-exceptions.html">http://functional-orbitz.blogspot.com/2013/01/int=
roduction-to-resultt-vs-exceptions.html</a>
</p>
</div>
</div>
</div>




<div id=3D"outline-container-org815fc3f" class=3D"outline-2">
<h2 id=3D"13">Making web calls to OCaml</h2>
<div class=3D"outline-text-2" id=3D"text-13">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/making-web-calls-to-ocaml/6=
932/1">https://discuss.ocaml.org/t/making-web-calls-to-ocaml/6932/1</a>
</p>
</div>

<div id=3D"outline-container-orgda4f381" class=3D"outline-3">
<h3 id=3D"orgda4f381">Peter Fishman asked</h3>
<div class=3D"outline-text-3" id=3D"text-orgda4f381">
<p>
Hi, I am new to OCaml and in fact, I'm not a even a programmer (although I =
did study CS at Cornell back
in the 80's and learned functional programming in a language called scheme.=
)  I am thinking about
developing financial wellness web applications with the underlying computat=
ions in OCaml, but with the
user interface in something else - like java script.  How would a java scri=
pt website make a call to an
Ocaml program (or function)?  Or put another way, can I publish a financial=
 model built in OCaml so
that a web (or mobile) application could call it - passing arguments to the=
 function and receiving back
the result of evaluating the functional expression?    My apologies if this=
 is not asked correctly or
if it is a very basic question, but I am not sure I have the right terminol=
ogy to ask the question
properly!  Help is appreciated!
</p>
</div>
</div>


<div id=3D"outline-container-org1fa02c5" class=3D"outline-3">
<h3 id=3D"org1fa02c5">Wojtek Czekalski replied</h3>
<div class=3D"outline-text-3" id=3D"text-org1fa02c5">
<p>
You can, there are multiple ways to achieve what you want. If I understand =
correctly you want to build
a web server in OCaml and a web app front end. Here's a list of what differ=
ent projects used:
<a href=3D"https://discuss.ocaml.org/t/your-production-web-stack-in-2020/66=
91/11">https://discuss.ocaml.org/t/your-production-web-stack-in-2020/6691/1=
1</a>
</p>

<p>
Edit: To elaborate because I realized I didn't answer your question, typica=
lly you'd have a frontend
which uses something like <a href=3D"https://en.wikipedia.org/wiki/Represen=
tational_state_transfer">rest</a> or
<a href=3D"https://en.wikipedia.org/wiki/GraphQL">graphql</a> to fetch data=
 from your server. There's a lot to
unpack here. I'm sure you'll be able to pull it off but if you're not comfo=
rtable with programming make
sure that you approach the problem gradually and make sure to avoid analysi=
s paralysis.
</p>
</div>
</div>


<div id=3D"outline-container-org9f31e80" class=3D"outline-3">
<h3 id=3D"org9f31e80">Yawar Amin also replied</h3>
<div class=3D"outline-text-3" id=3D"text-org9f31e80">
<p>
Hi, a couple of thoughts here. As @wokalski said, you will need to set up a=
 server application, and a
web frontend. I don't know much about your background but, my guess is you =
would like to avoid
complexity and keep things simple. Personally here's what I would recommend:
</p>

<ol class=3D"org-ol">
<li><p>
Write a simple command-line application, in the style of a <a href=3D"https=
://en.wikipedia.org/wiki/Filter_(software)#Unix">Unix filter</a>, in OCaml =
that takes 'requests' in the form of plain text on standard input and print=
s its calculation result to standard output. E.g., to take an input of <cod=
e>add 2 2</code> and output <code>4</code>, it could work like this:
</p>

<pre class=3D"example">
$ echo 'add 2 2' | my_calculator.exe
4
</pre></li>

<li>Next, use <a href=3D"https://github.com/joewalnes/websocketd">websocket=
d</a> to wrap your calculator tool and serve it over WebSocket, which is a =
standard Web technology that allows clients to continuously talk to servers=
 (2-way communication). So, clients could send a plain text command like <c=
ode>add 2 2</code> (note, exactly the same as you would have on the command=
 line), and get back a response <code>4</code>.</li>

<li>Finally, write a web application (just some HTML and JavaScript) that c=
onnects to the WebSocket server from step (2) and sends and receives messag=
es. Here is an example of that: <a href=3D"https://developer.mozilla.org/en=
-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications">http=
s://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSock=
et_client_applications</a></li>
</ol>

<p>
The reason I am recommending this strategy, is to let you start small and s=
imple, and skip over much of
the complexity of dealing with modern web application development. You can =
focus on writing your
calculator as a simple command-line tool, and 'outsource' the server part t=
o a specialized tool.
</p>

<p>
Final thought: if you are working on a financial wellness tool, you almost =
certainly need decimal
arithmetic (as opposed to binary arithmetic from OCaml's built-in float typ=
e). You will want to use a
decimal package like <a href=3D"https://github.com/janestreet/bigdecimal">h=
ttps://github.com/janestreet/bigdecimal</a> , or (disclaimer: mine)
<a href=3D"https://opam.ocaml.org/packages/decimal/">https://opam.ocaml.org=
/packages/decimal/</a> .
</p>

<p>
Good luck!
</p>
</div>
</div>


<div id=3D"outline-container-org432e2a2" class=3D"outline-3">
<h3 id=3D"org432e2a2">=F0=9F=98=B7 Marcus Rohrmoser also replied</h3>
<div class=3D"outline-text-3" id=3D"text-org432e2a2">
<p>
@peter  I think I'm doing something similar =E2=80=93 a simple web tool for=
 geographic calculations from
character sequences called geohash to gps coordinate pairs and vice versa. =
Here is it:
<a href=3D"https://demo.mro.name/geohash.cgi/u154">https://demo.mro.name/ge=
ohash.cgi/u154</a>. You'll find the source there, too.
</p>

<p>
Key is, I scale towards n=3D1, need no state.
</p>

<p>
The backend is &lt;200 LOC to handle all the http stuff (there isn't much, =
no auth, no state, no cookies)
and another ~100 LOC for the actual computation.
</p>

<p>
1 dependency, no 'modern' web toolkit, no client libs/frameworks, no concur=
rency
</p>
</div>
</div>
</div>




<div id=3D"outline-container-orge0d9ad3" class=3D"outline-2">
<h2 id=3D"14">wasmtime 0.0.1: lightweight WebAssembly runtime</h2>
<div class=3D"outline-text-2" id=3D"text-14">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-wasmtime-0-0-1-lightwei=
ght-webassembly-runtime/6936/1">https://discuss.ocaml.org/t/ann-wasmtime-0-=
0-1-lightweight-webassembly-runtime/6936/1</a>
</p>
</div>

<div id=3D"outline-container-orgc04fd2a" class=3D"outline-3">
<h3 id=3D"orgc04fd2a">Laurent Mazare announced</h3>
<div class=3D"outline-text-3" id=3D"text-orgc04fd2a">
<p>
We just released a first version of a package providing OCaml bindings to t=
he
<a href=3D"https://wasmtime.dev">wasmtime</a> WebAssembly runtime. The pack=
age is available on opam and can be found
in this <a href=3D"https://github.com/LaurentMazare/ocaml-wasmtime">GitHub =
repo</a>. It can be used to run .wasm
modules in an OCaml process, including modules making system calls through =
<a href=3D"https://wasi.dev/">WASI</a>.
For now, the package only provides a low-level api closely matching the Rus=
t implementation. We intend
to provide a higher level api on top of this.
The GitHub repo contains various examples in the <code>tests</code> directo=
ry which reproduce some examples from
the main wasmtime repo.
Feedback/issue reports are very welcome!
</p>
</div>
</div>
</div>




<div id=3D"outline-container-orge0981aa" class=3D"outline-2">
<h2 id=3D"15">First release of Lwt-exit</h2>
<div class=3D"outline-text-2" id=3D"text-15">
<p>
Archive: <a href=3D"https://discuss.ocaml.org/t/ann-first-release-of-lwt-ex=
it/6938/1">https://discuss.ocaml.org/t/ann-first-release-of-lwt-exit/6938/1=
</a>
</p>
</div>

<div id=3D"outline-container-org6579f97" class=3D"outline-3">
<h3 id=3D"org6579f97">Rapha=C3=ABl Proust announced</h3>
<div class=3D"outline-text-3" id=3D"text-org6579f97">
<p>
On behalf of <a href=3D"https://nomadic-labs.com/">Nomadic Labs</a>, I'm ha=
ppy to announce the first release of
Lwt-exit, a small opinionated library to cleanly handle exits and signals i=
n applications that use Lwt.
</p>

<p>
The library is available through opam: <code>opam install lwt-exit</code>,
hosted on gitlab: <a href=3D"https://gitlab.com/nomadic-labs/lwt-exit">http=
s://gitlab.com/nomadic-labs/lwt-exit</a>,
distributed under the MIT license: <a href=3D"https://gitlab.com/nomadic-la=
bs/lwt-exit/-/blob/master/LICENSE">https://gitlab.com/nomadic-labs/lwt-exit=
/-/blob/master/LICENSE</a>
and the documentation is available online: <a href=3D"https://nomadic-labs.=
gitlab.io/lwt-exit/">https://nomadic-labs.gitlab.io/lwt-exit/</a>
</p>

<p>
This library is used in the <a href=3D"https://gitlab.com/tezos/tezos">Tezo=
s codebase</a> to clean up system
resources (flush buffered writes, cleanly close p2p connections, etc.) duri=
ng exits. It is also used to
attach signal handlers (both for interactive use via Ctrl+C and for daemoni=
sation via systemctl).
</p>
</div>
</div>
</div>




<div id=3D"outline-container-org27184e8" class=3D"outline-2">
<h2 id=3D"org27184e8">Old CWN</h2>
<div class=3D"outline-text-2" id=3D"text-org27184e8">
<p>
If you happen to miss a CWN, you can <a href=3D"mailto:alan.schmitt at polytec=
hnique.org">send me a message</a> and I'll mail it to you, or go take a loo=
k at <a href=3D"http://alan.petitepomme.net/cwn/">the archive</a> or the <a=
 href=3D"http://alan.petitepomme.net/cwn/cwn.rss">RSS feed of the archives<=
/a>.
</p>

<p>
If you also wish to receive it every week by mail, you may subscribe <a hre=
f=3D"http://lists.idyll.org/listinfo/caml-news-weekly/">online</a>.
</p>

<div class=3D"authorname">
<p>
<a href=3D"http://alan.petitepomme.net/">Alan Schmitt</a>
</p>

</div>
</div>
</div>
</div>
</body>
</html>


--=-=-=--



More information about the caml-news-weekly mailing list