18

This might be a stupid question, but since OCaml is not pure and has side effects built-in, what is the use of monads in OCaml?

Bob Fang
  • 6,963
  • 10
  • 39
  • 72
  • Monads are like "programmable semicolons" so they can be used for asynchronous or "remote" programming or normal sequencing. – aoeu256 Mar 27 '21 at 22:46
  • The semicolons in OCAML have a "single" meaning decided by the language. By using "custom semicolons" you can change the meaning of the semicolons later on. Another thing is creating a mini-language where your semicolons are only compatible with certain "statements" or "semantics" or "procedures" so that you can encode in the type system what statements you are going to use in a certain block / pipeline. – aoeu256 Mar 27 '21 at 22:59

4 Answers4

28

Monads have nothing to do with purity, except that a pure language without Monads would be almost entirely useless.

In layman's terms, a Monad is just a set of rules that describe how a sequence of steps can be executed. Having a Monad abstraction gives you the ability to define a DSL for executing stuff. A Monad can be built to intelligently handle things like exceptions, ATOMIC rollbacks/commits, retry logic, sleeping between each step, or whatever.

Here are some examples of Monads:

https://wiki.haskell.org/Monad#Interesting_monads

I realize that this list is for Haskell, which is a pure language, but don't let that confuse you.

You don't need to understand category theory to understand what a Monad is, contrary to popular belief. A monad basically has 2 things: (paraphrased from this wikipedia article)

  1. A unit function, defined as (a -> M a), called "return" in Haskell, used to put a value into the context of a Monad.

  2. A binding operation, defined as (M t -> (t -> M u) -> M u), which looks scary but if you look carefully, this is a function that gets invoked between each step of the process, this is where you inject the good stuff.

Depending on the language, there may be more things, but this is the heart of it.

James Watkins
  • 4,806
  • 5
  • 32
  • 42
  • Pure languages aren't useless. It depends what use you have of them. For a proof-assistant, I believe you would rather have no side effect at all. – Théo Winterhalter Apr 25 '15 at 08:55
  • 10
    @Sheeft at some point you need side effects, if only to get the result of your computation. A language that cant do this is hardly a "programming language" and is instead a formal notation. – James Watkins Apr 25 '15 at 16:19
  • I just meant, that if you see a function as a proof, you only care about its termination and type, not about what it computes. But I agree this is not for the same purpose. – Théo Winterhalter Apr 25 '15 at 20:17
  • @JamesWatkins point of interest maybe: as I understand it originally in Haskell there was no operator or command statement to perform the final output and it is left up to the computing environment to retrieve it. That is pretty much some i/o I guess, but it isn't explicitly part of the language – James Cat Mar 26 '16 at 15:54
  • @JamesCat Haskell is a very academic language. It does not surprise me that the designers would leave out side-effects until the last minute. Lack of I/O in a language spec is not practical. There's a big difference between what can be done and what should be done. – James Watkins Mar 26 '16 at 17:05
  • 3
    The first versions of Haskell's IO subsystem didn't use monads, either. There was one intensely awkward version that had `main :: [RequestResult] -> [Request]` (roughly speaking) and depended crucially on laziness, but you can also use a continuation-based approach with just ordinary algebraic datatypes. It ends up looking pretty similar to monadic IO, but results in less generalizable and reusable code, so it was eventually replaced by monads. – Ben Millwood Aug 28 '16 at 12:54
9

Whilst OCaml supports the standard side-effects provided by most languages, this does not include all possible side-effects. There are a number of effects which OCaml does not provide native support for. Many of these effects can be encoded using Monads. For example,

  • Concurrency (see Lwt and Async libraries)
  • Non-deterministic choice
  • First-class continuations
  • Ambivalent choice and backtracking

Using more sophisticated representations of computation, such as parameterised monads, even more exotic effects can be encoded. For example,

  • Polymorphic state
  • Linear resources
Leo White
  • 1,131
  • 5
  • 9
4

While OCaml allows one to write imperative code it is still functional by its nature, it is used by functional programmers. And we prefer to use persistent data structures and algorithms whenever possible.

What concerning your question, then in particular monads are usefull, for asynchronous computations, e.g., Lwt, Async, where they're used to bind computations (instead of usual way of setting callbacks). Also, monads are used for error handling, instead of exceptions. Also, monads are very helpful in writing parsers, see mparser library. There're also other uses, I enumerated only the most popular.

In general monads just allow you to hide a complex control flow under simple sequential syntax.

ivg
  • 34,431
  • 2
  • 35
  • 63
2

This may be a lot more naive than the answer you want but a monad is just a simple abstraction that's useful for structuring computation. It's a little math thing like an equivalence relation (or for people smarter than I am, like a group). Once you learn what they are, you see them everywhere, and they help organize your thinking.

Jeffrey Scofield
  • 65,646
  • 2
  • 72
  • 108