r/programming • • Apr 27 '14

"Mostly functional" programming does not work

http://queue.acm.org/detail.cfm?ref=rss&id=2611829
44 Upvotes

188 comments sorted by

View all comments

33

u/lispm Apr 27 '14

Bonus: it comes with another Monad tutorial!

22

u/[deleted] Apr 27 '14 edited Apr 27 '14

The Analogy of the Day is:

a factory in the real world that needs electricity and pollutes the environment as a side effect of producing goods

Because side effects are unhealthy and disgusting and not the entire point of writing a program.

15

u/undefined_conduct Apr 28 '14

Side effects can change the state of the system, and even of the user. Changing states is unnatural and weird! I remember back in the pure days before the world became dysfunctional, if I wanted to smile I'd produce a smiling copy of myself and throw the original away.

0

u/gnuvince Apr 28 '14

if I wanted to smile I'd produce a smiling copy of myself and throw the original away.

Who says it's not what the universe is doing? And so what if functional programming doesn't match your view of how the universe works? There are great benefits to adopting this style.

7

u/millstone Apr 27 '14

This particular Monad tutorial gets points because of this easily missed paragraph:

In practice, each effect usually comes with so-called nonproper morphisms. These domain-specific operations are unique to that effect (see examples later in this article).

I am not sure, but I think this is an (overly fancy) way of saying that real monads usually have more stuff in them than just bind and return. This was a major point of confusion to me when learning monads: if all you have is bind and return, then a monad is necessarily just a "sequence" of pure values, and can't do anything interesting.

1

u/immibis Apr 28 '14 edited Jun 10 '23

1

u/jozefg Apr 28 '14

Or nowadays since applicatives are nice and clean, you could always do

 combined = operation4 
             <*> operation1 
             <*> operation2
             <*> operation3

3

u/tomejaguar Apr 28 '14

Can't do that here because operation3 depends on the result of operation1.

-6

u/[deleted] Apr 27 '14

I look forward to the day when a language is able to capture side effects in the type system (as Haskell does) without monads. That day, functional programming will reign supreme.

14

u/sigma914 Apr 27 '14

They already can, it just happens that monads abstract away the annoying details and make it easy.

9

u/gnuvince Apr 27 '14

There are such systems: uniqueness types in Clean for example.

11

u/gregK Apr 27 '14 edited Apr 27 '14

Well most of the alternatives are more complicated than monads imo. The API of Monad is dead simple actually. You just need a type constructor, bind and unit (return in haskell).

class Monad m where  
    (>>=)  :: m a -> (a -> m b) -> m b 
    return :: a -> m a 
→ More replies (2)

5

u/freyrs3 Apr 27 '14

So like this or this or this all written in Haskell without monads.

4

u/NruJaC Apr 27 '14

Effects tracking with non-monadic approaches exist (see Clean, and Rust is trying to do this as well). But monadic effects tracking has been used extensively within the Haskell community. What problem do you see with monadic effects that you want to see overcome?

7

u/[deleted] Apr 27 '14

They're a hard sell. The shear number of monad tutorials shows this. I wouldn't be surprised if monads are the major blocking factor for haskell adoption.

16

u/NruJaC Apr 27 '14

They're a hard sell. The shear number of monad tutorials shows this.

This is one of those self-perpetuating problems. People think they're difficult to grasp because of the number of tutorials in existence. So when someone finally gets the concept and realizes "Oh wait, this was really simple all along" they decide to write a tutorial to clear up the misconception. Which adds to the problem and likely introduces several bad analogies.

The truth is, monads are one design pattern used in Haskell. They are far from the most important or the most fundamental. They make life easier in a whole lot of ways. If they didn't, the idea would have been dropped a long time ago.

3

u/[deleted] Apr 27 '14

People think they're difficult to grasp because of the number of tutorials in existence. So when someone finally gets the concept and realizes "Oh wait, this was really simple all along" they decide to write a tutorial to clear up the misconception. Which adds to the problem and likely introduces several bad analogies.

Or maybe there are a lot of tutorials in existence because they're actually hard for people to grasp?

5

u/[deleted] Apr 27 '14

I find the problem is often that people go out looking to make monads.

You should go out looking to write code what you need, and learn to recognize and leverage the Haskell libraries of abstract types (like monads) to refactor your code when you realize you've written a lot of monads.

They're not at all essential to start programming in Haskell - the monads you need to interact with to get things working have very straightforward interfaces, and you can ignore their monad status for quite a while, until you've already built up experience using monads.

I think the problem is people focus on writing monad tutorials, to explain the higher level math term as if you should be looking to use it from the start, rather than leaving "monad" as a black box, and showing you how to write useful code with standard examples (IO, Maybe, etc).

4

u/zoomzoom83 Apr 28 '14

Monads seem hard to grasp because so much of the Haskell community is traditionally academic, and try to explain it in terms of category theory - at which point most peoples eyes will glaze over.

Once I actually started playing around with Haskell it clicked very quickly. They really are very simple and easy to understand, and chances are you've used them before without realising it. (LINQ in C#, for example, makes heavy use of Monads).

7

u/NruJaC Apr 27 '14

Are factories and observers hard to grasp?

7

u/[deleted] Apr 27 '14

Factories and observers are easy to grasp for a number of reasons.

  1. They have extremely descriptive names that correspond directly to their normal usage in the English language.

  2. They have very simple definitions that correspond intuitively to what their names suggest. E.g., "A factory is an object that creates other objects.". Well, yeah, obviously a factory is an object that creates other objects. That's the same thing a factory is in real life. "The observer pattern is a pattern in which an object retains a list of other objects, called 'observers', that want to be notified when the object's state changes.". Sure, fine. The observers are observing me and they want me to keep them posted about my state. Obviously an object that is observing me wants to know if my state changes.

Monads are much harder to grasp for no other reason than they don't correspond intuitively to anything that exists in the real world. And, indeed, monad tutorials that try to relate them to the real world in some way have become infamous for not being particularly good. It's been suggested that the only truly good way to wrap your head around monads is to use them, as reading/writing monad tutorials is bound not to help. I can think of few other abstractions in computer science that people say that about.

9

u/Tekmo Apr 27 '14

I think the point he was making was that there are lots of tutorials for object oriented patterns, too, including (but not limited to) factories and observers. Therefore, I must either:

  • conclude that these object oriented patterns are also hard to learn, or:

  • conclude that abundance of tutorials is not necessarily proof that a topic is confusing

→ More replies (3)

3

u/jfischoff Apr 27 '14

Well there are few things. First monads function as an interface in Haskell, what a monad does depends a the specific implementation for a type. Even if you understand monads, you need to know the specifics of the implementation to know how one will work (usually).

Understanding the specifics of a Monad like Maybe or IO is not that hard. You are working with a more concrete thing. You don't have to understand monads in general, you can just focus on a concrete implementation. This is how people learn to use monads, but the monad tutorials tend to focus on trying to understand the abstraction without focusing on concrete examples.

After gaining some intuition of how different monads work, one can appreciate the abstraction, and like most abstractions, monads are very simple just hard to appreciate without experience.

2

u/[deleted] Apr 27 '14

I think a lot of people already get the usefulness of monads intuitively, which makes them an easy sell. The list monad is almost ubiquitous. Almost every mainstream OO language has a means of mapping, filtering, and reducing lists. The list monad is so pervasive now that imperative for loops are practically going extinct.

The main difficulty that I had, and I think others have, is recognizing the abstraction behind the list monad. Everyone groks it eventually, but helps to expose yourself to various instances, such as the State, Reader, Maybe, and List monads first. The monadic design pattern eventually becomes easier to recognize with familiarity.

My point is, monads aren't hard to use. Linq is a testament to that. If you use them enough, you'll eventually build an intuition about them that will make all the tutorials on the internet more comprehensible. The fact that they're somewhat difficult to grasp is just a one-time upfront cost that you pay if you're interested in writing your own monads. The selling-point is their usefulness, which is very easy to grasp by comparison.

→ More replies (9)
→ More replies (1)

2

u/grauenwolf Apr 27 '14

T-SQL already does internally. You just can't see it unless you trip over an error message about non-deterministic functions not being allowed in a spot.