Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Why even have the concept of a monad in Swift? The language is neither lazy nor purely functional, so the problem monads were introduced to solve doesn't exist. You can just write regular code to do I/O.


Monads exist regardless of whether you call them that. They are a mathematical idea. An algebraic structure.

If you made a language that used conditionals based on 1 and 0, it could do boolean logic, even if you didn't include boolean values explicitly.

Monads exist in just about every programming language. They weren't introduced to solve a problem. They already existed, and just happen to be useful to solve certain problems.


I've read that synchronously executed code from a text file is actually a form of monad in itself. Is this true?


Sequences of bytes form a monad. Sequences of machine instructions form a monad. (Indeed, for any x, sequences of x form a monad). This is occasionally a useful fact (e.g. it's what tells you that you can debug an assembly program by debugging the first half, then debugging the second half starting from the state it was in at the end of the first half).

The definition of a monad is really simple - a lot of things form monads. Which is what makes them so powerful, because if you write a function that works on a generic monad, you find you can use that function for a lot of things.


Your question is meaningless as you've written it. An object equipped with a "return" and a "bind" operation is a monad if the operations follow the three monad laws of left identity, right identity and associativity.

To say whether something is a monad or not, you must first identify the object you're talking about and describe its "return" and "bind" operations.


They weren't introduced to solve a problem.

Monads were definitely introduced to Haskell as a way to solve the problem of I/O -- see Section 7 of http://www.scs.stanford.edu/~dbg/readings/haskell-history.pd... for more details.

It's true that monads existed as a concept in category theory before they were used in programming languages, but they didn't really catch on until their use in Haskell. Certainly you don't see articles about applying other esoteric category theory concepts to Swift programs.


Monads are generally useful beyond IO, and pure programming style is available (and recommended) in almost every language.

From the article you linked:

"Although Wadler’s development of Moggi’s ideas was not directed towards the question of input/output, he and others at Glasgow soon realised that monads provided an ideal framework for I/O."


Yes, definitely. To be clear, I'm a fan (and long-time user) of monads in Haskell, and I think they're a great solution to the problem of embedding impure effects in a pure language. I just don't understand why you'd use them in a language where you can just write the impure effects in a direct style, especially when there's no 'do' notation equivalent.


You don't usually need them to do IO and state, but they're useful for things like optional and error values. Otherwise, it is mostly pedagogical.

Besides, writing things that exist in other languages is useful when you're writing other languages. If you were using C to write a new language with closures (for instance,) you're going to have to implement closures in C. That's a useful exercise, even if nobody is going to use such an inevitably clunky construct in C directly.


You use them precisely when you need a computational/imperative context which differs from the natural ambient one of your language. E.g., Promises in Javascript.


I/O is not the only thing monads are useful for, far from it. Having the concept of a monad lets you write generic code that will operate on any monad (just as e.g. having the concept of a collection lets you write generic code that will operate on any collection, or indeed having the concept of a number lets you write generic code that will work for any number rather than having to write your program as a big lookup table with explicit cases for every number).

Once you have a library of functions that work with any monad, custom monads are really easy to work with. So you can do things like http://typelevel.org/blog/2013/10/18/treelog.html or http://michaelxavier.net/posts/2014-04-27-Cool-Idea-Free-Mon... .


Generic operations on monads are great, but you need code written in terms of monad operations to take advantage of them. Monadic code in Swift has a few problems.

1. There's no do-notation in Swift. Your code will be littered with weird operators that make it (at least slightly) harder to read.

2. It's less efficient. The runtime system has to create and destroy additional closures, increment and decrement additional reference counts, and so on.

3. It's difficult to interface with procedural code, since your monadic code must be pure.

So when do you write monadic code versus procedural code? In practice, the monadic parts of your code will end up associated with particular tasks that lend themselves to the monadic style. But why not then specialize this code to its particular task? In the Treelog example, using specific Treelog terminology instead of generic monad operators would make the code easier to read and understand.


When you have specialized code you use the specific terminology - just as when you have code that works only with a list, you'll use list terminology rather than generic collection terminology. You use the monadic parts when you need to abstract over it, just like with generics.

E.g. I have three client reports that share a common superclass but have different requirements. One of them needs some extra aggregated statistics (Writer, similar to treelog). One of them needs us to make an async call to their system for each row (Future). One of them needs some data from redis. But the superclass logic of "read a bunch of rows from our database, combine the per-row results into a single report" is common. So the superclass uses the generic monad operations, and the subclasses have the specific implementations, and I don't have to copy/paste the same code for the three different reports.


It might help to look at it another way.

You can consider monads as being a design pattern that's been shown to be useful when dealing with laziness.

In Haskell they are endemic as the language itself is lazy. However, they are also useful in eager languages where one wishes to model a behaviour in a lazy manner.

The most common examples of the latter are probably: modelling temporal delays in async code (with Futures); delaying processing of exceptions (with Results) and delaying handling of nulls (with Optionals).

Where monads come in handy is that their composability allows you to decide precisely when you want to handle the relevant behaviour.

As with all design patterns they're no silver bullet. They have trade offs as do their alternatives, be that callbacks, exceptions etc. But they can be useful.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: