[cwn] Attn: Development Editor, Latest OCaml Weekly News

Alan Schmitt alan.schmitt at polytechnique.org
Tue Sep 10 06:11:01 PDT 2019


Hello

Here is the latest OCaml Weekly News, for the week of September 03 
to
10, 2019.

Table of Contents
─────────────────

Implicits for the masses
Ppx_yojson_conv: deriving plugin to generate Yojson conversion 
functions
Memory usage in recursive function as infinite loop
Receiving/sending http requests in an Ocaml program
Other OCaml News
Old CWN


Implicits for the masses
════════════════════════

  Archive:
  <https://sympa.inria.fr/sympa/arc/caml-list/2019-09/msg00003.html>


Oleg announced
──────────────

  This is to announce a simple, plain OCaml library to experiment 
  with
  type-class/implicits resolution, which can be thought of as 
  evaluating
  a Prolog-like program. One may allow `overlapping instances' – 
  or
  prohibit them, insisting on uniqueness. One may make the search 
  fully
  deterministic, fully non-deterministic, or something in-between.
  There is an immediate, albeit modest practical benefit: the 
  facility
  like "#install_printer", which was restricted to top-level, is 
  now
  available for all – as a small, self-contained, plain OCaml 
  library
  with no knowledge or dependencies on the compiler internals. We 
  show
  an example at the end of the message.

  This message has been inspired by the remarkable paper
        Canonical Structures for the working Coq user
        Assia Mahboubi, Enrico Tassi
        DOI: 10.1007/978-3-642-39634-2_5
  Its introduction is particularly insightful: the power of
  (mathematical) notation is in eliding distracting details. Yet 
  to
  formally check a proof, or to run a program, the omitted has to 
  be
  found. When pressed to fill in details, people `skillful in the 
  art'
  look in the database of the `state of the art', with the context 
  as
  the key. Computers can be programmed similarly; types well 
  represent
  the needed context to guide the search.

  Mahboubi and Tassi's paper explains very well how this eliding 
  and
  filling-in is realized, as a programmable unification, and used 
  in
  Coq. Yet their insights go beyond Coq and deserve to be known 
  better.
  This message and the accompanying code is to explain them in 
  plain
  OCaml and encourage experimentation. It could have been titled
  `Canonical Structures for the working OCaml (meta) programmer'.

  The rudiment of canonical structures is already present in 
  OCaml, in
  the form of the registry of printers for user-defined types. 
  This
  facility is available only at the top-level, however, and deeply
  intertwined with it. As a modest practical benefit, this 
  facility is
  now available for all programs, as a plain, small, 
  self-contained
  library, with no compiler or other magic. The full potential of 
  the
  method is realized however in (multi-) staged programming. In 
  fact,
  I'm planning to use it in the upcoming version of MetaOCaml to
  implement `lifting' from a value to the code that produces it –
  letting the users register lifting functions for their own data 
  types.


  • <http://okmij.org/ftp/ML/canonical.ml>
    The implementation and the examples, some of which are noted 
    below.
  • <http://okmij.org/ftp/ML/trep.ml>
    A generic library of type representations: something like 
    Typeable
    in Haskell. Some day it may be built-in into the compiler
  • <http://okmij.org/ftp/ML/canonical_leadup.ml>
    A well-commented code that records the progressive development 
    of
    canonical.ml. It is not part of the library, but may serve as 
    its
    explanation.

  Here are a few examples, starting with the most trivial one
  ┌────
  │ module Show = MakeResolve(struct type 'a dict = 'a -> string 
  end)
  │ let () = Show.register Int string_of_int    (* Define 
  `instances' *)
  │ let () = Show.register Bool string_of_bool
  │ Show.find Int 1;;
  └────

  However contrived and flawed, it is instructive. Here (Int : int 
  trep)
  is the value representing the type int. The type checker can 
  certainly
  figure out that 1 is of the type int, and could potentially save 
  us
  trouble writing Int explicitly. What the type checker cannot do 
  by
  itself is to find out which function to use to convert an int to 
  a
  string. After all, there are many of them. Show.register lets us
  register the *canonical* int->string function. Show.find is to 
  search
  the database of such canonical functions: in effect, finding 
  *the*
  evidence that the type int->string is populated. Keeping 
  Curry-Howard
  in mind, Show.find does a _proof search_.

  The type of Show.find is 'a trep -> ('a -> string). Compare with
  Haskell's show : Show a => a -> String (or, desuraging => and 
  Show)
  show : ('a -> string) -> ('a -> string).  Haskell's show indeed 
  does
  not actually do anything: it is the identity function. All the 
  hard
  work – finding out the right dictionary (the string producing
  function) – is done by the compiler. If one does not like the 
  way the
  compiler goes about it – tough luck. There is little one may do 
  save
  complaining on reddit. In contrast, the first argument of 
  Show.find is
  trivial: it is a mere reflection of the type int, with no 
  further
  information. Hence Show.find has to do a non-trivial work.  In 
  the
  case of int, this work is the straightforward database search – 
  or, if
  you prefer, running the query ?- dict(int,R) against a logic 
  program
  ┌────
  │ dict(int,string_of_int).
  │ dict(bool,string_of_bool).
  └────
  The program becomes more interesting when it comes to pairs:
  ┌────
  │ dict(T,R) :- T = pair(X,Y), !,
  │     dict(X,DX), dict(Y,DY), R=make_pair_dict(DX,DY).
  └────
  Here is how it is expressed in OCaml:
  ┌────
  │ let () =
  │   let open Show in
  │   let pat : type b. b trep -> b rule_body option = function
  │     | Pair (x,y) ->
  │ 	Some (Arg (x, fun dx -> Arg (y, fun dy ->
  │ 	  Fact (fun (x,y) -> "(" ^ dx x ^ "," ^ dy y ^ ")"))))
  │     | _      -> None
  │   in register_rule {pat}
  │
  │ let () = Show.register (Pair(Bool,Bool))
  │ 	   (fun (x,y) -> string_of_bool x ^ string_of_bool y)
  └────

  Our library permits `overlapping instances'. We hence registered 
  the
  printer for generic pairs, and a particular printer just for 
  pairs of
  booleans.

  The library is extensible with user-defined data types, for 
  example:
  ┌────
  │ type my_fancy_datatype = Fancy of int * string * (int -> 
  string)
  └────

  After registering the type with trep library, and the printer
  ┌────
  │ type _ trep += MyFancy : my_fancy_datatype trep
  │ let () = Show.register MyFancy (function Fancy(x,y,_) ->
  │   string_of_int x ^ "/" ^ y ^ "/" ^ "<fun>")
  └────

  one can print rather complex data with fancy, with no further 
  ado:
  ┌────
  │ Show.find (List(List(Pair(MyFancy,Int)))) [[(Fancy ...,5)];[]]
  └────

  As Mahboubi and Tassi would say, proof synthesis at work!

  We should stress that what we have described is not a type-class
  facility for OCaml. It is *meta* type-class facility.  Show.find 
  has
  many drawbacks: we have to explicitly pass the trep argument 
  like
  Int. The resolution happens at run time, and hence the failure 
  of the
  resolution is a run-time exception. But the canonical instance
  resolution was intended to be a part of a type checker. There, 
  the
  resolution failure is a type checking error. The trep argument,
  representing the type in the object program, is also at
  hand. Likewise, the drawbacks of Show.find disappear when we use 
  the
  library in a meta-program (code generator). The library then 
  becomes a
  type-class/implicits facility, for the generated code – the 
  facility,
  we can easily (re)program.


Ivan Gotovchits
───────────────

  Very interesting and thought-provoking writeup, thank you!

  Incidentally, we're investigating the same venues, in our CMU 
  BAP
  project, as we found out that we need the extensibility in the 
  style
  of type classes/canonical structures to decouple complex 
  dependencies
  which arise in the program analysis domain.  In fact, we build 
  our new
  BAP 2.0 framework largely on your [tagless-final] style which, 
  let's
  admit it, works much better with type classes. Therefore we 
  ended up
  implementing extensible type representations along with 
  registries for
  our type classes. Unfortunately, the idea of storing rules in 
  the
  registry didn't visit us, but we're now thinking about how to
  incorporate it (the classes that we have are very nontrivial, 
  usually
  having hundreds of methods, so we're currently using functors to
  manually derive on class from another, and registering the 
  resulting
  structures - but using your approach we can register functors as 
  well
  and automate the derivation). We also didn't generalize the type 
  class
  instantiation, so our solutions do have some boilerplate (but I 
  have
  to admit, that the total number of type classes that we need is 
  not
  very big, so it really never bothered us). What could be 
  surprising is
  that the universe of types actually grew quite large, that large 
  that
  the linear search in the registry is not an option for us 
  anymore. In
  fact, we have so many comparisons between treps, that instead of
  extracting the extension constructor number from an extensible 
  variant
  we had to rely on our own freshly generated identifier. But I'm
  running in front of myself, an important lesson that we have 
  learned
  is that treps should not only be equality comparable but also 
  ordered
  (and even hashable) so that we can implement our registries as 
  hash
  tables. It is also better to keep them abstract so that we can 
  later
  extend them without breaking user code (to implement 
  introspection as
  well as different resolution schemes). This is basically an
  elaboration of your approach (which is also could be commonly 
  found in
  Janestreet's Core (Type_equal.Uid.t) and other implementations 
  of
  existentials). In our case, we ended up with the following
  implementation
  ┌────
  │ type 'a witness = ..
  │
  │ module type Witness = sig
  │   type t
  │   type _ witness += Id : t witness
  │ end
  │
  │ type 'a typeid = (module Witness with type t = 'a)
  │
  │ type 'a key = {
  │   ord : int;
  │   key : 'a typeid;
  │   name : string; (* for introspection *)
  │   show : 'a -> Sexp.t; (* also for introspection *)
  │ }
  └────
  Now, we can use the `ord' field to order types, compare them, 
  store in
  maps, hash tables, and even arrays. E.g., this is how our `teq'
  function looks like,
  ┌────
  │ let same (type a b) x y : (a,b) Type_equal.t =
  │   if x.id =  y.id then
  │     let module X = (val x.key : Witness with type t = a) in
  │     let module Y = (val y.key : Witness with type t = b) in
  │     match X.Id with
  │     | Y.Id -> Type_equal.T
  │     | _ -> failwith "broken type equality"
  │   else failwith "types are not equal"
  └────

  It is often used in the context where we already know that `x.id 
  =
  y.id', e.g., when we already found an entry, so we just need to 
  obtain
  the equality witness (we use Janestreet's Type_equal.T, which is 
  the
  same as yours eq type).

  Concerning the representation of the registry, we also 
  experimented
  with different approaches (since we have a few ways to make a 
  type
  existential in OCaml), and found out the following to be the 
  most
  efficient and easy to work with,

  ┌────
  │ type ordered = {
  │     order : 'a. 'a key -> 'a -> 'a -> int;
  │   } [@@unboxed]
  └────

  Notice, that thanks to `[@@unboxed]' we got a free unpacked
  existential. We will next store `ordered' in our registry, which 
  is a
  hash table,

  ┌────
  │ let ordered : ordered Hashtbl.M(Int).t = Hashtbl.create 
  (module Int)
  └────
  and register it as simple as,
  ┌────
  │   let register: type p. p Key.t -> (p -> p -> int) -> unit = 
  fun key order
  │ ->
  │     Hashtbl.add_exn vtables ~key:(uid key) ~data:{
  │       order = fun (type a) (k : a key) (x : a) (y : a) ->
  │ 	let T = same k key in (* obtain the witness that we found 
  the right structure *)
  │ 	order x y
  │      }
  └────

  Instead of a hashtable, it is also possible to use `ordered 
  array ref'
  (since our `ord' is just an integer which we increment every 
  time a
  new class is declared). This will give us even faster lookup.

  I hope that this was interesting. And if yes, I'm ready to 
  elaborate
  more on our design decision or to hear suggestions and critics. 
  Here
  are a few links:

  • <https://github.com/BinaryAnalysisPlatform/bap> - the BAP 
  project
    per se.
  • <https://binaryanalysisplatform.github.io/knowledge-intro-1> - 
  a
    small introductionary post about BAP 2.0 Knowledge 
    representation
  • 
  <https://github.com/BinaryAnalysisPlatform/bap/blob/master/lib/knowledge/bap_knowledge.ml>
    - the implementation of the knowledge system
  • 
  <https://github.com/BinaryAnalysisPlatform/bap/tree/master/lib/bap_core_theory>
    - The Core Theory, an exemplar type class of the theory that 
    we're
    developing :)


[tagless-final] <http://okmij.org/ftp/tagless-final/index.html>


Ppx_yojson_conv: deriving plugin to generate Yojson conversion 
functions
════════════════════════════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-ppx-yojson-conv-deriving-plugin-to-generate-yojson-conversion-functions/4109/7>


Hhugo announced
───────────────

  @trefis has worked on splitting the ppx_yojson_conv runtime to a
  different library. See
  <https://github.com/janestreet/ppx_yojson_conv_lib>


Memory usage in recursive function as infinite loop
═══════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/memory-usage-in-recursive-function-as-infinite-loop/4320/1>


Diego Guraieb asked
───────────────────

  On my project I have a process that has to run every 1 sec, 
  fetching
  events and doing some work with them.

  Should I use. a while true loop or recursive function?  How does 
  it
  affect memory usage?


Ivan Gotovchits replied
───────────────────────

  A tail recursive function doesn't affect memory usage and is no
  different in that sense from a while/for or any other loop. A 
  tail
  recursive function is such function that calls itself in the 
  tail
  position. In general it means that the recursive call is not 
  followed
  by any other operation, that uses the result of the call. For 
  example,
  this is a tail recursive function

  ┌────
  │ open Printf
  │
  │ let reс loop rounds =
  │    if rounds > 0
  │    then begin
  │       printf "Round %d\n" round;
  │       loop (rounds - 1)
  │    end
  │    else printf "We are done!\n"
  └────

  In this function, the `loop (rounds - 1)' call is in the tail 
  position
  and is not followed by any other expression.

  Any loop could be rewritten using tail-recursion, so if you're 
  having
  a choice between using a while/for loop and a recursive 
  function,
  then, given that recursion is a more natural representation of
  iteration, it is better to use the recursive function, instead 
  of
  relying on adhoc for or while loops.


Chimrod then added
──────────────────

  Nothe that you also can add the [@tailcall] annotation to ensure 
  that
  the function will be properly tranformed in a loop. This code 
  trigger
  a warning at the compilation

  ┌────
  │ open Printf
  │
  │ let rec loop rounds =
  │    if rounds > 0
  │    then begin
  │       printf "Rounds left %d\n" rounds;
  │       try (loop [@tailcall]) (rounds - 1)
  │       with Not_found -> printf "Error\n"
  │    end
  │    else printf "We are done!\n"
  └────

  ┌────
  │ ocamlc test.ml
  │ File "test.ml", line 7, characters 10-41:
  │ Warning 51: expected tailcall
  └────


[@tailcall]
<https://caml.inria.fr/pub/docs/manual-ocaml/manual035.html#sec265>


Receiving/sending http requests in an Ocaml program
═══════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/receiving-sending-http-requests-in-an-ocaml-program/4332/1>


Luc_ML asked
────────────

  I have an Ocaml program that does its job.  Now I would like to 
  make
  it deliver services over the internet as soon as possible.  I'm 
  not
  experienced in the web side of an Ocaml program. I've just 
  studied
  some tutorials.  Could you please indicate me how to setup that 
  in a
  straigth manner?

  I understand that I need two things:
  1. receiving http request:
     • get incoming data flow from listened port
     • transform (json/xml) data in OCaml values

  2. sending http request:
     • transform Ocaml values in json data
     • send data over http (http request targetting IP:port)

  That should be pretty simple for people doing that everyday.

  I see that Yojson can read a json data flow
  (Yojson.Basic.from_channel) and print a json data
  (Yojson.Basic.pretty_to_string).  So it should answer one
  requirement. Am I right?

  I intended to wrap curl command to send request, but there 
  should be
  more elegant methods.

  My main question seems to be: how can I receive and send http 
  requests
  using a json (or xml) object?


Philippe replied
────────────────

  `yojson' is a good choice for the JSON part. Here are two simple
  options for the web server:
  • either `cohttp' [0], to have total control on your server
  • or `opium' [1] which seems well-suited for your task and is 
  more
    high-level (opium runs on top of cohttp)

  [0] <https://github.com/mirage/ocaml-cohttp>
  [1] <https://github.com/rgrinberg/opium>


Other OCaml News
════════════════

From the ocamlcore planet blog
──────────────────────────────

  Here are links from many OCaml blogs aggregated at [OCaml 
  Planet].

  • [On complete ordered fields]
  • [An introduction to fuzzing OCaml with AFL, Crowbar and Bun]
  • [What is algebraic about algebraic effects?]
  • [The blog moved from Wordpress to Jekyll]
  • [OCamlPro’s compiler team work update]
  • [What the interns have wrought, 2019 edition]


[OCaml Planet] <http://ocaml.org/community/planet/>

[On complete ordered fields]
<http://math.andrej.com/2019/09/09/on-complete-ordered-fields/>

[An introduction to fuzzing OCaml with AFL, Crowbar and Bun]
<https://tarides.com/blog/2019-09-04-an-introduction-to-fuzzing-ocaml-with-afl-crowbar-and-bun.html>

[What is algebraic about algebraic effects?]
<http://math.andrej.com/2019/09/03/what-is-algebraic-about-algebraic-effects/>

[The blog moved from Wordpress to Jekyll]
<http://math.andrej.com/2019/09/03/the-blog-moved-from-wordpress-to-jekyll/>

[OCamlPro’s compiler team work update]
<http://www.ocamlpro.com/2019/08/30/ocamlpros-compiler-team-work-update/>

[What the interns have wrought, 2019 edition]
<https://blog.janestreet.com/what-the-interns-have-wrought-2019/>


Old CWN
═══════

  If you happen to miss a CWN, you can [send me a message] and 
  I'll mail
  it to you, or go take a look at [the archive] or the [RSS feed 
  of the
  archives].

  If you also wish to receive it every week by mail, you may 
  subscribe
  [online].

  [Alan Schmitt]


[send me a message] <mailto:alan.schmitt at polytechnique.org>

[the archive] <http://alan.petitepomme.net/cwn/>

[RSS feed of the archives] 
<http://alan.petitepomme.net/cwn/cwn.rss>

[online] <http://lists.idyll.org/listinfo/caml-news-weekly/>

[Alan Schmitt] <http://alan.petitepomme.net/>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.idyll.org/pipermail/caml-news-weekly/attachments/20190910/f1b7b053/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 487 bytes
Desc: not available
URL: <http://lists.idyll.org/pipermail/caml-news-weekly/attachments/20190910/f1b7b053/attachment-0001.pgp>


More information about the caml-news-weekly mailing list