warpedjavaguy

Imperative by day and functional by night

Archive for the ‘programming’ Category

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

Polymorphism by Closure Injection?


Instead of defining many classes to do the same thing differently through polymorphism, you could define just one class and achieve the same through closure injection!
 

I recently downloaded the feature complete BGGA closures prototype and had a bit of a play. My first experiment was to refactor an existing codebase and replace all anonymous inner classes with closures. The ones that extended single abstract method (SAM) interfaces were easy to convert. The ones that extended multiple method (non-SAM) types were a bit trickier. In the end though, I managed to successfully convert all of them, and with very little effort.

In converting the non-SAM types, I discovered that the functional equivalent of polymorphism can be achieved by injecting closures into a single concrete implementation having no subclasses.

The codebase I refactored was a small (fictitious) railroad application that provided customers with information about routes. In particular, it calculated things like the number of routes between two cities, the number of routes that do not exceed a given number of stops, the distances of individual routes, and the like. It did this by deriving routes on the fly from a given set of legs and dynamically yielding only those that match a given predicate (or condition).

Here is the original predicate code using anonymous inner classes:

public abstract class Predicate<T> {

  public boolean eligible(T item) {
    return yield(item);
  }

  public abstract boolean yield(T item);

  /* Pre-defined predicates follow */

  public static Predicate<Route> routesWithMaxStops(final int maxStops) {
    return new Predicate<Route>() {
      public boolean yield(Route route) {
        return route.getLegs().size() <= maxStops;
      }
    };
  }

  public static Predicate<Route> routesWithStops(final int stops) {
    return new Predicate<Route>() {
      public boolean eligible(Route route) {
        return route.getLegs().size() <= stops;
      }
      public boolean yield(Route route) {
        return route.getLegs().size() == stops;
      }
    };
  }

}

In the above code only two predefined predicates are shown for brevity (the actual code has got more).

Note that the predicate has two methods. Only routes for which both methods return true are yielded.

  • eligible – determines if a route satisfies a boundary condition
  • yield – determines if a route should be yielded

Here is the converted closure equivalent:

public class Predicate<T> {

  private {T => boolean} eligible;
  private {T => boolean} yield;

  public Predicate({T => boolean} yield) {
    this(yield, yield);
  }

  public Predicate({T => boolean} eligible, {T => boolean} yield) {
    this.eligible = eligible;
    this.yield = yield;
  }

  public boolean eligible(T item) {
    return eligible.invoke(item);
  }

  public boolean yield(T item) {
    return yield.invoke(item);
  }

  /* Pre-defined predicates follow */

  public static Predicate<Route> routesWithMaxStops(int maxStops) {
    return new Predicate<Route>(
      {Route route => route.getLegs().size() <= maxStops});
  }

  public static Predicate<Route> routesWithStops(int stops) {
    return new Predicate<Route>(
      {Route route => route.getLegs().size() <= stops},
      {Route route => route.getLegs().size() == stops});
  }

}

If you look carefully, you will notice that both the original and converted code produce a redundant invocation when the eligible and yield expressions are identical. Fortunately, this is a flaw that can be very easily corrected in the closure version.

A possible correction is shown below (see lines 5, 17, 18, and 22):

public class Predicate<T> {

  private {T => boolean} eligible;
  private {T => boolean} yield;
  private boolean isEligible;

  public Predicate({T => boolean} yield) {
    this(yield, yield);
  }

  public Predicate({T => boolean} eligible, {T => boolean} yield) {
    this.eligible = eligible;
    this.yield = yield;
  }

  public boolean eligible(T item) {
    isEligible = eligible.invoke(item);
    return isEligible;
  }

  public boolean yield(T item) {
    return (isEligible && eligible == yield) ? true : yield.invoke(item);
  }

  /* Unchanged pre-defined predicates not shown here */

}

Applying the same correction to the original closureless version is not nearly as simple. It would require a more complex solution and could even involve changing the interface.

It is very interesting that polymorphic functionality can be achieved by injecting closures into one concrete class instead of defining multiple subclasses of an abstract class. Closures and anonymous inner classes, injection and inheritance, deferred execution and late binding. So many great choices!

Written by warpedjavaguy

September 4, 2008 at 11:31 pm

Posted in java, programming

Tagged with

%d bloggers like this: