Rob Kraft's Software Development Blog

Software Development Insights

Archive for June, 2014

Advantages of Pure Functions and Idempotent Functions in .Net

Posted by robkraft on June 28, 2014

Summary

This article will define a “Pure Function” and an “Idempotent Function”. It will also explain the advantages of each type of function using examples in C# .Net.

Definitions

A method is a “Pure Function” when it always returns the same results when given the same inputs.  This method is a “Pure Function”:

An Idempotent method

This method is not a “Pure Function”:

A method that is not Idempotent

“Idempotent Functions” have two slightly different definitions.

  • In much of computer science, an “Idempotent Function” is a function that always returns the same result when given the same input and can include calls to methods that retrieve data from a database and also calls like HTTP GET and HTTP DELETE.  Methods that can be called repeatedly that will return the same result are “Idempotent”.

 

  • In “Functional Programming”, “Idempotent functions” are more like “Pure Functions” that go a step further. In “Functional Programming”, if you take the output of an “Idempotent function” and call that function again using the output of the last call as the input for the next call, you will get the same result again. Here is an example of using an “Idempotent Function” named abs:

var x = abs(-3); //x = 3

var y = abs(x); // y = 3

The result of calling abs(-3) is 3.  And that is the same result as calling the abs(abs(-3)).

More succinctly:

abs(abs(x)) = abs(x)

Apology

I previously wrote an article that I titled “Advantages of Making Your Methods Idempotent and Static in C#“, but I misunderstood idempotent. My article was really about “Pure Functions”, not “Idempotent Functions”. So in this article I attempt to make amends for putting something untrue on the Internet.  I want to think Phil Atkins in Cambridge, UK for patiently and persistently helping me to realize the error in my original article.

Advantages of Pure Functions

When adding methods to classes, many developers spend little time deciding if the method should be a pure function. Making use of the properties in the class causes the method to not be a pure function, as in this example of the method named ReturnNumberOfDaysSincePersonWasBorn:

Here is the ReturnNumberOfDaysSincePersonWasBorn method re-written to be a pure function:

A method that is not Idempotent

And here is another version of the method that is not a pure function. This time, the method is not a pure function because it is changing the value of a variable (Age) scoped outside of the method.

Here are the advantages to methods that are pure functions:

  • The methods are easier to maintain. They are easier to maintain because a developer needs to spend less time analyzing the impacts of changes to the method. The developer does not have to consider the state of other inputs that are used in the method. When considering a change to a method that is not a pure function, the developer must think about the impact on properties used in the method that were not passed in.
  • The methods are easier to test. When writing a unit test, it is easy to pass values into the method and write the test to verify the correct output. But writing tests on methods that are not pure functions take longer and are more complicated because more setup or injection of values is necessary for the test.
  • The methods are easier to re-use. You can call the method from other places in the module, or call the method from several different modules easily when the method is a pure function.
  • The methods are easier to move to other classes. If you have a pure function in one class and you want to move it to a utility class to be used by other modules, it is easy to do so.
  • The methods are more likely to be thread-safe. Pure functions don’t reference variables in shared memory that are being referenced by other threads. Caveat: variables such as objects that are passed by reference could still experience threading problems when used inside of static methods that are pure functions.

Resist the Temptation!

When you encounter a case like the one below, where Method3() needs the BirthDate for a calculation, it can be tempting to change the methods from static to be non-static and to reference the BirthDate property in Method3(). The other alternative is to pass the BirthDate into Method1(), and from Method1() to Method2(), and from Method2() to Method3(). Although we don’t like to make those changes, doing so allows keeps the method as a pure function and keeps the advantages provided by pure functions.

Resist the Temptation to Lose Idempotency

In C# .Net, if you are unable to mark your method “static”, then it is probably not a pure function. If the method makes database calls, API calls, updates properties outside of the method, or uses variables that have scope outside of the method, then it is not a pure function, but it may still be considered idempotent according to the non-functional definition of idempotent.

Advantages of Idempotent Functions

If you are not a functional programmer and you define idempotent functions as “functions that always return the same result for specific inputs”, then the benefits of idempotent functions are the same as the benefits of pure functions, except when they involve retrieving or update data in locations outside the function.  I rarely think about idempotent functions from a functional perspective, but idempotent functions do provide the following benefits to intelligent code compilers.

  • In some languages, if a compiler recognizes that calling abs(abs(abs(abs(x)))) will always return the same results of abs(x), it can substitute abs(abs(abs(abs(x)))) in the written code with the more efficient abs(x) in the compiled code.
  • In some languages, if a compiler recognizes that a function is idempotent, it may be able to cache the result of the call to the function and provide the cached value in place of making calls to the function again with inputs previously used.

In functional languages, the primary advantages of idempotent functions do not apply to the developer writing and maintaining code, but rather to the compiler and performance of the program.

 References

http://en.wikipedia.org/wiki/Idempotence#Computer_science_meaning

 

Advertisements

Posted in Code Design, CodeProject, Coding | Leave a Comment »

Advantages of Making Your Methods Idempotent and Static in C#

Posted by robkraft on June 22, 2014

THIS ARTICLE IS INCORRECT

I apologize for putting incorrect information on the Internet.  This article explains “Pure Functions”, not “Idempotent Functions”.  I have written a new article to provide a more accurate description of “Idempotent” and also “Pure Functions” here:

https://csharpdeveloper.wordpress.com/2014/06/28/advantages-of-pure-functions-and-idempotent-functions-in-net/

My thanks to Phil Atkins in Cambridge, UK for making me aware of my error.


Read the rest of this entry »

Posted in Code Design, CodeProject, Coding | Leave a Comment »

Use Fuzzy Hours for Your Software Task Time Estimates

Posted by robkraft on June 14, 2014

Like many software development shops, we need to provide estimates of the time required to fix each bug and add each new feature.  The primary reason for the estimates is to set expectations for when tasks will be completed and to prioritize what is to be worked on.

As an agile shop, we have tried a few scales for estimating such as:

tiny, small, medium, and large and also the Fibonacci sequence:    1, 2, 3, 5, 8

but the one we have been using for years that we like best is fuzzy hours.

We use the symbols 1,2,3, and 4 where:

  • 1 means 0 to 2 hours
  • 2 means 1 to 8 hours
  • 3 means 4 to 40 hours
  • 4 means more than 30 hours

Notice that our ranges overlap and that is what makes them fuzzy.  When an estimator feels an estimate is in a fuzzy zone it is up the estimator to pick one zone or the other based on their gut feeling.

We have also learned that the velocity for all items sized 1 and 2 are the same, and items with a size 3 take only slightly longer to reach a completed state (development, testing, quality assurance, and documentation all complete).  Items with a size of 4 take longer, but only about twice as long on average as a 3.

Posted in Estimating, Process | Leave a Comment »