Sealing Algebraic Data Types in Java


Recently I caught up on Dick Wall’s Devoxx UK talk, “What have the Monads ever done for us?”*. Dick does a great job of introducing terms such as “monoid”, “functor” and “monad” in a way that’s easy to grasp, even for Java-damaged minds like my own. I thoroughly recommend watching the talk to all developers who have heard these terms and want a simple way to understand them, without trudging through tutorials using silly metaphors like space suits or burritos.

Also, achievement unlocked: met Dick Wall at the speaker’s dinner. A thoroughly (and completely predictably based on the Java Posse podcasts!) lovely chap.

As well as heartily recommending you check out Dick’s talk, I wanted to pick up on something he mentioned, and suggest an approach. Dick introduces an algebraic data type, a simplified linked list implementation, using an abstract class DeadSimpleList with exactly two subclasses: DeadSimpleListNil and DeadSimpleListCons. The base class looks like this:

public abstract class DeadSimpleList<T> {
   public abstract <U> DeadSimpleList<U> map(Function<T, U> function);
   public abstract boolean isEmpty();
   public abstract String contentsAsString();
}

(For clarity, most of the useful functions and generics had been omitted.)

One of the points of these algebraic data types is that subclassing is limited and controlled. As opposed to an interface, they are explicitly intended not to be extended by users of the type. For example, Scala’s abstract Option type is extended by the concrete Some and None types, and nothing else. Some and None entirely define Option’s behaviour. You want to explicitly prevent someone coming along and adding a new extension of Option, like SomethingWhenIFeelLikeIt. If it’s possible for such a beast to exist, it becomes more difficult to reason about.

In talking about how extension should be prohibited, Dick says:

“[Haskell and Scala let you] keep the superclass public, inherit from it, in a controlled way, but then stop anyone else from inheriting from it… and I don’t know that there’s a good answer for that in Java”.

I think there is a good answer. Or at least, as good as these things can ever be in Java.

As the example continues, the two subclasses are declared as public class DeadSimpleListNil<T> and public class DeadSimpleListCons<T>, which would have to reside in different files from the superclass. I think the desired trick is to limit subclassing by reducing visibility of the abstract class’ constructor. Like so:

public abstract class DeadSimpleList<T> {
  public abstract <U> DeadSimpleList<U> map(Function<T, U> function);
  public abstract boolean isEmpty();
  public abstract String contentsAsString();

 // add this constructor
 private DeadSimpleList() { }

 ...

Adding the private constructor will cause the subclasses to fail to compile, because the constructor of the abstract class will not be visible. The only way to get them to compile is to move the subclasses into a scope where they can invoke the private constructor of the superclass, like so:

public abstract class DeadSimpleList<T> {
    // abstract methods, private constructor, as before
    
    public static final class DeadSimpleListNil<T> extends DeadSimpleList<T> {
      // method implementations as before
    }
    
    public static final class DeadSimpleListCons<T> extends DeadSimpleList<T> {
      // concrete constructor and method implementations as before
    }
    
    ...

Now you have complete control over how the abstract class is subclassed. Users can still reference the inner classes, and construct instances of them. Crucially, they can’t create their own subclass called RandomlyEmptyDeadSimpleList, and thus nobody has to waste any brain cycles fretting about the possibility of its existence.

Although the semantics are quite different from Scala’s sealed keyword, the outcome is roughly equivalent: only when you control the source code of base class can you add subclasses. Surprisingly for Java, this mechanism isn’t as annoyingly cumbersome as one might have predicted.


* I missed it when I attended Devoxx UK, since I was giving my talk at the same time on another track. It’s common for me to visit conferences where talks I’m interested in clash, this was the first time where one of those talks was mine.


Authored by Graham Allan.
Published on 17 July 2014.
Comments
Tags: devoxxuk , java , scala , software


What My Vote In Scottish Independence Will Not Be About


This September, the people of Scotland will vote in a referendum to decide if we should leave the United Kingdom, and become an independent country. There are many questions about what would happen to Scotland and the rest of the UK (rUK) in the event of a Yes vote. Questions that nobody can definitively answer. I expect I will vote Yes, in favour of independence.

While visiting London over the past couple of years, I've had several conversations about the referendum with colleagues and acquaintances. Since having these conversations, I've found it's easier to articulate what my vote will not be about, than what it will. Below is a list of what my vote will not be about.

Romantic Nationalism

As far as I'm concerned, the vote is a political one. That the legalities of independence involve dissolving an agreement made in 1707, and that Scotland happens to have border at all, is more or less a convenient coincidence. The border could be moved a few miles north or south. Newcastle, Liverpool and Manchester would all be welcome. The new country could have a new name, a new flag, a new national anthem, I wouldn't really mind. What matters are those people who make up the society, wherever we're from, and what we do with our new found self-determination. As much as I cheer on (or commiserate over) the Scottish football team, nationalism and patriotism as ideas seem a bit silly to me.

My vote will not be about romantic notions of bagpipes; thistles; whisky, or Rabbie Burns.

Anti-English Sentiment

I will not be voting because I dislike English people, or to rid Scotland of the Auld Enemy. Nor will I be consumed with a sense of vengeance for injustices or oppression that happened hundreds of years ago, whether given the Hollywood history-distorting treatment or not. Over 400,000 thousand English people currently live in Scotland. They're more than welcome. They'll be eligible to vote in the referendum. That's a good thing. I dislike the way the south of England votes, that's entirely different from disliking English people.

My vote will not be about anti-English sentiment.

Alex Salmond

I don't have especially strong feelings about Alex Salmond. Which is rather fortunate, since the referendum is not about voting for Alex Salmond, or the Scottish National Party. In the result of a Yes vote, about six weeks after the transition is complete, there will be a Scottish general election to vote on the first government of an independent Scotland. I might vote for the Labour Party, the Scottish Green Party or The Pirate Party. Maybe the Conservatives, as a protest vote, or to be ironic. The point is that our choice in independence is separate and distinct from the choice of government that will follow.

My vote will not be about Alex Salmond.

Maggie Thatcher

As prime minister, Margaret Thatcher became a figure of hatred for the working class, and after introducing the Poll Tax, for the Scottish working class particularly. Some of the hatred is deserved, some of it is misdirected. As the opposition leader, she battled against the first referendum for Scottish devolution back in 1976. Perhaps I do enjoy the thought of the Milk Snatcher spinning in her grave after Scotland finally “wins one”. But that's a petty mindset, and I choose to think in more positive terms. She's dead, how she felt about Scottish independence is irrelevant. What's more relevant is that I can hear faint echoes her cruelty in what the Conservatives are enacting today. When it comes to marking a ballot: don't hate the politician, hate the policies.

My vote will not be about Maggie Thatcher.

Saving the rUK from the Tories

If you're left-leaning and live in the rUK, you may have been told that Scottish independence, and the resultant Labour seats that will be lost, will forever consign you to Tory rule. You're perhaps hoping that your Scottish comrades will show you compassion, stick around and spare you from endless Conservative governments. That theory has been debunked. Although for a long time Scotland has contributed way more Labour than Conservative MPs to the House of Commons, those seats very rarely cause a change in government. In the few cases where Scottish seats made the difference, the governments that formed didn't last. As a general rule, the party that rUK votes for is the party that Scotland gets. rUK is quite capable of electing a non-Tory government.

My vote will not be about preventing Tory rule.

Subsidies: Oil or Otherwise

There's an oft-repeated ping-pong match in independence debates: “The UK subsidises Scotland!” one side volleys, “No, Scotland puts in more than it gets back!”, the other side returns (usually citing hypothetical oil revenue). The argument that's picked is the argument that supports whatever point the person is trying to make. Lies and statistics and all that. I tend to split the difference and assume that we get back in spending what we put in, and if there's a difference, it won't be big enough to matter in the long run. That is also to say, we're self-sufficient, and would continue to be under independence. We appear to be able to support ourselves, and even if we're worse off, I am prepared for me and my family to be poorer in the pursuit of a fairer society.

My vote will not be about subsidies, from oil or anywhere else.

Sprinkling the magic fairy dust that will make everything all right

Scotland has it's problems. A worse health record than the rest of the UK, and lower life expectancy, than most of Europe. We have our share of social issues, such as sectarianism and alcoholism, that conspire together in such a horrendous way that the reports of domestic abuse dramatically increase in the evening following Celtic playing Rangers in a game of football. Scotland is not a socialist paradise that is besmirched only by the influence of a Thatcherite Westminster. Our current devolved parliament is not magically immune to bureaucracy and corruption. Voting for independence will not solve these and the many other challenges that Scotland faces. Independence is not the silver bullet, but I believe that in governing ourselves, we are better placed to tackle those challenges. For me, independence is merely a step in the right direction.

My vote will not be about thinking independence magically solves everything.

Conclusion

Hopefully I've given an insight into part of the thought process behind deciding which way to vote in September. While I work on articulating what my vote will be about, at least I can share what it won't be about.


Authored by Graham Allan.
Published on 08 May 2014.
Comments


Distributed Pair Programming @ TIM Group with Saros


There’s a particular technology used within TIM Group that has been too useful for too long to continue to go uncelebrated. The tool is called “Saros”, it is an Eclipse plugin for distributed pair programming that is used extensively at TIM Group.

Why We Need A Distributed Pairing Solution

We have developers spread across London and Boston offices, and a few “Remoties” working from home in various far flung lands. As one of said Remoties, I believe I would not have the opportunity to continue to work at TIM Group and live where I want to live (hint: not London) if it not for Saros.

Having been entirely colocated just a few years ago, our choice to use pair programming by default didn’t really have technical limitations. With an extra seat, keyboard and mouse at every developer’s workstation, the barrier to pairing was low. Just pull up a chair and pair. When we first started having distributed developers, we didn’t want to give up on pairing for technical reasons, so the search began for how to adapt pair programming to a distributed environment.

Why Other Solutions Don’t Match Up

An oft-cited solution for this problem is to use a screen sharing technology and remote access technology. There’s plenty to choose from: Windows’ Remote Desktop; TeamViewer; LogMeIn; GoTo MyPC; VNC; NX; etc. However, we found them all far too limited for pairing. Just like colocated pairing, there’s only one cursor, so only one person can use the keyboard and mouse at any time. Unlike colocated pairing, there’s a large bias towards the person hosting the session, as they get much faster feedback from typing, since they don’t have to suffer the latency. When it’s (figuratively) painful to type, it’s much easier to shy away from being the “driver”, which hinders the collaboration. We never found a solution that reduced that latency to an acceptable level.

Another cited solution is to use a terminal editor like tmux, that does not have the overhead of screen sharing. The feedback when typing is much better, however, there’s one major drawback: being limited to terminal editors only. I’ve seen people whose terminal environments are well suited for developing in a language like Ruby or JavaScript. For those of us coding in Java and Scala, we didn’t want to give up the powerful features we appreciate in our IDE, so tmux is not suitable.

Saros To The Rescue

Thankfully, we discovered Saros, a research project from the University of Berlin. The most relatable way I’ve found to describe it is as:

"Google Docs within the Eclipse IDE"

It works by connecting two or more developers through Eclipse, so that when Alice enters some text, Bob sees it appear in his editor. The experience for both users is as if they were editing files locally[0]. Rather than sharing the image of a screen, edit commands are serialised and sent over the wire, changing the other participant’s local copy. This comes with several other benefits over remote access technologies:

  • the feedback when typing is instant, for both parties
  • the latency for seeing your partner’s keystrokes is much lower than when transmitting an image of the screen[1]

There are even benefits over colocated pairing:

  • neither the host nor guest has to leave the comfort of their familiar work environment to pair; you can set up fonts and shortcuts however you like
  • since you are both editing as though it was local, each participant has their own cursor, and can be editing different files, allowing ad-hoc splitting of tasks[1], which can be very handy
  • you can have more people involved (up to 5) which we’ve used for code review and introducing a project to a group of people, sparing the discomfort of hunching around a single desk

There are other distributed pairing solutions, such as Cloud9 IDE, and Kobra.io, but none (that we’ve found) that let you stick with your own IDE setup, retaining parity with how you would develop locally.

There are of course drawbacks to distributed pairing, regardless of technology, which I’m not going to cover here; they’re generally not problems Saros, or any technology, will be able to solve.

IntelliJ Support Is On The Roadmap

After a long search, we have not found anything that really compares with Saros. For me, it really is a killer feature of Eclipse. So much so that I’ve basically kept IntelliJ in a dusty old drawer, even when it would be better for certain tasks (like Scala development). Fortunately, it looks like that’s about to change. Work has just begun to port the Saros platform to IntelliJ, which is really exciting. Whenever I’ve talked to people about Saros, alternative IDE support inevitably arises. If the core Saros technology was agnostic of the IDE, it could be a huge leap forward for collaborative development in general.

At TIM Group we were so keen on the idea that a handful of us spent a “hack week” throwing together the first steps towards an IntelliJ plugin for Saros. We were able to demonstrate a proof-of-concept, but didn’t get anything truly viable. Having brought this effort to the attention of the Saros team, I hope that in some small way it inspired them to start work on it, but I doubt that’s something we can take credit for. Hopefully, during the development of the IntelliJ plugin there will be something that we can contribute, and give something back for our many hours of happy usage.

If you’re looking for an answer to the problem of distributed pairing, I heartily endorse Saros!

[0] for more details of the theory behind this aspect of collaborative editors, see http://en.wikipedia.org/wiki/Operational_transformation
[1] we have acquired a habit of being vocal about whether we are in Driver/Navigator mode, and if your pair is following you, since you can’t assume they are


Originally published on devblog.timgroup.com


Authored by Graham Allan.
Published on 12 March 2014.
Comments



ABOUT GRUNDLEFLECK

Graham "Grundlefleck" Allan is a Software Developer living in Scotland. His only credentials as an authority on software are that he has a beard. Most of the time.

© Copyright 2013-2022