Thursday, November 22, 2012

Graham Now Hacking Scala at GrahamLea.com

This is just a quick post for people who've been following 'Graham Hacking Scala' to let you know that I am now blogging - often about Scala but sometimes about other stuff - at www.grahamlea.com Hope to see you there! Graham.

Friday, January 20, 2012

JavaScript and Scala: Good Parts and Bad

I've just finished reading "JavaScript: The Good Parts" by Douglas Crockford. It's a fantastic book, mostly because it's incredibly concise, elaborating only the details that experienced programmers should need to understand the true form of JavaScript. If you do ANY JavaScript programming and you haven't read it, I suggest you go out and get it straight away, and don't write a single line more of buggy JS code until you do.

What is 'this'?
Early on in the book, Crockford highlights one of JavaScript's oddest and most dangerous quirks: the late binding of 'this'. Basically, whenever you call a function, the value of 'this' within the function is determined by HOW you called the function!

To demonstrate: If object 'a' has a function called 'run()' and you invoke it like this:
a.run();
then the value of 'this' within 'run()' will be 'a'. JavaScript is a functional language, so functions can be passed around as values. If you instead invoked the function above using only a reference to the function value, like this:
var f = a.run;
f();
then the value of 'this' within 'run()' will be... the global variable pool! As you can imagine, that can lead to some pretty nasty and hard to track bugs.

Functional Limitations
 If you're a fan of functional programming, you might have tweaked straight away that this could place limits on the usefulness of functions as first class objects, and specifically higher-order functions (i.e. functions that take other functions in their parameters).

Here's an example of an object that doesn't work with higher-order functions:
var object1 = {
    total: 0,
    add: function(numbers) {
        var i;
        for (i = 0; i < numbers.length; i++) {
            this.total += numbers[i]
        }
        return this.total;
    }
};

var valueOf = function (f, p1) {
    return f(p1);
}

var numbers = [1, 2, 3, 4];

document.writeln(object1.add(numbers) + " / " + valueOf(object1.add, numbers));
// outputs: 10 / NaN
Obviously the reason this quirk causes confusion is because JavaScript has borrowed a keyword from other languages but uses it to mean something subtly different. Most OO languages use 'this' to represent a pointer to an object in which the function seemingly resides. Importantly, in OO/functional languages, when a function is used as a value, it takes with it a closure around 'this' that is used when invoking it. In JavaScript, however, the 'this' pointer just refers to the object on which the function was called, or if there was no object, just to the global variable pool.

This Naughtiness Explained
There is a reason for this weirdness. Because JavaScript is classless, the function doesn't actually belong to the object in which it resides. In fact, it's not hard to imagine situations where JavaScript's behaviour is what you'd expect. If I took a function from one object and placed it in another object (which I can do, because the function is also a value), I actually would expect 'this' to refer to the new object when I invoked it, and JavaScript provides just that capability:
var b = {};
b.run = a.run;
b.run(); // 'this' will refer to 'b'
Once you understand where JavaScript is coming from a bit better, it's not too hard to see the solution to this problem. 'this' doesn't provide a closure around the context where your function was defined, so if you want a closure around the context where your function was defined, then give your function a closure around that context, rather than assuming that 'this' will be the same context whenever the function is invoked. To demonstrate this by correcting the example above:
var object2 = (function () {
    var that = {};
    that.total =  0;
    that.add = function(numbers) {
        var i;
        for (i = 0; i < numbers.length; i++) {
            that.total += numbers[i]
        }
        return that.total;
    };
    return that;
})();

document.writeln(object2.add(numbers) + " / " + valueOf(object2.add, numbers));
// outputs: 10 / 20
Scala: The Bad Parts?
 Does any of this have anything to do with Scala? Well, in the details, no, but in the general sense there is a very important approach in Crockford's book. His suggested solution to the problem above is simple: don't use 'this' in JavaScript and don't use its accompanying feature, 'new'. In fact, he suggests not using LOTS of features of JavaScript. He dedicates 14 pages of appendix to listing them.

Crockford also spends a very un-indulgent two pages discussing the modern phenomenon of "feature-driven design", both in products and programming languages, explaining how "Features that offer value to a minority of users impose a cost on all users" and concluding the book with this pearler: "It would be nice if products and programming languages were designed to have only good parts."
It was those two lines that caused me to reflect on Scala. I started asking myself questions like: Are there too many features in Scala? Are there parts that aren't "good parts"? Are there features that very few people make use of but that cost everyone because of the complexity they add? From my own experience, the answer to all three of these is "yes".

Crockford explains that we all crave simplicity and that, when we aren't given it, we make it for ourselves by creating our own feature subset, and I realised that I've done this to some extent in the way I use Scala. So finally I began wondering how long it will be until someone publishes "Scala: The Good Parts", complete with appendices listing all the features that you should steer clear of for everyone's sake. What confusing or dangerous feature of Scala do you reckon will be at the top of the list?

Want to learn more?

From Amazon...

From Book Depository...

Sunday, January 8, 2012

Updates to Scala/Spring/Hibernate/Maven Webapp

One of the projects I maintain is a public domain code base on GitHub called Scala-Spring-Hibernate-Maven-Webapp. The repository contains source code for kickstarting your own webapp project using the latest versions of Scala, Spring Web, Hibernate and Maven.

Project Updates
I've been committing some major changes over the last couple of weeks, including:
  • Upgrading to Scala 2.9.1, Spring 3.1.0 and Hibernate 4.0.0 
  • Adding to the existing REST-ful Create and Retrive examples some Update and Delete operations 
  • Adding server-side form validation using JSR-303 annotations with Spring Web MVC 
  • Creating examples of automated web testing using Selenium WebDriver and the PageObjects pattern
 If you're about to start your own project with these technologies, or are just keen to see how they all work together, you can get your own copy of the source code from here:
https://github.com/GrahamLea/scala-spring-hibernate-maven-webapp

Resolved Issues
I encountered a couple of time-consuming issues during the upgrades to the latest versions and I think it would be worth sharing how they were resolved in order to save some time for others googling for solutions to the same problems.

Spring Schema SAXParseException
After upgrading the versions of all the Spring Schemas in my Spring XML files, I started getting the following error while trying to start up the webapp:
org.xml.sax.SAXParseException: cos-all-limited.1.2: An ''all'' model group must appear in a particle with '{'min occurs'}'='{'max occurs'}'=1, and that particle must be part of a pair which constitutes the '{'content type'}' of a complex type definition.
At first this appears to be a bug in the Spring schema, but a bit more investigation revealed that it is, in fact, a bug in an old version of the Xerces XML parser library. In my case, an old version of the library was being pulled in through commons-dbcp. The solution I took was to explicitly add a dependency on the latest version of Xerces:
        <dependency>
            <groupId>xerces</groupId>
            <artifactId>xercesImpl</artifactId>
            <version>2.9.1</version>
            <scope>runtime</scope>
        </dependency>

Hibernate Function Not Supported
After upgrading Hibernate to 4.0.0, I started getting this error message whenever I tried to execute a query:
org.hibernate.exception.GenericJDBCException: This function is not supported
Caused by: java.sql.SQLException: This function is not supported
I don't remember whether HSQLDB appeared in the stack trace or not, but the solution to this was to upgrade the version of HSQLDB I was using from 1.8.0.10 to 2.2.6. If you get the same error and you're not using HSQLDB, I would suggest considering an upgrade of your JDBC driver or maybe even your database server.

"No Session found for current thread" 
Also after upgrading to Spring 3.1.0 and Hibernate 4.0.0, and after changing all my Hibernate 3 Spring beans to the corresponding Hibernate 4 versions, I started getting the old classic "No Session found for current thread" error when trying to view any page with a transaction. I thought this was very odd, because the traditional solution to this has always been to make sure you have an OpenSessionInViewInterceptor, but I already had one, defined like this:
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
        <property name="interceptors">
            <list><ref bean="openSessionInViewInterceptor"/></list>
        </property>
    </bean>
By pure chance, I'd seen a Spring documentation page earlier the same day where I'd noticed an alternative way of declaring interceptors using the 'mvc' namespace:
    <mvc:interceptors>
        <ref bean="openSessionInViewInterceptor"/>
    </mvc:interceptors\>
Replacing my old DefaultAnnotationHandlerMapping definition with the one above got my OpenSessionInViewInterceptor working again and solved the "No Session found for current thread".

No Appenders for Log4J
Finally, this one is a bit silly, but I spent a good half hour on it without finding any good help on the web so I thought it was worth documenting. At some point I started getting this error out of Log4J every time I started my webapp:
log4j:WARN No appenders could be found for logger
After all kinds of googling, experiments with winding back dependency upgrades and investigations into ClassLoaders, I eventually noticed that I just had a typo in the Log4J configuration file:
og4j.rootCategory=INFO,Console
Notice the 'l' missing at the start of that line? Ouch. So if you're getting this error message about no appenders and you think your log4j config is all set up properly, check whether the config for your root category is correct before investing too much time in breakpoints inside Log4J classes.

Want to learn more?
Here's some books you might find useful if you plan to go further with Spring, Hibernate, Scala or Maven:
From Amazon








From The Book Depository

Spring in Action - Craig Walls & Ryan Breidenbach (Manning)

Hibernate in Action - Gavin King & Christian Bauer (Manning)

Spring Recipes - Gary Mak (Apress)

Programming in Scala - Martin Odersky, Lex Spoon & Bill Venners (Artima)

Maven - A Developer's Notebook - Vincent Massol & Timothy M. O'Brien (O'Reilly)

Tuesday, December 20, 2011

SodaTest 0.2.1 Released


I've just released the second milestone of SodaTest, the spreadsheet-driven integration testing framework.
A significant change with this release is that SodaTest is now available from the Maven Central repository. You should be able to access the latest versions of all SodaTest artefacts from Maven Central right now as org.sodatest : sodatest-* : 0.2.1
As well as a couple of small bug fixes, this release incorporates a number a improvements based on feedback from use of SodaTest in corporate environments. The key enhancments were:
  • Coercions can now be created in Java without any knowledge of Scala
  • Built-in support was added for coercing strings into Java enums
  • An implicit function is available for converting into a Coercion any function with the type: (String) => _
  • A CurrencyAmountCoercion and CurrencyAmountCoercionForJava are now available for coercing a variety of financial value formats into your own custom Currency or Money class
  • Reports no longer report a mismatch due to trailing empty cells in the actual output
  • A bunch of usability fixes such as handling unusual situations, reporting better error messages, correct usage messages, more scaladoc and READMEs.
So, if you've been holding out from using SodaTest wondering if anyone is using it for real, whether it's going to be improved over time, and whether you should even bother trying it out, the answers are yes, yes and yes!
(And in case you're wondering why this release is 0.2.1 and not 0.2, it's because 0.2 got lost in the first, failed attempt to release from Sonatype to Maven Central.)

Thursday, December 8, 2011

Will Typesafe Address Scala Criticisms?

If you've been paying attention to the Scala corner of the web over the last week, you'll no doubt have heard something about Yammer - an enterprise-focussed social network - switching from Scala back to Java.

If you've been on holidays and missed it all, basically what happened was that Coda Hale, the Infrastructure Architect at Yammer, wrote a private email to the Typesafe team giving loads of mostly critical feedback regarding Scala, but the email was subsequently leaked and became the talk of the town, among both Scala supporters, like David Pollak, and critics, such as Stephen Colebourne.


A Painfully Honest Critique

Firstly, let me summarise the main points in Coda's email:

* Yammer have decided to change their "basic infrastructure stack" from Scala to Java.

* The main reason is that Scala has "friction and complexity" that isn't offset by enough productivity gain.

* Some seemingly simple constructs in Scala, e.g. List, actually have very complex interfaces and behaviour that necessitate explaining a lot of concepts to beginners. The belief by some that this complexity can be ignored except by library authors has proven to be false in practice.

* The most vocal members of the Scala online community are generally very academic in their practice and discussion of Scala.

* Existing libraries seem to be being re-written just because people want to practice their use of advanced functional programming concepts, but these re-writes are then being recommended as the library of choice.

* The Yammer team eventually decided the most sensible way to deal with the Scala community was to ignore it.

* Learning Scala properly is important, but doing so is neither quick nor easy.

* Java is not going away, so the choice to use Scala is actually a choice to use Scala and Java, along with the interaction challenges that brings.

* The Yammer team had "endless issues" with SBT, and found themselves writing plugins to replicate Maven functionality.

* Switching to Maven solved most of their problems, but they found it has been marginalised by the Scala community, with poor support and constant encouragement to switch to SBT.

* The backwards-incompatibility of Scala major releases requires library authors to cross-compile,  which has resulted in library re-invention when authors are no longer committed to the project.

* The backwards-incompatibility also causes headaches for developers, which has resulted in many production Scala deployments not being upgraded to 2.9.

* Yammer found idiomatic Scala code performed very poorly. By eliminating for-comprehensions, avoiding Scala's collection library, avoiding closures and marking everything with private[this], they were able to achieve speed ups of 100x in some components.

So that was that. For what it's worth, Coda's email is also quite complimentary of Scala. I think he gives the impression that he likes it and would really like to keep using it, but the realities of making it work in a day-to-day production-deploying team have weighed them down so much that the benefits have been eclipsed.

A Frustratingly Measured Official Response

Not long after Coda's email became public, Typesafe published on their blog what is quite obviously a public response to the email, and it's that blog I'd like to take a closer look at today.

Here are the main points from the Typesafe blog:

* Typesafe are investing in Scala IDE support by contributing to the Scala IDE for Eclipse

* They are addressing the learning curve by developing training courses, but also provided references to some of the free resources on the web.

* 'scalac' is slow because it has more work to do than 'javac', but they are investigating using parallel and incremental techniques to improve speed, with a focus on improving sbt.

* If you don't want to (or can't) upgrade your Scala version, you can purchase commercial support from Typesafe to get access to long-term maintenance releases of previous versions.

* In order to reduce people's major-release upgrade issues, they are planning to fold a bunch of existing libraries into the Scala release .

* They take performance seriously, but are wary of engaging in premature optimisation.

* Typesafe are not just focused on the Scala language and core libraries but also on frameworks to help build applications more easily.

* They describe the Scala community using a couple of niceties as well as the words "opinionated" and "quirky".

* They say there's many places where Scala could be improved and they're hard at work doing so.

* They mention Yammer amongst a group of other companies with successful production deployments of Scala.



What Aren't They Telling Us?

What I think is most interesting about this response is the things it doesn't mention and the places where it's specific about what they're doing to solve issues.

Firstly, there's no mention of Maven. There is some commitment to improving compile times, but they seem to suggest that this will be for sbt users only. It has to be considered odd that Maven has been given so little attention by the chief proponents of Scala. One of the main advantages often cited for adopting Scala is its easy integration with Java, "so you can continue using all your favourite libraries". But the commitment to prolonging the life of people's Java API knowledge doesn't extend to the Java build chain. Should it? Why is Maven important? It's important because it works, and it's almost ubiquitous. It has had years and years of work poured into it and has been tested and improved by feedback from hundreds of thousands of users and plugin developers. It has a global ecosystem that is well understood. It has become a lingua franca; many people would know how to build their project with Maven but couldn't tell you how to build it with javac and jar. If you want to distribute your project to the world through Maven Central via Sonatype's Nexus repository, they've got fantastically detailed instructions for how to do so... with Maven. The Java-fluent world - which Typesafe want to convert into the Scala world - don't need another build tool. We need relatively minor improvements to Maven and its plugins to ensure we can keeping working without having to learn something completely new.

Secondly, Typesafe give no commitment to eliminating the backwards compatibility problems in future major releases. In fact, one of the parts of their workaround - the offering of paid support for people who want to continue using older releases - actually makes it in their interest to not solve the problem. The other half of their workaround - bringing certain libraries into the Scala release - will mean that, as a developer, your backwards compatibility issues will only be solved if your taste in libraries is similar to those of the Typesafe team. If you like a library that hasn't been deemed worthy of inclusion, you'll be left with all the same cross-compiling and "version-x-for-scala-y" dependency issues that you have now.

Thirdly, they seem to fob off Yammer's performance problems as an issue specific to their environment, suggesting that fixing such things for everybody would be "premature optimisation". I've heard this argument before: that it only makes sense for companies like Yammer and Twitter to spend time optimising tiny bits of code because it can save them millions across all their computers. But the same argument applies to small businesses just as well. If my business is growing rapidly, but I have limited cash flow, having a 100x performance increase is going to make a significant contribution to my bottom line if I can serve all of my customers on one machine instead of 100 machines. "Premature optimisation" is a phrase that should be reserved for application developers, not framework developers. Just optimise the hell out of it, please.

Finally: the community. While Typesafe dropped a small comment about the community in its response, its really not an issue that they can solve, though I do think it will greatly effect the measure of their success in the long term. Really, the comments in Coda's email should be a wake up call to the Scala community at large: a sizable Scala software development team, full of very smart people who've written some very scalable and successful software, found the Scala community to be so fractured and unhelpful that they eventually decided to ignore it and, I would assume, not be a part of it. That's not just a loss for the community, but also a warning, because for every developer that finds the community unhelpful and so decides to program Scala in his own microcosm, there will be numerous others who decide to not bother with Scala at all for the same reason. This alone could be a weighty enough issue to relegate Scala to a hobby language in the long term rather than seeing wide-spread adoption in the enterprise community.



Hope and Trepidation

When I originally read through Coda's email I was nodding my head in agreement and hoping that Typesafe would be listening carefully and would take it as an opportunity to shift their focus, maybe just temporarily, but long enough to knock over these major objections. Unfortunately, when I read through Typesafe's response, I didn't see any real hint that they plan to fix the problems that I find most annoying. In some cases I even saw excuses about why they won't be doing anything. I don't think "We're focusing on making sbt better" is  a response to "Why isn't there decent Maven support?". I know they've been meeting with influential Scala teams in the days since this response, I just hope they listen to what they've got to say.

So now I'm left feeling a little unsure about Scala. Will it continue to improve for me and people like me? People who like to use IDEA + Maven, not Eclipse + sbt, who are educated in creating applications rather than composing mathematical proofs? Or is the current state of the art in Scala, along with its broad range of minor but resonating annoyances, what I should expect to still be grappling with in five years time? Only time will tell whether Typesafe can navigate this wave of criticism and find a promised land of general popularity, but I think it is an indication that Scala's window of opportunity has entered the waning phase, and now is the critical time at which to capitalise on the extant interest.

What do YOU think?
Do you sympathise with the Yammer team's frustrations?
Are you confident that Typesafe will listen and respond to current criticisms with relevant and prompt action?