Tuesday, 15 December 2015

Build intuition around quality metrics

When you hear that a car drives at a speed of 250km/h or that a tree has 2 meters height you can intuitively classify it as fast/slow or short/tall.

When you hear that Cyclomatic complexity of you code is 2.7 or LCOM4 is 1.6 can you do the same? For many developers the answers is unfortunately - no - because in general there is no such real life intuition about programming. Many times I saw people surprised when they found four embedded ifs in their code. It looks like It appeared from nowhere.

We are not born with internal knowledge about surrounding code. Here you have first article returned by google which claims that we are actually born with some intuition about physics : Babies are born with 'intuitive physics' knowledge, says researcher. Some knowledge about world around us was quite useful for many generations - on the other hand Computers are relatively new thing in the history of human species.

So the idea of this exercise is to actually observe how complex code is created step by step and also to learn how some approaches helps keep value of this metric small. Code is used only for demonstration so some bugs may appear in it.

Cyclomatic Complexity A.K.A Hadouken code

Wikipedia says that cyclomatic Complexity can by defined as "It is a quantitative measure of the number of linearly independent paths through a program's source code." but maybe more intuitive for practitioners will be fact that when CC=2 you need to write 2 tests, CC=3 3 tests - etc.

Sounds trivial but now we are going to learn that Cyclomatic Complexity has non-linear nature which means that if you couple two pieces of code with CC=2 you may obtain code with CC>4. Let's see this on the battlefield.

We are going to start with Java because it has maybe the best tools to measure complexity and than we will see what we can measure in Scala Code.

Battlefield

Out experimental domain is very simple. Notice that at this stage we build just types with values. I used call those DTOs in my old Java days. Now I'd call them Records. Later we will see how nature of those classes will change during OOP refactoring.

class User{
    public final String name;
    public final Integer age;
    public final Gender gender;
    public final List<Product> products;

    public User(String name, Integer age, Gender gender, List<Product> products) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.products = products;
    }
}

enum Gender{MALE,FEMALE}

class Product{
    public final String name;
    public final Category category;

    public Product(String name, Category category) {
        this.name = name;
        this.category = category;
    }
}

enum Category{FITNESS,COMPUTER,ADULT}

Laboratory

We are going to develop and measure a piece of code which simulates transformation of business object into it's text representation. It's more than enough for this experiment so let's see the first version.

  public String complexMethod(User u){
        String value="";

        if(u.age > 18){
            value="Adult : " +u.name;
        }else{
            value="Child : " +u.name;
        }

        return value;
    }

We can easily measure CC of this code and to do this we are going to use Sonarqube 4.5.6



And also "Metrics Reloaded" plugin will be usable in some places.

So after the first measurement we receiveCC=2 - we have just one if statement so we need two tests.

CC=4

Now let's add another conditional which execute different actions according to Gender property.

       if(u.age > 18){
            if(u.gender==Gender.MALE){
                value="Adult Male: " +u.name;
            }else{
                value="Adult Female: "+u.name;
            }
        }else{
            if(u.gender==Gender.MALE){
                value="Child Male: " +u.name;
            }else{
                value="Child Female: "+u.name;
            }
        }

Now let's try to guess what is CC of this code. Following path of execution are possible.

  1. IF -> IF
  2. IF -> ELSE
  3. ELSE -> IF
  4. ELSE -> ELSE

Sonar agrees.

CC=5

Our logic is expanding. Now we need to also add information about products...but only for User who is Adult Male.

public String complexMethod(User u){
        String value="";

        if(u.age > 18){
            if(u.gender==Gender.MALE){
                value="Adult Male: " +u.name;

                for (Product p: u.products) {
                   value+="has product "+p.name+",";
                }
            }else{
                value="Adult Female: "+u.name;
            }
        }else{
            if(u.gender==Gender.MALE){
                value="Child Male: " +u.name;
            }else{
                value="Child Female: "+u.name;
            }
        }

        return value;
    }

Technically sonar just counts number of for and ifs to calculate CC but we can understand result of CC=5 this way :

  • For empty collection nothing changes : CC+0
  • For non empty collection we have another possible path : CC+1

CC=6

Let's make things more interesting by adding filtering condition to products.

 public String complexMethod(User u){
        String value="";

        if(u.age > 18){
            if(u.gender==Gender.MALE){
                value="Adult Male: " +u.name;

                for (Product p: u.products) {
                    if(p.category!= Category.ADULT) {
/*HAAADUUUKEN  ~~~~@ */    value += "has product " + p.name + ",";
                    }
                }
            }else{
                value="Adult Female: "+u.name;
            }
        }else{
            if(u.gender==Gender.MALE){
                value="Child Male: " +u.name;
            }else{
                value="Child Female: "+u.name;
            }
        }

        return value;
    }

We have another single if in our code. Cyclomatic complexity is CC=6 which may seem small but it isn't. We already have Arrow Code Anti pattern. and context awareness of this piece of (sh...) code makes it almost impossible to reuse anywhere else.

Soon we will see how this way of coding rises complexity in more exponential than linear way. But first let's look at something called essential complexity.

Essential Complexity

What if we don't want to initialize mutable variable but we would like to return from withing embedded ifs?

public String complexMethod(User u){
        if(u.age > 18){
            if(u.gender==Gender.MALE){
                String value="Adult Male: " +u.name;

                for (Product p: u.products) {
                    if(p.category!= Category.ADULT) {
/*HAAADUUUKEN  ~~~~@ */    value += "has product " + p.name + ",";
                    }
                }

                return value;
            }else{
                return "Adult Female: "+u.name;
            }
        }else{
            if(u.gender==Gender.MALE){
                return "Child Male: " +u.name;
            }else{
                return "Child Female: "+u.name;
            }
        }

    }

Now Sonar will return CC=10 because technically complexity in sonar is not just Cyclomatic Complexity but CC + Essential Complexity (and maybe + something else). Here we will receive better measurement with metrics plugin.

So Complexity=CC+EC=6+4=10 . Essential Complexity - in my understanding it measures number of places where your logic execution can end. So because we have multiple returns it makes code more difficult to analyze. If this statements is correct is a matter of discussion but generally since I started learning Functional Programming and thinking in expressions I believe I haven't used such construction like return in the middle of the code. (BTW now I'm going to change syntax color to have a comparison what is better)

Ok we see the problem , now let's find a cure.

Refactoring OOP way

The easiest thing at the beginning is to move logic responsible for displaying product to a dedicated component. It's not easy to think about proper domain abstractions where actually we don't have any domain problem but let's try with something generic.

interface ProductPolicy{
    boolean isCensored(Category category);
}

interface PolicyFactory{
    ProductPolicy create(Collection<Category> forbiddenCategories);
}

interface ProductDisplayer{
    String display(Collection<Product> products);
}

So there is a policy which may be configured through factory. And we have interface for our displayer which may look like this:

class CensoredDisplayer implements ProductDisplayer{

    private ProductPolicy productPolicy;

    public CensoredDisplayer(ProductPolicy productPolicy) {
        this.productPolicy = productPolicy;
    }

    @Override
    public String display(Collection<Product> products) {
        String result="";
        for (Product p: products) {
            result+=addToDisplay(p);
        }
        return result;
    }

    private String addToDisplay(Product p){
        return productPolicy.isCensored(p.category)? "" : " has product "+p.name+",";
    }
}

Now let's take a look at our laboratory code.

 private ProductDisplayer productDisplayer;

    public String complexMethod(User u){
        String value="";

        if(u.age > 18){
            if(u.gender==Gender.MALE){
                value="Adult Male: " +u.name;
                value+= productDisplayer.display(u.products);
            }else{
                value="Adult Female: "+u.name;
            }
        }else{
            if(u.gender==Gender.MALE){
                value="Child Male: " +u.name;
            }else{
                value="Child Female: "+u.name;
            }
        }

        return value;
    }

Complexity of this code is CC=4 and complexity of Displayer is CC=1.7 so technically whole system is a little bit less complex already. (And "Beans" is the name of a class where I put all interfaces)

OOP data types

To move further we can change nature of data types from records into richer entities and use inheritance polimorphism to dispatch execution between specific pieces of code.

Check the code.

abstract class User{
    protected final String name;
    protected Integer age;
    protected final List<Product> products;

    public User(String name, Integer age,  List<Product> products) {
        this.name = name;
        this.age = age;
        this.products = products;
    }

    abstract String introduceYourself();

    abstract List<Product> showProducts();
}

class MaleUser extends User{

    public MaleUser(String name, Integer age, List<Product> products) {
        super(name, age, products);
    }

    @Override
    String introduceYourself() {
        return (age>18?"ADULT MALE":"CHILD MALE") + " : "+name;
    }

    @Override
    List<Product> showProducts() {
        return age>18? products: new LinkedList<>();
    }

}

class FemaleUser extends User{

    public FemaleUser(String name, Integer age, List<Product> products) {
        super(name, age, products);
    }

    @Override
    String introduceYourself() {
        return (age>18?"ADULT FEMALE":"CHILD FEMALE")+ " : "+name;
    }

    @Override
    List<Product> showProducts() {
        return new LinkedList<>();
    }
}

What is important here is to notice how context information was now moved to children of (now) an abstract class User. Context information is now encapsulated inside classes and this construction reduces Cyclomatic Complexity in the place where objects are used. Look at this:

 public String complexMethod(User u){
        String result=u.introduceYourself();
        result+=productDisplayer.display(u.showProducts());
        return result;
 }

So once again - we take control over context awareness of particular logic by moving this logic inside classes. Execution is controlled by polymorphic method dispatch.

Refactoring FP Way

We are going to start in similar way as we did in an OOP example. So at the beginning let's move logic responsible for filtering and displaying products into dedicated functions.

Function<Set<Category>,Function<Category,Boolean>> policy=
            forbiddenCategories -> category -> !forbiddenCategories.contains(category);

Function<Category,Boolean> adultPolicy=policy.apply(new HashSet<>(Arrays.asList(Category.ADULT)));
  

Function<Function<Category,Boolean>,Function<Collection<Product>,String>> displayProducts= policy-> ps ->
        ps.stream()
                .filter(p->policy.apply(p.category))
                .map(p->" has product "+p.name)
                .collect(Collectors.joining(","));

So we have Policy, Parametrized Policy and Product Displayer. Complexity of our lab method will be now reduced to CC=4

public String complexMethod(User u){
        String value="";

        if(u.age > 18){
            if(u.gender==Gender.MALE){
                value="Adult Male: " +u.name;

                displayProducts.apply(adultPolicy).apply(u.products);
            }else{
                value="Adult Female: "+u.name;
            }
        }else{
            if(u.gender==Gender.MALE){
                value="Child Male: " +u.name;
            }else{
                value="Child Female: "+u.name;
            }
        }

        return value;
    }

Now let's introduce some conditional logic into next functions mainly to check how good is sonar in measuring CC of Functions.

Function<User,String> ageLabel= u -> {
        if (u.age>18)
            return "ADULT";
        else
            return "CHILD";
    };

Function<User,String> introduce=u-> {
        String result="";
        switch(u.gender) {
            case MALE:
                result= ageLabel.apply(u) + " MALE" + " : " + u.name;
                break;
            case FEMALE: result= ageLabel.apply(u) + " FEMALE" + " : " + u.name;
        }
        return result;
    };
Function<User,Collection<Product>> getProducts = u-> {
        if(u.gender==Gender.MALE && u.age>18 )
            return u.products;
        else
            return new ArrayList<>();
    };

And finally let's see how all this functional machinery can help us!

//composition!!
Function<User, String> productDisplayer = getProducts.andThen(displayProducts.apply(adultPolicy));


public String complexMethod(User u){
     return introduce.apply(u) + productDisplayer.apply(u);
}

This looks wonderful - and now good and bed news.

We have reduced Complexity of our lab function to CC=1 but unfortunately Sonar is unable to measure complexity inside functions. I tried Sonar 4.X and Sonar 5.X - both without success. The only solution I found to have proper CC measurements is to use method references.

static String introduceMethod(User u){
        String result="";
        switch(u.gender) {
            case MALE:
                result= ageLabel.apply(u) + "pełnoletni" + " : " + u.name;
                break;
            case FEMALE: result= ageLabel.apply(u) + "pełnoletnia" + " : " + u.name;
        }
        return result;
    }
Function<User,String> introduce=BlogComplexityFP::introduceMethod;

We saw how to chandle complexity in Java both in OOP and FP way - now let's quickly check how to measure complexity in the Scala world.

Scala Measurements

I believe that Scala main quality tool is Scala Style. It has plugin for sonar but is not as rich as the one for Java. Generally in Scala Style we can set acceptable Cyclomatic Complexity level and if code exceeds it then a warning will be risen.

So if I have this ugly piece of code

def complexMethod(u: User): String = {
    if (u.age > 18) {
      if (u.gender == MALE) {
        var value: String = "pełnoletni : " + u.name
        for (p <- u.products) {
          if (p.category != Category.ADULT) {
            value += "i ma produkt " + p.name + ","
          }
        }
        value
      }
      else {
        "pełnoletna : " + u.name
      }
    }
    else {
      if (u.gender eq MALE) {
        "niepełnoletni : " + u.name
      }
      else {
        "niepełnoletnia : " + u.name
      }
    }
  }

Then I will only receive a warning

More info will be displayed in the sbt console

ProceduralExample.scala:26:6: Cyclomatic complexity of 6 exceeds max of 1

And finally Scala code with CC=1

object FPExample {

  object Gender extends Enumeration{
    type Gender=Value
    val MALE,FEMALE=Value
  }

  object Category extends Enumeration{
    type Category=Value
    val FITNESS,COMPUTER,ADULT=Value
  }

  import Gender._
  import Category._

  case class Product(name:String,category: Category)
  case class User(name:String,age:Int,gender:Gender,products:List[Product])


  val policy : Set[Category] => Category => Boolean =
    forbiddenCategories => category => !forbiddenCategories.contains(category)

  val adultPolicy = policy(Set(ADULT))

  def displayProducts(policy:Category=>Boolean)(ps:Seq[Product]):String=
    ps
      .filter(p=>policy(p.category))
      .map(" and have product " + _.name)
      .mkString(",")

  val agePrefix: User=>String= u =>
    if(u.age>17) "adult" else "child"

  val introduce : User=>String = _ match {
    case u @ User(name,_,MALE,_) => agePrefix(u) + " Male :" + name
    case u @ User(name,_,FEMALE,_) => agePrefix(u) + " Female :" + name
  }

  val getProducts: User=>Seq[Product]= _ match {
    case User(_,age,MALE,products) if age>18 => products
    case _ => Seq[Product]()
  }

  val productDisplayer=getProducts andThen displayProducts(adultPolicy)

  def complexMethod(u: User): String = introduce(u) + productDisplayer(u)
}

Is it a complex or a simple code? It's difficult to say because Cyclomatic Complexity tends to be not very helpful when lambdas enter the scene. In a couple paragraph below we will think about possible solution.

Non Linear Nature of Complexity

Ok after all those examples and exercises let's try to understand non linear nature of Complexity. We saw that when we are moving logic to external components or functions - we can make them context unaware to some degree. Then they are receiving information about context they are being used in by various types of parametrization.

So if for example if I have a Component A with CC=2 and I want to use this component in some Component B then this action does not raise CC of Component B. Of course I assume that Component A was properly tested and it behaves in predictable way

Now when I would take logic our from Component A and paste it directly into Component B then most likely I can not use this piece of code in Component C because it is already embedded in Context B. This way I raised CC by 4 with the same piece of code.

If it is not clear yet then let's return to this part :

if(age>18){
   if(MALE){...} //1
   else{...}
}else{
   if(MALE){...} //2
   else{...}
}
Both ifs //1 and //2 are similar but they are aware than one is in the context of age>18 and second one in age<=18. So every occurence of similar code will raise CC by 2.

OOP & FP

I hope I also managed to show that proper usage of both OOP or FP mechanism reduces complexity. According to my observation programmers generate complexity mainly not by using wrong paradigm but by using any paradigm in a wrong way - in shorter words - first learn OOP or FP properly and only then discuss FP vs OOP (and of course I should do this too).

Psychological Aspect

Till now we discussed how code complexity influence code itself but can we actually check how this complexity affects developers?

Actually there was an interesting experiment more than half century ago - an experiment which described borders of humans' cognitive limits. Experiment description can be found here : The magic number seven plus/minus two. According to researcher - George A. Miller - Human being can process 7 +/- 2 chunks of information at once. You can find more info on wikipedia to better understand what exactly is chunk of information

The answer to question "why developers have to write code with bugs" - because developers are (still) humans ;)

Summary

I hope that this "complexity adventure" will be helpful to those who are curious how their code obtain "arrow shape" and where complexity is lurking. Also we checked how usage of FP influences Cyclomatic Complexity and a limitation of procedural metrics in FP world. It opens up an interesting question about how to measure complexity of functional code. Very often functional constructs build solution without ifs and fors which are base for CC calculation.

What can we do?

  • build more intuition around scala style rules
  • research functional programming complexity measurements papers
  • Some materials for further investigation:

    Monday, 9 November 2015

    Understanding composition

    "Composition over inheritance" - I think I've heard this for the first time around 2006 when programming in Java 5 with generics was still a luxury and everything was literally "an Object". I remember an enormous shock after reading "Head First design patterns" when my mind started understanding a difference between OOP and procedural programming. This was a shock because as a Junior I had to work with large classes (with over 1000 lines per method) called SomethingManager or SomethingHelper - and then "the book" stated "well... this is wrong.. it's not Object Oriented Programming"

    A decade later - we can hear that another approach called Functional Programming promises better composition that anything you tried before. Normally we would write couple "hello worlds" to gain better intuition, gradually gather new knowledge and make some judgement.

    Yet... with FP something magical is hidden underneath - something marginalized yet very powerful, something scary yet very helpful and finally something which is denied but exists everywhere.

    But let start with something simple...

    What does it mean "to compose" ?

    Literally "Composition" can be understood as an usage of N simple elements to create more complex construction. For example a tap below is a composition of some elements, It is technically working, passed acceptance criteria and is a good metaphor of many IT project which I saw in my life.

    Of course we have an intuition that although this mechanism is working something is wrong with it. So let's think a little bit about composition in generally - can we answer a question about when things are easy to compose and how FP can help us with it. Writing finally some code - if for example I have a function in Java.

    Function<Integer, Integer> f1 = i -> i + 1;
    

    I have an Integer as an input and Integer as an output. So we could use this function with anything what ends with Integer or starts with Integer like this

    Function<Integer, String> f2 = i -> "composition is beautiful : " + i;
    Function<Integer, String> composed = f1.andThen(f2);
    

    Or we could literally call this operation a composition

    Function<Integer, String> alsoComposed = f2.compose(f1);
    System.out.println(composed.apply(1));          //composition is beautiful : 2
    System.out.println(alsoComposed.apply(1));      //composition is beautiful : 2
    

    Before Java8 when there was no concept of a function as a value we would have to treat them like standard methods and invocation would look like this :

    Integer result1 = f1.apply(1);
    String finalResult = f2.apply(result1);
    

    It is still a form of composition but we can feel that more work is needed here. This was Java - now let's do the same in Scala which is more expressive

    val f1:Int=>Int= i=>i+1
    val f2:Int=>String = i=> "composition is beautiful : " + i
    
    val composed=f2 compose f1
    composed(1) // res0: String = composition is beautiful : 2
    

    It looks nice with simple numbers but to gain better intuition let's simulate more real life example.

    More real life example

    type Money=Double //yes it's very bad and evil
    type DataBase = Map[Int,User]
    case class User(val name:String,val salaryNet:Money)
    

    This will be our model with very unprofessional usage of Double as Money. Let's create mock database with some records of keys and users

    val database:DataBase=Map(
      1->User("Stefan",10.0),
      2->User("Zdzislawa",15.0),
      3->User("Boromir",20.0)
    )
    

    And finally actors of this spectacle - three simple functions which we are going to compose together:

    val lookup:DataBase=>Int=>User = db=>key => db(key)
    val salary:User=>Money= _.salaryNet
    val net:Money=>Money= _ * 1.23
    

    Perfect World Style

    //perfect word style
    val composedLogic: (Int) => Money =net compose salary compose lookup(database)
    composedLogic(1)
    composedLogic(2)
    composedLogic(3)
    //res1: Money = 12.3
    //res2: Money = 18.45
    //res3: Money = 24.6
    

    Isn't it beautiful and simple? We took all parts and now we have fully functional program... but really have we? What if reality hit us with inpurity?

    //problem
    //composedLogic(4)
    /// java.util.NoSuchElementException: key not found: 4
    

    Most likely we had this problem at some point in our professional life - it's time to use the infamous "If" solution

    When composition is difficult - the "dark ages" approach

    Let's handle missing case in a classical DAO style

    val lookupDarkAges:DataBase=>Int=>User = db=>key =>
      if(db.contains(key)) db(key) else null
    

    For now looks fine. Let's do the composition :

    val composedLogicDark: (Int) => Money =net compose salary compose lookupDarkAges(database)
    

    It compiles... can it be IT? Well no, of course not ->

    //composedLogicDark(4)
    //composedLogicDark: Int => Money = <function1>
    //AND the Stack Trace is SWEET
    //java.lang.NullPointerException
    //at pl.pawelwlodarski.fp.math.one.A$A109$A$A109$$anonfun$salary$1.apply(CompositionScala.sc0.tmp:19)
    

    Now let understand why this don't compose. To safely use lookup function in Dark Ages style we need to adapt usage of another function by manually checking for null value and in real life this is how the arrow code is created

    val lookupResult = lookupDarkAges(database)(4)
    if(lookupResult!=null){
      val salaryResult=salary(lookupResult)
      if(salaryResult!=null){
        net(salaryResult)
      }
    }
    

    But now with full power of FP we can use another approach

    the Scary "M" approach - "ehhh another Option example..."

    //scary "M" style
    val lookupScaryM:DataBase=>Int=>Option[User] = db=>key =>
      if(db.contains(key)) Some(db(key)) else None
    //or just db.get(key) but let's keep it similar to previous examples
    

    There are thousands of code examples on internet about Option construct but let's explain this for people who may don't know. Our methods now returns a wrapper which can be modified by special mechanism which receives some lambda/function as an argument. That's why we can call it high order function and from version 8 it can be also used in Java.

    It allow us to use functional composition in context of real world problems like missing values and it protects us from null checks and arrow code.

    val stillPerfectComposition: (User) => Money =net compose salary
    val composedScaryM :Int => Option[Money]=
      key => lookupScaryM(database)(key) map stillPerfectComposition
    
    composedScaryM(1)
    //res4: Option[Money] = Some(12.3)
    composedScaryM(4)
    //res5: Option[Money] = None
    

    And now we can contact real world somewhere over there

    //Leave mathematical world
    case class HttpMessage(code:Int,bod:String)
    val error=HttpMessage(404,"<div>I'm so sorry for this error</div>")
    val success=(salary:Money)=>HttpMessage(200,s"<div> salaray : $salary</div>")
    
    val httpMessage = result.fold(error)(success)
    // HttpMessage(200,<div> salaray : 12.3</div>)
    

    Java example

    For Java fans

    Map<Integer, User> database = new HashMap<>();
    
    database.put(1, new User("Stefan", 10.0));
    database.put(2, new User("Zdzislawa", 15.0));
    
    Function<Map<Integer, User>, Function<Integer, Optional<User>>> lookup = db -> key -> {
                User u = db.get(key);
                return Optional.ofNullable(u);
    };
    
    Function<User, Double> salary = User::getSalaryNet;
    
    Function<Double, Double> gross = money -> money * 1.23;
    
    Function<User, Double> perfectComposition = gross.compose(salary);
    
    Function<Integer,Optional<Double>> program =key -> lookup.apply(database).apply(key).map(perfectComposition);
    
    System.out.println(program.apply(1));
    System.out.println(program.apply(4));
    //Optional[12.3]
    //Optional.empty
    

    Ok but I promised something powerful. Option is very useful but it is only part of something bigger, a lot bigger...

    The "F" word and another scary "M" word

    There is something scary hidden under THIS MYSTERIOUS LINK. Just a moment ago I stated that Option is just a wrapper - I lied (to some point). "A wrapper" is an old way of thinking - we can look at it from a very different perspective and see that we actually used power of Type System to signalize possibility of a missing value.

    If you entered the mysterious link you saw a page which looks maybe scary but for sure is not "cool". It leads to a wiki page about Functor and open gates to another scary concept denied by most of programmers something called... Mathematics

    It may look scary but you have already used it - yes by using Option. My interpretation may not be accepted by mathematician but generally we can see there that Functor changes something like this X => Y into F(X) => F(Y). In our example it changed USER=>MONEY into OPTION(USER) => OPTION(MONEY)

    And this is what map method on Option does. Imagine it as a standalone function: map(A=>B): Option[A] => Option[B]. Ok great, but does it have any practical value? You know in every scala presentation everyone carefully states "you don't need to know category theory". But when you write program how do you know you are doing it "correctly" ?

    "CUSTOM" Driven Development

    Once upon a time a guy lived in Scotland and his philosophy became one of the most important though movements in history - this guy was David Hume and according to his words people in generally organize their lives around set of Customs. "I don't have proof that tomorrow sun will rise but it happened 10000 times before so what the hell - I will assume that tomorrow situation will repeat".

    I'm wondering if we are not doing the same thing with Computer Science which in most areas is not science anymore but became a "set of principles created by few and adapted by many". Look - OOP is not a science - even Alan Kay who created this term doesn't have strict definition ---> http://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en

    Most discussion about OOP which my inexperienced eyes saw and most discussion which may novice ears heard happened according to schema : My Opinion vs. your Opinion. This maybe convenient for drinking beer but maybe not so useful for engineering science. At the same time mentioned Functor is a part of bigger theory and it has some formal laws - yes, formal laws. Moreover "Scalaz" - a Functional library for scala - is shipped with prepared automated tests in scalacheck to check if your implementation of Functor from your domain is correct according to thoseformal laws!

    This is really very new approach. After decade of "Opinion based development" this is something really new for me. It seems very promising but we are living in strange times when "being a programmer" is very blurry concept. For some you are an artist and for some you are just a fucking resource.

    But let's return to something more pelasent

    Functional purity - Haskell Kindergarden

    This is as far as I can get with Haskell today but using a pure functional language where you can not cheat is a very interesting exercise. As a warm up let's do a simple composition. in Haskell you are composing by "dot" - -->.<-- (by "dot"? This is stupid! - In Java your are calling method by "dot"... -Ok.. continue)

    Prelude> let f1 i =i+1
    Prelude> let f2 i= "composition is beautiful : " ++ show i
    Prelude> let f3= f2 . f1
    Prelude> f3 1
    "composition is beautiful : 2"
    

    You can declare type aliases similarly to the way we are doing it in Scala (or in the other way - I believe Haskell was first)

    Prelude> type Money=Double
    Prelude> data User = User {name :: String, salaryNet :: Money} deriving (Show)
    
    Prelude> import qualified Data.Map as Map
    Prelude Map> type DataBase = Map Int User
    Prelude Map> let database = fromList [(1,User "Stefan" 10.0),(2,User "Zdzislawa" 15.0)]
    

    First Interesting this is that I was unable to create "Dark Ages" example in Haskell because... there is no null. (there is a function called "null" which checks if list is empty). And Option in Haskell is called "Maybe" and it has two values "Nothing" and "Just"

    let ourLookup database key = Map.lookup key database
    Prelude Map> :t ourLookup
    ourLookup :: Ord k => Map k a -> k -> Maybe a
    

    SalaryNet was generated automatically when we declared User structure

    :t salaryNet 
    salaryNet :: User -> Money
    

    And finally our composition

    let grossValue money = money * 1.23
    
    let perfectComposition = grossValue . salaryNet 
    Prelude Data.Map Map> :t perfectComposition 
    perfectComposition :: User -> Money
    

    And "scaryM" approach usage

    let lookupScaryM key  = fmap perfectComposition (ourLookup database key)
    
    lookupScaryM 1
    Just 12.3
    
    lookupScaryM 4
    Nothing
    

    What is fmap? This is wonderful moment because this is the place where practice meets formal theory (hint: word "FUNCTOR"...)

    Prelude Map> :t fmap
    fmap :: Functor f => (a -> b) -> f a -> f b
    

    Now let's return to Scala and see some more powerful functional composition mechanisms

    Even more composition - summon the Dragon

    Let's recall last example of our Scala composition

    val stillPerfectComposition: (User) => Money =net compose salary
    val composedScaryM :Int => Option[Money]=
      key => lookupScaryM(database)(key) map stillPerfectComposition
    

    We can summon the dragon

    import scalaz._
    import Scalaz._
    

    And use something called Kleisli Composition

    val findUser=(database:DataBase)=>Kleisli.kleisli[Option, Int, User] {
      (key:Int) => lookupScaryM(database)(key)
    }
    
    //HERE IS THIS BETTER COMPOSITION
    val program=findUser(database) map stillPerfectComposition
    program.run(1)
    //res6: Option[Money] = Some(12.3)
    program.run(4)
    //res7: Option[Money] = None
    

    We can even eliminate "database" parameter from composition generating functional dependency injection mechanism

    val dependencyInjection = findUser andThen(_ map stillPerfectComposition)
    val result=dependencyInjection(database)(1)
    // res8: Option[Money] = Some(12.3)
    
    dependencyInjection(database)(4)
    //res9: Option[Money] = None
    

    In 2004 there was a movie - The village. If I remember correctly it was about a group of people who was cheated that there is still XIX century while it really really XXI. I had the same feeling three years ago when I left "Java comfort zone". There are some very powerful languages over there with syntax a lot different than Java (which syntax was borrowed C++ which syntax was borrowed from C . Haskell has underscores, OCaml has underscores so maybe it's really worth to learn new way of thinking even if syntax is not from Java.