Sunday, January 27, 2019

Functional programming memo (with Java)

What the functional programming is

Object oriented programming has been often used to create programs so far. But recently, Functional programming is also considered to be as useful as object oriented programming, or even better than it in some respects.
The functional programming is:
In computer science, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.
It is a declarative programming paradigm, which means programming is done with expressions or declarations instead of statements. In functional code, the output value of a function depends only on the arguments that are passed to the function, so calling a function f twice with the same value for an argument x produces the same result f(x) each time; this is in contrast to procedures depending on a local or global state, which may produce different results at different times when called with the same arguments but a different program state.
Eliminating side effects, i.e., changes in state that do not depend on the function inputs, can make it much easier to understand and predict the behavior of a program, which is one of the key motivations for the development of functional programming.
-- wikipedia Functional_programming
According to Tutorial point, functional programming offers the following advantages −
  • Bugs-Free Code − Functional programming does not support state, so there are no side-effect results and we can write error-free codes.
  • Efficient Parallel Programming − Functional programming languages have NO Mutable state, so there are no state-change issues. One can program "Functions" to work parallel as "instructions". Such codes support easy reusability and testability.
  • Efficiency − Functional programs consist of independent units that can run concurrently. As a result, such programs are more efficient.
  • Supports Nested Functions − Functional programming supports Nested Functions.
  • Lazy Evaluation − Functional programming supports Lazy Functional Constructs like Lazy Lists, Lazy Maps, etc.
But functional programming usually requires more memory. This Quora question compares Haskell (functional language) and C/C++.

Side effect

Side effects (in the context of computer science) are rarely used in functional programming.
In computer science, a function or expression is said to have a side effect if it modifies some state outside its local environment, that is to say has an observable interaction with the outside world besides returning a value. Example side effects of a particular function might consist in modifying a non-local variable, modifying a static local variable, modifying a mutable argument passed by reference, performing I/O or calling other side-effect functions.
-- wikipedia Side effect (computer science)

Referential transparency

Absence of side effects is a necessary, but not sufficient, condition for referential transparency. Referential transparency means that an expression (such as a function call) can be replaced with its value. This requires that the expression is pure, that is to say the expression must be deterministic (always give the same value for the same input) and side-effect free. A function without side effects can return different values according to its history or its environment, for example if its output depends on the value of a local static variable or a non-local variable respectively.
-- wikipedia Side effect (computer science)

Functional programming in practice

Use Haskel if you want to see what functional programming looks like. Or if you prefer JVM language, see Clojure.

Recursion


(This table is from tutorial point)

According to this table, functional programming uses recursive concept to iterate collection data. If you already know how to program in Java/Python, you can practice recursion in codingbat (recursive basic or recursive advanced).

Recursion in practice

For example, this is the recursive function (of Java code):
public int factorial(int n) {
  // Base case: if n is 1, we can return the answer directly
  if (n == 1) return 1;
  // All other cases except the base case above.
  return n * factorial(n-1);
}
This is the function that returns the factorial of n. For example, if the n is 3, it works like this:
  1. First iteration: n is 3, so this is not the base case, so the function returns
    3 * factorial(3-1);
  2. Second iteration: n is 3-1=2, so this is not the base case, so the function returns
    2 * factorial(2-1);
  3. Third iteration: n is 2-1=1, so this is the base case, so the function returns
    1;
So, overall, factorial(3) returns "3 * 2 * 1". So we could calculate "3!" without using for-loop or while-loop. This is the recursion.
By the way, if you forget to write the base case:
public int factorial(int n) {
  // All other cases except the base case above.
  return n * factorial(n-1);
}
The recursion doesn't stop at 1 and the function will be continued after 1 like "1 * factorial(1-1)" and then "0 * factorial(0-1)"... for infinite times. So this will cause a stack overflow.

String in a recursive function

We will see how to treat string data in a recursive function. This is an example of recursive function that changes all "pi" of a string to "3.14".
public String changePi(String str) {
  if(str.length() <= 1) return str;
  if(str.substring(0, 2).equals("pi")) return "3.14"+changePi(str.substring(2));
  return str.substring(0, 1) + changePi(str.substring(1));
}
So "piABCpi" becomes "3.14ABC3.14". This is one of the codingbat problems.
The following is the explanation of what the function changePi() is doing.

First check - whether the function should stop or not (or whether the string is too short)

This function, at first, checks if the str is too short or not.
if(str.length() <= 1) return str;
If you the string data is shorter than or equal to 1 letter, we don't need to check the str anymore because A string that contains only 1 letter can not be "pi". If this validation returns true, that is the time the function finishes the execution.

Second check - whether the first 2 letters of the string are "pi" or not

Then this part checks if the first two letters are "pi".
if(str.substring(0, 2).equals("pi")) return "3.14"+changePi(str.substring(2));
If it's "pi", it will return "3.14" and hand over the "str.substring(2)" to the next iteration. "str.substring(2)" means the string except the first two letters, so it is replacing the first two letters with "3.14" and continuing the iteration.

Third - returns the checked letter and hand over the rest to the next iteration

The third line of the function is this:
return str.substring(0, 1) + changePi(str.substring(1));
It is returning the checked letter and hand over the rest of the string to the next iteration. As a result of the second check, this string str.substring(0, 1)  can not be "p" with "i" behind it, so this is executed only when the function doesn't find "pi" in the checked string. 

Overall

By bringing the above together, when input string is "piABCpi", the changePi()function returns as follows:
First iteration
returned value from changePi(): "3.14"
the value handed over to changePi(): "ABCpi"
Second iteration
returned value from changePi(): "3.14A"
the value handed over to changePi(): "BCpi"
Second iteration
returned value from changePi(): "3.14AB"
the value handed over to changePi(): "Cpi"
And the third, fourth, fifth... it continues until the length of str variable handed over to the function becomes less than 1. Finally it returns "3.14ABC3.14" for the input "piABCpi".

IF

If/else can be repaced by these things. (Vavr’s Option)

A little more (with Javascript)

This video is nice. Though she is using Javascript, not Java.