When would you use functional programming? What criteria do you use to decided if functional programming is a better choice?
Functional programming has one big advantage: it avoids (on conceptual level) 'states' during the runtime. Thus, the value of a term is always predetermined by the input.
This advantage is at the same time a disadvantage: people are used to think in terms of states, and thus it seems to be a bit harder to learn a functional language.
Functional languages are used especailly where the code correctness is of special importance. It is much easier to provide a (usable) formal sematics for functional languages than for stateful languages (imperative languages). Most important projects to actually prove software use therefore functional languages.
In addition, most people that are familiar with functional languages claim that one can programm in a much more elegant way.
The criteria to decided if functional programming is a better choice are the same a for any such decision: Does the language fits your needs? What your needs are may vary. However, if you need correctness and elegance, you should consider functional languages.
Functional programming has one big advantage: it avoids (on conceptual level) 'states' during the runtime. Thus, the value of a term is always predetermined by the input.
This advantage is at the same time a disadvantage: people are used to think in terms of states, and thus it seems to be a bit harder to learn a functional language.
Functional languages are used especailly where the code correctness is of special importance. It is much easier to provide a (usable) formal sematics for functional languages than for stateful languages (imperative languages). Most important projects to actually prove software use therefore functional languages.
In addition, most people that are familiar with functional languages claim that one can programm in a much more elegant way.
The criteria to decided if functional programming is a better choice are the same a for any such decision: Does the language fits your needs? What your needs are may vary. However, if you need correctness and elegance, you should consider functional languages.
No one programming language is good for all problems. Over the years, there have been attempts to define a single language - Algol68, IBM's PL/1, and US DoD Ada - and others have decided to use existing languages for things they were never intended for.
Functional Programming is good for a set of problems, but not every problem that we use computers to solve. When I was focused on those types of languages, FP (http://en.wikipedia.org/wiki/FP_(programming_language)) was the "hot" language. I never had access to a working compiler/run-time, but we did a lot of work in it. Somehow doing manipulation of text strings wasn't very easy (if I remember correctly), so you will need to figure out if Functional Programming maps well to the problem domain you are attempting to solve.
Functional programming is useful to tackle certain types of problems. Functional programming has its advantages in a certain set of conditions and situations. There are also set of problems in which functional programming is not particularly useful.
So use of Functional programming strongly depends upon the type of problem.
Although I agree that there are certain problems that match particular programming paradigms, it is important to recognise that a programming paradigm is a way of thinking about a problem. By having knowledge of the different paradigms and the ways of thinking that are relevant to them, it encourages greater diversity in thinking and possibly innovation.
If we start by restricting the paradigm to the type of problem, we can lose the value of the thinking that the paradigm encourages.
Functional programming does seem to have some analytic advantage but I do not see that as a reason to use a language restricted to functional programming. It can just be treated as as restriction on the style of writing within a language. Is there any valid reason to have separate language for functional programming? Is functional programming very common?
@Edward: Functional programming is very common everywhere where clear algorithm design is of importance. It supports solution-focused thinking (not what to *do* but what to *accomplish*). Therefore many universities teach functional languages as first programming languages.
A practical reason to restrict a language to functional programming is the avoidance of any sideeffect. As Samy said, that predestines functional languages to deal with concurrency.
Functional programming languages are introducing a different way of thinking in programming. It is good to learn functional programming languages during the study because it builds sophistry programming, impose consistency in thinking and push the boundaries of expectation. They are especially suitable for complex logical problems, matching functions and implementation of compilers. I know that Technical University of Chemnitz has a good tradition in education and research of functional programming.
Functional, and more generally declarative, languages have two main advantages: (1) they provide powerful abstractions, namely higher-order programming, that allow problems to be solved more concisely and elegantly than in imperative or OO languages; and (2) they naturally create more modular programs, permitting programmers to reason more effectively about their programs. People tend to focus on the first advantage, and languages like Python and Ruby, and next week, Java, support higher-order programming to gain this advantage. But I think the second advantage is the more important one, and that can't be added to imperative languages without completely changing the underlying computational model by removing destructive update. To me, it is invaluable to be able to look at a function (method, subroutine, whatever) call and know that its only effect will be to produce its output(s).
If there are libraries or existing codebases making a problem much easier for non-declarative languages that are not available for a declarative language, I would probably use them. If the performance a program or part of a program were more important than my time and sanity, I'd probably use C. If I needed to work with a team, I'd use the best language we all knew, which might not be declarative. Otherwise I'd prefer a declarative language.
Functional programming enables and encourages a more abstract way of solving a problem. A more "mathematical" programming way. You build a program as a mathematical abstraction. The result is less prone to error, more clean, more elegant and more functional.
Compared to imperative programming, in functional programming you have less chance of creating "spaghetti code" programs.
In order to teach our beginners important concepts (like recursion, recursive type definitions, higher order functions) and at the same time avoid the complications of programming with states, we (like many others) start computer science education with a course on functional programming using Haskell. Only after that, imperative programming and object-oriented programming are introduced using Ada and Java.
This year, we have replaced the three languages (Haskell, Ada, Java) by one which combines most of their features in an elegant way: the "object-functional" language Scala. Scala runs on top of the Java Virtual Machine, i.e., on all platforms supporting Java. Also, Scala and Java are interoperable: Scala programs can use Java classes and vice versa. This gives Scala programmers direct access to the comprehensive Java class library.
Since we aim to teach concepts, not programming languages, we are very happy with this decision. Instead of teaching three different syntaxes and tool sets, we can spend more time on teaching concepts. A smaller, but very useful aspect is type inference, which allows Scala programmers to leave out redundant "boiler plate" code. Scala is freely available in an Eclipse environment.
If you want to take a look for yourself, visit
http://www.scala-lang.org/ and
http://www.scala-lang.org/documentation/
for a wealth of material.
A good starting point is the web tutorial (including a Scala interpreter)
http://www.simplyscala.com/ (site appears to be down right now)
For the friends of functional programming, the course "Functional Programming Principles in Scala" by language designer Martin Odersky, can be enjoyed for free on Coursera (https://www.coursera.org/course/progfun).
Unfortunately, this sounds like an advertisement - I couldn't help it!
Other people have mentioned several advantages: lack of mutation makes it easier to parallelize, higher-order constructs enable you to write programs more concisely (not writing the same loop over and over again), and the functional setting encourages people to solve problems based on properties of a correct solution, rather than on capabilities of the machine you're running on.
The most important advantage to me (in teaching beginning programming) is testing. It's enormously easier to write test cases for functional code than for imperative code. If f(a) is a pure function (taking in only parameters, not global state, and producing only a value, not changes to global state), you just write something like
assertEqual (f(7), 12)
assertEqual (f(2), 29)
By contrast, if f were a method of an object with state, you might have to say
thing.setA(7)
thing.setB(4) // another piece of state that shouldn't be changed by the call to f
thing.doF()
assertEqual (thing.getResult(), 12)
assertEqual (thing.getB(), 4) // make sure what wasn't supposed to change didn't
thing.setA(2)
thing.doF()
assertEqual (thing.getResult(), 29)
assertEqual (thing.getB(), 4) // make sure it still hasn't changed
Another advantage that some people have touched on, but not really addressed: in my experience, students trained in functional programming tend to write lots of short, single-purpose functions with clear, reusable and composable interfaces (even when they're NOT working in a functional paradigm or a functional language), while students trained primarily in imperative programming tend to write longer functions that do several different jobs and have more-complex interactions with their environments. I would claim that the former style of programming is objectively better, regardless of whether you're actually writing functionally or not.
What about disadvantages? The main disadvantage is run-time efficiency. For certain problems, there are well-known mutating algorithms that are significantly more efficient than the best known functional algorithm for that problem. Dijkstra's shortest-paths algorithm is a good example.
In many such cases (e.g. table-based dynamic programming), the "mutation" involved is of a special kind: a data structure is initially "blank", and various slots are filled in with values, but once a slot has a value, it is never changed again. This is "almost functional", and in fact can often be implemented in a functional language with lazy evaluation (a really neat, expressive language feature that really doesn't work except in a functional setting).
In other cases, one can build a functional data structure that simulates the traditional mutable data structure at the cost of a multiplicative factor of O(log(n)), which may be good enough that the other benefits of functional programming still justify it.
@Edward wrote: "I do not see that as a reason to use a language restricted to functional programming. It can just be treated as as restriction on the style of writing within a language."
For many purposes, this is correct. Languages like Scala that make functional programming easy, but OO and imperative programming possible too, take this approach. But there are certain language or compiler features that are *incompatible* with mutation, so if there is any mutation anywhere in the program, those features can't be used.
One is laziness (which I mentioned in my previous comment): you can define a very large, even infinite data structure in terms of rules for filling in any desired finite part of it. When any particular entry is needed for a computation, that entry is filled in (and memoized, so it doesn't need to be recomputed if needed again), but the infinitely many entries that haven't been needed yet don't cost you any computation or storage. For example, a standard exercise for beginning Haskell programmers is to define a variable which is a list of all the prime numbers. If you ask Haskell to print out the tenth element of this list, it'll print the tenth prime. If you ask it to print out the first hundred elements, it'll print the first hundred primes. If you ask it to print out the whole list, it'll go infinite.
Another (behind the scenes) is garbage collection. I'm not a garbage-collection expert, but as I understand it, "generational" garbage collectors take advantage of the lack of mutation to guarantee that memory cells can only point to older memory cells (i.e. cells that were allocated longer ago), not newer ones. So if you scan a chunk of recently-allocated memory, marking cells that are referenced, you can free up any cell that isn't referenced in this chunk without worrying that some older variable is referencing it. (I welcome correction by actual garbage-collection experts!)
@Stephen wrote: " Languages like Scala make ... OO and imperative programming possible too. But there are certain... features that are *incompatible* with mutation, so if there is any mutation anywhere in the program, those features can't be used. One is laziness ... Another (behind the scenes) is garbage collection."
These two points are technically incorrect: Ever since Smalltalk, many OO languages employ garbage collection; this includes Java and Scala. For lazy evaluation, e.g., to compute the infinite sequence of prime integers, Scala provides Stream classes.
I'm sorry if my wording suggested that garbage collection is inconsistent with mutation. I meant to say that one particular APPROACH to garbage collection is inconsistent with mutation. Generational garbage collectors have been implemented for languages that also support mutation, but I don't know how they handle the scenario of a recently-allocated memory cell pointing to an older memory cell that points to another recently-allocated memory cell (a scenario that can't happen without mutation).
And yes, Scala (and, as of a few days ago, Java) provides lazy Streams. I haven't played with these enough to know how well they coexist with mutation. The issue is that if a value is computed lazily, you don't know exactly WHEN it'll be computed, and if its computation depends on mutable global state, that means you can't guarantee its value.
A main feature of functional programming is that it works with functions as values. This means that functions can be named, passed as arguments to function calls, or created as results of function calls. The paper
J. Hughes. Why functional programming matters. Computer Journal,
32(2), 1989.
argues convincingly that modularity is crucial in the development of real world applications, and that functional programming achieves this requirement by providing (1) useful abstractions to specify modules with generic functionality, and (2) the right glue to combine modules into more complex modules.
Also, pure functional programming (that is, functional programming restricted to operations without side effects) is referentially transparent. This means that we can replace equals by equals without disturbing the computed result (however, the efficiency of the computation may e affected). This property is extremely useful because it enables equational reasoning about functional programs, and thus the development of automatic tools for program verification and optimization.
Functional programming has its benefits, no doubt. There are no side effects, for instance.
But I am an embedded systems / real-time systems guy!
Now, what an embedded systems does all day long is essentially
- reading sensors and
- setting actuators.
This means in short: Side effects! All day long!
Should I use functional programming? Should I teach functional programming? I dont't.
(Yes, I know about monads. This is sequential programming, disguised as "functional" programming, isn't it?)
T. Tempelmeier returns us to the original question with a splendid example of when NOT to use functional programming. Anybody who tells you functional programming is ALWAYS better than imperative programming, or vice versa, has checked his/her brain at the door.
By similar reasoning, MIT a few years ago reworked its CS1 course to be "build and program a robot". Controlling a robot is very similar to Tempelmaier's description of embedded-systems programming: a lot of reading and writing global variables that are tied to hardware devices. It wouldn't make much sense to do this functionally, so MIT switched its CS1 language from Scheme (which it had been for the previous twenty-odd years) to Python.
I must agree with Stephan, there is no tool for any purpose. However, there are a lot of embedded applications where functional programming makes lots of sense: Of course, a control loop consist of reading sensors and setting actuators, but exactly this does *not* constitute a need for imperative programming. In embedded systems, the software plays frequently the role of a controller in control theory. I.e., the output is a function of the input stream.
Again, functional programming may also here enforce a different way of thinking. But again, understanding functional programming in this area improves the programming style even one does not apply it actually. Everybody who is interessted should look for functional reactive programming.
I agree with Matthias: every programming style enforces a different way of thinking. And thinking in terms of functions to do reactive programming may not be that obvious at first glance. A clever solution, based on lazy evaluation and programming with streams, is described in the book
Paul Hudak: The Haskell School of Expression. Learning functional programming through multimedia.
The book illustrates the fun of using functional programming (as supported by Haskell) for multimedia applications -- including graphics, sound, and animation.
Thinking in terms of streams and lazy evaluation is not quite trivial, but I believe it is worth the effort: you get extremely elegant and concise solutions to complex problems, like those for reactive systems.
As many have said, functional languages are purer, clearer and cleaner. In my two cents, functional languages or the like paradigm can be used to implement standalone and relatively small library functions and algorithms, involving only input and output. Your code gets more elegant and easier to reason about.
For large software pieces, they are state-ful in nature, using functional structures such as monads to simulate states isn't that easy nor elegant any more. When a program is large enough, the relation between components is more important than the others. Those paradigms which suit describing relations and facilitating compositions have the advantage, thus OO+functional (Scala) is a very good combination. With runtime polymorphism and higher order functions as the glue, the integration of different parts of a program is again clean and elegant.
Functional programming is important in concept and paradigm, not necessary a particular language. Once the concept is understood, programmers can stretch their thinking about function programming even in an imperative language. Sealing state-ful imperative code pieces into pure functional components seems to be a good choice to me.
Matthias and Mircea point out correctly that many important aspects of an embedded system CAN be well represented by pure functions. (Not the low-level parts that poll devices and stuff like that, but the high-level controller stuff.) For example, finite-state automata sometimes encode very naturally into functional form: if there are N states, you write N functions, each deciding what transition to make and then tail-calling the appropriate other function. And since many functional languages guarantee that tail-calls carry no memory penalty, you can run such a finite-state automaton indefinitely without running out of stack space.
For another example, we teach GUI programming to English and Music majors who have never written a program before, using a beginner-friendly functional API: students specify the type of their model, then write a model->model function as a clock-tick handler, a model->view function as a redisplay handler, a model X key -> model function as a keyboard-event handler, and so on. Students learn from the beginning to cleanly separate model from view, because they CAN'T do anything else.
Stephen is quite right, mentioning the low-level stuff. Device registers have to be set (or read) in a *specific sequential order* in order to function properly.
Sorry to all functional programming enthusiasts, but I cannot accept the attitude "Let's discuss the high-level stuff and forget about low-level device registers". Of course, I use pure functions (without side effects if at all possible) to the utmost extent for the high-level things, even in a language like C. But I have to have in mind (and to teach) the things which require sequential ordering.
By the way, could anybody point me to a functional programming version for a PID controller? The integration part (the I in PID) does an integration over time. So the result of this function (yes, I think it is a function in the mathematical sense) depends on (real) time. Similarly, the differentiation part (the D in PID) depends on the value of the last control cycle (one time step backwards, at least). I have trouble to figure out a functional programming version for this. And I don't find one on the internet. Thanks in advance for giving me a reference.
Note: PID does not mean ProcessID in this context, but Proportional/Integral/Derivative (Controller).
I have to admit first that this is a very controversial topic. Let's hope that what I write is not going offend any campaign. Believe me, this is purely my technical verdict...
One thing which is often overlooked is that, in today's software industry, there is only a very fine selection of problems where FP is the right solution for. Phil Wadler has an excellent paper [1], which -- based on this observation -- promotes identification of that selection.
However, there are those who still believe in FP as a general-purpose paradigm. In my opinion, this is exactly what makes people feel uncomfortable with it, because: Except for that fine selection, FP is indeed counterintuitive. Expecting average programmers to have done enough Yoga to handle all that twist is just unrealistic.
My other suspicion against FP is software maintenance: FP solutions often involve ingenuous tricks that read well only once you finally manage to get them. This is well beyond the level of everyday programmers. Additionally, my humble experience is that FP codes are often what Scott Meyers calls "write-only" [2]. This one is rather a matter of syntax, but, mostly overlooked. Having said that, I am not aware of any study on FP software maintenance.
Finally, from a code-reading point of view, FP also lacks good code break down mechanisms. (I am intentionally avoiding the term "encapsulation" here to prevent misunderstandings.) FP modules are usually composed of a couple of ADTs/monads plus a large collection of functions. The code reader has hard time categorising the functions (and sometimes ADTs) according to their level of importance, purpose, layer of service, etc etc.
I would like to remind that I use FP in my daily research. Yet, I won't give up honesty against it. :)
[1] http://www.ugcs.caltech.edu/~lordkaos/why-no-one.pdf
[2] Item 47 at "Effective STL": http://www.amazon.com/Effective-STL-Specific-Standard-Template/dp/0201749629
My answer to the original question is always and never.
Like many others I'd like to make a case for declarative languages. I think they are much more concise than imperative languages. In many cases the code can be even shorter than with imperative programming. If a functional language is the right choice of a declarative language is another thing (SQL for example is a declarative language that is not a functional language). I don't easily agree with another comment that functional languages are harder to learn than imperative languages. At least it seems that way having first learned an imperative language because of the different mind set.
There are a couple of points against functional languages (though I am not sure if they all apply to declarative languages in general). I wanted to write that functional languages are not well suited for GUI programming since this means changing state. Reading through previous comments this point seems to be mute, though. One big point against functional programming languages, though, is performance. As mentioned earlier sometimes the best functional algorithm is worse than a simple imperative solution. Also, I think that recursive solutions are not always the best, especially if it means calling the function with the same arguments a couple of times without caching results. In scientific computing, where software runs a couple of hours or days, every tiny performance gain is relevant. It is not possible to tweak functional programs to run faster on an imperative CPU (whereas imperative languages are perfect for this task). I've also read so many times that functional languages parallelize themselves so easily. I have never seen proof of that. Functional languages sometimes have the possibility to do many computations in parallel, but not always are all these computations necessary. Just because 8 cores are running at 100% does not mean that a sequential program cannot be faster! Parallel programming in an imperative language is hard, but recently it becomes easier as more and more people understand how to do it and thus more people are able to teach good style. To me, learning parallel programming in an imperative language is as hard as learning a functional language.
Maybe, functional languages are the best choice, but we don't have the right functional language, yet. Scala is a good step in the right direction, in my opinion. It allows to mix different programming styles. I still like C++ because it combines so many programming paradigms and I can choose the one that fits best to my problem (though true functional programming is still missing).
So, I'd like to sum up my answer. Always use declarative languages because they allow you to describe the problem instead of the solution. Never use declarative languages because it is very tedious to get high performance and it is impossible to fully optimize functional source code as it is possible with imperative languages (on imperative CPU architectures).
PS: To those of you who mentioned embedded systems: I guess not being able to use functional programming languages on every level is a problem of the hardware architecture. A different type of declarative language (probably not functional) could say something like "On sensor input A react within 3ms with action B." There could be hardware which is directly capable of executing code on this abstraction level. A couple of decades ago people built computers that could rung LISP or Prolog programs directly in hardware. The disadvantage, though, is that it is impossible (or really complicated) to run imperative programs on this type of hardware.
Advantages include:
1. Easier to use subprograms. A subprogram's function is completely described by what goes in and what comes out.
2. Most functional languages provide a nice, protected environment.
3. FP encourages quick prototyping.
4. Functional programming enables and encourages a more abstract way of solving a problem.
5. A more "mathematical" programming way. You build a program as a mathematical abstraction. The result is less prone to error, cleaner, more elegant and more functional.
6. Compared to imperative programming, in functional programming you have less chance of creating "spaghetti code" programs.
Disadvantages include:
1. Generally more difficult to pick up for new coders.
2. Functional idioms often do lots of laziness which often has a negative impact on debugging.
3. It doesn't match the hardware as well as most imperative languages.
4. The main disadvantage is run-time efficiency. For certain problems, there are well-known mutating algorithms that are significantly more efficient than the best known functional algorithm for that problem. Dijkstra's shortest-paths algorithm is a good example.
Commenting on Simon's contribution:
Quote: "... embedded systems ... problem of the hardware architecture. A different type of declarative language (probably not functional) could say something like "On sensor input A react within 3ms with action B." There could be hardware which is directly capable of executing code on this abstraction level."
We, the embedded systems peolpe, do have such a thing! We call it interrupt service routine. (1)
But the big question is: How do you continue after action B and how is action B defined *on the premise of using functional programming*?
- Put the sensor value in some variable or blackboard database?
- Forward the sensor value via message passing?
I'm interested to hear.
I do not see immediately how to integrate this approach with functional programming. Note that spontaneous sensor inputs (interrupts!) are almost indispensable in real life systems (2). Further, these inputs are unpredictable concerning their arrival time. So, any "function" reading the sensor will produce different values over time (depending on, say, prior actions of the driver or the pilot).
Once again, I do appreciate many aspects of functional programming. But in real-time systems, one has to deal with time and is dependant on time. And time does not fit in nicely with functional programming.
A few remarks with wihich I did not want to distract the reader from the overall arguments above:
(1) Maybe, one may combine the interrupt service routine (ISR) with a task (for "action B") as in the 'primary/secondary reaction' pattern. (http://www2.cs.unibw.de/Proj/GROOM/OMER-2/papers/OMER2-Tempelmeier.pdf). But this is only a refinement with respect to avoiding times where no interrupts are allowed and to facilitate programming - in a task one has more freedom than in an ISR.
(2) One could also use purely cyclic systems (reading all sensors - doing all combinational actions - setting all actuators). In this case the set of input registers of all sensors would act as the blackboard database. Still dependant on time. A discussion about synchronous programming languages or about the programming language Erlang may evolve from this ...
(3) Quote: "A couple of decades ago people built computers that could rung LISP or Prolog programs directly in hardware." Yes, true, but all these machines (as well as other hardware tailored to specific programming languages) are gone. And the promise that we would get hardware directly executing Java has vanished, too.
@Theodor: I don't have a lot of experience with embedded systems. So, i would definitely be the wrong guy to propose a new programming language for embedded systems. You should also distinguish between declarative and functional languages. Functional languages are only a subset of declarative languages. Logic programming is another subset. SQL (for databases) is also a declarative language.
I agree with you that functional programming would most likely not help with embedded systems. But, this doesn't mean that there wouldn't be a way to have another form of declarative programming language. Since you mentioned timings this would definitely be part of such a language. A declarative language could have statements that specify maximum latencies for actions.
There is a specification language for embedded systems (which basically makes it a declarative language). However, it can not model everything. It thus has the possibility to directly include C code as well (as the specification is translated to C anyways). It's called SDL: https://en.wikipedia.org/wiki/Specification_and_Description_Language
Erlang is a functional programming aimed at a class of embedded systems. It is particularly focused on soft real-time systems. Hard realtime systems really cannot use a garbage collector for instance making them a poor match for functional programming. Lustre and Estrel are two declarative languages aimed at that domain you might look at. That said, there are several embedded domain specific languages aimed at FPGAs and hard-realtime that might be of interest. Such languages allow the user to write the application in a functional style, but generate C or VHDL code to run on embedded systems.
Advantage: in debugging, you ask yourself "what is the value of this variable?" rather than "what is the value of this variable *at this time*?". It removes a whole temporal dimension from the reasoning and makes it easier to understand what your program is doing.
Advantage: in automated testing, it's shorter and easier to say "call this function on these arguments and check whether the return value is this" than "set this variable to this, set that variable to that, call this function on these arguments, check whether this variable is this other thing, check whether that variable is yet another thing". Test cases that don't have side effects can be reordered, commented out, and even run in parallel without affecting one another's passing or failing. This reduces exponentially the space of possible test results.
Advantage: in event-driven programming (e.g. GUI and video games), you need to specify event handlers, which are functions, so you need a way to talk about a "function" as a thing. Being able to create functions on the fly ("lambdas") and capture some aspects of the local variable environment into them ("closures") buys you a whole lot of flexibility in this.
Advantage: in parallel programming, the bane of your existence is race conditions, when two or more threads try to modify the same shared state and the results depend on which one gets there first. If you don't modify shared state, that problem goes away.
Advantage: in teaching beginning programming, you can introduce iteration using only syntax rules you've already learned (conditionals and function calls) rather than having to introduce an additional syntax rule for loops. (No big deal for experienced programmers, but for beginners, every extra syntax rule is a burden.)
Advantage: for big-data manipulations, it's simpler and easier to specify an operation to perform on a whole data set, and an operation to perform on the result of that, and so on, than to get into the details of how each operation needs to be iterated over individual data elements. (I work at Google now, and this is a life-saver!) The resulting code is much more readable, maintainable, and extensible than if it were written imperatively... and I can run the same code without worrying about whether it's running on one processor or a thousand.
Advantage: for memory management, it's easier to know what you can safely deallocate if you know that each variable refers only to objects that already existed before the variable did.
Disadvantage: Since most actual processors work by sequentially mutating and overwriting memory cells, a functional program doesn't map as directly to machine operations. A programmer who only knows functional programming may have a difficult time learning lower-level assembly and machine languages.
Disadvantage: Many important efficient algorithms depend on mutation, e.g. dynamic programming, marking algorithms for garbage collection and cycle detection, etc. Some of these can be made to work with "limited" mutation (e.g. each entry in the table is initially empty, and once it has a value, that value never changes), but some can't. If the problem at hand lends itself to such an algorithm, the advantage of run-time efficiency may outweigh other disadvantages.
@Alwyn: Good examples! However, I am into hard real-time systems (take flight control as an example), this rules out garbage collection.
Synchronous languages: Is the operator pre in Lustre (pre p returns the previous value of p) in accordance with functional programming? Lustre is declarative, but not functional in my view. Compare the notion of a *previous* value of a variable with the first paragraph of Stephen's post.
Decalarative languages: I am already happy that I can use
for i in 0 to 7 loop (VHDL) or for i in 0..7 loop (Ada) which is pretty more "declarative" than for (int i = 0; i