Dec 27

Now that we have covered the somewhat “dry” foundations of the Scala language, let’s move on to the good stuff. That is to say, let’s move on to the functional aspects of Scala. Some of these may appear foreign to you if your main language is object-oriented or procedural. They definitely appeared foreign to me at first. It cannot be stressed enough that functions are primary language constructs in Scala. I mentioned function literals. Here is an example:

(x: Int) => x - 1

A function literal is simply a function without a name. You can assign this expression to an ordinary variable and then use it later to execute the function:

1
2
var decrease = (x: Int) => x - 1
decrease(11)

You can probably guess what the value of decrease(11) is. Up to this point, this isn’t very exiting. However, because decrease is a var and not a val, you can reassign it a different function literal later on depending on some condition. Or you could pass it as an argument to another function. You might begin to see the possibilities behind the first class function concept. Instead of the trivial example above you can use this capability with more complex methods. For example, you could use it for callback methods, or for wrapping methods in an API and facilitating common OOP patterns, such as the facade and adapter patterns. All of this can be done, unlike in Java, with a minimum of syntactical fuss.

But it gets even better. Functions in Scala are not limited to use simple parameters as in the above example. For example, you could write something like this:

var decrease = (x: Int) => x – something

Obviously, the variable something, which is subtracted from x is not defined in this expression. The assignment is still syntactically valid. This means the variable decrease is properly defined, but it cannot be applied. In other words, to apply a value or to execute the function meaningfully, it must be executed in a context where something is defined. The above expression is an “open term” and something is called a “free variable”. An open term is the principal ingredient of a closure. Simply put, a closure closes an open term by providing the necessary context. This is an example of a closure:

1
2
something = 10
decrease(100)

The first line defines the free variable something. The second line therefore produces a meaningful value. That’s the closure. In terms of computer science, a closure is a function that is evaluated and whose result depend on an outer context. It’s like an inner class in Java that references variables of its outer class. However, the Scala construct is more powerful and much easier to write. It can be useful in a number of situations where the place where behaviour is defined is removed from the place where the behaviour is applied.

While closures are supported by languages that one wouldn’t consider functional programming languages, higher-order functions are a hallmark of the functional paradigm. The concept is simple enough. A higher-order function is a function that either takes one or more function parameters or returns a function, or both. The prime example would be the map function. The map function takes an list as input and produces an output list using a specific algorithm. The algorithm is of course represented by another function that is passed as a parameter to the map function. In Java, this would typically require a the use of a for loop or an iterator. In Scala, the mapping can be expressed succinctly with a single line. Here are some examples:

1
2
3
4
5
6
7
8
9
10
scala> List("alpha", "beta", "crash").map(
  p => p.substring(0,1))
res0: List[java.lang.String] = List(a, b, c)
 
scala> List(1, 2, 3) map (_ * 2)
res1: List[Int] = List(2, 4, 6)
 
scala> List("Tango", "Mango", "Bobo", "Gogo")
    map (_.endsWith("go"))
res2: List[Boolean] = List(true, true, false, true)

These examples are quite trivial, but they illustrate the basic idea of higher-order functions. The first line maps a list of strings to another list of strings. The result elements retain only the first characters. The second line is produced by the interactive Scala Interpreter; it displays the result of the expression. A function literal is used as the parameter of the map function in line 1. Line 5 and 9 make use of the underscore notation which is a placeholder for the bound variable, which is the list element parameter in this case. Thus (_*2) is equivalent to (i => i * 2).

Higher-order functions are not just a succinct form of control abstraction. They are also very useful for reducing code duplication and redundancy. The typical use case is abstracting behaviour. There are a number of design patterns for abstracting behaviour which are popular in languages like C++ or Java, such as the strategy pattern. Consider the following Java example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.io.*;
import java.util.*;
 
interface FileNameMatcher {
  boolean matchFileName(String fileName, String query);
}
 
class FileNameMatcherEnding implements FileNameMatcher {
  public boolean matchFileName(String fileName,
    String query) {
    return fileName.endsWith(query);
  }
}
 
class FileNameMatcherContaining implements FileNameMatcher {
  public boolean matchFileName(String fileName,
    String query) {
    return fileName.contains(query);
  }
}
 
class FileNameMatcherRegex implements FileNameMatcher {
  public boolean matchFileName(String fileName,
    String query) {
    return fileName.matches(query);
  }
}
 
public class FileMatcher {
 
  public static String[] filesMatching(FileNameMatcher
    fileNameMatcher, String query) {
    File[] files = new File(".").listFiles();
    List<string> matchResult = new ArrayList<string>();
    for (File thisFile : files) {
      if(fileNameMatcher.matchFileName(
        thisFile.toString(), query))
        matchResult.add(thisFile.toString());
    }
    return matchResult.toArray(new String[] {});
  }
 
  public static void main(String[] args) {
    String query = args[0];
    String[] matchingFiles;
    matchingFiles = filesMatching(
      new FileNameMatcherEnding(), query);
    matchingFiles = filesMatching(
      new FileNameMatcherContaining(), query);
    matchingFiles = filesMatching(
      new FileNameMatcherRegex(), query);
  }
 
}

This is a classic example of the strategy pattern. The core piece of this code is the one-method interface named FileNameMatcher. This interface abstracts different ways to match a file name. The three implementing methods match a file name either by looking whether a file name ends with a given string, whether it contains a given string, or whether it matches a regular expression. The filesMatching() method of the FileMatcher class takes a strategy implementation and applies it to a list that contains all files in the current directory. Finally, the main() function calls the FileMatcher with the three different strategy objects that were defined earlier. All together that’s 55 lines of Java code. Compare this to the Scala equivalent which appears in the book Programming in Scala by Odersky, Spoon and Venners (page 199):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
object FileMatcher {
 
  private val filesHere=(new java.io.File(".")).listFiles
 
  private def filesMatching(matcher: String => Boolean)=
    for (file <- filesHere; if matcher(file.getName))
      yield file
 
  def filesEnding(query: String)=
    filesMatching(_.endsWith(query))
  def filesContaining(query: String)=
    filesMatching(_.contains(query))
  def filesRegex(query: String)=
    filesMatching(_.matches(query))
}
 
object Main {
  def main(args: Array[String]) {
    val query = args(0);
    var matchingFiles = FileMatcher.filesEnding(query)
    matchingFiles = FileMatcher.filesContaining(query)
    matchingFiles = FileMatcher.filesRegex(query)
  }
}

Brevity is the soul of wit. Obviously, there is no need to create strategy objects in Scala. With higher-order functions, the strategy pattern simply evaporates. This is one of the areas where Scala’s powerful language constructs eliminate the need for patterns. Critical voices have said that design patterns are crutches for weaknesses in certain programming languages. Although I don’t fully agree with this statement, it seems to hold true in case of the strategy pattern. The above Scala example is actually more verbose than necessary. One could make the filesMatching() method public and call it directly with a function parameter from outside the FileMatcher object. At the cost of full encapsulation, this would make the code three lines shorter.

Share and Enjoy:
  • Digg
  • del.icio.us
  • Technorati
  • Facebook
  • Mixx
  • Google
  • YahooMyWeb
  • Slashdot
  • LinkedIn
  • blogmarks
  • Live
  • description
  • StumbleUpon
  • Ma.gnolia
  • MisterWong
  • NewsVine
  • Reddit
  • Spurl
  • Yigg
  • E-mail this story to a friend!
Dec 15

I have a bit of a dilemma with programming languages. Next year, I expect to be able to free up a little extra time for a private programming project (call me an optimist!) and I am wondering which language/technology to use. The project is quite straightforward. It’s a business application that I use for my own work as a software engineer. It consists of four components. There’s a contact manager component (or CRM as it’s now fashionably called), a project management component, a time tracking component, and a billing component. That may sound like a tall order, but obviously I don’t need the full-blown functionality of applications like Siebel, MS Project, or SAP. I just need an application that brings certain functionality together in a quite specific way to suit my needs.

The software I am currently using for this purpose consists of two different programs. The CRM and billing components are contained in a Delphi application which I wrote more than 10 years ago. The time sheet and project management components are part of a PHP application that I developed in 2002. Needless to say that these two programs are neither cutting-edge, nor are they well integrated. The Delphi application uses an outdated Borland Paradox DB  and the PHP application contains large swathes of ugly procedural code. Although the whole shebang fulfils its purpose, I feel it’s high time for a replacement. Of course, I could acquire an existing software package and save a lot of time writing code myself. But hey, I am a software engineer. I do like a creative challenge and I want something that fits my needs. I also want to learn new technologies.

The question I am asking myself now is what to use for the task. I am considering Java, PHP, and Scala. There are pros and cons for each of these:

(1) Java, JSP and a web framework with an app server. This is the obvious choice. Most of my professional work is JEE-based these days. I believe that I can work productively with Java, although the language inevitably involves a lot of boilerplate code and redundancy, which has a negative impact on productivity. In spite of this, it would be an good opportunity to deepen my knowledge of JSF (Java Server Faces), Hibernate, or try out some other persistence layer. It would also offer an opportunity to learn a new Java web framework that I haven’t yet worked with such as Spring or Tapestry. From a business point of view, this may be a good choice because Java technologies are in high demand and it is also a very robust platform. The JEE universe is really quite large and there’s enough territory that would be fun to explore. The downside is that Java, the language, is slightly tedious.

(2) The second choice is PHP and the Zend framework in combination with some AJAX toolkit, such as YUI or Dojo. I have the feeling this would be the most productive way to go; the biggest bang for the buck so to speak. For a project of this size (around 50 kloc), the development time may be even half of that with Java. PHP 5 and the Zend framework are mature technologies and I am quite familiar with both. Another advantage of PHP is that it’s wide spread. Almost every hosting company offers PHP, whereas the number of Java hosting companies is considerably smaller (and usually more expensive). So, there wouldn’t be any problem hosting the finished product anywhere. The downside is that PHP, being a dynamic language, is less robust  and slower than JVM bytecode. The language is also less expressive. But the biggest disadvantage is that I’d hardly learn anything new in the process.

(3) The third alternative is using Scala in combination with the Lift framework and a standard web container. I find this the most exciting choice, but it’s very likely to be the most time consuming. I am rather new to Scala and functional programming. What I have seen so far is great. Programming in Scala is much more fun than coding in Java or PHP. I am afraid though, it would take a bit of time to wrap my head around it and work productively. Scala is still a foreign language to me. Another downside is that there is a limited choice of frameworks, APIs, and tools available at this point. Actually, Lift is the only Scala web framework I know of. Another question I am asking myself is whether acquiring Scala skills does make any business sense. I haven’t seen too many Scala job offerings so far. Seems like the most fun choice, but also the least promising from a business point of view.

Decisions, decisions, decisions…

Share and Enjoy:
  • Digg
  • del.icio.us
  • Technorati
  • Facebook
  • Mixx
  • Google
  • YahooMyWeb
  • Slashdot
  • LinkedIn
  • blogmarks
  • Live
  • description
  • StumbleUpon
  • Ma.gnolia
  • MisterWong
  • NewsVine
  • Reddit
  • Spurl
  • Yigg
  • E-mail this story to a friend!