warpedjavaguy

Imperative by day and functional by night

Page Objects Begone

with 2 comments

Because we can emulate them with page scopes instead.

Page objects are a commonly used design pattern for developing web tests with Selenium web driver. But coding page objects and tests to an API is a very developer centric activity. The role of a tester is to write and execute tests and not to develop and compile code. The same can be said for developers when they put their test hats on.

Gherkin features that describe the expected behavior of a system are good enough to drive tests. There is no need for a fancy GUI interface that requires up front modelling and compiling to generate tests. It is much simpler to just specify the expected behavior and have an interpreter dynamically evaluate it against the system under test.

Introducing gwen-web

gwen-web is a tool that aims to give testers this dynamic capability and do away with page objects and compilation altogether. It is powered by gwen; a functional specifications interpreter that maps gherkin features to executable code. In the case of gwen-web, it maps Gherkin features to precompiled Selenium code to drive a web browser. As a user of this tool, you never have to write any Selenium code or develop any page objects at all.

Page Scopes

Gwen-web introduces the concept of page scopes. A page scope is a stack of name-value pairs bound to a namespace in memory. They can be used to store information about individual pages and how their web elements can be located. In this way gwen does not store or manage any web element references but rather just binds their names to locator expressions (or lookup strings) that you provide. You specify what pages and bindings you require through a prescribed set of steps that gwen-web knows how to interpret and understand.

It is best to illustrate with an example. The floodio challenge walks you through a series of web pages and asks you to perform some relatively simple tasks. In the remainder of this post, we will use the gwen REPL (read-eval-print loop) console to perform these tasks for us and complete the challenge.

Build and install gwen-web – Note that gwen-web is an open source project that is currently still under development and a binary release is not yet available. On the bright side it is fully functional and you can download the source and build and install it on your local machine by following the instructions here. Gwen is written in Scala and you will need to download the sbt build tool to build it (the details are in the instructions). But once built, you only need Java to run it.

After completing the installation, open a command prompt to your installed gwen-web directory and enter the following command:

bin/gwen

REPL Console

The gwen REPL will start and you will see the following console displayed:

page-objects-begone-1

The REPL is case sensitive and does not accept fuzzy input. So be sure to enter all steps and commands exactly as shown in this post.

When gwen starts up, it always implicitly creates and activates a default global page scope with no bindings in it. This global scope can be used to set bindings for elements that are common and accessible across multiple pages.

The first thing we will do is create and activate a new page scope explicitly for the floodio start page. No need to write a page object, just type the following into the gwen prompt and hit enter:

When I am on the start page

Gwen will create a new page scope called “start” and activate it in memory before informing you that it has successfully completed the step. If you enter env at the gwen prompt, you will see the output of the environment context in memory and our newly created page scope called “start” at the bottom.

{
  "env" : {
    "data" : [ {
      "page" : [ {
        "scope" : "global",
        "atts" : [ ]
      }, {
        "scope" : "start",
        "atts" : [ ]
      } ]
    } ]
  }
}

All we have done here is defined a new page scope called “start” and made it the currently active scope. Now we will store the url of the floodio start page into this scope so that gwen can know where to navigate to. Enter the following to bind the floodio start page URL to the currently active “start” page scope:

Then the url will be "https://challengers.flood.io/start"

When it successfully completes, enter env at the prompt again to see our bound URL:

..
{
  "scope" : "start",
  "atts" : [ {
    "navigation/url" : "https://challengers.flood.io/start"
  } ]
}
..

We have now told gwen what the url of the floodio start page is. We will now instruct gwen to open a browser to that page. Enter the following, and observe!

Given I navigate to the start page

This step will start a new browser window, locate the URL for the start page, and point the browser to that location.

page-objects-begone-2

Gwen-web supports the Firefox, Chrome, Safari, and IE browsers. It uses Firefox as the default browser since it does not require you to install a native web driver on your local machine. To use a different browser, follow the instructions in this user guide.

Now we will tell gwen how to locate the Start button that appears on the start page. But to do that, we need to know how the button has been defined on the page. If you right click the Start button in the browser page and click “inspect element”, you will see that it is defined as an input element with a name attribute set to “commit”.

<input class="btn blue" name="commit" value="Start" type="submit">

Now enter the following at the gwen prompt to bind this information to the “start” page scope that is currently active:

And the Start button can be located by name "commit"

Type env at the command prompt again if you would like to see how this locator information is bound to memory.

Before continuing, be sure to close the “inspect element” pane if you still have it open in your browser. Leaving it open may interfere with gwen and could result in errors.

Now enter the following to verify that gwen can locate the Start button:

And I highlight the Start button

This step locates the Start button and highlights it for a short time. You should see the Start button being highlighted and then unhighlighted.

page-objects-begone-3

This confirms that gwen can locate the button and that we have bound the locator correctly. Now enter the following to have gwen click the Start button:

When I click the Start button

Gwen will now click the Start button and the browser will navigate to the next page.

page-objects-begone-4

To proceed from here, we again first need to create a new page scope for this page, and then tell gwen how to locate the elements we wish to interact with. Enter the following to create a new page scope for this page:

Then I am on the step 2 page

This will create a new empty page scope in memory called “step 2″ and make it the currently active scope. If you type env at the command prompt, you will see it printed at the bottom right after the “start” page scope we created earlier.

{
  "env" : {
    "data" : [ {
      "page" : [ {
        "scope" : "global",
        "atts" : [ ]
      }, {
        "scope" : "start",
        "atts" : [ {
          "navigation/url" : "https://challengers.flood.io/start"
        }, {
          "the Start button/locator" : "name"
        }, {
          "the Start button/locator/name" : "commit"
        }, {
          "the Start button/action" : "click"
        } ]
      }, {
        "scope" : "step 2",
        "atts" : [ ]
      } ]
    } ]
  }
}

All page scopes are managed in memory as JSON objects on a stack with the most recently active scope appearing at the bottom. For more details about how this stack works, you can study the documented source on the gwen project site here.

Moving on, we can now proceed to bind the locator information for the ‘how old are you’ dropdown and the ‘Next’ button elements that appear on the step 2 page. If you inspect these elements in the page source, you will find that they are defined as follows:


<select class="select optional" id="challenger_age" name="challenger[age]">
  <option value="">How old are you?</option>
  <option value="18">18</option>
  <option value="19">19</option>
  ...
</select>

<input class="btn" name="commit" value="Next" type="submit">

Again, be sure to close the “inspect element” pane (if you opened it) in the browser before continuing.

Enter the following into the gwen prompt to let gwen know how to locate the ‘how old are you’ dropdown element (in this instance we locate it by Id).

Given the how old are you dropdown can be located by id "challenger_age"

Now for the next button. We could locate it by name in the same way we did for the Start button on the start page, but to mix things up a bit (and because we can), we will locate it by class instead. Enter the following to let gwen know how to locate the next button:

And the next button can be located by class name "btn"

You can confirm that both of these locators work by entering the following steps in the console (one after the other) to highlight them:

And I highlight the how old are you dropdown
And I highlight the next button

After confirming the above, we can proceed to select an age and click the next button before creating a scope for the next page:

And I select "21" in the how old are you dropdown
And I click the next button
Then I am on the step 3 page

We are now on the step 3 page. Here we need to select and enter the largest order value from the list of radio buttons displayed on the page.

page-objects-begone-5

How do we instruct gwen to find the largest order value? Lets see if we can find it with some JQuery scripting first. Open the browser console view and enter the following lines of script to locate the largest order value:

var orderRadios = $('.radio'); 
var orderValues = $.map(orderRadios, function(x) { return parseInt($(x).text()); });
var maxValue = Math.max.apply(Math, orderValues);
var maxRadio = $('.radio:contains("' + maxValue + '")').get(0);
$(maxRadio).text(); // should return largest order value

The above can be reduced to a one-liner to get the maxRadio element as follows:

$('.radio:contains(' + Math.max.apply(Math, $.map($('.radio'), function(x) { return parseInt($(x).text()); })) + ')').get(0);

We have shown above that we can locate the largest order value using JQuery. Luckily for us, gwen-web allows us to locate elements by JavaScript (but only through one liner expressions). Futhermore, if the page in the browser has loaded the JQuery library then we can use it too. Now enter the following into the console so that gwen can know how to locate the element containing the highest order value (note that we use the one-liner expression version here to locate and return the element):

Given the largest order value can be located by javascript "return $('.radio:contains(' + Math.max.apply(Math, $.map($('.radio'), function(x) { return parseInt($(x).text()); })) + ')').get(0);"

Now enter the following to highlight the largest order value and confirm that the locator works:

And I highlight the largest order value

We had to use some JQuery scripting here to locate the largest order value. Scripting is necessary in this case because we need to enter values and select buttons based on the results of functions applied to the elements and values on this page. This is a good example of an interaction that cannot be readily automated without some level of scripting. For this reason, gwen-web supports locating elements by javascript.

The other things we need to locate on this page are the input field into which we will need to enter the largest order value into and the next button. We define the location of these by entering the following:

And the largest order value field can be located by id "challenger_largest_order"
And the next button can be located by class name "btn"

We are now ready to let gwen find the largest order value, enter it into the input field, click the radio button for that value, and then click next. We do that by entering the following steps:

When I enter the largest order value in the largest order value field
And I click the largest order value
And I click the next button
Then I am on the step 4 page

The step 4 page merely asks us to click the next button when we are ready. We do this straight away by entering the following:

Given the next button can be located by class name "btn"
When I click the next button
Then I am on the step 5 page

This will bring us to the step 5 page (the last page in the floodio challenge).

page-objects-begone-6

This page requires that we copy a provided token value into a field and then click next. Inspecting the page source reveals that the token is displayed in a span element defined with a class="token" attribute. The input field has an id of “challenger_one_time_token”, and the next button is defined in the same way it was in the previous pages. We now define locators for these by entering:

Given the one time token can be located by css selector ".token"
And the one time token field can be located by id "challenger_one_time_token"
And the next button can be located by class name "btn"

If you take a closer look at the source you will see that the token value is actually loaded by an ajax request when the page is loaded. Waiting for this value to load is not a problem when running gwen in REPL mode as the ajax request will have most likely completed in the time that the REPL is idly waiting for us to enter the next step at the prompt. But if we were running all the steps we’ve entered so far very quickly (as if in automated batch mode), then we would need to wait for the ajax request to complete and the token value to be populated first before attempting to access the value. Enter the following to have gwen wait for the token value to be populated (note: if the token is already populated, then gwen will immediately return without waiting).

And I wait for the one time token text

Now that we know the token is loaded, we can proceed to copy it into the input field and click the next button to complete the challenge. Enter the following steps to do that:

When I enter the one time token in the one time token field
And I click the next button
Then I am on the done page

This will take us to the done page, telling us that we’re done.

page-objects-begone-7

To finish, type exit at the gwen prompt. The browser and the REPL will shut down.

Separation of Concerns

Two major benefits that page objects provide include the separation of test logic from configuration and the elimination of unwanted redundancies. Gwen can provide these same benefits through meta features.

Configuration by Meta

A meta feature is simply a configuration specification expressed as a gherkin feature (a feature describing a feature if you like). Recall that some of the steps we typed into the REPL above just configure (or tell gwen) what the url to a page is or how an element on a page can be located. This configuration information can all be captured in a meta feature file and loaded into gwen on startup. We can also eliminate duplicated steps and other redundancies too. For example, you will have noticed that the step that configures the next button locator was repeated above for every page that contains a next button. Since this button is common across multiple pages, it makes sense to define it once and reuse it. This can be done by binding it to the default global page scope that is implicitly created and activated by gwen when it starts up.

So we can now capture all the configuration steps into a single meta feature file. Note that this meta is representative of everything that would otherwise need to be programmed into a page object. But with gwen meta features, that programming is never necessary.

Now create a new file called floodio.meta in your gwen-web install directory and edit it to contain the following meta specification:

 Feature: Flood IO Meta

Scenario: Configure common locators
    Given the next button can be located by class name "btn"

Scenario: Configure start page
     When I am on the start page
     Then the url will be "https://challengers.flood.io/start"
      And the Start button can be located by name "commit"

Scenario: Configure step 2 page
     When I am on the step 2 page
     Then the how old are you dropdown can be located by id "challenger_age"

Scenario: Configure step 3 page
     When I am on the step 3 page
     Then the largest order value can be located by javascript "return $('.radio:contains(' + Math.max.apply(Math, $.map($('.radio'), function(x) { return parseInt($(x).text()); })) + ')').get(0);"
      And the largest order value field can be located by id "challenger_largest_order"

Scenario: Configure step 4 page
   # noop - this page only has a next button (we have already defined a common locator for it above)
    
Scenario: Configure step 5 page
     When I am on the step 5 page
     Then the one time token can be located by css selector ".token"
      And the one time token field can be located by id "challenger_one_time_token"

Loading Meta

The above meta can now be loaded into gwen on startup through the -m command line option as follows:

bin/gwen -m floodio.meta

You will notice this time that the REPL console will load the meta when it starts up.

page-objects-begone-8

You can type env at the gwen prompt to view the meta bindings in memory:

{
  "env" : {
    "data" : [ {
      "page" : [ {
        "scope" : "global",
        "atts" : [ {
          "the next button/locator" : "class name"
        }, {
          "the next button/locator/class name" : "btn"
        } ]
      }, {
        "scope" : "start",
        "atts" : [ {
          "navigation/url" : "https://challengers.flood.io/start"
        }, {
          "the Start button/locator" : "name"
        }, {
          "the Start button/locator/name" : "commit"
        } ]
      }, {
        "scope" : "step 2",
        "atts" : [ {
          "the how old are you dropdown/locator" : "id"
        }, {
          "the how old are you dropdown/locator/id" : "challenger_age"
        } ]
      }, {
        "scope" : "step 3",
        "atts" : [ {
          "the largest order value/locator" : "javascript"
        }, {
          "the largest order value/locator/javascript" : "return $('.radio:contains(' + Math.max.apply(Math, $.map($('.radio'), function(x) { return parseInt($(x).text()); })) + ')').get(0);"
        }, {
          "the largest order value field/locator" : "id"
        }, {
          "the largest order value field/locator/id" : "challenger_largest_order"
        } ]
      }, {
        "scope" : "step 5",
        "atts" : [ {
          "the one time token/locator" : "css selector"
        }, {
          "the one time token/locator/css selector" : ".token"
        }, {
          "the one time token field/locator" : "id"
        }, {
          "the one time token field/locator/id" : "challenger_one_time_token"
        } ]
      } ]
    } ]
  }
}

Now we can open a new browser session to the floodio start page and click the start button by entering only the following steps into the REPL:

Given I navigate to the start page
When I click the Start button
Then I am on the step 2 page

And similarly for the remaining pages..

Step 2 page:

Given I select "21" in the how old are you dropdown
When I click the next button
Then I am on the step 3 page

Step 3 page:

Given I enter the largest order value in the largest order value field
And I click the largest order value
When I click the next button
Then I am on the step 4 page

Step 4 page:

When I click the next button
Then I am on the step 5 page

Step 5 page:

Given I wait for the one time token text
And I enter the one time token in the one time token field
When I click the next button
Then I am on the done page

When ready, type exit to close the browser and quit the REPL.

Conclusion

In this post, we used the gwen REPL to directly interact with a web application from scratch. We then factored out the configuration steps into a meta feature and loaded that into the REPL and interacted with the same web application again without reentering any of the configuration steps. We did it all with no page objects too! :)

Next..

In the next post we will write a feature file to automate the same floodio challenge in batch mode and generate evaluation reports. We will also compose custom step definitions and perform some assertions on each page. Lastly we will solve some common ajax and page loading problems that arise when automating web tests.

Written by warpedjavaguy

August 27, 2014 at 12:28 am

Posted in automation

Tagged with ,

One Gwen Interpreter, Many Evaluation Engines

with 5 comments

There is so much more that can be achieved with Gherkin.

In the previous post, I announced the open sourcing of the Gwen interpreter project. In this post I will introduce the interpreter and evaluation engine concepts and describe the difference and relationship between them.

The Gwen interpreter translates Gherkin features into executable code. The code that each step is translated to is not defined in the interpreter itself, but rather in separate modules called evaluation engines. When a feature is executed, the interpreter delegates the processing of each step to a mixed in engine that you define or provide. This is necessary since evaluation varies across systems and it would be futile to try and code for every conceivable behavior in one implementation. For this reason Gwen abstracts the evaluation engine to support many implementations. In this way, you decide which engine to use based on the type of software behavior that you want to evaluate. For example, if you want to evaluate the behavior of a web application, then you would choose to mix in a web engine. Each engine must prescribe a supported set of steps and use at least one API to interact with a system.

one-gwen-interpreter-many-engines

Engines can be defined to replicate any software behavior that is reproducable through one or more API’s.

There are many useful engines that can be built. A web engine for automating web application testing is an obvious one that comes to mind. But Gwen engines need not be confined to just testing. Engines can be defined to automate, emulate, or simulate any mechanical process that can be driven by software. Engines can also be built to generate data and other resources too.

In summary,

I hope that many engines emerge from the community and that many of them are shared for everyone to download and use. But everyone is also permitted to build their own proprietary or commercial engines too.

Written by warpedjavaguy

May 27, 2014 at 12:17 am

Posted in automation, bdd, gherkin, scala

Tagged with

Gwen – A Gherkin DSL Interpreter

leave a comment »

A common platform for mapping Gherkin features to executable code.

Gherkin is a language for describing software behavior. Any software behavior. It makes sense to use it for evaluating software behavior too. But how can you evaluate any software behavior?

A Gherkin interpreter with an abstracted evaluation engine could be one way to do it.

This interpreter would parse Gherkin features and dispatch the processing of each step to an evaluation engine that you provide and mix in. You could implement your own specialised engines to support specific steps and target specific types of software. You could share them too. The interpreter would translate plain text feature specifications into executing instructions and report the evaluated results. It would support sequential or parallel execution. Ideally it would also have a REPL. It would provide all the necessary processing and tooling required to interpret gherkin features and execute them against any software system for which a compatible engine has been defined. A public library of engines would emerge and be available for download. The one interpreter would work with all of them.

It’s a simple idea that a colleague and I have been working on. We haven’t built a library of engines but we have built a core interpreter that any engine can be mixed into. We wrote it in Scala and open sourced it as a project called Gwen.

gwen-logo-1

Check it out and have a play. We would like to get some feedback and help from the community before publishing a 1.0 release.

Written by warpedjavaguy

May 17, 2014 at 3:31 pm

Posted in automation, bdd, gherkin, scala

Tagged with

flatMap on the Monad in Java

Imagine writing entire programs by coding only what is necessary.
Now create an abstraction for that.

There was a time when OO was considered king. Those days are over. FP is leaking into every modern JVM language and the functional programming community is pushing boundaries. This has introduced new challenges for traditional Java programmers. They need to learn some FP.

One way Java programmers can ease their way into learning FP is to learn some Scala. The expressive power of functional programming quickly becomes apparent when you learn to use map, flatMap, filter, and friends. But then, just as you begin to feel comfortable with these, someone comes along and utters the phrase “flatMap on the monad”. flatMap on the what? They start to explain, but it goes over your head. You think nothing of it and move on with learning more FP. But before too long, you stumble upon a random blog somewhere where someone is raving about “the Maybe monad”. There’s that m word again! It seems that the entire FP community knows what a monad is, but you do not. You try to read along and follow, but struggle. You tell yourself to think harder and read again. You struggle again. At this point you can choose to either keep going round in circles or put aside everything you think you know about FP and start learning it.

After about two years of going back to basics and studying up on some programming history, lambda calculus, logic, a little bit of math, and experimenting with OO and FP, I believe I have finally got it! It has perhaps taken me a lot longer than it should have, but I wouldn’t change a minute of it. If you’re interested in seeing monads in Java, this might be for you!

Functions

In FP there are no variables and objects, only constants and functions. Functions are first class citizens. You can pass them as arguments, return them as values, and assign names to them. You can apply functions anywhere where values are expected. Functions map input values to output values. The general form of a function is:

T -> U

 

Here we are using the standard Java naming conventions for types. This is a function that accepts a parameter of type T and returns a result of type U, commonly referred to as: “a T to U function”. Pure functions produce output based on input and do nothing else. They always produce the same output for a given input, do not modify any state, and produce no side effects. They are known to be what is termed ‘referentially transparent’, which means that for a given input, you can replace a function with its output throughout a program without impacting behavior. Achieving referential transparency with Java will require some discipline on our behalf, since most data structures are mutable.

Functions only execute and produce output when they are applied to an input. They do nothing otherwise. You can think of them as reusable pieces of result yielding code. We need functions to implement monads for three reasons:

  1. To accept functions as input
  2. To return functions as output
  3. To have deferred execution.

There are no functions in Java, so the first thing we need to do is define our own function type. We will define this as a single method interface as follows:

Function

public interface Function<T, U> {
    U apply(T arg);
}

With this interface in place, we can define objects that emulate functions and apply them to values (or other functions). We can define functions either through anonymous inner instances of this interface or through named classes that implement it. As with any other Java interface, we can pass Function references as arguments, return them as results, and store them in variables. For example, we could define a utility function for creating and returning bean property getter functions like this:

@SuppressWarnings("unchecked")
public static <T, U> Function<T, U> getter(final String property) {
    return new Function<T, U>() {
        public U apply(T bean) {
            try {
                Method getter = 
                    new PropertyDescriptor(property, bean.getClass()).getReadMethod();
                return (U) getter.invoke(bean);
            } catch (Exception e) {
                return null;
            }
        }
    };
}

/* Sample Usage */

// Create a ContactInfo.email property getter function
Function<ContactInfo, String> getEmail = getter("email");

// Apply the getter function to a contactInfo bean to get email address
String email = getEmail.apply(contactInfo);

You may have noticed that the apply method in the Function interface does not declare to throw any exceptions. This was done deliberately in the interest of preserving referential transparency. That’s right, throwing an exception is considered a side effect. Unfortunately there is no escaping checked exceptions in Java, so you will need to handle any checked exceptions that may occur in your functions (tip: do not throw checked exceptions). Runtime exceptions on the other hand are legitimate errors that we will treat as failures (tip: do not use this as an excuse to wrap and throw checked exceptions in runtime exceptions).

Functors

Now that we have a way to define functions, we can move on to the next thing we need to define monads; functors. A functor is a generic type that gives meaning or context to a value of some type. You can think of a functor as a kind of typed object. All monads are functors. To apply a function to a value in a functor, we need to somehow get the function into the functor where it can be applied. We can do this through a function called fmap which looks like this (where F is for Functor):

(T -> U) -> (F[T] -> F[U])

 

This is a function that maps a T -> U function to a F[T] -> F[U] function. (We use square brackets instead of angle brackets to denote parameterized types to avoid confusion with the functional arrow syntax). You can think of fmap as either a function that maps over a function, or as a function that lifts a function. Either way, it provides a means of applying a function to a value in a functor through a wrapper function. We will define Functor as an abstract class instead of an interface so that we can restrict public access to fmap (later on we will implement a public method at the monad level called map which will implicitly apply fmap to the current instance).

Functor

public abstract class Functor<F, T> {
    protected abstract <U> Function<? extends Functor<F, T>, ? extends Functor<?, U>>
		fmap(Function<T, U> f);
}

Type F is the parameterized type of the functor. A concrete implementor can pass itself or a generic type that it implements in as this type. Types T and U are the input and output types of the function argument f in fmap. T is provided as a parameter and U is inferred by the compiler.

Let’s go through an example to get a feel for how fmap works. Imagine that you have a functor that is a box with a value in it that is not accessible from the outside. The box has no getters or setters, only the fmap function. How do you apply a function to the value in the box and get another box with the result of the function in it? The solution is to create a function that can be applied to the value and then apply fmap to that to get another function that when applied will return the new box.

public class Box<T> extends Functor<Box<T>, T> {
    private T value;
    public Box(T value) {
        this.value = value;
    }
    @Override
    public <U> Function<Box<T>, Box<U>> fmap(final Function<T, U> f) {
        return new Function<Box<T>, Box<U>>() {
            public Box<U> apply(Box<T> box) {
                return new Box<U>(f.apply(box.value));
            }
        };
    }
}

// create an increment function
Function<Integer, Integer> increment = new Function<Integer, Integer>() {
    public Integer apply(Integer num) {
        return num + 1;
    }
};

// create a box with 1 in it
Box<Integer> box1 = new Box<Integer>(1);

// create a box that has the incremented value of box1 in it
Box<Integer> box2 = box1.fmap(increment).apply(box1);

So now that we have functions and functors, let’s move on to monads.

Monads

What is a monad?

A monad is a typed object that can be mapped to other typed objects in a functional way. It is a functor capable of performing one or many operations in a single computation. This capability is facilitated through a bind function which maps a value in one functor to another functor through a given function. This allows processing pipelines to be constructed, where the output of one function is piped through as input to a next function in a chain of functions. The bind function looks like this (where M is for Monad):

M[T] -> (T -> M[U]) -> M[U]

 

This function accepts a value of type M[T] and returns a value of type M[U] through a given function T -> M[U]. Following this through from left to right, you could be forgiven for thinking that we could do this by directly applying T -> M[U] to the T in M[T] and returning the result M[U]. But before we can even apply this function to T, we need to first put it into the same context as T. T is in M. Therefore we need to put the function into M. We cannot simply apply it to T from the outside, since from the outside we only have M[T] and we cannot apply a function that accepts a T to a value of type M[T]. Recall that a monad is a functor, and to apply a function to a value in a functor we need to go through fmap (kind of like we did in our box functor example above). So bind will still look like the above to a caller, but its implementation will look like this:

M[T] -> (T -> M[U]) -> (M[T] -> M[M[U]]) -> M[U]

 

We’ll now compose this by using fmap to lift the given T -> M[U] function up one level:

fmap(T -> M[U]) = M[T] -> M[M[U]]

 

Substituting this into the above, we get:

M[T] -> fmap(T -> M[U]) -> M[U]

 

Let mt = an instance of type M[T]

Applying the above to mt, we get:

fmap(T -> M[U])(mt) -> M[U]

 

Let f = the function T -> M[U]

Substituting f, gives us:

fmap(f)(mt) -> M[U]

 

We now introduce a function called join to flatten the lifted output of fmap(f)(mt) back down one level.

join(M[M[U]]) = M[U]

 

We combine the two functions to get:

bind(f) = join(fmap(f) (mt))

 

In our Java implementation, bind, join, and fmap, will be methods on object mt. For convenience, and to eliminate the redundancy of calling fmap on mt and applying the returned function to mt, we’ll introduce a new map function to do it implicitly so that:

mt.map(f) = mt.fmap(f)(mt)

 

Replacing fmap with map, we get:

bind(f) = join(map(f))

 

We have composed bind in terms of map and join, and map in terms of fmap. If we were to rename join to flat (since join makes things flat), we would have:

bind(f) = flat(map(f))

 

Remind you of anything? Hey yeah, it’s flatMap! So that’s what that “flatMap on the monad” thing is all about!

To simplify our Java implementation we will make the join function a parameterless method that can be called directly on a lifted M[M[U]] result.

bind(f) = map(f).join()

 

Now let’s have a look at how we will implement fmap. We know that fmap will accept a T -> M[U] function and return a M[T] -> M[M[U]] function. This returned function when applied to M[T] will return a result of type M[M[U]]. It will do this by lifting the result of the original T -> M[U] function one level up into M. For this purpose, we will define a function called unit that can lift any value into M. It will look like this:

U -> M[U]

 

The unit function will lift both values and functions into M. It will lift values of type U to M[U] and values of type M[U] to M[M[U]], and functions of type T -> U to M[T -> U] and functions of type T -> M[U] to M[T -> M[U]], and so on.

Composing fmap in terms of unit:

fmap(T -> M[U])
= M[T] -> M[M[U]]
= M[T] -> M[T -> M[U]]
= M[T] -> unit(T -> M[U])

 

Notice that we are using unit here to lift the T -> M[U] function into M to get:

M[T -> M[U]]

 

Monads are Applicative Functors

The T -> M[U] function is now lifted into M. So both the function and the value that we want to apply it to are in M. But how do we apply a lifted function M[T -> M[U]] to a lifted value M[T]? The solution is introduce a function that will map the lifted function to another function that when applied to M[T], will extract and apply the T -> M[U] function to T inside M and return the result M[U] lifted into M. The introduced function will look like this:

M[T -> M[U]] -> M[T] -> M[M[U]]

 

The general form of this function is:

M[T -> U] -> M[T] -> M[U]

 

This is the signature of what is known as an applicative functor. It takes a function in M and applies it to a value in M and returns the result in M. It effectively just applies a function in the context of M. This is exactly what fmap will do for all monads. So we can say that all monads are applicative functors. We’ll now create an Applicative type class to capture this in a function called apply.

Applicative

public abstract class Applicative<F, T> extends Functor<F, T> {

    public abstract <U> U get();
    protected abstract <U> Applicative<?, U> unit(U value);

    protected final <U> Function<Applicative<F, T>, Applicative<?, U>>
        apply(final Applicative<Function<T, U>, U> ff) {
            return new Function<Applicative<F, T>, Applicative<?, U>>() {
                public Applicative<?, U> apply(Applicative<F, T> ft) {
                    Function<T, U> f = ff.get();
                    T t = ft.get();
                    return unit(f.apply(t));
                }
            };
    }
}

Note that apply also calls unit to lift the result of f. So unit is used twice in every function application; once to lift the function and once again to lift its result.

Now fmap becomes:

fmap(T -> M[U])
= M[T] -> unit(T -> M[U])
= M[T] -> apply(unit(T -> M[U]))

 

Substituting f, we get:

fmap(f) = M[T] -> apply(unit(f))

 

Substituting apply(unit(f)) for M[M[U]] in our original bind yields the following complete bind signature:

M[T] -> (T -> M[U]) -> (M[T] -> (M[T -> M[U]] -> M[T] -> M[M[U]])) -> M[U]

 

The overall effect is a bind operation that performs the following:

  1. Accepts a T -> M[U] function and lifts it into M
  2. Applies it to T in M and yields a lifted result M[M[U]]
  3. Extracts and returns the contained M[U] result

Currently, the function returned by fmap unconditionally invokes apply to yield a lifted result. To give individual monads the opportunity to override this, we will move this logic into a new function called yield and have fmap call that instead. Individual monads that wish to skip over functions and yield their own results can do so by overriding this default yield implementation.

yield(f) = apply(unit(f))

 

We now compose fmap in terms of yield:

fmap(f)
= M[T] -> apply(unit(f))
= M[T] -> yield(f)

 

Notice here that if yield is overridden, then apply will be bypassed. In a bind scenario, join would then no longer be guaranteed to receive a lifted result. For example, an overridden yield could skip over a function and yield the enclosing monad instance as the intended result. In this case, join would be called on a non lifted value of type M[U] that it would not be able to flatten. Therefore, if yield is overridden to return a non lifted result, then join must also be overridden to return that same result (the same instance that join is invoked on). Otherwise join will error.

We said earlier that we would treat runtime exceptions as failures. So we will introduce one last function called fail to give monads the opportunity to deal with failure in their own way. This function will accept a RuntimeException and return a value of type M[U]. The default implementation will simply rethrow the runtime exception. Monads that wish to introduce their own failure values can override this function.

So finally, fmap becomes:

fmap(f) = M[T] -> (
    try {
        yield(f)
    } catch (RuntimeException e) {
        fail(e)
    }
)

 

We now have everything we need to define a monad base class with concrete and final implementations of fmap and apply, default implementations of map, bind, yield, join, and fail, and two abstract methods; unit and get.

Monad

@SuppressWarnings("unchecked")
public abstract class Monad<M, T> extends Applicative<M, T> {

    protected Monad() { }

    protected <U> Monad<?, U> yield(Function<T, U> f) {
        Applicative<Function<T, U>, U> ff = (Applicative<Function<T, U>, U>) unit(f);
        return (Monad<?, U>) apply(ff).apply(this);
    }
    protected <U> Monad<?, U> join() { return get(); }
    protected <U> Monad<?, U> fail(RuntimeException e) { throw e; }
    protected final <U> Function<Monad<M, T>, Monad<?, U>> fmap(final Function<T, U> f) {
      return new Function<Monad<M, T>, Monad<?, U>>() {
        public Monad<?, U> apply(final Monad<M, T> mt) {
          try {
            return mt.yield(f);
          } catch(RuntimeException e) {
            return mt.fail(e);
          }
        }
      };
    }
    public <U> Monad<?, U> map(Function<T, U> f) { return fmap(f).apply(this); }
    public <U> Monad<?, U> bind(Function<T, ? extends Monad<?, U>> f) {
	    return map(f).join();
	}
}

We can now extend this base class to define specific kinds of monads. Subclasses need only implement unit and get (inherited from Applicative), and override yield, join, and fail where necessary. For stronger type inference, subclasses can override map and bind and change their return types to match the subclass type and delegate to super.map and super.bind respectively.

The Maybe Monad

Now that we have a class for building monads, let’s build one. An easy one to start with is the Maybe monad. A Maybe monad is a container for a value that exists or does not exist. That is; it contains just one value or it contains nothing.

Maybe

@SuppressWarnings("unchecked")
public abstract class Maybe<T> extends Monad<Maybe<T>, T> {

    public static <U> Maybe<U> instance(U value) {
        return (Maybe<U>) (value != null ? Just.instance(value) : Nothing.instance());
    }

    @Override public final <U> Maybe<U> map(Function<T, U> f) {
        return (Maybe<U>) super.map(f);
    }
    @Override public final <U> Maybe<U> bind(Function<T, ? extends Monad<?, U>> f) {
        return (Maybe<U>) super.bind(f);
    }
    @Override protected <U> Maybe<U> fail(RuntimeException e) {
	    return Nothing.instance();
	}

    public abstract boolean isJust();
    public abstract boolean isNothing();
}

Just

@SuppressWarnings("unchecked")
public final class Just<T> extends Maybe<T> {

    public static <U> Just<U> instance(U value) { return new Just<U>(value); }

    private T value;

    private Just(T value) { this.value = value; }
    @Override public <U> U get() { return (U) value; }
    @Override protected <U> Maybe<U> unit(U value) { return Just.instance(value); }

    @Override public boolean isJust() { return true; }
    @Override public boolean isNothing() { return false; }
    @Override public String toString() { return "Just(" + get() + ")"; }
}

Nothing

@SuppressWarnings({"unchecked", "rawtypes"})
public final class Nothing<T> extends Maybe<T> {

    private static final Nothing INSTANCE = new Nothing();

    public static <U> Nothing<U> instance() { return INSTANCE; }

    private Nothing() { super(); }

    @Override public <U> U get() { throw new NoSuchElementException("Nothing.get"); }
    @Override protected <U> Maybe<U> unit(U value) { return INSTANCE; }
    @Override protected <U> Maybe<U> yield(Function<T, U> f) { return INSTANCE; }
    @Override protected <U> Maybe<U> join() { return INSTANCE; }

    @Override public boolean isJust() { return false; }
    @Override public boolean isNothing() { return true; }
    @Override public String toString() { return "Nothing"; }
}

The Maybe base class overrides fail to return Nothing. It has an instance factory method that accepts a value and returns a new instance of Just containing that value if it is not null, or a Nothing otherwise. Both Just and Nothing extend Maybe and implement unit. Nothing additionally overrides yield and join to return itself (which is Nothing). If you map or bind on Just, you will get a new Just with a value. If you map or bind on Nothing, you will get back the same Nothing. How is this useful? It’s best to illustrate with examples.

Consider the following Java code:

String email = bank.getBranch().getContactInfo().getEmail();

Chaining properties like this in Java is nasty. The bank object could be null and any one of the other getters could return null. They are all NullPointerExceptions waiting to happen. To cater for them, we could do something defensive like this:

String email;
try {
    email = bank.getBranch().getContactInfo().getEmail();
} catch (NullPointerException e) {
    email = null;
}
return email;

This is neither ideal nor sufficient, as the final result in the email result could still be assigned null. Let’s lift the bank object and all properties into a Maybe monad and use bind. To reduce the redundancy associated with writing anonymous inner Function classes, we’ll write a Maybe getter utility function (one that delegates to the standard getter function we created earlier).

@SuppressWarnings("unchecked")
public static <T, U> Function<T, Maybe<U>> mgetter(final String property) {
    return new Function<T, Maybe<U>>() {
        public Maybe<U> apply(T bean) {
            return (Maybe<U>) Maybe.instance(getter(property).apply(bean));
        }
    };
}

Function<Bank, Maybe<Branch>> getBranch = mgetter("branch");
Function<Branch, Maybe<ContactInfo>> getContactInfo = mgetter("contactInfo");
Function<ContactInfo, Maybe<String>> getEmail = mgetter("email");

Maybe<String> email =
    Maybe.instance(bank).bind(getBranch).bind(getContactInfo).bind(getEmail);

Solved! We now have one Maybe result, and no nulls to worry about. That’s right, they don’t exist anymore. A null property anywhere in the chain will resolve to Nothing and propagate to the result as Nothing without invoking any getters below that point in the chain. This is because our mgetter function lifts every property through the Maybe.instance factory method which returns Nothing if given a null, and a Just otherwise. In the happy scenario, the last bind will return Just(email) as the final result.

The previous example specifically dealt with nulls, but the Maybe monad can be used to deal with any failure. Consider the following:

Function<Integer, BigDecimal> reciprocal = new Function<Integer, BigDecimal>() {
    public BigDecimal apply(Integer num) {
        return new BigDecimal(1).divide(new BigDecimal(num), 4, RoundingMode.HALF_UP);
    }
};

Random random = new Random();
int num = random.nextInt(10);
BigDecimal result = reciprocal.apply(num);

If random returns zero, reciprocal will fail and throw an ArithmeticException (divide by zero error). Unguarded, the exception will propagate and terminate the program. To guard against this and have your program continue, you would have to explicitly catch and handle the exception in some way. For example:

BigDecimal result;
try {
    result = reciprocal.apply(num);
} catch (ArithmeticException e) {
    result = new java.math.BigDecimal(0); // undefined value = 0 ???
}

Having to handle runtime exceptions like this is bad enough, but what makes it even worse is the fact that the failed result of zero is misleading. The reciprocal of zero is definitely not zero! If we instead execute the division inside a Maybe monad, we can do away with the error handling and always get a meaningful result.

Maybe<BigDecimal> result = Maybe.instance(num).map(reciprocal);

Now we’ll get a Just containing the result if num is non zero, or a Nothing otherwise. A guaranteed meaningful result either way. How does this work? Maybe overrides fail to return Nothing, and fmap calls fail whenever a runtime exception occurs.

The Either Monad

Let’s build another monad; the Either monad. Either is a container for a value that can have one of two types. One type is called Left, and the other is called Right. The common convention is to use left for failure values and right for success values, but you can use them to represent any two types of values you like. We will define an Either interface that accepts two type parameters L and R (for left and right respectively). We will extend Monad and implement the Either interface to define a new class called EitherMonad that will be the base for Left and Right. This class will accept three concrete types; L, R, and T. Left will pass in [L, R, L] and Right will pass in [L ,R, R], partially applying L and R respectively through the Monad parameter T. This partial application is necessary since Monad only accepts one concrete type parameter.

Either

public interface Either<L, R> {

    Left<L, R> left();
    Right<L, R> right();

    boolean isLeft();
    boolean isRight();
}

Either Monad

@SuppressWarnings("unchecked")
public abstract class EitherMonad<M, L, R, T> extends Monad<M, T>
implements Either<L, R> {

    private T value;

    protected EitherMonad(T value) { this.value = value; }

    public final <U> U get() { return (U) value; }

    @Override public final <U> EitherMonad<M, L, R, U> map(Function<T, U> f) {
        return (EitherMonad<M, L, R, U>) super.map(f);
    }
    @Override public final <U> EitherMonad<M, L, R, U>
		bind(Function<T, ? extends Monad<?, U>> f) {
			return (EitherMonad<M, L, R, U>) super.bind(f);
		}
}

Left

@SuppressWarnings("unchecked")
public class Left<L, R> extends EitherMonad<Left<L, R>, L, R, L> {

    public static final <L, R> Left<L, R> instance(L value) {
		return new Left<L, R>(value);
	}

    protected Left(L value) { super(value); }

    @Override protected <U> Left<U, R> unit(U value) { return instance(value); }
    @Override public final Left<L, R> left() { return this; }
    @Override public final Right<L, R> right() {
        return new Right<L, R>((R) get()) {
            @Override protected <U> Right<L, U> yield(Function<R, U> f) {
				return (Right<L, U>) this;
			}
            @Override protected <U> Right<L, U> join() { return (Right<L, U>) this; }
        };
    }
    @Override public final boolean isLeft() { return true; }
    @Override public final boolean isRight() { return false; }
    @Override public final String toString() { return "Left(" + get() + ")"; }
}

Right

@SuppressWarnings("unchecked")
public class Right<L, R> extends EitherMonad<Right<L, R>, L, R, R> {

    public static final <L, R> Right<L, R> instance(R value) {
		return new Right<L, R>(value);
	}

    protected Right(R value) { super(value); }

    @Override protected <U> Right<L, U> unit(U value) { return instance(value); }
    @Override public final Right<L, R> right() { return this; }
    @Override public final Left<L, R> left() {
        return new Left<L, R>((L) get()) {
            @Override protected <U> Left<U, R> yield(Function<L, U> f) {
				return (Left<U, R>) this;
			}
            @Override protected <U> Left<U, R> join() { return (Left<U, R>) this; }
        };
    }
    @Override public final boolean isLeft() { return false; }
    @Override public final boolean isRight() { return true; }
    @Override public final String toString() { return "Right(" + get() + ")"; }
}

Both Left and Right implement unit, left and right. Left implements left() by returning the current Left instance and right() to return a new anonymous Right instance containing the current value. The anonymous Right instance overrides yield and join to always return itself. This is to ensure that a map or bind on Left.right() has no effect. On the other hand, a map or bind on Left.left() will return a new Left containing the new result as expected. Conversely, Right is implemented in the same manner.

One use case of Either is to use it as an alternative to throwing exceptions. With this approach, a method that could fail can be defined to return a value of type Either instead of throwing an exception. Callers of that method are then guaranteed a result and can focus all their processing on either success or failure (right or left). A caller that is only interested in success can be completely oblivious to failure. If a failure does occur, it will bypass all operations and transparently propagate to the result and be ignored. If failure does not occur, all operations will execute without having to unnecessarily catch and ignore exceptions that never occur.

Let’s consider an example that involves encoding and uppercasing a string that we know will never fail.

public String encode1(String str) throws UnsupportedEncodingException {
    return URLEncoder.encode(str, "utf-8");
}

public Either<UnsupportedEncodingException, String> encode2(String str) {
    try {
        return Right.instance(URLEncoder.encode(str, "utf-8"));
    } catch (UnsupportedEncodingException e) {
        return Left.instance(e);
    }
}

Function<String, String> toUpper = new Function<String, String>() {
    public String apply(String arg) {
        return arg.toUpperCase();
    }
};

// caller of encode1 has to ignore an exception that will never happen
try {
    String encoded = encode1("will always succeed");
    encoded = toUpper.apply(encoded);
} catch (UnsupportedEncodingException ignore) {
    // will never happen
}

// caller of encode2 can just get on with the job
String encoded = encode2("will always succeed").right().map(toUpper).get();

The List Monad

The Maybe and Either monads that we have created so far deal with only single values. Let’s now create a List monad for dealing with multiple values. Every value in this monad will be a list of zero or many values of some type. When you apply map or bind to a function on a list monad, the function will be applied to every element in the list and the individual results will be returned in a list. For a function that outputs a single value, map will return a list of single value results. For a function that outputs a list, map will return a list of lists where each nested list is a list of results. The bind function of the list monad will only accept functions that return lists. Therefore bind will always return a concatenated (joined) list of all nested results as returned by map. In a list bind, the list is the monad:

List[T] -> (T -> List[U]) -> List[U]

 

All we have done here is replaced M with List. To implement this, we will define a subclass of Monad called ListMonad that will implement the List interface to delegate to a given list. In this way, the ListMonad will be a list and the outputs of both map and bind will also be lists. We will override yield to operate on all elements of the list, join to concatenate the results, and fail to return an empty list. Additionally, we will add the following useful list functions:

  1. foldLeft(z, op)where
    • z is an initial value of type U
    • op is an operator function of type (U -> T) -> U

    This function will combine all elements in the list into a single value of type U. It will work from left to right by applying the operator to the original value z and the first element in the list, followed by applying it again to the result of that and the next element in the list, followed by the result of that and the next element, and continue in this manner until the end of the list before returning the accumulated result. yield, join, and reduceLeft will be implemented in terms of this function.

  2. reduceLeft(op)where
    • op is an operator function of type (T -> T) -> T

    This function will reduce all elements in the list to a single value of the same list element type T. It will also work from left to right applying the operator to the first and second elements, followed by applying it again to the result of that and the next element, followed by the result of that and the next element, and continue in this manner until the end of the list before returning the accumulated result. It will do this by reusing foldLeft.

  3. filter(pred)where
    • pred is a predicate of type T -> Boolean

    This function will return all elements in the list that satisfy a given predicate. This function will be implemented using bind.

There are many other useful list functions we could add, but we will start with only these for our minimal list monad. The foldLeft and reduceLeft functions will accept an operator function requiring two arguments. To support this, we will introduce the following Operator interface:

Operator (2-arg function)

public interface Operator<T, U> {
    U apply(U arg1, T arg2);
}

List Monad

@SuppressWarnings("unchecked")
public final class ListMonad<T> extends Monad<List<T>, T> implements List<T> {

    public static final <U> ListMonad<U> instance(U value) {
		return new ListMonad<U>(Collections.singletonList(value));
	}
    public static final <U> ListMonad<U> instance(List<U> list) {
		return new ListMonad<U>(list);
	}

    private LinkedList<T> list;

    public ListMonad() { this.list = new LinkedList<T>(); }
    public ListMonad(List<T> list) { this.list = new LinkedList<T>(list); }

    public <U> U get() { return (U) list; }

    @Override public final <U> ListMonad<U> map(Function<T, U> f) {
        return (ListMonad<U>) super.map(f);
    }
    @Override public final <U> ListMonad<U> bind(Function<T, ? extends Monad<?, U>> f) {
        return (ListMonad<U>) super.bind(f);
    }

    @Override protected <U> ListMonad<U> unit(U elem) { return instance(elem); }
    @Override protected <U> ListMonad<U> fail(RuntimeException e) {
		return new ListMonad<U>();
	}

    @Override protected <U> ListMonad<U> yield(final Function<T, U> f) {
        return foldLeft(new ListMonad<U>(), new Operator<T, ListMonad<U>>() {
            public ListMonad<U> apply(ListMonad<U> result, T elem) {
                result.add(f.apply(elem));
                return result;
            }
        });
    }

    @Override
    protected <U> ListMonad<U> join() {
        return foldLeft(new ListMonad<U>(), new Operator<T, ListMonad<U>>() {
            public ListMonad<U> apply(ListMonad<U> result, T nested) {
                result.addAll((List<U>) nested);
                return result;
            }
        });
    }

    public <U> U foldLeft(U z, Operator<T, U> op) {
        U result = z;
        for(T elem : list) {
            result = op.apply(result, elem);
        }
        return result;
    }
    public T reduceLeft(final Operator<T, T> op) {
        if (!list.isEmpty()) {
            T head = list.getFirst();
            if (list.size() > 1) {
                ListMonad<T> tail = instance(list.subList(1, list.size()));
                return tail.foldLeft(head, op);
            } else { return head; }
        } else { throw new UnsupportedOperationException("empty.reduceLeft"); }
    }

    public ListMonad<T> filter(final Function<T, Boolean> pred) {
        return bind(new Function<T, ListMonad<T>>() {
            public ListMonad<T> apply(T elem) {
                if (pred.apply(elem)) {
                    return instance(elem);
                } else {
                    return instance(Collections.EMPTY_LIST);
                }
            }
        });
    }

    @Override public String toString() { return list.toString(); }

    // List interface delegator methods..
    @Override public boolean add(T e) { return list.add(e); }
    // ..remaining delegators omitted for brevity
}

We can do a lot of useful things with the list monad. Here are some examples:

Encrypt a pass phrase:

Function<String, ListMonad<Character>> strToChars =
	new Function<String, ListMonad<Character>>() {
		public ListMonad<Character> apply(String str) {
			ListMonad<Character> chars = new ListMonad<Character>();
			for (char ch : str.toCharArray()) {
				chars.add(ch);
			}
			return chars;
		}
};

Function<Character, String> encrypt = new Function<Character, String>() {
	public String apply(Character ch) {
		int intval = ((int) ch) - 32;
		int encrypted =
			new BigDecimal(intval)
				.pow(7).remainder(new BigDecimal(97)).intValue();
		return String.format("%02d", encrypted);
	}
};

Operator<String, String> concat = new Operator<String, String>() {
	public String apply(String str1, String str2) {
		return str1 + str2;
	}
};

String passPhrase = "The list monad rocks!";

// will return "634920008743820700692742116000142746228201"
String encrypted =
    ListMonad.instance(passPhrase).bind(strToChars).map(encrypt).reduceLeft(concat);

Decprypt a pass phrase:

Function<String, ListMonad<String>> encryptedChars =
	new Function<String, ListMonad<String>>() {
		public ListMonad<String> apply(String str) {
			return ListMonad.instance(Arrays.asList(str.split("(?<=\\G.{2})")));
		}
	};

Function<String, Character> decrypt = new Function<String, Character>() {
	public Character apply(String str) {
		int decrypted =
			new BigDecimal(Integer.parseInt(str))
				.pow(55).remainder(new BigDecimal(97)).intValue();
		return Character.toChars(decrypted + 32)[0];
	}
};

Operator<Character, String> concat = new Operator<Character, String>() {
	public String apply(String str, Character ch) {
		return str + ch;
	}
};

String encrypted = "634920008743820700692742116000142746228201";

// will return "The list monad rocks!"
String passPhrase =
  ListMonad.instance(encrypted).bind(encryptedChars).map(decrypt).foldLeft("", concat);

Increment all the numbers in a list:

Function<Integer, Integer> increment = new Function<Integer, Integer>() {
    public Integer apply(Integer num) {
        return num + 1;
    }
}

List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);

// will return [2, 3, 4, 5, 6]
List<Integer> incremented = ListMonad.instance(nums).map(increment);

Sum all the numbers in a list:

Operator<Integer, Integer> plus = new Operator<Integer, Integer>() {
    public Integer apply(Integer int1, Integer int2) {
        return int1 + int2;
    }
};

List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);

// will return 15
int sum = ListMonad.instance(nums).reduceLeft(plus);

Get the names of all users that have an email address:

public class User {
    private String name;
    private String email;
    public User(String name) { this(name, null); }
    public User(String name, String email) {
        this.name = name;
        this.email = email;
    }
    public String getName() { return name; }
    public String getEmail() { return email; }
}

Function<User, Boolean> hasEmail = new Function<User, Boolean>() {
    public Boolean apply(User user) {
        return user.getEmail() != null;
    }
};

Function<User, String> getName = new Function<User, String>() {
    public String apply(User user) {
        return user.getName();
    }
};

List<User> users = Arrays.asList(
    new User("Jack", "jack@acme.com"),
    new User("Scott"),
    new User("Jill", "jill@acme.com"));

// will return [Jack, Jill]
List<String> names = ListMonad.instance(users).filter(hasEmail).map(getName);

The list monad can also deal with failure. If any element in a list causes a function to fail, then the entire computation will fail and an empty list will be returned.

Function<Integer, Integer> increment = new Function<Integer, Integer>() {
    public Integer apply(Integer arg) {
        return arg + 1;
    }
};

// list with null entry
List<Integer> list2 = Arrays.asList(1, 2, null, 4, 5);

// will return an empty list []
List<Integer> result = ListMonad.instance(list2).map(increment);

There are many other things we can do with monads and many other monads we could go on to create.

Conclusion

Now you may be thinking “What kind of Java programmer writes code like this?”. If you are, then don’t worry. Monads are FP abstractions. They are not well suited for non referentially transparent and imperative code. This and the lack of first class functions in Java makes them a very unnatural fit. Creating a type safe and user friendly interface with generic methods having bounded types is also difficult. The result is less than ideal type inference and code that is scattered with type annotation clutter. But I hope I have demonstrated the usefulness of monads or at least effectively introduced them to Java programmers who may be interested. I would suspect that anyone who is serious about transitioning from OO to FP will at some point find themselves going through a similar learning experience.

Written by warpedjavaguy

April 9, 2013 at 2:06 am

Posted in fp, java, monads

Tagged with , ,

How I defeated the maven-release-plugin in a flat structured multi module project

Rules are made to be broken so that paradoxes can be created.

Maven is a handy tool and has a lot of available plugins. It adopts the convention over configuration philosophy and provides a standard build lifecycle out of the box. This makes it very easy to automate a build and release process without writing a single line of script. But there’s a catch! It only works if you do things the “maven way” and follow the maven rules.

Most projects are made up of one or more multiple smaller projects. In the maven world, such projects are called multi module projects. A multi module project has a parent project and one or more nested child projects known as modules. When you build the parent project the child projects are also built. The recommended maven way of structuring a multi module project is to mirror the parent child hierarchy using a nested project structure.

So maven recommends that you create a parent project that contains the child projects using a physical project structure like this:

workspace/parent/pom.xml
workspace/parent/child1/pom.xml
workspace/parent/child2/pom.xml

Modules are then declared in the parent POM like this:

<modules>
  <module>child1</module>
  <module>child2</module>
</modules>

This was good for maven but it was is not good for eclipse. The eclipse IDE does not support nested projects. This was clearly a problem! I wanted to import all my projects (parent and children) into eclipse but the nested structure made this impossible. So I decided to use a flat project structure instead and moved all my child projects out of the parent project.

Now my parent and child projects were organised in a flat physical structure like this:

workspace/parent/pom.xml
workspace/child1/pom.xml
workspace/child2/pom.xml

And I then redefined the maven modules in the parent POM like this:

<modules>
  <module>../child1</module>
  <module>../child2</module>
</modules>

Now I could import all my projects into eclipse. This worked well and life was good until I decided to use the maven release plugin to automate the release process. I learned the hard way that the release plugin only supports the nested project structure recommended by maven. Reverting back to the nested structure was not an option. I had broken a maven rule and was being punished for it! I needed a paradoxical solution that would support both the nested and flat structures at the same time. It was then that I realised that my parent POM was responsible for two things: POM inheritance and module composition. It served two “parental” roles. In one role it provided all the common properties, dependencies, plugins, and profiles to all children through inheritance and in the other it defined itself as the parent project of all child projects. In OO terms, this was akin to defining a superclass that contains a list of all its subclasess.

My parent POM had violated the single responsibility principle. So I decided to split it up into two separate parent POMs. I removed the modules declaration from the original POM in my parent project. This POM was now purely to be used for inheritance purposes only. All child POMs continued to reference this POM as the parent POM. Nothing changed there. I then created a new POM that inherited this modified POM and aggregated all the other child POMs. I placed this new top level POM file in the workspace root alongside all my existing projects. My flat project structure now had a top level POM file that defined all the child projects as modules.

The final project structure looked like this:

workspace/pom.xml
workspace/parent/pom.xml
workspace/child1/pom.xml
workspace/child2/pom.xml

The workspace/parent/pom.xml was inherited by all child POMs and also the top level workspace/pom.xml. It was the parent POM for inheritance purposes. The top level workspace/pom.xml aggregated all the child projects into one container project. It was the (root) parent POM for composition purposes. It defined the parent and child modules like this:

<parent>
  <groupId>?</groupId>
  <artifactId>?</artifactId>
  <version>?</version>
  <relativePath>parent/pom.xml</relativePath>
</parent>
<modules>
  <module>parent</module>
  <module>child1</module>
  <module>child2</module>
</modules>

Both the maven release plugin and the eclipse IDE were happy with this structure. It was flat enough for eclipse and hierarchical enough for the maven release plugin.

Note: After experiencing and resolving this problem first hand I later discovered that the issue has already been reported and discussed here and mentioned at the very bottom of the maven eclipse plugin page. But I still cannot find any mention of this limitation on the maven release plugin page itself. I suspect that this is a well known issue in the maven community. If anyone is aware of any fixes or better solutions, please let me know. Interestingly also the title of this issue suggests that the problem has been fixed but the actual contents therein state otherwise.

Sample POM snippets – Posted on 22 Aug 2011 by request

workspace/pom.xml (The top level root POM)

  <parent> 
    <groupId>maven.demo</groupId> 
    <artifactId>parent</artifactId> 
    <version>1.0.0-SNAPSHOT</version>
    <relativePath>parent/pom.xml</relativePath>
  </parent> 

  <groupId>maven.demo</groupId>
  <artifactId>root</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

  <modules>
    <module>parent</module>
    <module>child1</module>
    <module>child2</module>
  </modules>

workspace/parent/pom.xml (The parent POM)

  <groupId>maven.demo</groupId>
  <artifactId>parent</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>pom</packaging>

workspace/child1/pom.xml (The child1 POM)

  <parent> 
    <groupId>maven.demo</groupId> 
    <artifactId>parent</artifactId> 
    <version>1.0.0-SNAPSHOT</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent> 

  <groupId>maven.demo</groupId>
  <artifactId>child1</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>jar</packaging>

workspace/child2/pom.xml (The child2 POM)

  <parent> 
    <groupId>maven.demo</groupId> 
    <artifactId>parent</artifactId> 
    <version>1.0.0-SNAPSHOT</version>
    <relativePath>../parent/pom.xml</relativePath>
  </parent> 

  <groupId>maven.demo</groupId>  
  <artifactId>child2</artifactId>
  <version>1.0.0-SNAPSHOT</version>
  <packaging>war</packaging>

Written by warpedjavaguy

August 8, 2011 at 11:21 pm

Posted in automation, maven

Hey Null, Don’t Touch My Monads!


Null handling.. we’ve been doing it completely wrong!

Nulls are a big problem! They are a most constant annoyance and the single root cause of all NullPointerExceptions. It is common practice in Java to defensively check for nulls everywhere. It would be nice if they could just go away. But they won’t because we’ve been using them on purpose to denote missing values. Almost every Java API uses nulls in this way.

When we integrate with Java API’s we have to check for nulls. Fortunately, Scala provides the Option monad to help deal with nulls. It is basically a container that can hold two types of values; Some or None (some value or no value). But for Java interoperability purposes, Some can also hold null. Is this a problem? Lets explore..

First, we’ll define a User class like this (overly simple I know)

case class User (name: String)

Now we’ll define a list of users and filter it

val users = List(User("Wendy"), User("Bob"))
users filter { _.name == "Bob" }

This yields List(User(Bob)). So far so good! Now lets redefine the user list by including a null entry.

val users = List(User("Wendy"), null, User("Bob"))
users filter { _.name == "Bob" }

Bang! NullPointerException! Lets fix it by checking for null.

users filter { u => u != null && u.name == "Bob" }

This yields List(User(Bob)) again. Good, but this is ugly. We don’t want to check for nulls. Let’s wrap every element in an Option instance.

users flatMap { Option(_) } filter { _.name == "Bob" }

Option(null) resolves to None and the expression yields List(User(Bob)) again. Nice! Now let’s try and wrap every element in a Some instance instead and see what happens.

users flatMap { Some(_) } filter { _.name == "Bob" }

Some(null) resolves to null and oh no, we get a NullPointerException! This is a problem. We want Some(null) to resolve to None. So lets define our own Some function that overrides this behavior.

def Some[T](x: T) = Option(x)
users flatMap { Some(_) } filter { _.name == "Bob" }

Now Some(null) returns Option(null) which resolves to None and the expression yields List(User(Bob)) as expected. Ok, so we’ve solved the Some(null) problem. Now lets look at another null problem. Lets blindly extract the second user element in the list (the null entry) and print the name property.

val user = users(1)
println(user.name)

The user reference is null and we get a NullPointerException. Oh dread, we didn’t check for null. Let’s do that.

if (user != null) {
  println(user.name)
}

Now we skip the printing of the name if the reference is null. But we don’t want to check for nulls. So lets wrap the null user in an Option and use foreach.

Option(user) foreach { u => println(u.name) }

Option(null) resolves to None and all is good. With our overriding Some function still in scope, we can do the same using Some also.

Some(user) foreach { u => println(u.name) }

Just like before, our call to Some(null) returns Option(null) which resolves to None and we’re good. But we want cleaner code that looks like this:

user foreach { u => println(u.name) }

This results in a compile error because foreach is not a member of User. But we can fix that by making our overriding Some function implicit. With this implicit in scope, Scala converts user to Option(user) and the above will now work.

implicit def Some[T](x: T) = Option(x)
user foreach { u => println(u.name) }

Taking this a step further, we can map the user name and print it like this. If the user is null, the name is never mapped and never printed.

user map { _.name } foreach println

Nulls be gone! :)

Now of course there are many cases in Java where nulls are legitimate values, and for this reason Scala supports Some(null) = null. But as shown above, that doesn’t mean we can’t override that with Some(null) = None.

Written by warpedjavaguy

June 8, 2011 at 4:35 am

Posted in java, scala

The “Scala is too Complex” Conspiracy


They don’t want pragmatic Scala programmers.

 

The “Scala is too complex for the average programmer” movement is disturbing. It conspires that Scala is too difficult for the average programmer to learn and that it is too academic. Scala is a hybrid programming language that is object oriented and functional. Java is a programming language that is object oriented and imperative. This means that Java programmers have no functional programming power.

This year I read Programming in Scala and practiced some functional programming. I converted some Java code I had lying around to Scala and gained some hands on experience with case classes, pattern matching, lazy evaluation, implicit conversions, lambdas, and closures. I also reduced and folded lists and wrote curried functions. I was pleasantly shocked and surprised!

It is true that moving from object oriented to functional programming requires a shift in mindset. It is true also that many Java programmers are already thinking functionally but are unaware of it. In Java we use immutable objects when programming for concurrency. We use anonymous inner classes to simulate lambdas and closures. We use iterators and predicates to simulate list comprehensions. We recognize these and other functional concepts but implement them in roundabout ways because there is no direct support for them in the Java language.

Fortunately Java 7 is looking to add lambda support to the language so we will soon no longer have to write anonymous inner classes wherever single method interfaces and abstract classes (SAM types) are expected. In the meantime Scala has emerged as a functional language that Java programmers can learn and transition to without sacrificing their object oriented skills and without leaving the JVM platform.

For any programmer who has not looked at Scala or who has been deterred by a “too complex” conspirator, here are some code samples..

Case classes

Lets create a class named Path that accepts a source and destination city as two separate characters and exposes them as public read only properties.

case class Path (origin: Char, destination: Char)

Prefixing a class definition with the “case” keyword automatically exposes constructor arguments as public read only properties. It also adds a factory method to your class so you don’t have to instantiate it with new, so Path(‘A’, ‘B’) will suffice for example. It also provides a toString method that returns a string literal like Path(A,B). You also get a natural implementation of the hashCode and equals methods. You get constructor pattern matching support too. All this for free with a one liner case class.

Factory method with pattern matching

Now lets create a factory method that accepts a string, parses it, and returns a Path instance. For example, passing the string “AB” should return a Path(‘A’, ‘B’) instance whereas passing the string “ABC” should fail.

object Path {	
  val PathRE = "^([A-Z]{1})([A-Z]{1})$".r
  def apply(pathStr: String): Path = pathStr match {
      case PathRE(origin, destination) 
      	=> Path(origin(0), destination(0))
      case _ 
      	=> throw new IllegalArgumentException(pathStr)
  }
}

Now we can instantiate a Path as Path(“AB”) in addition to Path(‘A’, ‘B’). Any string that does not contain exactly two characters that are not between A and Z will result in an IllegalArgumentException. So the strings “a”, “1”, “A1″, and “ABC” will all fail construction. As a safeguard we can add an assert statement to the Path constructor to ensure that the source and destination cities are never equal like this:

case class Path (origin: Char, destination: Char) {
  assert (origin != destination, "origin and destination are same")
}

Implicit conversion

Now lets make it possible to assign the string literal “AB” directly to any Path type anywhere so that we don’t have to call the factory method explicitly. We do this by prefixing our apply(String) factory method with the keyword implicit as shown below:

implicit def apply(pathStr: String): Path

Now the string literal “AB” can be accepted anywhere where a Path instance is expected.

Folding Lists

Now suppose we want to write an application that accepts a list of Path string literals from the command line. We can convert the incoming list of Path strings to a Set of Path instances by using a fold left operation. The following creates a new empty Set and adds to it every Path in the incoming list. Each string in the list is automatically converted to a Path instance through implicit conversion.

def main(args: Array[String]) {
  val pathSet = (Set[Path]() /: args) (_+_)
}

Lambda expressions

Now lets say we have already written a function named find, that finds all the routes from one city to another based on some route condition. This function accepts two arguments, a Path containing the from and to cities, and a predicate lambda expression. The signature looks like this:

def find(path: Path, predicate: Route => Boolean): List[Route]

We can invoke this function to find (for example) all the routes from city ‘A’ to city ‘E’ having less than 3 stops like this:

val routes = find("AE", route => route.stops < 3)

Currying

We can curry the find function by splitting its two argument parameter list into two one argument parameter lists like this:

def find(path: Path)(predicate: Route => Boolean): List[Route]

Now when we invoke the find function with a Path argument we get a second function that we can then invoke with the predicate argument to get the result. We can invoke our curried function like this:

val routes = find("AE")(route => route.stops < 3)

Scala allows us to optionally wrap the sole argument to a single argument function in curly braces instead of parenthesis. So we can also invoke our curried function like this:

val routes = find("AE") { route => route.stops < 3 }

Now our call to the find function looks like a built in Scala construct.

Is Scala too Complex?

If you think that the above Scala code is too complex then I urge you to try and achieve the same in Java with less complexity.

Written by warpedjavaguy

August 2, 2010 at 11:14 pm

Posted in java, programming, scala

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: