Ppx_let vs. binding operators

It seems that there are two alternatives to have monadic lets: using ppx_let, or binding operators as described in here. Which one is recommended? Are there different usage cases for each?

I was using Base, in particular, the module Result. It has support for ppx_let with Result.Let_syntax as follows:

    let open Result.Let_syntax in
    let%bind x = ... in

Is there something similar already built-in in Result for using binding operators?

I don’t know that there’s a universal answer here.

At Jane Street, we make use of ppx_let and don’t use OCaml’s new built-in binding operators. This is in part because we have several extensions that aren’t supported by the built-in operators yet (e.g., match%bind), and in part because there are some future improvements to our monadic libraries that we’re contemplating that would move them yet further away from what the built-in language support can do (e.g., having binding operators take location information to make it possible for various monadic and applicative libraries like Async, Incremental, and Bonsai to provide better error reporting and debugging tools).

It’s a little unclear how this will shake out longer term, but for now, ppx_let is very much what we use.



There doesn’t seem to be a let* operator for standard library Result.t variants provided in the Result module, if that is what you were referring to, but to make your own you can just do:

let ( let* ) = Result.bind

I don’t use the Jane Street libraries but the transformations should all be the same, except that I have been told that with Lwt, let%lwt provides better debugging support for the concurrency monad than does aliasing let* to Lwt.bind.

Given a choice between having to use a PPX and not, I would rather not. PPXs are difficult to maintain and add complexity to the compilation pipeline.

There is an open PR adding let operators to the OCaml standard library, it just hasn’t been approved yet (probably no one got around to it).

1 Like

I appreciate the perspective, but PPXs provide so much utility I find the cost well justified, especially as the standard open source tooling (notably, Dune and Merlin) has made use of PPXs so much better.

The “deriving” PPXs are I think the most important ones. Writing hash functions, comparison functions, serializers, deserializers, etc, by hand, is dull, repetitive, and error prone. I find automating all of these away is well worth the costs of learning how to use the PPX ecosystem. And once you’ve bought in to, a useful-but-less-critical example like ppx_let is a clearer win.