HN2new | past | comments | ask | show | jobs | submitlogin

The not-always-pure FP that sometimes uses state is what real-world functional programmers actually use. We manage state. It's neither possible nor desirable to eliminate it outright.

It wasn't until recently (a couple weeks ago, when giving a presentation on FP) that I realized why stateful programming lends itself so easily to evil. If a program is a serial collection of possibly unrelated stateful actions, everyone can add new intermediate behaviors to a function to satisfy some dipshit requirement, and the API doesn't change. Writ large, this allows silent complexity creep.

I think a major reason why FP is better is that changing a purely referentially transparent function requires an API change: more parameters or a different return type. If nothing else, this tends to break tests. It's hard to change functions that already exist, and it should be hard. You should be writing new ones instead. Also, if there's only one way to combine programs (function composition) it's easier to break them up. So you don't get the 500-line monsters that plague enterprise codebases.

That said, the worst thing about OOP isn't state. It's inheritance, which is the 21st-century goto.



I've sometimes heard the complaint that FP is more complicated than imperative programming, what with having to pass more variables around instead of just incrementing counters or whatever. I am of the opinion that FP isn't more complex, but rather it makes visible the complexity that was already there. Programming with states implicitly requires ordering dependencies between those states, which means that there are hidden relationships in your code. Converting states to passed parameters isn't adding complexity, it's exposing it.


I am of the opinion that FP isn't more complex, but rather it makes visible the complexity that was already there.

Edit: This is a very interesting statement, seriously. How easily do we stumble onto a statement whose truth hinges on the purpose of programming languages. There are a lot of ways one can look at this.

For example, the statement may be true but then if failure-to-hide complexity is what's making things hard, something is still making things hard. Reframing someone's problem won't make it go away unless you also hand them a way to deal with it.

Also, isn't whole point of a high level language that it hides complexity appropriately in order to allow the limited human brain to deal with the ungodly complexity of a large computer program? Having to paste ten boiler-plate arguments to a group of functions (when if one was using OO the arguments would be subsumed in the object) might not add complexity to the resulting logical object but without other mitigating factors, it seems to me that such an approach would add to the complexity of the code creation process, which is really the major bottleneck in computer programming, right?


Having to paste ten boiler-plate arguments to a group of functions...

is completely unnecessary. Depending on how you plan to use the boilerplate arguments, you'll typically encapsulate them with either a Reader, Writer or State monad.


Haskell, for example, has records and product types for bundling data.

It also has carrying, for ad hoc accumulation of arguments, so you don't need the boilerplate of ten overloaded methods or a builder class just to accumulate arguments.


Also, this kind of complexity can actually be measured and tracked, so policies can be enforced.


Good programmers in any language manage state and know that too much state is dangerous.

I'm programming in C++ and C# right now, and my general mantra is "state is bad".

Of course I learned that from doing functional programming... :)


In the interest of being pedantic its not inheritance but implementation inheritance that causes all the trouble (which I'm sure you meant)


You had me until you knocked goto.


I found the analogy to be pretty accurate. It's very easy to shoot yourself in the foot with both goto and inheritance, it's common to see both of them abused, and in either case there are alternatives that generally equivalent but result in cleaner code.

Of course, both of them can also come in handy if you are careful and know what you're doing.


Are you sure he knocked goto? Like inheritance, it has great potential to turn code into spaghetti. Like inheritance, it can be useful if you're careful.


Goto is fine in self-contained uses, but turns catastrophic on large, enterprise codebases, like inheritance.

http://michaelochurch.wordpress.com/2012/08/15/what-is-spagh...


I'll include part of my comment to that post:

"Are goto’s always bad eventually? Who cares? There’s far bigger problems with gradual change in codebases, let’s think harder about them. My peer reviewers, hold off review until you’ve used what I’ve built and found problems with it. Managers and programmers, wrestle with judgement everyday, the stuff not easily put into rules. Leave the comforting shallows and engage with the abyss."

http://michaelochurch.wordpress.com/2012/08/15/what-is-spagh...




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: