Thursday, April 28, 2011

New XPath functions to get a control's current label, help, hint, or alert

In XForms 1.1, a control's label, help, hint, or alert (or LHHA as we call them at Orbeon) can read its value from data, in particular using the ref attribute. But the converse is not possible: for example if a control has a given label, you cannot figure out the value of that label from an XPath expression.

So we have just implemented in Orbeon Forms the following convenient functions:

Usage is very simple. In this example, when the user presses the button, the current value of the label is displayed in a message:


This raised a small design question: is it better to write xxf:label('id'), or xxf:lhha('id', 'label')? We have opted for the former, which is more explicit and better typed. Also, it doesn't seem like many more similar control properties will be added in the future.

The functions are also documented on the Orbeon Forms wiki.

For the curious, the implementation of these 4 functions is really simple in a single short Scala class, and it plugs very nicely into the Saxon XPath engine:

Note the uses of:

  • pattern matching: case control: XFormsControl if control.isRelevant =>
  • a nested function: evaluateControlItem is local to evaluateItem
  • first-class functions: XFormsControl.getLabel, etc. are passed as a parameter to evaluateControlItem
In this case, the implementation would probably not have been outrageously different in Java: we would have used if instead of match, a private method instead of a local function, and passed one of the LHHA values to that private method instead of passing functions around.

Tuesday, April 12, 2011

The beauty of Scala's Option/Some/None

Here is a simple feature of Scala that is worth gold.

Take this Java method:
Foo computeFoo() { … }
The implementor of this method may well return an actual object of type Foo, but may also return null.

Usually returning null tells the caller, "well I know I am supposed to return a Foo, but here I just can't return one, so here is null instead, and you deal with it".

There is nothing really wrong with that: there are just cases where you reasonably cannot return a value and need to tell that to the caller.

The issue is that just by looking at the method, you don't know if it can return null. You have to look at the documentation for the method, or its implementation.

Because of this, the caller will often place null checks all over the place, maybe as part of a "defensive programming" strategy. And then, what do you do if the value is null? You have to think about what's reasonable. If the method never actually returns null, it was all a waste and it clogs the code.

If like us you have been burned for 20 years or more with languages that use this kind of paradigm (from C to C++ to Java to JavaScript and others), you might think that this is just a normal way of doing things.

But as a new Scala programmer, you suddenly realize that it is not! And Scala has a nice solution to this problem: the Option class.

In Scala, if you know the method might not return a value, you would write it this way instead:
def computeFoo: Option[Foo] = { … }
Notice the "Option of Foo" return type.

As a user of the function or method, by looking at this function, you know that it may not always return a Foo. So what does it return? This is better shown with pattern matching:
computeFoo match {
  case Some(foo) => … // got a Foo, do something with it
  case None => … // did not get a Foo, deal with it
}
The beauty is that you know that you don't need to do this for methods and functions that do not return an Option. If the method above always returns a value, you would write it in a way very similar to the Java way:
def computeFoo: Foo = { … }
Here, in good Scala land, the caller can assume that the function returns a value, avoid null checks, and gain clarity and confidence in the process.

And of course Option can also be used for parameters to functions, not only as function return values.

Now there is a twist: Scala, I assume for compatibility with the Java ecosystem, also supports null. So nothing actually prevents these methods from returning a null. It's just considered bad practice to do so and to not use the Option/Some/None trio. And if you are calling Java methods, those typically will return null as that is the convention in Java.

But for pure Scala libraries (including the standard Scala library), Java libraries with proper Scala wrappers, and of course your own Scala code, the use of Option/Some/None is the rule and life is good :)

Tuesday, April 5, 2011

From Java to Scala

Believe it or not, there was a time when Java was cool!

But obviously this is no longer the case. Language features and syntax matter, and while Java still rocks because of its rich ecosystem of libraries and its VM, the Java language itself has stalled (Java 7 adds a few welcome but very minor improvements only).

As a programmer, you want to use the best tools at your disposal, and Java-the-language is no longer such a tool, nor is it likely that it will ever be again. It is missing crucial features that you can take for granted in many mainstream languages today, including closures, functional aspects, and much, much more.

Now if you are going to move from Java to another language that runs on  the JVM, Scala is an obvious choice as it is was designed to be interoperable with Java. There are other options like JRubyClojure, and others, but they are bigger departures from Java (e.g. Ruby is a dynamic language while Clojure is a Lisp dialect). 

So last summer we decided to experiment and use Scala to implement the XForms engine's XPath dependency system. The experience has been positive, and since then we have been using more and more Scala in Orbeon Forms.

The net result so far: we are happier programmers and we care and feel excited about writing (and talking about!) code again!