For the record, I generally think that people exaggerate the complexity of Functional styles.
I think the reason that stateful, imperative code is the default is because that is how we tend to "think". Example, if I wanted to get a list of items for the grocery store, I get a piece of paper (instantiate an array), go through the list of things I might need (loop through a source array) and write down the ones I definitely need (append onto the destination array). If I run out of space, I get a new piece of paper and continue the process.
With that algorithm, I can stop and test each individual statement; I don't need to "think about it" because I can write and execute a tiny part of it (even if I'm only executing it in my mind).
In a functional style, I have to think more declaratively. Given all my items, filter out the ones that need replacing and give me that list. It's much easier to reason about abstractly, but I have no details about w how that's actually happening.
I think this kind of thinking is superior most of the time: I would rather read map.filter.reduce more than a for loop with branch statements any day of the week, but I am trusting the implementations of the mapping and filtering and reducing functions. Of course, for any non-trivial algorithm one is still passing a function into the map/filter/reduce anyway so I can still reason about those smaller stateful sections without worrying about the map/filter/reduce piping.
Perhaps I've never worked in a truly pure functional style so I may not be dealing with the mountains of abstractions others seem to complain about
I think the reason that stateful, imperative code is the default is because that is how we tend to "think". Example, if I wanted to get a list of items for the grocery store, I get a piece of paper (instantiate an array), go through the list of things I might need (loop through a source array) and write down the ones I definitely need (append onto the destination array). If I run out of space, I get a new piece of paper and continue the process.
With that algorithm, I can stop and test each individual statement; I don't need to "think about it" because I can write and execute a tiny part of it (even if I'm only executing it in my mind).
In a functional style, I have to think more declaratively. Given all my items, filter out the ones that need replacing and give me that list. It's much easier to reason about abstractly, but I have no details about w how that's actually happening.
I think this kind of thinking is superior most of the time: I would rather read map.filter.reduce more than a for loop with branch statements any day of the week, but I am trusting the implementations of the mapping and filtering and reducing functions. Of course, for any non-trivial algorithm one is still passing a function into the map/filter/reduce anyway so I can still reason about those smaller stateful sections without worrying about the map/filter/reduce piping.
Perhaps I've never worked in a truly pure functional style so I may not be dealing with the mountains of abstractions others seem to complain about