2 ms·
Kinda. There are tricks to make it less burdensome. One of the tricks is the use of monads in Haskell. Monads are really just a small set of functions that o
by peterfirefly 11y ago
Kinda. There are tricks to make it less burdensome.
One of the tricks is the use of monads in Haskell. Monads are really just a small set of functions that operate in a certain way (that "satisfies the monadic laws") on a type.
What that gives you is (among many other things) a way to carry an implicit "world" around with you without needing to refer to it all the time.
One use for such a "world" would be a seed for a random number generator so different parts of your program can use their own, isolated streams of random numbers (nice for determinism, testing, debugging, etc), even if they execute asynchronously because Haskell is a "lazy" language where code doesn't necessarily get evaluated unless it really needs to.
Another use is for the "world" to actually represent the real world -- all of it -- so the I/O interactions happen in the right order. That's very important in a language where the evaluation order is so "loose" as it is in Haskell.
There are other tricks as well. One of them is to have lots of small transformation functions that don't need to understand all of the world, just their little bit of it. You create the big world transformations by composing the smaller transformations. The data structures you use are slightly different: you don't want to modify your data structures, you want to create new ones all the time, i.e. inserting an object into a tree shouldn't modify the tree but return a completely new tree with the new object in it WHILE KEEPING THE OLD TREE AROUND UNCHANGED. This doesn't have to be as expensive as it sounds, in fact, it can be quite cheap. Data structures where you can do this cheaply are called persistent data structures and they work really well with a functional programming style.
(They don't have to implemented purely functionally internally as long as they present a pure interface.)
https://en.wikipedia.org/wiki/Persistent_data_structure https://en.wikipedia.org/wiki/Persistent_data_structure
Persistent data structures can also be confluent, which means that they use sharing internally if two versions of a data structure end up being logically the same. Tarjan and Sleator have some really nice papers on that -- well worth reading, even if you don't care one bit about functional programming.