Log in

No account? Create an account


How to Hack Java Like a Functional Programmer

How to Hack Java Like a Functional Programmer

Previous Entry Share Next Entry
I am currently working on a document. It's kind of a manual. Maybe more like a manefesto. But really, it's a collection of the ideas and strategies that I use when writing Java code. As it turns out, many of those ideas and strategies come from my attempts (and the attempts of other's that I have learned) to use Java in a style that is more like functional languages, particularly the ML languages with which I have some experience.

This document is really targetted at people with some Java experience, and some functional experience, but people who would not consider themselves experts. In particular, it's not targetted at academics, or at least not at PL people. But hopefully it may contain some ideas that you find cool.

Part of the reason that I am posting this now rather than after I have completed a first draft is due to my relatively slow progress. I am hoping that if I post what I've got, you guys may give me some feedback and some cooler ideas, and that this enthusiasm will be enough to help me complete this in a reasonable amount of time. That being said, after this post I will not put up any more blog posts until I at least have an entire draft. If you want to wait until then to read, please be my guest.

So without futher ado, the current draft of, "How to Hack Java Like a Functional Programmer" will be posted at the following URL, and will be updated just as often as I work on it until it is complete:
  • (Anonymous)
    That anonymous inner class initializer trick is awesome, I am going to go use it right away.

    --Anonymous Jake Donham

  • I'd like to point out that I am not the author of Hardcore Java, and if I was then it would be way more awesome, recommending that every immutable object implement Throwable so you can at least to case analysis pleasantly.
    • It's true. Actually, after looking at the cover again, it appears that his name is Robert Simmons Jr. That should clear things up.

      Although really, and I hate to break this to you, the book is apparently not so great. It gets pretty bad reviews on Amazon from some fairly articulate reviewers:

      The general theme being, "a.) the book is full of errata and b.) the book is not really hardcore, but medium core at best."
    • It kind of works:

      abstract class Expr extends RuntimeException {
      abstract int eval();

      class Val extends Expr;

      class Add extends Expr;

      static void foo(Expr e) {
      try {throw e;}
      catch( Add a ) {
      catch( Val v ) {

      However, there were two issues. The "coverage checking" didn't quite work out the way that I had hoped. Unless you make Expr extend RuntimeException, you will get a compiler error if you don't catch "Expr" itself. In other words, it is not enough to catch every subtype of Expr, because of course with Java's type system you can always add new subtypes.

      Then, I am forced to make Expr an abstract class rather than an interface, as I'd prefer, because Expr itself must be some subclass of Throwable.
      • Well I guess Python is better for this particular travesty, then. Support for :? style stuff is really a no-brainer:
        static void foo(Expr E) {
          match e with 
            | :? Add -> e.getE1;
            | :? Val -> e.getVal();
        ...and I think all the fuss over Active Patterns (which are cool) obscures this point.
  • why aren't maps amenable to the varargs trick? couldn't you pass in a variable number of pairs, adding each one to the map, just like you did with lists?
    • Hmm... good point. I'll probably add this. Here's what I cooked up:

      static <K,V> Map<K,V> mapMe(Pair<K,V>... pairs) {
        Map<K,V> result = new HashMap<K,V>();
        for( Pair<K,V> pair : pairs) {
          result.put(pair.getP1(), pair.getP2());
        return result;
      static void useMapMe() {
        Map<Integer,String> myMap = mapMe( Pair.pairMe(1, "Nels"),
                                           Pair.pairMe(2, "William"));		

      This does have one problem though; it returns a Java Generics warning at the use of mapMe, "Type safety : A generic array of Pair<Integer,String> is created for a varargs parameter."
      • (Anonymous)
        Wait, type safety is a warning?!

        --Anonymous Jake Donham
        • ;-)

          Yeah, due to the desire for backward-compatibility (code that compiled under Java 1.4 should still compile under Java 1.5) many of the type errors related to Java generics are warnings and not errors. You'll still get errors if you, for example, try to put an Integer into a List<String>. That's good. But, for example, if I explicitly cast a List to a List<String>, I will get a type safety warning.

          Then there are a bunch of weird rules involving generics and arrays. I don't understand them all, but this appears to be one of them.
Powered by LiveJournal.com