Showing posts with label Higher Order Function. Show all posts
Showing posts with label Higher Order Function. Show all posts

Tuesday, March 7, 2017

ConcurrentCounter - Reduce code with Functional programming

The fashion of functional programming

Now a days functional programming already made its come back and every language, companies and developers want to embrace functional programming. When we look at their works we can see it needs to travel more to reach the functional programming world. It was same for object oriented world as well. People used C++ but the code looked like C.

That is not the concern with this post. One of the reasons we here when people adopt FP is that it helps us to achieve things with less code. This is just a scenario where FP can reduce some amount of code.

Scenario - Thread safe manipulation of resources

We are in the world of threads. Knowingly or unknowingly we had to deal with threads. Some languages / technologies already has better ways to deal threading without developer write any explicit line. NodeJS can be an example. But for C# guys like me, has to write programs properly to make sure it works with threads. If all the tasks are ready to run in parallel,  there are no issues. But the reality is not that way. There will be so many critical sections we had to handle to achieve a good working software. We rely heavily on thread synchronization mechanisms to achieve the same. Whenever we deal with those, it is nightmare and there are so many chances to produce duplicate code. That is the place functional programming can help us.

Taking one situation. We have a counter inside a web service.That counter can be considered as a resource just like file or other resources. Counter variable is accessed by multiple service methods, some reads some writes. So the first way comes to our mind would be C# lock (VB.Net SyncLock) keyword. When we implement it there are chances that we may write lock statement in multiple places. Below is a mechanism to avoid that by using functional techniques of C#.
Please note that in real world no one should use this mechanism for integers as far as Interlocked class is there in .Net framework. This is just a sample for understanding purpose.

Wrap the lock statement in fuction and pass the actions into it

The technique here is simple as anyone might have guessed. Just have a wrapper around the lock and inside the locked section execute the real manipulation code which is passed into it as Action<T>. Lets see the code snippet below.
internal class ThreadSafeCounter
{
    private int internalValue;
    private object lockObject = new object();
    public int Value
    {
        get
        {
            return ExecuteWithLock(() => { return internalValue; });
        }
    }
    public ThreadSafeCounter(int initialValue)
    {
        this.internalValue = initialValue;
    }
    public void Increment()
    {
        ExecuteWithLock(() => { internalValue++; });
    }
    public void Decrement()
    {
        ExecuteWithLock(() => { internalValue--; });
    }
    public void Reset()
    {
        ExecuteWithLock(() => { internalValue=0; });
    }
    #region Helpers
    private void ExecuteWithLock(Action action)
    {
        lock (lockObject)
        {
            action();
        }
    }
    private int ExecuteWithLock(Func<int> fun)
    {
        int result = 0;
        ExecuteWithLock(() => result = fun());
        return result;
    }
    #endregion
}
The main functions to notice here are as below.

ExecuteWithLock(Action a)
ExecuteWithLock(Func)

The lock(){} is there only in one function named ExecuteWithLock() and all other functions those wants to execute critical section of code has to call ExecuteWithLock and pass the code as parameter. That code passing as parameter is obtained by the well known Action<T>. Hope there is no need of further explanation. 

Tuesday, January 19, 2016

What if there are no looping constructs in your language?

Being a professional software engineer, we cannot say that we are done we cannot program without looping control flow. Developers who started their career in machine or assembly language don't get scared of this. Similarly who understood and practiced machine and assembly language in college in. They will simply use 'go to' along with if statement and get the things done.

Forgot to tell in the question 'go to' is banned as always.So how can we tackle it without goto.

Lets come to code. Here we are going to see the scenario in 2 famous languages C# and Javascript. Below is the code to display numbers 1,2,3...10 in descending order which is written using loops.

JavascriptC#
function LoopWithWhileKeyword(loopCount) {
    while (loopCount > 0) {
        logLine(loopCount);
        loopCount -= 1;
    }
}
void LoopWithWhileKeyword(int loopCount)
{
    while (loopCount > 0)
    {
        logLine(loopCount);
        loopCount -= 1;
    }
}

This is straight forward. The code to call these functions is omitted to get focus, Now lets think how we can avoid this loop.

What is happening here

If we step back and think we can see there are mainly 2 code blocks. 
  • One block determines the continuation of execution.
  • Second is the actual code to execute multiple times.
Some idea might have triggered in everybody's brain who had done some programming. Nothing but extracting those separate blocks to functions.

We can use 'if' statement to decide whether to continue execution or not based on the return value if we move the condition logic to function. Then how do we execute the repeatable code block again without go to?

Execute the same function again. All of us has tried this in college when dealing with Fibonacci series. If we call a function from inside same function we can simulate loops. Yes recursion!!!

Lets see the code below which is rewritten with recursion.
JavascriptC#
function LoopWithoutWhileKeyword(loopCount) {
    WhileLoop(function () {
        return loopCount > 0
    },

    function () {
        logLine(loopCount);
        loopCount -= 1;
    });
}

function WhileLoop(condition, action) {
    if (condition()) {
        action();
        WhileLoop(condition, action);
    }
}
void LoopWithoutWhileKeyword(int loopCount)
{
    WhileLoop(
        () => loopCount > 0,
        () =>
    {
        logLine(loopCount);
        loopCount -= 1;
    });
}
void WhileLoop(Func<bool> condition,
Action action)
{
    if (condition())
    {
        action();
        WhileLoop(condition, action);
    }
}

Good. Isn't it? For those who gets headache on seeing recursion please read the explanation.

Here the WhileLoop function accepts 2 functions. It checks whether I should continue or not. Similar to the evaluation inside the while loop condition check. If the result of condition check is true, it calls the action method which has the code  needs to be executed multiple times.

Then it calls the WhileLoop function again to repeat the cycle. Since the action function has the code to reduce the loop count, it will end when the loopCount becomes 0.

Higher Order Function

We learned a jargon in programming called Higher Order Function. Any function which accepts another function or returns a function can be called as higher order function. Thinking that its this simple refer wiki

Most of us might be thinking, why we learned the loops if functions can do the job of loops. Why there are many ways to do same thing in computer science?

Tail call optimization

Normally developers has a tendency to use new things learned in their day job because of excitement. They might have heard it or saw one demo which touched the good parts of the concept / feature / technology.

Before anybody apply this technique in your production app understand and test it properly. Let's test this code by given 100,000 to the function.

In C# your will encounter 
An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll

In browser, you will get 
Uncaught RangeError: Maximum call stack size exceeded

In my machine I got javascript error when the recursion reaches 17911 and c# 4.0 failed after 12202 iterations.

Don't think that this issue will occur always. There are technologies and languages in which this issue will never occur. If we we are getting this, that tells us that our run-time or compiler does not do tail call optimization. Google for what is tail call optimization.