Functional Groovy

1. What is FNZ

This project is a collection of ideas taken from other functional languages translated to Groovy.

The main objectives of this library are:

  • Create more control structures (let, letm, where…​)

  • Understand persistent collections (TODO)

  • Ways of enforce immutability

If you have a copy of the code and you want to start playing with the examples writen along the documentation. You can use both groovyshell and groovyConsole. Both are accessible through two gradle tasks.

Of course you should have at least installed JDK 7 in your machine. Otherwise gradle won’t work.
using FNZ in groovysh
./gradlew -q shell

or

using FNZ in groovyConsole
./gradlew console

2. Functional Abstractions

2.1. Introduction

Category Theory is a huge topic not related per se to programming, but nowadays is the basis of what functional programming has become today.

In this chapter I’ll try to explain and give examples of some terms taken from Category Theory and why they could be useful to us as programmers in our daily work.

Many of the examples are based on Haskell programming language. As a pure functional language is the best place if you want to learn the basis of functional programming, and also because there aren’t much documentation out there other than Haskell. Here you have my two cents :)

I’m aware that terms like Functor, Monad…​etc seem to be something strange, odd, difficult for most of the programmers born in the OOP era (including myself by the way).

I know it’s difficult…​ bad news: it becomes harder along the way, good news …​ there is no good news. I’m jocking good news is that the more you learn about Category Theory applied to functional programming the more you understand how to use functional programming at work…​ but stop! it’s about time…​ LETS DO THIS

2.2. Functor

In Category Theory a Functor is a mapping between categories…​WHaAaAAAaaTT?? O_o

A Functor represents a container/wrapper of some sort, along with the ability to apply a function to elements wrapped in the container.

Ok, so a Functor is like a container, like a box. It contains a value. That value can be transformed by functions applied to the container, not to the value directly.

The formal definition of a Functor in Haskell is:

Functor definition
class Functor f where
    fmap :: (a -> b) -> f a -> f b

What does it mean ? Well it means that in order to build a new instance of a Functor type the type should implement a fmap method.

The fmap method receives a function (a -> b) which transforms an object of type a in another object of type b, it also receives a Functor of type a and finally returns a functor of type b.

How could we implement this ?

2.2.1. Example

Functor (Java)
package fnz.data;

/**
 *
 * @param <A> The contained type
 */
public interface Functor<A> {
    public <B, F extends Functor<B>> F fmap(Function<A,B> fn);
}
Some of the interfaces or classes shown here are implemented in plain Java™. I’m planning to migrate them to Groovy 2.3+ with @CompileStatic any time soon.

So basically a functor allows us to transform the contained value applying a function. There’re some differences between the Java™ implementation and the Haskell one.

  • (a->b) becomes Function<A,B>

  • fa parameter will be the instance of the functor itself

  • fb becomes Functor<B>

Now imagine we had a function adding 3 to any number. In Haskell we would be seeing this:

Haskell example
fmap (+3) (Just 1)

I’ll try to reproduce the same behavior, this time with Groovy :) We will be following these steps:

  • We need a function receiving a number and returning a number (a->b)

  • Then the functor will receive the function and will know how to unwrap the value and after applying the function how to wrap it again.

2.2.2. Function (a→b)

A function represents a transformation applied to a given input, giving a certain result.

We need a function adding 3 to any given number. Here is a simple java interface defining a function:

Function (Java)
package fnz.data;

/**
 *
 */
public interface Function<A,B> {
    B apply(A input);
}

Because this interface is in fact a functional interface, it could be substituted by a Closure expression. So instead of building a new class or building a verbose inner class implementation we will be using a closure to define a new implementation of the Function interface.

Function<Integer,Integer>
void 'Building a simple function'() {
    given: 'a function instance using closures'
        Function<Integer,Integer> plus_3 = { Integer v ->
            v + 3
        } as Function<Integer,Integer>
    when:  'using it'
        Integer result = plus_3.apply(5)
    then: 'the value to be the number plus 3'
        result == 8
}
Be aware that because closures only declare the return type you should add the type to the closure parameter if you care about input type.

2.2.3. Functor<A>

Well now we need an instance of a functor of type A, pass to the functor our previously created function and expect to receive a certain value with a certain type.

Functor<Integer>
void 'applying a given function to a functor'() {
    given: 'a function'
        Function<Integer,Integer> plus_3 = { Integer v -> v + 3 }
    and: 'a functor implementation. This time Maybe.Just implements functor'
        Functor<Integer> boxOfFive = Maybe.just(5)
    when: 'applying the function to functor to get another functor'
        Functor<Integer> result = boxOfFive.fmap(plus_3)
    then: 'the result should be the expected'
        result.typedRef.value == 8
}

Ok but how Maybe.Just gets something and transform it to another functor. Lets see what the fmap implementation does:

Maybe Functor#fmap implementation
@Override
public <B, F extends Functor<B>> F fmap(Function<JUST, B> fn) {
    return (F) just(fn.apply(this.getTypedRef().getValue()));
}

First I’ll try to describe which types are involved:

  • JUST is the value contained by the Maybe instance (which among other things is a functor).

  • <B> is the type of the function applied. Then the Maybe implementation wraps that value into another instance of a functor (this time another Just instance).

Basically here the fmap method takes as an argument a function transforming the contained value in the source functor and then wraps it again in another functor instance.

By the way, althought fmap is implemented in Functor in languages like Haskell, you won’t see fmap being invoked like "myObject.fmap(…​)" but instead you will find something like fmap(functor, function)

In the source code you will see that there’re several methods adding some syntactic sugar to inner functors/applicative/monads methods mimicking the way Haskell does it.

Public API
import static fnz.Fnz.val
import static fnz.Fnz.fmap
Functor<Integer>
void 'applying a given function to a functor with public api'() {
    when: 'using fmap function to execute the fmap method from Just'
        Functor<Integer> result =
            fmap(Maybe.just(5)) { Integer x ->
                x + 3
            }
    then: 'executing val() to get Just inner value'
        val(result) == 8
}

2.2.4. Plain Groovy

Well under the hood many of the methods added to the Groovy API (api, gapi, gdk) resemble monadic behaviors. For example there is the with method all Groovy objects have. Although it could be seen more like a bind action (we’ll cover it later on) we can create a lighter version of fmap with this with.

Groovy map
def map(Object o, Closure function) {
    o?.with(function)
}

As we’ll see later on, many monadic estructures don’t execute functions when they detect something went wrong, or the type at a hand means nothing can be executed (a Maybe.Nothing , Either.Left value, or a Try.Failure values could be an example for that)

This with on steroids executes the closure (function) passed as parameter when the value exists (and represents a Groovy truth of couse ;) ). Notice was achieved by using the safe operator from Groovy (foo?.unsafeMethod()).

Groovy map
void 'Groovy light version of fmap'() {
    when: 'using fmap function to execute the fmap method from Just'
        def result = map(input) { Integer x ->
            map(x + 3) { Integer y ->
                y
            }
        }
    then: 'executing val() to get Just inner value'
        result == expected // 8 and null
    where:
        input    | expected
            5    | 8
            null | null
}

And I can’t finish this section without talking about collect. Collect is the closest version of fmap I can think about within Groovy. Collect transforms each item in a collection into something else.

Same way our map method was safe so is collect.

Groovy collect
void 'Groovy collect is "similar" to fmap'() {
    when: 'Applying a function to collect'
        def result =
            input.collect { Integer x ->
                x + 1
            }
    then: 'checking'
        result == expected
    where: 'possible messy values'
        input      | expected
            [1, 2] | [2, 3]
            null   | []
}

So…​ why don’t we make a better world and use both ideas combined ?

Groovy collect
void 'Groovy light version of fmap and collect combined'() {
    when: 'Making the world a safer place'
        def result =
            input.collect { Integer x ->
                map(x) { Integer y ->
                    (y + 1) * 2
                }
            }
    then: 'checking'
        result == expected
    where: 'possible messy values are'
        input         | expected
            [1, 2]    | [4, 6]
            [1, null] | [4, null]
}

2.3. Applicative Functor

Remember I was saying a Functor is a container, a box if you like, containing a simple value ? You can think about Applicative like a Functor containing a Function. This time the box contains a Function.

Why then the name of Applicative ? I’m not quite sure, but I think it came from the idea that a function can be applied to some other values.

In Haskell:

(<*>) :: Applicative f => f (a->b) -> (f a -> f b)

This time instead of containing a plain value the functor has a function. So we can read the Haskell function as a function receiving an applicative f (a->b) (a functor containing a function transforming from a to b) and returns the transformation from a functor containing a to a functor containing b (f a -> f b).

2.3.1. Example

package fnz.data;

/**
 *
 * @param <A> The type contained in this container
 */
public interface Applicative<A> extends Functor<A> {
    public <U extends Type<A>> U getTypedRef();
    public <B> Applicative<B> fapply(Applicative<Function<A,B>> afn);
}

We have included in our Java™ version a way of accessing the inner value forcing any Applicative to implement the getValue() method.

Instead of getValue returning a raw value I’ve implemented getTypedRef which returns a wrapper having the raw instance. I did it becauseI didn’t found a solution to resolve the problem of having the ListMonad sharing the same interface with Monads sharing single values and still respecting the fmap, fapply and bind methods. I’m not perfect so I will be very happy if someone gives me a better solution :)

But the most important method is fapply which in in charge of receiving another applicative and use the value of that applicative and apply it to the inner value of the instance of the source applicative.

Lets take a look to the implementation of the fapply method in the Maybe.Right class we can see how it works.

@Override
public <B> Just<B> fapply(Applicative<Function<JUST, B>> afn) {
    return this.fmap(afn.getTypedRef().getValue());
}

How can we use it ?

In this example I’m using implementations of Maybe. This implementation is not only an Applicative but a Functor (which is implied) and a Monad. Instead of creating object with new operator every object has a static method to do it.

import static fnz.Fnz.val
import static Maybe.just
import static Maybe.nothing
import static Maybe.maybe

This is the example:

void 'Applicative: Maybe applicative implementation'() {
    when: 'combining two closures'
        def inc = { Integer v -> v + 1 }
        def byTwo = { Integer v -> v * 2 }
    and: 'using the combination as a Function'
        def combination = (inc >> byTwo) as Function
    then: 'if the value is nothing the function shouldnt be applied'
        val(nothing().fapply(just(combination))) == null (1)
    and: 'otherwise if the initial value is correct the function will work'
        val(just(1).fapply(just(combination))) == 4 (2)
}
1 The implementation of the Maybe.Nothing fapply method doesn’t apply the function to the current instance and returns an instance of new Nothing(null)
2 The implementation of the Maybe.Just fapply method applies current value to the function contained within the Applicative passed as parameter.

2.4. Monad

What is a Monad ?

While Functor applied a function to a wrapped value, and an Applicative applied a wrapped function to a wrapped value, a Monad applies a function to a wrapped value and returns a wrapped value.

Because Monad is an Applicative and an Applicative is a Functor, likewise a Monad has some inherit methods such as fmap or fapply. But the method that makes a Monad a Monad is the bind method (or >>= which is its alias in Haskell).

How does bind looks like ? Like always , first step, Haskell syntax:

class Monad m where
    (>>=) :: m a -> (a -> m b) -> m b

A bind method receives a wrapped value m a then a function (a -> m b) which transforms the wrapped value to another wrapped value, and finally returns the transformation result m b.

In my humble representation of a Monad type in Java™ I came up with the following code:

package fnz.data;

/**
 *
 * @param <A> The contained type
 */
public interface Monad<A> extends Applicative<A> {

    public <B,M extends Monad<B>> M bind(Function<A,M> fn);

    /**
     * The behavior is the same as the bind(Function&lt;A,M&gt;) method but with type awareness.
     * <br>
     * This method was created exclusively for type inference for the $do/$return expressions.
     * For instance in an expression like the following:
     * <pre>
     *     $do {
     *         x = Just(1)
     *         y = Just(x + 1)
     *
     *         $return x + y
     *     }
     * </pre>
     * The expression is translated into this:
     * <pre>
     *     Just(1).bind { _clazz1231, x -&gt;
     *         Just(x + 1).bind { _clazz2324, y -&gt;
     *             _clazz2324.unit(y)
     *         }
     *     }
     * </pre>
     * That way we don't have to specify the type of the Monad needed to
     * end the expression, the function itself carries the type.
     *
     * @param <B> The type contained in the monadic result
     * @param <M> the result monadic type
     * @param fn a function aware of the type of the returned monad
     * @return a monad as a result of the function execution
     *
     */
    public <B,M extends Monad<B>> M bind2(TypeAwareFunction<A,M> fn);

    /**
     * This method is a helper to return the real value wrapped in
     * this container
     *
     * @return an instance of T
     * @param <U> the type you want to return
     */
    public <U> U get();

}

3. Types

This chapter has to do with other ways of creating/using/extending types with Groovy.

3.1. func

A functional interface is an interface that has just one abstract method (aside from the methods of Object), and thus represents a single function contract

— Java(TM) spec

func allows you to declare and create a functional interface in one line without the verbosity of having to write a full Java interface.

Normally if you wanted to create a functional interface and use it you should be doing something like this:

class A {

    interface Fx {
        Integer apply(String word)
    }

    Integer applyFunction(String word, Fx function) {
        return function.apply(word)
    }

}

With func you can create in one line the same interface:

package fnz.samples.type

class A {
     static {
         func Fn >= String >> Integer
     }

     boolean simpleFunctionalInterface() {
         Integer result = executeFunction('1') { String x ->
              x.toInteger()
         }

         return (result == 1)
     }

     Integer executeFunction(String number, Fn fn) {
         return fn.apply(number)
     }

}

In general the use cases are:

3.1.1. Simple types

class OuterClass {
    static {
        func InterfaceType >= ParameterType >> ReturnType
    }
}

Of course you can declare as many interfaces as you want:

class A {
    static {
        func Fa >= String >> Integer
        func Fb >= String >> String
        func Fb >= String >> Date
    }
}

3.1.2. Using generics

You can also use generics:

class OuterClass {
    static {
        func InterfaceType(A,B) >= A >> B
    }
}

You first should to declare the name of the type and maybe generic types used in the Functional Inteface signature as a parameter or as return type.

InterfaceType(A,B)

And then you should declare the signature of the function:

A >> B

In this case it means that we will be having a method like this:

B apply(A a)

So as a whole it will be the same as writing:

interface InterfaceType<A,B> {
    public B apply(A a)
}

The parameters and the return type can both use the generic types declared by the interface type:

class OuterClass {
    static {
        InterfaceType(A,B) >= ParameterType(A) >> ReturnType(B)
    }
}

The following example declares some generic type used at return type:

package fnz.samples.type

import fnz.Fnz
import fnz.data.Maybe

import groovy.transform.CompileStatic

@CompileStatic
class A {

     static {
         func Fx(X) >= String >> Maybe(X)
     }

     Maybe<Integer> executeFunction(String number, Fx<Integer> fx) {
          return fx.apply(number)
     }

     boolean simpleFunctionalInterface() {
          Maybe<Integer> result = executeFunction('1') { String x ->
               Fnz.Just(Integer.parseInt(x))
          }

          Fnz.val(result) == 1
     }

}

Now the example uses generics both as parameter and return type

package fnz.samples.type

class A {
    static {
        func Fx(X,Y) >= X >> Y
    }

    Integer executeFunction(String source, Fx<String,Integer> fx) {
        fx.apply(source)
    }

    String executeAnotherFunction(Integer source, Fx<Integer,String> fx) {
        fx.apply(source)
    }

    boolean complexFunctionalInterface() {
        Integer result1 = executeFunction('1') { String x ->
            Integer.parseInt(x)
        }

        String result2 = executeAnotherFunction(1) { Integer x ->
            x.toString()
        }

        result1 == 1 && result2 == '1'
    }
}

And mixing generics with other types:

package fnz.samples.type

import fnz.Fnz
import fnz.data.Maybe

class A {
    static {
        func Fx(X,Y) >= Maybe(X) >> Y
    }

    Integer executeFunction(String source, Fx<String,Integer> fx) {
        fx.apply(Fnz.Just(source))
    }

    boolean complexFunctionalInterface() {
        Integer result = executeFunction('1') { Maybe<String> x ->
            Fnz.val(x.fmap { Integer.parseInt(it) })
        }

        result == 1
    }
}

3.1.3. Multiple parameters

So far we’ve been showing functions with just one parameter or at most a parameter making use of generics, but wouldn’t be great to have a way of declaring a function with two or more arguments ?

It turns out you can. The syntax to acomplish this is to use the Groovy syntax for lists.

func SUM(X) >= [X,X] >> X

Here we had a funcion SUM which takes two parameters of the same type and returns a value of the same type. It makes sense right ?

In the following example we’re using this feature just to show how parameters can be parametrized (use generics) as well.

package fnz.samples.type

import static fnz.Fnz.val

import fnz.Fnz
import fnz.data.Maybe

class A {
    static {
        func Fx(X) >= [Maybe(X),Maybe(X)] >> X
    }

    Integer executeFunction(Fx<Integer> fx) {
        return fx.apply(Fnz.Just(1), Fnz.Just(2))
    }

    boolean complexFunctionalInterface() {
        Integer result =
            executeFunction { Maybe<Integer> a, Maybe<Integer> b ->
                return val(a) + val(b)
            }

        result == 3
    }
}

4. Data

This chapter will go through some monadic types implementations.

4.1. Maybe

The Maybe is normally used to avoid asking whether the value is null or it can contain any value. That’s why the Maybe object has two children: Maybe.Just and Maybe.Nothing.

In the JDK 8 you can find the Optional type. Sometimes is also called Option.

As we’ll be seeing along this chapter is that monads like Maybe, Either or ListMonad will allow to apply functions over the wrapped value, only if the wrapped value is considered valid. Otherwise the wrapped value will be returned.

To see how to use Maybe lets use it in a simple exercise:

Given a number, I want to divide it by half two times, and then if still not decimal, multiplied by three.

Because all even numbers will become decimals as soon as I try to dividing them by half I want to stop the process as soon as the process detects that number is no longer eligible to success.

void 'Monad: using maybe to shortcircuit a process'() {
    given: 'a function dividing only even numbers'
        def half = { BigDecimal possible ->
            return possible.intValue() % 2 == 0 ?
                Maybe.just(possible.div(2)) :
                Maybe.nothing()
        }
    and: 'another function multiplying by three'
        def threeTimes = { BigDecimal possible ->
            return Maybe.just(possible * 3)
        }
    when: 'starting the process'
        Maybe<Integer> result =
            Maybe.just(sampleNumber)
                .bind(half) (1)
                .bind(half) (2)
                .bind(threeTimes) (3)
    then: 'checking the result'
        val(result) == expected
    where: 'sample numbers and expectations are'
        sampleNumber | expected
            100      |    75
            200      |   150
             50      |   null
}
1 tries to divide, if not even returns nothing otherwise returns division result.
2 tries again to divide the number under the same premises.
3 If division ended successfully only then applies multiplication.

The nice thing about this plan is that if any of the previous steps ended with a Maybe.Nothing instance the process won’t go any further.

In order to understand what happens underneath, why process doesn’t continue, I would like to show you both implementation of Maybe.Just and Maybe.Nothing.

While Maybe.Just applies the function:

@Override
public <B, M extends Monad<B>> M bind(Function<JUST, M> fn) {
    return fn.apply(getTypedRef().getValue());
}

Maybe.Nothing like its name, does nothing but to return the current value :P

@Override
public <B, F extends Functor<B>> F fmap(Function<NOTHING, B> fn) {
    return (F) new Nothing();
}

Sometimes it would be useful to have an alternative when there’s no value. That’s what the method or does. It makes the monad to return the alternative value in case there was no value. Otherwise the current value is returned.

void 'testing maybe alternatives (I)'() {
    when: 'something has no value and adding an alternative'
        Maybe<String> name = nothing().or(just("john"))
    then: 'we should get the alternative'
        val(name) == 'john'
}

It’s pretty clear in the previous example, but it is even clearer when you do something ( a transformation for example) with the current inner value.

void 'testing maybe alternatives (III)'() {
    when: 'something has value and adding an alternative'
        Maybe<Integer> nameLength =
            just("mario")
                .bind { nothing() } // some fancy logic here
                .or(just(0))
    then: 'we should get first value'
        val(nameLength) == 0
}

4.1.1. Or expressions

Of course you can always use the | operator when thinking about or expressions:

Maybe<String> partial = just('mario').bind { String st -> maybe(st - 'mario') } (1)
Maybe<String> result = partial | just('anybody') (2)
1 The operation ends with and empty string. Using Maybe('') returns Nothing()
2 In case partial returns Nothing() we would like to use Just('anybody') instead

Using | makes expressions much more readable…​ and fun :)

Last example used an OR expression. That expression was a simple value. Sometimes we would like to use lazy expressions we only want to be evaluated just in case. When executed those lazy expressions will be returning a valid value.

Maybe<String> partial = just('mario').bind { st -> maybe(st - value) } (1)
Maybe<String> result = partial | { just('anybody') } (2)
1 The operation ends with and empty string. Using Maybe('') returns Nothing()
2 In case partial returns Nothing() we would like to use Just('anybody') instead. In this case the value is not computed until we made sure the previous computation returned Nothing()

4.1.2. The maybe truth

Sometimes you just don’t know whether the value is going to be valid or not. Then it could come handy to use the maybe method.

@Unroll
void 'using maybe() like the Groovy-Truth'() {
    when:
        Maybe<?> result = maybe(value)
    then:
        result.isPresent() == valid
    where:
        value | valid
     //---------------//
        null  | false
        []    | false
        ''    | false
        [:]   | false
     //---------------//
        false | true
        0     | true
        1     | true
        [1]   | true
        [0]   | true
        [a:1] | true
}

So expressions could become easier to understand when using maybe:

void 'using maybe() simple example (I)'() {
    when:
        String unknown = '' (1)
        Maybe<String> result = maybe(unknown) | just('me') (2)
    then:
        result.isPresent() (3)
        result.typedRef.value == 'me' (4)
}
1 We are using a possible not valid value
2 We build an expression that in case the left hand value is not valid we will be using the right hand side value instead
3 Because the value of the left was not valid then we used the right hand one, hence there is a present value
4 The value used was 'me'

If there had been a valid value at the right hand side, then that value would have been used instead:

void 'using maybe() simple example (II)'() {
    when:
        String unknown = 'valid' (1)
        Maybe<String> result = maybe(unknown) | just('me') (2)
    then:
        result.isPresent() (3)
        result.typedRef.value == 'valid' (4)
}

4.2. Fn

fnz.data.Fn is a class that can be used as a shorcut for all data structures explained in this chapter. Depending on the style of your code you could be either chaining actions over a monad using method-chaining or using the Haskell-like public methods in an in-out style.

Lets compare the Maybe monad using the Haskell-like style with Fn

fapply (method-chain) imports
import static fnz.Fnz.val
import static Maybe.just
import static Maybe.nothing
import static Maybe.maybe
fapply (method-chain)
void 'Applicative: Maybe applicative implementation'() {
    when: 'combining two closures'
        def inc = { Integer v -> v + 1 }
        def byTwo = { Integer v -> v * 2 }
    and: 'using the combination as a Function'
        def combination = (inc >> byTwo) as Function
    then: 'if the value is nothing the function shouldnt be applied'
        val(nothing().fapply(just(combination))) == null (1)
    and: 'otherwise if the initial value is correct the function will work'
        val(just(1).fapply(just(combination))) == 4 (2)
}
fapply (Fn) imports
import static fnz.Fnz.Just
import static fnz.Fnz.Nothing
import static fnz.Fnz.fapply
import static fnz.Fnz.bind
fapply (Fn)
void 'Applicative: Maybe applicative implementation (Fn)'() {
    when: 'combining two closures'
        def inc = { Integer v -> v + 1 }
        def byTwo = { Integer v -> v * 2 }
    and: 'using the combination as a Function'
        def combination = (inc >> byTwo) as Function
    then: 'if the value is nothing the function shouldnt be applied'
        val(fapply(Nothing(), Just(combination))) == null
    and: 'otherwise if the initial value is correct the function will work'
        val(fapply(Just(1), Just(combination))) == 4
}

4.3. Either

Either monad is also one of the classics. The Either monad instance can represent correct or error.

As imperative programmer I’m used to choose between branches in my code using conditional structures such as if. As Groovy programmer I’ve gone one step further and I’ve met the Groovy Truth that helps me a lot classifying instances between those which could be seen as a false statement and those which can be taken as a true statement.

But what if we go beyond ? What if we had a type saying it could be right or wrong depending on its own but still having content ?.

The following example tries to search certain type of people from a given list. The search will stop once a person has been found with any of the given rules.

void 'using Either to chain failback searchs'() {
    given:'a base function to search by a certain criteria'
        def baseSearch = { Closure<Boolean> search -> (1)
            return { List sample ->
                def pr = sample.find(search)
                // if found then return left to shortcircuit further
                // searchs
                Fnz.Either(pr).isLeft() ? Either.right(sample) : Either.left(pr)
            }
        }
    and: 'composed criterias on top of the base function'
        // they become Function<A,Monad<B>>
        def lookByNameJohn = baseSearch { it.name == 'john' } (2)
        def lookByAgeGreaterThan = baseSearch { it.age > 50 }
        def lookByCity = baseSearch { it.city == 'dublin' }
    when: 'chaining all search criterias'
        Either result = (3)
            Either.right(sample)
                .bind(lookByNameJohn)
                .bind(lookByAgeGreaterThan)
                .bind(lookByCity)
    then: 'there should be only one item'
        result.isLeft()
        !result.isRight()
        result.typedRef.value.name == name_of_the_result
    where: 'samples used in this spec are'
        sample          |   name_of_the_result
        firstSample     |       'john'
        secondSample    |       'peter'
        thirdSample     |       'rob'
}

First of all, I need to apologise because in this example It seems I’ve used Either just to do the opposite. This time think Either.Left as something telling us to stop looking because we’ve found what we were looking for.

1 baseSearch is a function that returns another function. That inner function returns an Either.Left instance with the result inside if the search function passed as parameter succeeded. I want the function to return Either.Left because I know when an Either.Left is returned no further action is done. And because I’ve found what I was looking for, I don’t want the search to go any further.
2 I’ve created three different functions valid to be used in an fmap function. That means they receive an unwrapped value but they will return a wrapped value.
3 Given the source we will try to apply three types of search in order to find someone. Because the rules of the monad, I know if the first search fails the second will be triggered, and so on. In case any of them succeed the value will be return immediately.

4.3.1. Or

The same way we used or in Maybe to express an alternative to wrong values we can use it in Either.

value
void 'using OR as an alternative value'() {
    when: 'a non valid expression'
        Either<Integer> possible = Either(value) | Right(0)
    then: 'we should get what we expected'
        val(possible) == expected
    and: 'eventually it will be right'
        possible.isRight()
    where: 'possible values are'
        value | expected
        null  | 0
        1     | 1
}
lazy expression
void 'using OR for a lazy computation alternative'() {
    when: 'a non valid expression'
        Either<Integer> possible = Either(value) | { Right(0) }
    then: 'we should get what we expected'
        val(possible) == expected
    and: 'rules must apply'
        possible.isRight()
    where: 'possible values are'
        value | expected
        null  | 0
        1     | 1
}

4.4. ListMonad

Collections in general are one of the most used data structures ever. Some languages use collections only as data structures and some others make them implement monadic semantics in order to be able to do things like list comprehensions.

According to Wikipedia a list comprehension is:

A list comprehension is a syntactic construct available in some programming languages for creating a list based on existing lists

— Wikipedia

I would add that implementations differ in which are capable of handling streams and those which don’t.

First of all I’m would like to start with a basic finite example. Like we did before, lets sneak a little bit on how Haskell does it ;)

(TODO)

4.5. Try

Nowadays JVM languages deal with exceptions using try-catch blocks. The problem is that these constructions force programmers to build their code in a certain way.

Try monad wraps the result of a given computation. That computation could either end on a desired value, having an instance of Success, or could throw an exception, having an instance of Failure instead.

4.5.1. Try()

Instead of using a typical try/catch expression we could handle an expression as a safe execution but with a possible failure value.

We can execute directly an unsafe function using:

Using Try directly with a initial value
Try(A a, Function<A,B>)

Of course a Function could be changed by a closure. Lets see the following example.

Using Try directly with a initial value
@Unroll
def 'check Try with a value and a function'() {
    when: 'executing an unsafe action'
        Try result   = Fnz.Try(value) { x -> 1 / x }
        Try computed = result.fmap { y -> y + 1 }
    then: 'asking if it is a failure or a success'
        computed.isSuccess() == isSuccess
        computed.isFailure() == !isSuccess
    and: 'getting value'
        val(computed) == resultExpected
    where: 'possible values are'
        value | isSuccess | resultExpected
          1   |   true   |       2
          0   |   false  |       0
}

In this example we should be expecting whether a Try.Success value containing the expected result or a Try.Failure with the exception thrown (if any) and the initial value used to trigger the execution.

There could be some cases where you don’t care about passing an initial value to the Try execution.

Using Try directly without a initial value
Try(Function<A,B>)
Using Try directly without a initial value
@Unroll
def 'check Try only with a function'() {
    when: 'executing an unsafe action'
        Try result = Fnz.Try { value / 0 } (1)
    then: 'asking if it is a failure or a success'
        result.isSuccess() == isSuccess
        result.isFailure() == !isSuccess
    where: 'possible values are'
        value | isSuccess
          1   |   false
          0   |   false
}
1 We can receive a Success or a Failure but we cannot expect to get the initial value because it never was provided in the first place.

4.5.2. wrap

In order to get a Try result we could also wrap the computation we think could fail within a function which returns a Try instance with the result of the computation (Try.Success or Try.Failure).

Like Either, composition has a special importance here, due to the fact that when having a Failure instance all possible actions applied over it will always return the same failure.

This first example tries to parse an invalid number and add one to it.

Parse a possible number
def 'parsing a non valid number: Try'() {
    when: 'trying to parse a non valid number'
        Function unwrapped = { x -> x + 1 }
        Function wrappedfn = wrap { v -> Integer.parseInt(v) } (1)
        Try result1 = bind(Just('2a'), wrappedfn) (2)
        Try result2 = bind(result1, unwrapped)
    then: 'computation failed'
        result1.isFailure()
    and: 'any possible composition will return the same failure'
        result2.isFailure()
}

Here we can see both behaviors.

1 First of all the given function fails and the instance returned is an instance of Failure we know that because only Failure instances return true when calling to isFailure() method.
2 Besides that we can also notice that using a failure instance to create further function composition will end returning the same failure, which is the same as saying that no further function will ever succeed using that failure.

When having a Failure instance, the exception that caused it is also wrapped within the instance, and you could whether get it to inspect it, or throw it like any other exception.

throwException
def 'throwing an exception'() {
    when: 'wrapping something that "could" fail :P'
        Function failure = wrap { 0.div(0) }
        (1)
        Try<Integer> result = bind(Just(1), failure)

        assert result.exception instanceof ArithmeticException
    and: 'wants to propagate the exception'
        result.throwException() (2)
    then:'the exception will be thrown as usual'
        thrown(ArithmeticException)
}
1 You can get the wrapped exception
2 Or throw the exception instead

4.5.3. Recover

Normally when having an exception we would like to have some alternative. Sometimes we may want to set, for example a default value in case something went wrong.

In our example I would like to get zero in case the number was not valid. Then I would like to add one to that given number.

What if we want a fallback behavior when something went wrong ?

Well there is the recover() method. This method has two arguments the possible Failure instance, and the Success instance to use instead.

recover()
def 'using recover()'() {
    when: 'you cant always get what you want'
        def someFnChain =
            recover (
                { 0.div(0) } as Function, // WRONG
                recover(
                    { new Date() + "1" } as Function,
                    { throw new IllegalArgumentException("Something bad") } as Function,
                    { 0 } as Function
                ) // WORST
            )
        def anything = bind(Just(1), someFnChain)
    then: 'you might find you get what you need :P'
        val(val(anything)) == 0 // TODO recover(Function... nFunctions)
}

5. Control Flow

In computer science, control flow (or alternatively, flow of control) refers to the order in which the individual statements, instructions or function calls of an imperative or a declarative program are executed or evaluated

— Wikipedia

Control flow is one of the most important topics in a programming language. Most languages have their own out-of-the-box control structures, and some others can create new ones on-the-fly. Although Groovy can’t create new control structures in the classical sense, it can create control structures based on functions and meta-programming.

Following up there’re some control flow structures I’ve been collecting while sneaking in some other programming languages.

Let’s go through them.

5.1. Let

Initializes a group of variables, makes them available within the scope of the closure passed as argument.

let(Map,Closure)

Let’s see some examples.

Simple values
    Integer simpleLetExample() {
        let(x:1, y:2, z:3) {
            x + y + z
        }
    }

Here values provided by the map are accessible within the scope of the closure block. What if I wanted to create values depending on previous values ? Let’s see the following example:

Dependant expressions
    Integer computedValues() {
        let(x:1, y:2, z:{ x + y }) {
            x + y + z
        }
    }

In this example value of 'z' depends on the values given to 'x' and 'y'. Every

Nested expressions
    Integer nestedLetExample() {
        let(a:5, b:15) {
            let(c:15, d:{ a + 25 }) {
                b + c + d
            }
        }
    }

Previous Spock specification shows how let expressions could be nested.

5.2. Letm

letm works the same way let does but instead of handling plain values it works with monadic values and eventually will return an instance of type fnz.data.Monad. Why is that ?

Well letm is meant to work with monad expressions. So when you’re seeing this:

letm(x: Just(1), y: { Just(x+1) } ) {
    Just(y)
}

Under the hood the expression will be transformed to:

bind(Just(1)) { x ->
  bind({ Just(x+1) }())) { y ->
     Just(y)
  }
}

This way you can play with other flavors of monads. Imagine you want to combine let with the Either monad.

    Either<Integer> workingWithOtherMonads(final Integer first, final Integer second) {
        return letm(x:Just(first),
                    y:Just(second)) {
                    letm(result:Just(first + second)) {
                        result == 3 ? Right(result) : Left()
                    }
               }
    }

You can also combine it with the Try monad. This time there’s a method you want to use, but it could throw some exceptions, you want to handle that possibility using Try.

    Try<Integer> combineWithTry(Integer first, Integer second) {
        letm(x:Just(first),
             y:Just(second)) {
              bind(Just(second), wrap(this.&dangerousMethod.curry(first)))
        }
    }

    Integer dangerousMethod(Integer x, Integer y) {
        return x / y
    }

5.3. Do

If you have seen Haskell’s do expressions, they look like this:

do
x <- Just 1
y <- Just (x + 1)
return x

There are a couple of nice things when using this control flow:

  • You don’t have to unwrapped/wrap monadic values. In the example when assigning Just 1 to x the value inside (1) it’s unwrapped and make it available for the next expression to use it.

  • In the end using the return expression make it easier for the programmer to wrap the final value in the proper monadic value without having to do it explicitly. It is assumed by the expression flow.

Well, Fnz has tried to mimic the behavior of this expression using both methods $do and $return:

               import fnz.Fnz
               import fnz.data.Maybe

               class A {
                    Integer returningDoWithReturn() {
                          Maybe<Integer> result =
                              $do {
                                  x = Maybe.just(1)
                                  y = Maybe.just(x + 1)
                                  z = Maybe.just(y)

                                  $return z + 1
                              }

                         return Fnz.val(result)
                    }
               }

Although in Haskell do notation you can be using assignments as long as other types of expressions, here is not possible. Only assignment expressions are allowed by design.

So you may be wondering…​ How can I use an expression not returning any value within the $do/$return statement ?

Well for that purpose a special rule has been added to the do notation expression. Whenever you wan to use an expression not returning anything you should assign that expression to _.

The _ variable name means that you don’t care about the returning type. In fact every time you use that name a unique identifier is created underneath.

               import fnz.Fnz
               import fnz.data.Maybe

               class A {

                    Maybe.Just PrintStrLn(Object val) {
                        println val
                        return Fnz.Just(val)
                    }

                    Integer returningDoWithReturn() {
                          Maybe<Integer> result =
                              $do {
                                  x = Maybe.just(1)
                                  _ = PrintStrLn("x: $x")
                                  y = Maybe.just(x + 1)
                                  _ = PrintStrLn("y: $y")
                                  z = { Maybe.just(y + 1) }

                                  $return z + 1
                              }

                         return Fnz.val(result)
                    }
               }

5.4. Unless

The rationale behind Unless is that sometimes is just a pain to create negative conditional expressions.

unless(Boolean,Closure)
Unless structure
        Maybe<Integer> result =
            unless(xparam <= 0) {
                return 3 + xparam
            }

This expression will allow the code block to be executed unless the condition evaluates to true.

5.5. Where

I would say Where control belongs to the family of switch statements or multiway branches. I first read about the Where clause while I was reading Haskell.

This version of Haskell’s Where expressions has:

check(Map) { (1)
    when { /evaluates to boolean/ } then { /returns a value/ } (2)
    otherwise { /returns a value/ } (3)
    where { /some constants/ } (4)
}
1 A check method is the entry point to this expression
2 When-Then are evaluated in two different phases. First all when clauses are evaluated until one of them is evaluated to true. Then the related then clause is evaluated.
3 The otherwise block is executed only if no when-then block has been evaluated successfully before.
4 The where block is a perfect place to initializate constants used in any of the other mentioned blocks.

There are different ways of using this control depending on the use of when-then expressions

Simple Where
            Maybe<String> result = check(weight: value) {
                when { weight <= underweight } then { "You're underweight" }
                when { weight <= normal }      then { throw new Exception("You're normal") }
                when { weight <= fat }         then { "You're fat" }
                otherwise { "You have a strange composition" }
                where {
                    underweight = 50
                    normal      = 70
                    fat         = 90
                }
            }

This is a simple example about how to use the where expression. You can also omit some of the parts mentioned before

Ommiting Where
            Maybe<String> result = check(weight: value) {
                when { weight <= 51 } then { "You're underweight cause you weight $weight" }
                when { weight <= 90 } then { "You're fat" }
                otherwise { "Default" }
            }
Only When-Then clauses
            Maybe<String> result = check(weight: value) {
                when { weight <= 51 } then { "You're underweight" }
                when { weight <= 90 } then { "You're fat" }
            }

The when-then clauses use closures to evaluate their content. But thanks to Groovy’s objects method isCase() we can create switch-like statements

Switch-case Where (Class)
            Maybe<String> result = check(value) {
                when String then { stringMessage }
                when Integer then { bigIntegerMessage }
                otherwise { otherwiseMessage }
                where {
                    stringMessage     = "Is a String"
                    bigIntegerMessage = "Is a Integer"
                    otherwiseMessage  = "No Idea"
                }
            }

Instead of passing a map you can evaluate a single value against some conditions. Those conditions are the same you would be using in a switch-case block in Groovy.

Switch-case Where (Collections)
            Maybe<String> result = check(value) {
                when 10..20 then { SMALL }
                when 20..30 then { MEDIUM }
                otherwise { BIG }
                where {
                    SMALL   = "Small"
                    MEDIUM  = "Medium"
                    BIG     = "No Idea"
                }
            }
Switch-case Where (Number)
            Maybe<String> result = check(value) {
                when 15 then { SMALL }
                when 25 then { MEDIUM }
                otherwise { BIG }
                where {
                    SMALL   = "Small"
                    MEDIUM  = "Medium"
                    BIG     = "No Idea"
                }
            }