Erik Meijer: The Curse of the Excluded Middle 237
CowboyRobot (671517) writes "Erik Meijer, known for his contributions to Haskell, C#, Visual Basic, Hack, and LINQ, has an article at the ACM in which he argues that 'Mostly functional' programming does not work. 'The idea of "mostly functional programming" is unfeasible. It is impossible to make imperative programming languages safer by only partially removing implicit side effects. Leaving one kind of effect is often enough to simulate the very effect you just tried to remove. On the other hand, allowing effects to be "forgotten" in a pure language also causes mayhem in its own way. Unfortunately, there is no golden middle, and we are faced with a classic dichotomy: the curse of the excluded middle, which presents the choice of either (a) trying to tame effects using purity annotations, yet fully embracing the fact that your code is still fundamentally effectful; or (b) fully embracing purity by making all effects explicit in the type system and being pragmatic by introducing nonfunctions such as unsafePerformIO. The examples shown here are meant to convince language designers and developers to jump through the mirror and start looking more seriously at fundamentalist functional programming.'"
Jump through the mirror? (Score:5, Insightful)
"The examples shown here are meant to convince language designers and developers to jump through the mirror and start looking more seriously at fundamentalist functional programming."
Or, perhaps, to acknowledge that it's very hard to do anything useful without side effects.
You can write beautiful, elegant, purely functional code, as long as it doesn't have to touch a storage system, a network, or a user. But, hey, other than that, it's great!
Re:Jump through the mirror? (Score:5, Insightful)
Wow (Score:4, Insightful)
After programming for 16 years, I finally realize I have no idea what I'm doing. I'm so glad these people are out there to point this out.
Sounds like my old comp-sci professor. (Score:5, Insightful)
I remember he used to lament the fact that we had to use computers to run programs, because they were always so impure. Hacked up with model-breaking input and output considerations. He loved APL. Had us write our programs as math equations and prove that they had no side effects. On paper. Step by step, like how elementary teachers used to have you write out long division. He was a computer scientist before they HAD computers, he'd point out.
To be fair, APL was a wonderful language, and perfect so long as you didn't want to actually /do/ anything.
Well, that's unfair. As long as you meant to do a certain type of thing, these languages work out fairly well. The issue is the old percent split issue you normally see with frameworks and libraries - by making it easy to do some percent, X, easily, you create a high barrier to performing the remaining percent, Y. The problem with adhering to pure functional languages is that Y is not only high, it's often the most common tasks. Iterating, direct input and output, multi-variable based behavior, a slew of what we'd call flow conditions - these are very hard to do in a pure functional language. The benefit you get is far outweighed by the fact that you could use C, or the non-functional aspects of OCaml, or some other so-called 'multi-paradigm' language to fix the problem in a fraction of the time, even with side-effect management.
Then, have you ever tried to maintain a complex functional program? There's no doubt you can implement those Y-items above. The problem is that it makes your code very specific and interrelated as you're forced to present a model that captures all the intended behaviors. It's a lot of work. Work that will then need to be repeated each time you need to make additional changes. Adding a mechanism to - for example - play a sound at the end of a processing job based on the status - that's a line of code in most languages. Not so in a functional language.
The problem here isn't the oft-cited 'Devs just have to think of things differently, and they'll see it's better.'. It's more basic. It's simple throughput. Functional languages might be a theoretical improvement, but they're a practical hindrance. That, in a nutshell, is why they're not in common use in a corporate environment, where "value" loses it's theoretical polish and is compared to hard metrics like time and cost for a given quality.
Not really (Score:4, Insightful)
Furthermore it can be mixed with imperative, or even object, programming. It's a useful technique for minimizing bugs.
Re:Sounds like my old comp-sci professor. (Score:4, Insightful)
Actually, it uses a 10-ary tree, which has O(log n) lookup, update, etc with a pretty low constant factor. Or, at least, that's what it does now.
It doesn't have to be this way. Haskell has O(1) arrays, but they live in a monad (either ST or IO) if they're not read-only. Plus, of course, Haskell has lazy evaluation, so read-only arrays are not necessarily as read-only as you might think.
Without knowing more details (and since I'm just some random guy on the Internet, you probably don't care enough to give details, so that's cool) it's difficult to say if you really needed imperative arrays for your algorithm, or you only thought you did because that's what the Visual Basic prototype used. Most people don't learn pure functional data structures in their undergrad classes, so they not always the solution which springs to mind when you have a problem to solve.
Mostly functional works quite alright (Score:5, Insightful)
From TFA:
mostly secure does not work
Spoken like a true academic. Mostly secure does work in practice. My house is mostly secure, my car is mostly secure, my bank is mostly secure. None of them are perfectly secure, as all of them would fail to a sufficiently strong attack, but generally they do fine.
So does mostly functional programming. It works great in practice even though it is not 100% safe but neither is functional programming once you allow monads which are needed to make FP Turing complete.
Re:Jump through the mirror? (Score:5, Insightful)
If you use fopen(), fread(), fclose() etc., you're already doing object oriented programming in C.