Archive for November, 2006

Is There Anybody Out There?

Tuesday, November 28th, 2006

I have met thousands of people in my life. Of all those people, each can be described in one of four ways:

  1. The person understands monads and would never, without duress, use an imperative programming language
  2. The person does not understand monads, would like to and has embarked on doing so in some form
  3. The person does not understand monads and would not like to (my doctor for example)
  4. The person does not understand monads and in an attempt to do so, has created erroneous simplifications since “not knowing” should be defended at all costs - even if it implies the creation of a false and somewhat convenient reality

I implore any person not to fall into the latter category, but I do understand that this imploration is based on my value system, which has a strong emphasis on the philosophy of epistemology. If the phrase, “ignorance is bliss” (without the negative connotation), is valuable to you, then so be it. I am also very keen to know of any persons who cannot be described this way, but to date, I have found none.

My school friends were sad when they found out that Santa Claus was not real - I was angry.

Australians in sport

Wednesday, November 22nd, 2006

If you live in Australia and you own a television, you’ll likely be aware of the retirement of Ian Thorpe - one of our best swimmers. As per usual for the media, the coverage of “Thorpy’s” retirement is disproportionate to the event and no doubt we (Australians) will be hearing about it for days to come, with follow ups of course. Personally, I do not enjoy watching swimming, regardless of the speed of the “fish” at hand - I find it boring, though I do admire the athleticism, training and dedication of its participants.

While Thorpe’s achievements in swimming should not be undermined, I turn attention to a sport that over the last couple of decades has lost the spotlight with respect to the media and remind Australians of some of our other courageous sports-persons. I hope Thorpey is grateful for my attempted diversion :) It must be horrible having a live and detailed personal profile plastered nation-wide.

David Palmer is an Australian who has held the world number 2 - repeat, world number 2 - position on the Professional Squash Association rankings list for almost all of 2006. I say “almost” because he achieved world number 1 in February and world number 4 in January. While his profile is not as high as our beloved Thorpe, he is just as strong an athlete and being a competition squash player myself, I have a personal admiration for the skill of players at his level, since they are skills that I aspire to.

If we take a look at the PSA World Rankings, we also note some other Australians; Anthony Ricketts, Stewart Boswell and Cameron Pilley, all of which I watch with awe as they perform on a squash court. If we turn our attention then to women, we have the two “Grinham sisters” within the top 5 and some rising Australian stars following on the WISPA World Rankings.

As Australia becomes the 52nd state of America (culturally and politically), we lose some of our tradition and along with it, our love of the sport of squash - Americans have a negative stigma attached to squash as they generally prefer racquetball, though I believe or at least, hope, that this is changing with some “education” i.e. Trying It And Seeing. You’ll note many British and Middle-Easterners on the world rankings list. Nevertheless, Australians need to be reminded of some of our equally talented athletes in other disciplines besides “getting from one end of the pool to the other as quick as you can”.

Cheers to Thorpey.

Revisiting Maybe in Java

Thursday, November 16th, 2006

I posted the link to Maybe in Java to programming.reddit.com and waited a good… hour or so, before giving up and going to bed. Actually, I happened to lose interest in posting it and by-chance, noticed my web browser still hadn’t completed the request on the way to bed. Nevertheless, it seems my HTTP request managed to make it there and when I woke up the next morning, there were all sorts of comments floating around. A few in particular asking something along the lines of, “what exactly has been achieved?”.

I will answer this question with “I have pointed out to Java programmers the concept of a very basic algebraic data type and importantly, in their language”. No mathematics, no type theory, nothing that will scare away your average J2EE Joey Jumper. I have also made a subliminal point of “hey! there are languages that already do this, only better!”. In particular, I have not provided anything that you should all go out and start using on your next WebSphere-fronted, RDBMS-backed, one-trillion-gazillion LOC web application. It seems the following points were missed in my original writing:

  • Throwing an exception is one of our possible options for evaluation of a partial function in Java. Here are all our options available in Java: … Emulate continuation passing style (CPS)
  • data Maybe a = Just a | Nothing (the Haskell equivalent i.e. omitting instances)
  • I’ll let your imagination run wild with possibilities from here :)

To remedy this situation, I have added further to the original Maybe type which was intentionally left incomplete, and it is still not complete. I hope this will help those who haven’t made the leap to do so and those who have made the leap, to understand my objective in this writing.

public abstract class Maybe<T> {
  private Maybe() {
  }
 
  public abstract <Q> Q maybe(JustC<Q, T> jc, NothingC<Q> nc);
 
  public static abstract class Nothing<T> extends Maybe<T> {
    private Nothing() {
    }
  }
 
  public static abstract class Just<T> extends Maybe<T> {
    private Just() {
    }
 
    public abstract T just();
  }
 
  public static <R> Maybe<R> _just(final R r) {
    return new Just<R>() {
      @Override
      public R just() {
        return r;
      }
 
      @Override
      public <Q> Q maybe(final JustC<Q, R> jc, final NothingC<Q> nc) {
        return jc.c(r);
      }
    };
  }
 
  public static <R> Maybe<R> _nothing() {
    return new Nothing<R>() {
      @Override
      public <Q> Q maybe(final JustC<Q, R> jc, final NothingC<Q> nc) {
        return nc.c();
      }
    };
  }
}
 
public interface JustC<Q, R> {
  Q c(R r);
}
 
public interface NothingC<Q> {
  Q c();
}

Those of you familiar with the Visitor Design Pattern (or any other GoF design euphemism) will immediately recognise the modification - hence the title of the post :). Please feel free to replace identifiers with your preferred view of the world; continuation, quasi-continuation, visitor, whatever.

For those who insist on returning null or throwing an exception/error, or more so, insist on failing to recognise the distinction, I have yielded to your pressure:

public final class NullNothingC<T> implements NothingC<T> {
  public T c() {
    return null;
  }
}
 
public final class ErrorNothingC<T> implements NothingC<T> {
  public T c() {
    throw new Error();
  }
}

Maybe in Java

Monday, November 13th, 2006

In Haskell, there is an algebraic data type called Maybe to represent evaluation of a partial function. That is, if you have a function, say f(x), and f(x) is defined for some x, but not all x, you return either:

  • A type Maybe that has a value available - called Just a where a is the value - representing defined function evaluation.
  • A type Maybe that has no value available - called Nothing - representing undefined function evaluation.

In fact, if we were to look at the source for the Maybe algebraic data type in GHC, we’d see this:

data Maybe a = Just a | Nothing

Not much to it, eh!? This Haskell snippet can be read as “Declare type Maybe with one polymorphic unbound variable ‘a’ that can be constructed as either Just ‘a’ or Nothing”.

Consider a real Java example, List.get(int index), which returns a type T where T is a type parameter (it once returned type Object prior to 1.5). For some Lists and some ints, this function is undefined. For example, for the list [1,2,3] and the int 7, List.get is undefined. In fact, this will throw an IndexOutOfBoundsException if attempted:

java.util.Arrays.asList(new Integer[]{1, 2, 3}).get(7);

Throwing an exception is one of our possible options for evaluation of a partial function in Java. Here are all our options available in Java:

  • Return null
  • Throw a compile-time checked exception
  • Throw an unchecked exception
  • Emulate continuation passing style (CPS)

I have distinguished checked and unchecked exceptions for a specific reason that I’ll leave for another day and I won’t go into great detail about any of these options in specific, since I am currently in the middle of documenting all this in more detail along with some basic type theory. However I will note that each of these options for evaluation of a partial function have some kind of nasty consequence. For example, the value null is assignable to any reference type and so can inadvertently be passed along to a method (I am sure you have seen this before):

  T t = f(x);
  // is t null?
  // the compiler doesn't force us to check!
  // how does the method behave now?
  method(t);

And how long has that checked/unchecked exception debate been going? Yes there is a reason it has been going for so long - in fact, it is riding on a flawed premise so it will continue on forever until its participants realise this flaw - but we’ll leave that for another day and smile and nod in the meantime. :)

With a Maybe data type, we might instead write our function/method as:

Maybe List.get(int index)

…where undefined behaviour is denoted by returning Nothing and defined behaviour is denoted with Just T. We should also be assured that only one of these two things will occur. No more returning null, no more throwing exceptions!! How wonderful would that be!? Well, if you’ve ever dabbled in Haskell or type theory, you’ll know immediately how great that would be - but what about Java?

An initial and naive attempt to emulate Maybe fails immediately:

interface Maybe<T> {
  T get();
}

We see that we have isolated our apparent anomaly that we are trying to resolve. We must still either return null or throw an exception from the Maybe.get method, but no other method ever need do so - as long as we (hopefully) remember to check for null for any given Maybe. While a slight improvement, this of course, does not solve our problem. We are still returning null or throwing exceptions and importantly, suffering the adverse consequences of doing so (we want the compiler to fail, not have to remember to do stuff!). Instead, we need to use types to represent Just and Nothing. Let’s try another attempt.

interface Maybe<T> {
}
 
interface Just<T> extends Maybe<T> {
  T get();
}
 
interface Nothing<T> extends Maybe<T> {
}

Done!! Or not. There is a specific guarantee that our Haskell data type makes that our Java attempt doesn’t. Specifically, if a Maybe is not Just, then it is definitely Nothing and vice versa in Haskell - this is important if we are to continue. We can see that this constraint does not hold for our Java Maybe because it can have any number of sub-types - of course - since it is an interface. We know how to constrain a type to have zero sub-types; by using a class with the final keyword. We know how to free a type to have infinite sub-types; without the final keyword or an interface. But what about constraining a type to 2 and only 2 sub-types?

This can be achieved by exploiting a little known Java language feature - a type cannot be sub-typed if it has only private constructors unless those sub-types are nested in the super-type. It seems we can indeed have a Maybe algebraic data type in Java by having 2 and only 2 sub-types!

public abstract class Maybe<t> {
  private Maybe() {
  }
 
  public static abstract class Nothing<t> extends Maybe<t> {
    private Nothing() {
    }
  }
 
  public static abstract class Just<t> extends Maybe<t> {
    private Just() {
    }
 
    public abstract T just();
  }
}

Looking good so far. We now know for sure that every instance of Maybe is either Just or Nothing and if it is Just, we have a value available through the get method - exactly what we ordered. As it stands though, we cannot create instances - let’s expose these through public methods.

public abstract class Maybe<T> {
  private Maybe() {
  }
 
  public static abstract class Nothing<T> extends Maybe<T> {
    private Nothing() {
    }
  }
 
  public static abstract class Just<T> extends Maybe<T> {
    private Just() {
    }
 
    public abstract T just();
  }
 
  public static <T> Maybe<T> _just(final T t) {
    return new Just<T>() {
      public T just() {
        return t;
      }
    };
  }
 
  public static <T> Maybe<T> _nothing() {
    return new Nothing<T>() {
    };
  }
}

And so there we have it - an algebraic data type in Java for evaluation of a partial function. How does our List method look now? How about this:

Maybe List.get(int index)

Clients of this method will now check if the return type is either Just or Nothing and in the case of Just, perform a downcast and retrieve the value. No more returning null. No more throwing exceptions. Not ever!

I’ll let your imagination run wild with possibilities from here :)

As I have mentioned, I plan to go into greater detail about this problem by documenting it in detail so keep an eye out on the Workingmouse Research page.

Until then, I’ll keep you wondering will a small piece of interesting code:

import java.util.List;
import java.util.LinkedList;
import java.util.Map;
import java.util.Hashtable;
 
class ListMap {
  public static void main(String[] args) {
    Map<Integer, String> map =
      new Hashtable<Integer, String>();
    map.put(0, "x");
    map.put(1, "y");
    map.put(2, "z");
 
    List<String> list =
      new LinkedList<String>();
    list.add(0, "x");
    list.add(1, "y");
    list.add(2, "z");
 
    // xyz
    System.out.println(map.get(0) + map.get(1) + map.get(2));
    // xyz
    System.out.println(list.get(0) + list.get(1) + list.get(2));
 
    // returns null
    System.out.println(map.get(7));
    // throws IndexOutOfBoundsException
    System.out.println(list.get(7));
  }
}

APLAS ‘06

Thursday, November 9th, 2006

After surviving day 1 of the Fourth ASIAN Symposium on Programming Languages and Systems, I have to say it is refreshing to be reminded of how much academic work is being put into providing solutions to the diverse set of software problems that exist today. I use the term “surviving” to annotate my lack of coherence as a result of attending the U2 Vertigo concert in Brisbane the night before and having received a total of 90 minutes sleep (0230-0400) before heading to the airport bound for Sydney on a 0530 (GMT +1000) flight. Since my spatial ability is generally proportional to the quality of my sleep, I have had to memorise much of the latter part of day 1 of APLAS ‘06 - ready for processing at a later date - batch processing if you will :)
There were some excellent presentations - all of extremely high quality - and more than expected in my specific areas of interest. There seemed to also be a pre-requisite understanding of the Haskell programming language and much of the theory behind it, which was also great to see, since it allowed some presentations to go into great detail about various topics. The invited presentation scheduled for 0930 (GMT +11) was given by Professor Peter Stuckey titled, Type Processing by Constraint Reasoning. It is in this talk that I learned of a project titled, Chameleon, which goes about providing a rich set of information for type errors. Professor Stuckey also seemed to highlight the common misunderstanding that comes with a type error as being interpreted as “something is wrong” with the correction “at least one of two things went wrong, since you have at least one contradiction that cannot be resolved” - at least, this is my translation of his emphasis. I think this distinction is extremely important and I applaud anyone who sets about making it. I won’t continue paraphrasing what appears to be a massive amount of work in understanding and then implementing an artifact of Type Theory, so if you have a chance, I encourage anyone to take a look at the paper.

It is also during this presentation that I learned of Helium for teaching Haskell to beginners. I have yet to take a detailed peek at Helium, but since I have an interest in teaching at the tertiary level as well as “weaning people of the mainstream guff”, I have hopes that Helium can be an extremely useful tool in achieving my objectives.

Have you ever wanted to do this?

Tuesday, November 7th, 2006

You’re working away on your Java (or .NET for that matter) project and you want to redefine the equality for some type; let’s say, for a String. The new requirement mandates that two Strings are “equal” as per usual except that if they have a length greater than or equal to 3, then it is only the first 3 characters that need to be equal for the Strings to be equal. For example:

  • “abcdef” and “abcxyz” are equal
  • “abc” and “abcdef” are equal
  • “ab” and “abc” are not equal
  • “ab” and “ab” are equal
  • “” and “a” are not equal
  • “” and “” are equal

Make sense so far? Good! :) If our problem was related to the ordering of instances of our type, we already have Comparator in the core API to cater for this scenario and best of all, the collections supports the use of our comparing strategy e.g. we can pass an instance to the constructor of TreeSet. However, our problem is related to testing for equality, not ordering. How would the analogous Comparator interface look for equality? How about this:

interface Equalable<T> {
    boolean isEqual(T t1, T t2);
}

It’s too bad the collections don’t support this type, ain’t it? We can’t plug in our own strategy for testing for equality like we can for comparing for order if we intend on using collections. Instead, the only way we can meet our requirement and still use collections (or anything that uses the inherent equals method) is by declaring a new type:

public final class XString
{
  private final String str;
 
  public XString(final String str) {
    this.str = str;
  }
 
  public String getStr() {
    return str;
  }
 
  public boolean equals(final Object o) {
    ...
  }
}

Now we can have collections of this type as it defines its own equality test strategy in accordance with our original requirement. What if the collection types allowed you to pass an instance of Equalable instead? Much easier than having to write our XString type!? Instead of having to create the XString type, we might be creating HashSet instances like so new HashSet(new MyEqualable()); and be done.

Let’s take a look at how this would look in another programming language - with Haskell - a purely functional programming language. In Haskell, we have the same two choices, we might implement the type-class Eq or we might pass a first-class function of type a -> a -> Bool

newtype XString = XString String
 
instance Eq XString where
  ...

Now, if we had a function of type a -> b [see note 1] and that function needed a strategy for equality over the type a to evaluate, we have two choices:

  1. we could bound the parameter by the Eq type-class, which would look like so as a function definition Eq a => a -> b and reads as “takes an argument of type a, where a is bound by the type-class Eq, and evaluates to an unbound type b”
  2. we could leave the parameter a unbound and pass a function as an argument. This function would be of type (a -> a -> Bool) and would define the strategy for determining if two a’s are equal. Thus our entire function definition would look like so (a -> a -> Bool) -> a -> b where we see that a is not bound by any type-class i.e. it is unbound.

Back into Java land… these two options in Haskell can be likened to java.lang.Comparable and java.util.Comparator. Suppose now you have a reference of type Set and you wish to call an existing method of type m(Set). It is only sensible that you are able to call this method, since (let’s assume) it has nothing at all to do with the only differentiator between the two types - the strategy for determining equality. Gotta write a new type right?

Now, since this is my first blog post ever, I reserve the right to throw out some incredibly bold and apparently absurd postulations :). Since such a simple requirement mandates the creation of so much code to fulfill accurately, I postulate, with more formal reasons forthcoming, that approximately 99.9999% of the content of the J2SE API Specification [see note 2] is a result of this problem that is inherent in a language such as Java with a substandard type system. I might name this problem, “Gotta write a new type, right?” for future reference and just to take the piss out of the dominant programming language(s) of our evolving [see note 3] industry. So that’s its name, OK? Great.

I do not envy you oh Senior J2EE Architect/.NET Super-duper Spanky Star (what do they call those anyway?).

[1] This can be read as “takes an argument of type a and evaluates to a type b where a and b are both polymorphic and unbound”. The analogous Java is:

interface I<a, b> {
  b f(a arg);
}

[2] The “thing” (monolithic abominable creature?) that I used to laboriously implement for IBM http://java.sun.com/j2se/1.5.0/docs/api/

[3] I must have backspaced 50 or so times before finally settling on the conservative adjective, “evolving” :)