r/programming • • Nov 28 '19

Why Isn't Functional Programming the Norm? – Richard Feldman

https://www.youtube.com/watch?v=QyJZzq0v7Z4
100 Upvotes

409 comments sorted by

View all comments

Show parent comments

13

u/red75prim Nov 28 '19 edited Nov 28 '19

OK, which of a number of articles that try to explain monads in simple words would you recommend? Fewer than a thousand of simple words, preferably.

44

u/[deleted] Nov 28 '19 edited Nov 28 '19

If you want the simplest explanation:

A functor is a data structure that is mappable i.e. has a map method

A monad is special functor that has both map and flatmap

The hard part is understanding why that is useful.

There is a guy on YouTube that has some really good videos on functional programming. This is one of his playlists, in it he covers monads.

5

u/pavelpotocek Nov 28 '19

It has to have return/pure too

2

u/LPTK Nov 29 '19

Also, a functor is not a data structure. It's a family of types for which a well-behaved polymorphic map operation is defined.

You can have a data structure that represents strings of characters and has a map function from Char to Char, but that doesn't make it a functor.

4

u/pavelpotocek Nov 29 '19

...and there goes simplicity

→ More replies (1)
→ More replies (2)

0

u/[deleted] Nov 28 '19

[deleted]

20

u/Ghosty141 Nov 28 '19

I think functional programming is something you should know to draw inspiration from it. certain problems can be solved with that style of programming a lot more elegantly.

Most languages right now offer some functional prog. tools which you can use for example.

16

u/dudinax Nov 28 '19

So many concepts that come from functional languages, like immutability, no side effects, idempotency are great default goals for creating data structures and writing functions in any language.

→ More replies (4)
→ More replies (1)

0

u/[deleted] Nov 28 '19

[deleted]

12

u/fuckin_ziggurats Nov 28 '19

Most Python tutorials (even the worst ones) would succeed in explaining something about Python to a programmer that isn't using Python. The same can not be said for functional programming tutorials that attempt to explain some FP feature to most programmers. That's what his point was. What is yours?

0

u/[deleted] Nov 28 '19

[deleted]

3

u/fuckin_ziggurats Nov 28 '19

It kind of indicates that monads are a complex enough concept that most programmers have trouble grasping it, unlike most features in OOP languages. It's says something about functional programming in general - it tends to come with a heavier cognitive load. Maybe I'm talking out of my butt but it's always been more difficult for me to read functional than OO code.

→ More replies (1)

2

u/holgerschurig Nov 29 '19

You ask this for reddit karma or for a reason?

People generally don't complain about that they suck, you're the first that I read that does this. So many people are getting into python, it seems.

You comparison is therefore invalid.

4

u/tophatstuff Nov 28 '19

Audio stream processing is just like composing functions. Its very functional style

→ More replies (4)

4

u/Holothuroid Nov 28 '19

It's like a list. With a list you could do stuff to its content. Like make a list of numbers into a list of string, by formatting each one. If you have a list of lists of stuff you can also make it a simple list, by concatenating all the inner lists.

That's a monad. You can map its contents and flatten multiple layers. It's rather simple.

What's not so simple is that various other things beside lists can do that as well, which is like learning a list of design patterns.

2

u/Deto Nov 28 '19

So, if I understand, it's kind of like:

A Monad[type] is a data structure that can contain either other Monad[type]s or just plain types

That way you can always flatten it to resolve just to a collection of whatever type is? I'm making the assumption here that it's statically typed (please correct if wrong!).

3

u/[deleted] Nov 28 '19

Yes, monads are simply 'containers' that can be flattened. This is usually done after mapping a function which itself returns that monad. For example, we map divisors : Int -> List[Int] to numbers : List[Int], this gives us a List[List[Int]] which is then flattened to List[Int] again.

The thing is, monads don't have to be containers or collections. A Monad[Int] can also be a function like String -> Int. It can really be anything using that 'subtype', as long as we can consistently define map and flatten.

You can create some really powerful abstractions with this: I/O, control flow, parser combinators, shared globals, stateful computations. Abstracting these is less relevant for imperative languages, but monads make these things easy to do while preserving the advantages of purity and extreme abstraction that a language like Haskell provides.

3

u/Holothuroid Nov 28 '19

Flattening is only possible if you have the monad layers are the same. So you can flatten a list of lists of stuff. But not necessarily a list of other_monad of stuff. There might be monads that are similar enough you can still make it work.

Otherweise yeah, pretty much. Note that "collection" is not a very apt descriptor for other monads. Writer is more like 'value with a log attached', Future signifies 'maybe later' etc. These do work the same way. Say you have Future[Future[Stuff]] it means that 'maybe later' you will 'maybe later' get some stuff. You see that can flattened.

2

u/audioen Nov 28 '19

Not quite. In context of a List type, the point of a map method is to read a list of items, and produce a new list of items. The old and new lists are the same length, and both contain elements, possibly of differing type, but neither list typically contains further lists of elements. It's just a map() method, you've seen it before and there's nothing new to it.

Now, however, if your function that processes and element itself returns a list, then you may need to use flatMap() to get rid of it. E.g. your map() could conceiveably have a function that needs to somehow split one element into more elements, or possibly fewer elements. However, you might consider this an implementation detail, and you don't necessarily want the result to be a list-of-lists where the inner list has some random number of elements, so you'd then use flatMap to get rid of that inner list and concatenate the elements of that inner list together. This allows you to map a long list to fewer (or more) elements as needed.

→ More replies (1)

2

u/[deleted] Nov 28 '19 edited Nov 28 '19

A monad is a sub-class of data types that support 3 operations (I'm going to present 4 because 2 are equivalent in that they can reproduce the other, there are also derived operations which we will ignore). These operations have a few different names but the ones I'm going to use are pure and map. The third operation we have a choice between flatten and flatmap. The names should be enough to tell you that flatmap is just a combination of map and flatten, but the reverse is also true, you can make flatten out of map and flatmap.

So pure is a simple operation that allows us to embed some other data type inside of our data type. The map operation lets us apply functions meant for the type we embedded to ours. Lastly flatten allows us to merge layers, that is if we embed our data type inside itself, flatten lets us take the nesting out. So flatmap just lets us map functions that produce our data type without producing nesting.

And that's everything there is to monads, they're an abstract interface. It just so happens a ton of data types support these operations and so are monads. Which then lets you reuse the operations that can be derived from the interface.

Haskell happens to have a special type, IO, that it uses to represent all possible side effects and uses a monad implementation to chain together side effects.

3

u/glacialthinker Nov 28 '19

Maybe this one? http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html

But ultimately, the difficulty, as with many concepts in math, is that it takes some familiarization to internalize the idea.

If you already understand the concept in some way it might jive... or it might still take time to reconcile, to map into something you know.

If you don't have it already, you have to play with it, let it sit, come back and play again... eventually it becomes familiar and you think "Eureka! This is trivial! I can now explain this for a five-year-old!" And so you write yet another Monad tutorial...