What are the basic things you reach for in almost every project?


#1

I’m curious what the basic things are that you need in every project. Having to reach for a library every time might suggest some areas that the core language could improve. Here are the things I always reach for:

  • @jaredly’s PPX “let-anything”: https://github.com/jaredly/let-anything
    :point_up:This one, though not strictly necessary, has become one of my most used tools. Being able to use a let binding for async operations has drastically improved the readability of my code. I also use it for the occasional monadic bind on non-async structures.

  • @glennsl’s bs-json: https://github.com/glennsl/bs-json because I almost always have to deal with encoding and decoding JSON, though this has been replaced in most cases by what I’m about to mention below.

  • @ryb73’s PPX “decco”: https://github.com/ryb73/ppx_decco automatically generates JSON encoders and decoders for almost all of the cases I need, and it speeds up development significantly, since I have to work with Json so often.

  • My own https://www.npmjs.com/package/bs-pom for working with Promises. I know there are many libraries out there for promise work, and this one doesn’t pass the “soundness” test. But I’ve found it to be very practical in real-world use (it’s still under development, and almost totally undocumented). But I use this library because it allows promises to reject, which I am taking advantage of on the server, and uses Bluebird under the hood to generate a long stack-trace (preserved through async calls!) that can be enabled in production for increased debuggability (a huge win when doing server work). It also offers modules for compatibility with let-anything, named monadic functions for chaining promises, and their haskell-ish infix equivalents like <$> (which I almost never use anymore because of let-anything).

Without these extra tools, the language feels incomplete for the tasks I’m performing. How about you? What libs are you constantly reaching for?


#2

Dependencies I always end up adding to my BuckleScript projects:

  • Atdgen for JSON. I always ended up missing Atdgen no matter what JSON deriver I used, so nowadays I’m sticking with it.

  • bs-webapi for all my DOM needs.

  • My go-to used to be ppx_let for monadic let-bindings. More recently, I’m using the new built-in syntax with OCaml 4.08, and reason-macros with BuckleScript.

  • For promises, I either use Repromise, or roll my own. Repromise is great when I need to deal with JS interop a lot. Most of the time, I define a Promise_result module that deals with ('a, 'b) Result.t Promise.t and never use promise rejection.

  • ReasonReact when I know I’ll benefit from React component ecosystem, or when working with other React developers. Otherwise, I often go with bucklescript-tea.

  • Containers is my standard library of choice.

  • I don’t want to get into native OCaml libs, but devtool-wise, I can’t imagine living without Merlin and OCamlFormat.

  • I also found Tailwind to be a great complement to my Reason/OCaml frontend projects.


#3

Does it generate good JavaScript code? I thought the whole idea of Belt (or at least the Belt. part of it) was that using OCaml starting library results in bloated JS.


#4

I have a fork of it that uses some Belt functions under the hood: https://github.com/glean-dev/ocaml-containers. Changes are very ad-hoc and not well-thought-out, but it’s serving me well at the moment. That said, I still use Belt data structures over stdlib ones. Oh, and I use ContainersLabels almost exclusively, and prefer labelled APIs.

I should mention that many of my choices above are driven by my desire to share as much code and idioms I can between client and server, and I really like OCaml library ecosystem. So, take it with a grain of salt.


#5

Not a library but I like setting somewhat stricter warnings and errors and adjusting as necessary for better safety and often better coding style (e.g. enforcing private modules). I wrote about it here https://dev.to/yawaramin/ocaml-reasonml-best-practice-warnings-and-errors-4mkm


#6

I wonder how’s the Tablecloth project coming along. I have a feeling you might like it :slight_smile:


#7

I’ve replaced all of my standard dependencies with relude and I’ve been very pleased with the results. I especially enjoy using the IO module and the built in Validation module makes user input validation easy.