Sunday, August 30, 2009

Groovy Console App and WIDE

In April 2008, I blogged about the WIDE: web-enabled IDE. I wondered if web tools might augment some of the standard stuff available in the IDEs.

(I realize many have 'scratchpads' but I wanted something more. Also, by environment, I don't mean a single app).

In particular, I've thought about a website dedicated to string and regex utilities. Whenever I find myself writing a little script to parse a data string, or to toy with a regex, I always think "there must be a better way".

Well, we're one huge step closer: check out the Groovy Web Console, by Guillaume Laforge.

It laughs at basic string utilities:

def s = "does this string fit into a 32-char column?"
println s.size()
And provides a test-bed for regular expressions:

(Note, this is a Java-Groovy hybrid. It's only somewhat 'Groovy'. Making it Groovier is left to the reader)


import java.util.regex.Pattern

def s = "1 - 314-867- 5309"
def p = Pattern.compile(/.*1.*(\d\d\d).*(\d\d\d).*(\d\d\d\d).*/)
def m = p.matcher(s)
if (m.matches()) {
println "area code = ${m[0][1]}"
println "exchange = ${m[0][2]}"
println "digits = ${m[0][3]}"
}

Count me in... I'm definitely going to have this site at hand in my environment.

The IDE is a Browser: Neuroscience and Language Design

Lizard Brain Web Design

Last winter, I saw a great talk by Scott Davis called "Lizard Brain Web Design". The theme was to apply psychology and neuro sci ideas to web sites, and to explain why simplicity and good design can really work. For example, we want the site to stay "out of the way" so that the users stay in a primal, "lizard" mode of consciousness with respect to the site. In this way, they can concentrate on what matters.

During the talk, I remember thinking that all of the principles discussed apply to more than surfing content on the web. They also apply to surfing code in an IDE. That is, topics such as:
  • Whitespace is a critical aspect of design
  • Group related items (locality of reference)
  • Our minds can only stack N items (N = 7 ?)
  • Principle of least surprise
apply just as well to our APIs, our code organization, and coding conventions.

For months now, I've wondered if there were studies that applied neuro sci to developers.

Subitizing

Let's play a game: as you add a parameter to a method, how many parameters triggers your sense of "this is too many -- I need to refactor this".

Seriously, go ahead, think of a number, N, for your threshold.

You probably said N = 3 or 4. True, that's what everyone says, but here is one reason why. The delightful book Mind Hacks discusses subitizing (item #35): given a set of N objects, where N is 4 or less, we process counting in a much faster way. The book claims 250 ms for the first 4 items and a full second (!) for every 4 items after that.

There is debate as to how this works (see Mind Hacks for academic references), but one conjecture is that when N <= 4, the "counting" is a side effect of visual processing: i.e. it is done by the lizard, reptilian level of the brain. When N goes past 4, we have to do some work.

Now, let's be clear: the book talks about counting shapes. Stars, circles, beads on an abacus. I have no idea if this applies to Java or C# parameters.

But I'm willing to bet money that it does.

Eye-Tracking and Variable Names

This article came across the transom recently, and dovetailed with the above ideas. The gist is that the researchers used scientific techniques (e.g. eye-tracking) to evaluate productivity of programming styles.

The claim in the paper is that the Scala style of using comprehensions is more productive than Java's iterative loops. Also, for small code blocks, well-named intermediate variables may not matter.

I didn't read the paper, and I have no idea of the validity of the science. However, I find the approach to be very fascinating. I'm sure scientific methods have been used for a long time with respect to lines of code, and productivity, but I wonder if neuroscience will have a future impact on language design?

It would be fascinating to see if researchers start hooking up developers to functional MRI machines, to see how the brain works while coding. (I know that my amygdala lights up when I see a 80-line method!)

The Upshot

Imagine a geek conference where a new language is unveiled: instead of its design being driven by a sense of tradition or aesthetic, what if its design was modeled on hard evidence from a neuro lab?

Neat stuff.

Tuesday, August 25, 2009

An Understated Feature in Groovy

Background

I have worked with Groovy for awhile, but have been averse to one feature: the implicit return of the last expression evaluated. For example:


def getFoo() {
def foo = null

if (something) {
foo = new Foo()
}

foo // no 'return' necessary
}

In the above code, I would use return because it felt safer to me. I tended to agree with Eric's post (with respect to explicit returns).

Revelation

I get it now, and it's all thanks to the enhanced collection methods in Groovy.

Consider the collect method. It transforms a list by applying a function. In pseudocode:


[ a, b, c, d] => [ f(a), f(b), f(c), f(d) ]

With that in mind, here's another example:


class Composer {
def name
// def era, etc
}

def list = [ 'Bach', 'Beethoven', 'Brahms' ]

// the closure returns the new Composer object, as it is the last
// expression evaluated.

def composers = list.collect { item -> new Composer(name : item) }

assert 'Bach' == composers[0].name

The idea is simply to build a list of Composer objects from a list of strings. As noted in the comment, the closure passed to collect uses the implicit return to great effect. At one time, I would have taken 3-4 lines to express that idea.

But now, this code is not merely concise: it is truly elegant. Very reminiscent of other languages such as Python.

The Take-Home Message

There are many lists of excellent Groovy features. However we rarely see 'implicit return' listed. I'm a fan: it greases the wheels for other features.

I realize it is available in many languages: I just haven't used it in Groovy. I suspect in a few weeks I won't be able to live without it.

Monday, August 17, 2009

The Case for Grails

David Jacobs, a friend and colleague, posted a comment in response to other comments on a previous post. The comments focused on scaffolding in Grails.

I thought it was worthy of a full-blown post, and he has kindly granted me permission. David's thesis is that there is much more to Grails than just scaffolding and quick demos.

By David Jacobs:

I've now been using Grails on my primary project for about 16 months (not just toying with it--this is at my "real job" on a large project for one of the 50 largest companies in America). My appreciation of it has continued to grow, and I have complete confidence in it as an appropriate choice for 95%+ of business applications.

Scaffolding is NOT a primary benefit of Grails. It enables cool 5 minute demos, but the real world benefits of Grails are much deeper. There are simplified (auto-wired) conventions, built in tools, or plugins for nearly every aspect of web development. This enables a massive increase in productivity by enabling and encouraging clean solutions that don't re-invent the wheel. Perhaps even more importantly, this keeps the code lean, which is very important for long-term maintenance, refactoring, and preventing "sleeper defects" that tend to hide in bloated code.

I needed to add caching for some web service calls to improve performance: 11 lines of code (entirely declarative).

To meet a versioning requirement (lock, copy as new revision), I needed to implement deep cloning of a persistent domain tree with child associations (mostly collections) five levels deep, with multiple branches, touching about 30 persistent objects. Some needed to be copied by reference (for example, a createdByUser association), and some cloned as new (recursively deep cloned). My implementation is completely generic and won't require changes if the domain model is changed. Pass the method a domain object instance, it hands you back a copy with all of the children copied and properly attached to their new parents. Then you call .save(), and all of the new ids are generated and your database has been updated. This one is a testament to the power of Grails metaprogramming with GORM and Groovy: 22 lines of code.

I needed to create a utility application for mocking a third-party SSO module to enable logins on staging/demo servers. It validates user inputs, makes an AJAX request to the target app with modified request headers to initiate a browser session, and launches it with the intended user now logged in. It uses a proper MVC architecture, the layout is configured with SiteMesh, it has configuration/build management and versioning, URL mapping/redirection to keep it friendly, and log4j integrated and configured. From creating the project to building the WAR file, it took 4 hours.

Point proven?

Sunday, August 16, 2009

Vending Machine: A Modest Groovy Example

I wasn't ready for the Language Shootout at the Lambda Lounge, but I've completed an example of the vending machine, and placed it up at GitHub. (The Language Shootout used a small specification to illustrate languages ranging from Haskell to Fan, and everything in between.)

Highlights

As Lambda Loungers know, these examples are not intended to be submissions for the Turing Award. My example is a modest program, but offers this to Groovy newbies:
  • The project uses Gant, has test cases, and is fairly complete.
  • The program accepts an input file, and supports a VERIFY action to "assert" the expected state of the machine. In some ways, the file could be an acceptance test (reminiscent of FIT).
  • One interesting idea (IMHO) is the execution of data as code. More below.
  • The example has some internal uses of Expando, and many uses of the elegant closure-based iterations.
Evaluating Data

Consider a command like so:


// N = Name, P = Price, C = Count
SERVICE [5,5,5,5] [[N:'A', P:'65', C:'10'],[N:'B', P:'100', C:'10']]

The pattern here is: Action Coins Inventory. In this example, Coins is evaluated as a Groovy list; Inventory is a Groovy map. This not only simplifies parsing, but affects the architecture of the example. This is hardly new (hello, Lisp!), but a powerful tool.

Java-esque

As with many languages, Groovy supports a wide-range of styles. I've dubbed this example as "Java-esque". Here's why:
  • Actions (like SERVICE) are objects. This is a nod to Java's style.
  • It does not use the MOP (see Matt Taylor's example), and is not really a DSL.
  • It eschews some common Groovyisms (e.g. using an expression as the return value, without specifying the return keyword).
Known Issues

There is no REPL-loop or interaction with the user: only file input. Also, it emits no output per se, and does not acknowledge corner-cases, such as requiring exact change. It simply allows verification of expected state.

Lessons Learned
  • I love evaluation of data as code. I always have.
  • Tests are essential with Groovy, and they become inextricably tied to your experience as a developer. This is hard to explain, but because of the dynamic types, the tests cement themselves into your dev cycle in a way that is much stronger than Java. If you cheat with a large method that does not have a test, you'll probably pay for it.
  • It is important to read the output when a test fails. Often, I just scan it and blithely assume I know where the problem is. This usually leads to frustration, until I realize that the test was trying to help me all along.
  • As an aside, this is my first project in Git. It is excellent and definitely worth studying.
The Gist

I hope this example helps someone. I hope to write some others, including a full-on Groovy MOP version.