There's aready a nice compact answer above. However, since you ask several related questions about FP, I propose some more explanations, if deemed useful.
Functional programming handles everything as either a declaration or an expression. In this paradigm, functions are the main mean of abstraction:
they are combined in expression (composition), can themselves be an operand/argument in an expression, and can be the result of a higher order function.
The driving idea is to move away from the sequential paradigm in which you tell the machine to do one thing after the other. This is not easy to understand in a statement oriented language like C#. Take the following simple calculation: statements:
double res; // computes something based on previously defined a and b
if (a>b)
res = Math.Sqrt( a*a - b*b );
else
res = - Math.Sqrt ( b*b - a*a);
This if
statement is not composable. If I want to use the result of the calculation in another calculation, I have to add a new statement that use res
, which means that I rely on a side effect:
res = res *2; // another side effect
if (res > 100)
...
The natural way forward would be to extract your statements into a function. THis isolates the side effects into local variables that are without effect on the rest of the code:
double f(double a, double b) { // abstract calculation in a function
double res;
if (a>b)
res = Math.Sqrt( a*a - b*b );
else
res = - Math.Sqrt ( b*b - a*a);
return res;
}
double growth(double x) {
return x*2;
}
You can then easily compose the functions:
if (growth(f(a,b))>100)
...
You could also try to express your functions as much as possible as an expression thus avoiding to rely on side effect. But be careful, because long expressions are also more difficult to write and to read:
double f(double a, double b) { // abstract calculation in a function
return a>b ? Math.Sqrt( a*a - b*b ) : - Math.Sqrt ( b*b - a*a);
}
C# also gives you use a more functional style. This facilitates breaking down problems into simpler functions (here local functions that do not polute the namespace) and use composition:
Func<double, double, double> f = (a,b) => (a>b ? Math.Sqrt( a*a - b*b ) : - Math.Sqrt ( b*b - a*a));
Func<double, double> growth = (x) => x*2;
Func<double, double, double> comp = (x,y) => growth (f(x,y));
THe idea behind this paradigm, is that in pure functional programming you express the problem independently of the order of operations. In theory, it's then the implementation's job to find out the most efficient execution path, whether it evaluates the expression in a sequential manner, or it distributes subexpressions for exploiting parallelisation potential.
This is, by the way, why functional programmers like immutability and don't like side-effects. Mutability and side-effects create constraints and expectations about the evaluation order.
If you want to grasp the spirit of functional programming, it would worth to give functional programming languages such as OCaml and F# a try. After a tutorial you can then easily go back to C#, and use functinoal style where it can help to make the difference.