Sunday, September 23, 2007

Functional Programming Is Worse Than Crap: State Changes Are Essential to Reliability

Geekism Is a Menace to Society

All Functional Programming Articles

(Skip this rant if you’re only interested in my criticism of FP)

I had assumed that functional programming was a mere harmless sideshow conducted by a bunch of math nerds pretty much for their own benefit and entertainment. Now that I had a little bit more time to think about it and after discovering (from doing a few searches on Google) that FP fanatics have been frantically promoting FP for use in safety-critical applications, I must say that I am becoming rather alarmed. Those geeks have found themselves a new religion to latch onto and have taken to proselytizing with a passion akin to that of Catholic missionaries in the days after Columbus stepped foot in the new world. They are convinced that they have found the holy grail of computing and will not consider any argument to the contrary. Any criticism is seen as a threat to the religion. In a sense, this is understandable since the religion has become their bread and butter.

In my opinion, computing has become too much a vital part of our daily lives to be entrusted entirely to a bunch of nerds whose main goal in life is to convince others of the superiority of their gray matter. Geekism is a threat to national security and society at large because it aims to create an elite class of individuals who consider themselves above public scrutiny and even above scrutiny from the government. In fact, they look down on the general public, not unlike the high priests of ancient religions. There is a need for checks and balances.

The Jihad Against States and State Changes

One of the stated goals of FP is that side effects between different parts of a program should be eliminated because they are inherently harmful. Never mind, for now, that we are already in crackpot territory (see below) but the FP fanatic’s prescription for avoiding side effects is a little strange, to say the least. They want to eliminate variables (changeable states) from programming altogether. And how do they propose to do this amazing feat, pray tell, given that computing is all about sensing and effecting changes? Well, never underestimate a geek’s capacity for self-deception. Their bright idea is that, whenever a variable must be changed, a new variable should be initialized and used in the place of the old one. Huh? Now, hold on a second. Run that by me one more time, por favor. How does creating a new variable to replace the old one not constitute a state change, pray tell? Aren’t these newly created immutable variables used as arguments to other functions so as to generate a new effect? When a function uses a new set of arguments that is not equal in value to the previous set, does that not constitute a change of state? And how is that any different from changing the value of the previous set?

Crackpot Territory

What most FP theorists fail to explain is that, in FP, the function itself is the variable. The variable value of functions are kept on the stack and are used as arguments for other functions. One function affects another. Insisting that there are no variables and thus no side effects in FP is wishful thinking at best and crackpottery at worst. The side effects are obvious to anybody who is willing to look. Certainly, you may claim that there is no side effects within a function but so what? It remains that one part of a program will affect another and that is unavoidable. Dependencies are a fact of life in software. The point I am driving at is that FP harbors a fundamental flaw in the way it deals with dependencies. Let me explain.

It often happens that a programmer is given the job of adding new functionality to a legacy program. It may happen that the programmer creates a new function to operate on a list but forgets to update an existing function with the new list? Worse, he or she may not even be aware of the existence of the other function or the need to update it. This is what I call a hidden side effect or blind code. That is to say, code that is unaware of changes that are relevant to itself and the proper functioning of the program. Publish and subscribe is not the answer. First, the programmer has to remember to subscribe and second, if the programmer is not familiar with the code, he or she may have no idea that a new subscription may be needed. What is needed is a software system that automatically discovers and resolves all data dependencies in a program. And, unfortunately for the FP lobby, this little bit of magic can only be performed with the use of shared mutable variables.

Why I Came to Love State Changes and Their Side Effects

Changes and effects are unavoidable characteristics of software. This is a given. The way I see it, the problem with traditional imperative languages is not that they allow side effects from state changes but that they are neither reactive nor deterministic. There are good side effects and bad side effects. A bad side effect is one that is either not propagated at the right time or not propagated at all, thus leading to false assumptions. A good side effect is one that is propagated immediately to every part of the program that is dependent on or affected by the change. A good side effect is one that cannot be ignored by the software designer because the system will not allow it. If the effect is unwanted, this is immediately obvious and the designer must take steps to correct the problem. The automatic discovery and resolution of state (data) dependencies is a must for reliable software. It can only be done in a purely reactive and deterministic system that uses named variables. For more on this issue, see how COSA handles blind code elimination.

Temporal determinism is essential to software reliability. It means that the execution order (concurrent or sequential) of reactions to changes is guaranteed to remain the same throughout the lifetime of the system. Deterministic control over the precise timing of changes is the only way to prevent deadlocks and unwanted side effects in a parallel system that allows the use of shared variables. There is more to it than that, though. Since the execution order of changes is expected to be stable, any violation should be seen as a potential defect. Timing watchdogs can be inserted in various places within a deterministic program in order to sound an alarm in the event of a violation. Deterministic timing can be used for security purposes but it primary use is for insuring reliability. It forces the designer to investigate any change to the timing of previously created software modules. Furthermore, a timing change may introduce a motor conflict, i.e., a situation where a data object is modified by multiple operators simultaneously. Motor conflicts are temporal in nature and are detectable only in deterministic system.

Why Functional Programming Is an Abomination

FP fanatics love to boast that FP is perfectly suited for parallel computers because, unlike threads in conventional programs, pure functions are free of side effects. By assigning functions to threads and using message passing between threads, one can create a thread-safe concurrent system. This is all fine and dandy but what the FP crowd conveniently forget to mention is that there are major drawbacks to using FP in a parallel environment.

  1. FP forces the use of a particular type of parallelism, thread-based parallelism. In other words, if your computer uses fine-grain parallelism (this is the future of computing, you can bet on it), FP will not support it because functions are inherently algorithmic. So if you want to implement a fast, fine-grain, parallel QuickSort routine, you might as well forget using FP. The widespread adoption of FP will only result in encouraging what I call the age of crappy concurrency.
  2. FP programs are notoriously wasteful of CPU cycles because they do not allow the use of shared variables or data. A collection of data can only be modified by one thread at a time. The entire collection must be copied onto a message queue and sent to another function/thread. FP proponents are afraid of side effects because they don't know how to handle them safely.
  3. The structure of FP is such that an automatic mechanism for the discovery and resolution of data dependencies cannot be implemented. The reason is that such a mechanism is only possible in a system that uses variables. This means that additions to legacy FP programs can introduce hidden dependency problems that are potentially catastrophic. FP is not suited for safety-critical applications for this reason.
  4. FP is non-deterministic. This is a serious flaw, in my opinion, because the precise execution order of changes, a must for reliable software, is not guaranteed. This is especially true in a thread-based parallel environment.

Invasion of the Mind Snatchers

(Another rant)

People ask me why I use pejorative qualifiers like “crap” and “geeks” in my arguments. The answer is simple. I use them for psychological effect. Computer geeks are notoriously political animals who cannot fathom that others may look down on their supposed intellectual superiority. Nothing infuriates them more than a total lack of respect. It’s like throwing holy water on vampire. But unlike a vampire, they want the minds and admiration of the populace, not their blood. Realize that I have nothing to hide. I am engaged in a battle to get the computer industry to adopt what I believe to be the correct approach to computing. It’s an uphill battle because I am asking for nothing less than the reinvention of the computer, both from a hardware and a software point of view. My main opposition comes from computer geeks. Why do they oppose me? Because their livelihoods are at stake, that’s why. If my approach is adopted, they become irrelevant. And the more famous a computer geek is, the more he feels threatened by any paradigm that may supplant the one he or she is championing. They’ll defend their turf with everything they got. I, on the other hand, am the fearless and relentless barbarian at the gate, the infidel climbing the makeshift ladder, threatening to overthrow the ramparts. My advice to the geeks is, give up now and join me before it's too late. It’s only a matter of time before the walls come crumbling down. I am in top shape and I've just begun to fight. ahahaha...

Next: Why Functional Languages Should Not Be Used for Safety-Critical Applications

6 comments:

Keymone said...

i have to disagree with you in few points:

1. when you say FP have to create new variable to proceed with calculations it is not exactly true. it depends on implementation of functional machine. functional program is a path - imagine you are on the road with a bag and you are pickung up the stones(yeah i know it's stupid idea but still - you need those stones), you won't create a new bag and move all stones from old one to new one. i hope.. the point is that data and the memory allocated for that data should be reused not recreated.

2. functionaol programs(i mean "programms written in functional language") of course must somehow manage the memory and calculation results. this is unavoidable. but this management is completely hidden from the programmer. he have to think about *what* to program not *how* to program. everything else is FL implementation problems.

3. the state itself cannot change. the state of a system changes. it changes from one state to another. and state change(a switch from one state to another) is exactly and only change which should be counted in reactive system. maybe i'm wrong but it's the way i see it...

Jeabo said...

Object programing is too abstract for my taste.

Its like an automatic transmission vs a manual. The military uses automatics because it's almost impossible to stall an automatic in a combat situation. Race car drivers, on the other hand, need as much power as possible. Plus, they have more skill and their goal is not stop and go all the time.

Its really an application based decision. Cerner codes almost all its stuff in OP because it can't go down and has money to buy better servers to make up for the extra cpu cycles. A dsp company codes all its stuff in C or verilog because it needs performance with variable few conditions.

Some things are just harder than others, my friend, but are both important.

I bet you program high level stuff.

Jeabo said...

I prefer using functions. Object programing is too abstract and usually is slower (unless it's a horrible C++ monstrosity).

It really boils down to the application. Its like automatic transmissions vs manuals. The military uses automatics because they do not stall engines easily. In combat, sitting would not be fun. Race car drivers always use manuals. They are much more skilled than the average GI and need all the power that is possible. Plus, they are not stopping all the time.

Some people think in terms of functions. Others in objects. They both have a place.

(By the way, PThreads need to be redesigned.)

Chris King said...

What most FP theorists fail to explain is that, in FP, the function itself is the variable. The variable value of functions are kept on the stack and are used as arguments for other functions. One function affects another. Insisting that there are no variables and thus no side effects in FP is wishful thinking at best and crackpottery at worst.

You are misunderstanding FP entirely; possibly due to FP zealots misunderstanding FP entirely. The key to FP is not some abstract hand-wavy idea of "stuff never changing", which is the strawman on which you built this entire post. It is referential transparency.

Referential transparency is the notion that any given expression can be replaced with its value without changing the result of the program. This property does wonders for formal verification since it allows programs to be broken into pieces for ease of verification (this is a huge win).

FP, by making all state explicit, trivially exhibits referential transparency (since the dependencies of an expression are syntactically present within it). Imperative languages, by making state implicit, do not exhibit this property.

I suggest you read up on referential transparency, and study languages which exhibit referential transparency yet have state, such as Mercury or Flapjax, so you can build an argument against an actual position. A solid understanding of reduction-semantics such as that used by the lambda calculus could help you form a more coherent argument as well.

Chris King said...

Also:

1. FP forces the use of a particular type of parallelism, thread-based parallelism. In other words, if your computer uses fine-grain parallelism (this is the future of computing, you can bet on it), FP will not support it because functions are inherently algorithmic. So if you want to implement a fast, fine-grain, parallel QuickSort routine, you might as well forget using FP. The widespread adoption of FP will only result in encouraging what I call the age of crappy concurrency.

Uh, false. Look at Mercury. It has syntactic support for fine-grained parallelism.

2. FP programs are notoriously wasteful of CPU cycles because they do not allow the use of shared variables or data. A collection of data can only be modified by one thread at a time. The entire collection must be copied onto a message queue and sent to another function/thread. FP proponents are afraid of side effects because they don't know how to handle them safely.

You should look at how Mercury has integrated software transactional memory into a purely functional language.

3. The structure of FP is such that an automatic mechanism for the discovery and resolution of data dependencies cannot be implemented. The reason is that such a mechanism is only possible in a system that uses variables. This means that additions to legacy FP programs can introduce hidden dependency problems that are potentially catastrophic. FP is not suited for safety-critical applications for this reason.

I honestly have no clue what you're talking about. Can you provide an example?

4. FP is non-deterministic. This is a serious flaw, in my opinion, because the precise execution order of changes, a must for reliable software, is not guaranteed. This is especially true in a thread-based parallel environment.

This is just false. Seriously, like, read a book on FP or something. This paragraph makes you sound like an idiot.

BernardH said...

Most excellent prank !
Us FP geeks are indeed much too serious about our "revelation".
I've had a blast reading your funny post ☺

(but don't forget to later make it explicit that this is a late April fool joke, lest the noobs amongst your reader might take it seriously ;) )