2 ms·
Some languages have frameworks with monads, currying, higher order functions, and other stuff that only makes sense if you have immersed yourself in functional
by jillesvangurp 5y ago
Some languages have frameworks with monads, currying, higher order functions, and other stuff that only makes sense if you have immersed yourself in functional programming, geeked out on type theory, etc. Been there done that ... 25 years ago.
Since then, I've learned that other languages exist that are often dismissed as impure, not worthy, etc. that take the more useful functional programming concepts and implement them in a straightforward / pragmatic way that can be explained without using a lot of big words to solve real problems. Functional programming has gone mainstream about 10-20 years ago when javascript, Go, Rust and a few more recent other things took off. Most of the popular languages today borrow heavily from features that used to be associated with functional programming or have gradually acquired such features (e.g. Java, python).
Side effects and state are topics that you have to worry about when doing asynchronous stuff. Like most Frontend and modern server side developers would need to deal with. The most popular languages for this are not pure functional languages. But they do tend to have lambda functions, reactive frameworks, functions, etc. that can be passed around as values, async await, coroutines, etc. Maybe, Optional, Result and other/similar constructs. But the word monad is not something you'd find in their documentation even though of course they kind of are there lurking in the background.
My simplistic interpretation of monads is "dealing with side effects by using functions". Useful when doing IO, dealing with error responses, and a few other things that break the leaky abstraction of "everything is a function". Not that big of a deal generally unless you make it one.
- Brian_K_White 5y agoOn this page I have heard so far: Monads are... * just a way of defining a list * very much not that * dealing with side effects using functions Apparently the article is spot on. The concept may be understood, but may not be communicated. It's quite interesting seeing the phenomenon play out just as described.
- Izkata 5y agoThough I'm not certain I do understand monads, this is what I eventually made sense to me from various tutorials: A container datatype that abstracts control flow in a composable way.
- Koshkin 5y agoOne popular example of a monad is a type constructor that extends the given type - a “wrapper”, if you will, where a value can be wrapped in a trivial way (e.g. x -> {x} or x -> x?), and a double wrapping can be trivially unwrapped (“naturally transformed”) into a single one: {{xyz}} -> {xyz}. (Note that unwrapping the last remaining layer will not be always possible - e.g., while {x} -> x does indeed make sense, {x, y, z} -> … or x? -> x do/may not.)
- nybble41 5y ago> where a value can be wrapped in a trivial way (e.g. x -> {x} or x -> x?) > and a double wrapping can be trivially unwrapped (“naturally transformed”) into a single one: {{xyz}} -> {xyz} You've described the "pure" and "join" operations (in Haskell terms), which are two of the three requirements for a monad. The third and final requirement is that there must be a way to lift an arbitrary function on plain values to work on "wrapped" values: (x → y) → ({x} → {y}).
- mbrodersen 5y agoYep agree. I actually understand Monads and have used them in Haskell but I still 100% agree with you. One of the problems is that understanding Monads is 100% needed in purely functional languages but not in non-pure functional languages. I have never used Monads outside of Haskell because it doesn’t make sense to use them in C++/Java/C#.
- nybble41 5y ago> Functional programming has gone mainstream about 10-20 years ago when javascript, Go, Rust and a few more recent other things took off. The problem with this is that Javascript, Go, and Rust are merely "multi-paradigm" (meaning imperative and procedural / object-oriented) languages, not functional programming languages. They may have some of the trappings of functional programming such as first-class closures, but they lack the mathematical functions (i.e. pure functions which deterministically map formal arguments to results with no side effects, as opposed to imperative procedures) which are the key concept of functional programming. You can't achieve functional programming by adding closures or coroutines or procedures-as-values to an imperative language. You can only get there by removing things like side effects which are incompatible with functions. Of course a program which consists of nothing but mathematical functions isn't very useful, since it can't interact with its runtime environment (no I/O), so you end up with a split between an imperative outer shell (e.g. the Haskell runtime) and a functional program which computes a stream of actions from a corresponding stream of inputs. At that point the concept of monads becomes very helpful to ensure that your input and output (action) streams remain synchronized and that the type of each input matches the corresponding action. As a bonus, the monad concept can be generalized to work in areas other than I/O (exception handling, nondeterministic computation, and probabilistic modeling, to name a few), and you can design combinators (e.g. loops) which are useful in any monadic context, not just the I/O context for which most languages provide special syntax.