18
votes

I have been through various papers/articles/blogs and what not about Monads. People talk about them in various context like category theory (what in world is that?) etc. After going through all this and trying to really understand and write monadic code, I came to the understanding that monads are just syntactic sugar (probably the most glorified of them all). Whether it is do notation in Haskell or the Computation Expressions in F# or even the LINQ select many operator (remember LINQ syntax is also a syntactic sugar in C#/VB).

My question is if anyone believe monads are more then syntactic sugar (over nested method calls) then please enlighten me with "practicality" rather than "theoretical concepts".

Thanks all.

UPDATE:

After going through all the answers I came to the conclusion that implementation of monad concept in a particular language is driven through a syntactic sugar BUT monad concept in itself is not related to syntactic sugar and is very general or abstract concept. Thanks every body for the answer to make the difference clear between the concept itself and the ways it is being implemented in languages.

6
Your view cannot be denied entirely, but notice that one culd also consider any Haskell code as "syntactic sugar" for machine code.Ingo
I like to think of my machine as a magic \-reductor. Then it makes particular sense to map the sugar to the underlying machine ops.Nicholas Wilson

6 Answers

22
votes

Monad aren't syntactic sugar; Haskell has some sugar for dealing with monads, but you can use them without the sugar and operators. So, Haskell doesn't really 'support' monads any more than loads of other languages, just makes them easier to use and implement. A monad isn't a programming construct, or a language feature as such; it's an abstracted way of thinking about certain types of objects, which, when intuited as Haskell types, provide a nice way of thinking about the transfer of state in types which lets Haskell (or indeed any language, when thought of functionally) do its thing.

14
votes

do notation, computation expressions and similar language constructs are of course syntactic sugar. This is readily apparent as those constructs are usually defined in terms of what they desugar to. A monad is simply a type that supports certain operations. In Haskell Monad is a typeclass which defines those operations.

So to answer your question: Monad is not a syntactic sugar, it's a type class, however the do notation is syntactic sugar (and of course entirely optional - you can use monads just fine without do notation).

12
votes

By definition, Monads aren't syntactic sugar. They are a triple of operations (return/unit, map, and join) over a universe of values (lists, sets, option types, stateful functions, continuations, etc.) that obey a small number of laws. As used in programming, these operations are expressed as functions. In some cases, such as Haskell, these functions can be expressed polymorphically over all monads, through the use of typeclasses. In other cases, these functions have to be given a different name or namespace for each monad. In some cases, such as Haskell, there is a layer of syntactic sugar to make programming with these functions more transparent.

So Monads aren't about nested function calls per-se, and certainly aren't about sugar for them. They are about the three functions themselves, the types of values they operate over, and the laws these functions obey.

5
votes

Monads are syntactic sugar in the same sense that classes and method call syntax are syntactic sugar. It is useful and practical, if a bit verbose, to apply object-oriented principles to a language such as C. Like OO (and many other language features) monads are an idea, a way of thinking about organizing your programs.

Monadic code can let you write the shape of code while deferring certain decisions to later. A Log monad, which could be a variant of Writer could be used to write code for a library that supports logging but let the consuming application decide where the logging goes, if anywhere. You can do this without syntactic sugar at all, or you can leverage it if the language you're working in supports it.

Of course there are other ways to get this feature but this is just one, hopefully "practical" example.

1
votes

No,

you can think of a Monad (or any other type-classes in Haskell) more in terms of a pattern. You see a pattern and you handle it every time the same way, so that you can generalize over it.

In this case it's the pattern of of values added information (or if you like data inside some kind of bags - but this picture does not hold for every monad) and a way to chain those together nicely.

The syntactic suggar is just some nice little way to compose the binds ;) Its a extension to the thing ;)

For the practical concepts: just look at async-workflows, or the IO monad - should be practical enough ;)

1
votes

I would first call it a pattern, in the sense that m a -> (a -> m b) -> m b (with a reasonable behavior) is convenient for many different problems / type constructors.

Actually so convenient that it deserves providing some syntactic sugar in the language. That's the do notation in Haskell, from in C#, for comprehensions in scala. The syntatic sugar requires only adherence to a naming pattern when implementing (selectMany in C#, flatMap in scala). Those languages do that without Monad being a type in their libraries (in scala, one may be written). Note that C# does that for the pattern Iterator too. While there is an interface IEnumerable, foreach is translated to calls to GetEnumerator/MoveNext/Current based on the name of the methods, irrespective of the types. Only when the translation is done is it checked that everything is defined and well typed.

But in Haskell (that may be done in Scala or OCaml too, non in C# and I believe this is not possible in F# either), Monad is more than design pattern + syntatic sugar based on naming pattern. It's an actual API, software component, whatever.

Consider the iterator pattern in (statically typed) imperative languages. You may just implement MoveNext/Current (or hasNext/next) in classes where this is appropriate. And if there is some syntactic sugar like C# for it, that's already quite useful. But if you make it an interface, you can immediately do much more. You can have computations that works on any iterator. You can have utilities methods on iterator (find, filter, chain, nest..) making them more poweful.

When Monad is a type rather than just a pattern, you can do the same. You can have utilities functions that make working with Monad more powerful (in Control.Monad) you can have computation where the type of monad to use is a parameter (see this old article from Wadler showing how an interpreter can be parameterized by the monad type and what various instances do). To have a monad type (type class), you need some kind of higher order type, that is you need to be able to parametrize with a type constructor, rather than a simple data type.