Wednesday, April 15, 2009

Member Literals

I am aware of the pro and cons of static and dynamic languages. I lean toward static because of my error-prone typing, IntelliJ addiction, identifier indecisiveness and unit-test laziness. All things being equal, I would rather have the compiler find my errors than write more tests (which will probably have errors and then I'll need to write a test for the test).

This is why I was excited about Scala. What I was hoping for from Scala's type system:

#1. Less intrusive than Java's type system (Scala succeeds here)
#2. Find more of my errors than Java does

For #2, Scala let me down in one area that is important to me (and i think many others). Can you find the typo in the code snippet below? If you can, then you are smarter than scala.

1  class Person{
2 var firstName:String;
3 var lastName:String;
4 //etc.
5  }
6
7  val rs = statement.executeQuery(
8  "select firstName,lastName from Person")
9
10 p.firstName = rs.getString("firstName")
11 p.lastName = rs.getString("lastName")
12
13 p.doSomeStuff();
14
15 val e = new XmlElement()
16 e.addTextElement("firtName",p.firstName)
17 e.addTextElement("lastName",p.lastName)
18
19 p.addPropertyChangeListener("firstName"){
20 txtFirstName.setText(p.firstName)
21 }
22
23 p.addPropertyChangeListener("lastName"){
24 txtLastName.setText(p.lastName)
25 }

I probably made 7 typos, but the one i was referring to was the "firtName" typo on line 16.

Q: Have you ever been burned by this type of error?
Q: Have you ever had the feeling that the compiler should be able help?
Q: Is it that hard for a compiler vendor to give a member literal syntax? Perhaps something like this:

e.addTextElement(Person#lastName,p.lastName)

I would actually pay money for a compiler that did that.

The only reasons i can think of that this feature does not seem to exist in Java and Scala:

1. I am the only one who wants the feature
2. It must be really hard to implement

By the way, I am aware of constants (static final), but it seems a bit silly to have code like this:

class Person{
String firstName;
public static final String FIRST_NAME = "firstName";

String lastName;
public static final String LAST_NAME = "lastName";






4 comments:

Anonymous said...

This is why I'm uncomfortable with the growing trend of specifying property names in Strings instead of code. Java does a great job of type checking, but it gets short circuited by this technique. Granted it can be very useful, but I'd rather use it in a language that was designed for it. I don't know of any.

That said, rather than put the responsibility for catching this error on the language, maybe this is something the IDE should be checking for.
-- Miguel

Anonymous said...

This is why constant vars are important for strings.

Mark Harrah said...

This comment will only addresses part of your complaint. If this is a common problem for you, consider a simple reflection library. David MacIver wrote a nice (small) class for sbt called ReflectUtilities. It'd have to be adapted to vars, but sample usage might be:

val members = ReflectUtilities.allVals[String](p)
for( (name, value) <- members) {
e.addTextElement(name, value)
}

It finds all members of p that are of type String and returns a map from name to value.

Thanks,
Mark

lacroix1547 said...

Member literals fully integrated with the type system. This is the future.