The Det about Programming

Just another progger’s blog

Verbose, concise and how Java relates to that

Often when reading a forum discussion somewhere about the verbosity of Java and conciseness of some language X we meet people trying to convince us that Java is good as it is, because “I want to express everything clearly, and when reading I want to see what I get. No crypticts, no implicits”.

And when debating about that opinion, it often comes to productivity, which is then answered with the hint to “good IDEs”, so that Java expressions are typed almost as fast as code in more concise languages.

So what is this thing about expressiveness and conciseness?

Let’s have a look at other formal languages, say: mathematics.

Imagine the following term: 5*4*3*2*1

This is more than a chain of multiplications. It is a chain of multiplications starting from a given number (here: 5) counted down to 1 with stepwidth 1. And this concept has a specific name: faculty.
So “faculty” is an unambiguous, single word for the concept descibed above in more verbose words.

Likewise in symbolic language, you write this concept as: 5! (say: five faculty)
That this symbol is far better than the multiplication expression, can be easily seen when trying to write 100! in long form.

Now consider writing mathematical formulas without the symbolic abstraction of faculty, always only expressing it as multiplication chain. You can argue, that you can easily grok the pattern 5*4*3*2*1 as being faculty by reflex. But be cautious. Could you really always and immediately say, that it is faculty five?
Or isn’t it too easy to mistake it with 5*4*3+2*1 (as typo when writing, but more often when reading it in a more complex context)?  Here you have a pattern-mismatch mistake.

The same now works for programming languages. When saying, that one wants to “express everything clearly”, it seems natural to write:

public static final

Indeed, it could be abbreviated to omit typing and “verbosity”, e.g. to:

pub sta fin

Easier to write, only slightly more cryptic to read.

Much more concise would it be, when we would introduce symbols, such leading to a more formal symbolic language.
Imagine + for public, ^ for static, _ for final, then the modifier chain above could be: +^_

Write this on a paper and read it three days later. You remember what the symbols mean?

So: Symbols are much more concise, perhaps even more precise, but maybe more cryptic for a reader, especially when trying to learn a language. You must not only learn the concepts behind public, static and final, but also their symbols.

But here it comes. The muttering about Java being to verbose is not about abbreviations or introduction of symbols. It is much more about abstraction of concepts.

Look: Combination of symbols construct patterns. And such patterns express more abstract
concepts .
So when seeing the above pattern (+^_) you can immediately think of it as a “word” with unknown letters, and understand it as the concept “constant”.

And here we are! Faculty is a higher order concept, compiled and expressed by lower level terms. Always using the lower level constructs (the “How-to”) instead of the concept is not as easily grokkable like having a symbol for the concept itsself.

Likewise, when reading public static final in Java, you always have the effort to transform it to the implicit higher order concept of “constant”, much easier expressable by, for example: const .

This is what this verbose vs. concise debate is all about.

Could you imagine to write always “Small house with big entrance to shelter cars” instead of “garage”?

That’s what Java obliges you to do. And regarding IDE support: I do not believe you really want to advise a template+shortcut enabled word processor as the best solution to write texts,  instead of creating better words for things.

In the end, Java expressions are not napkin-able, and are not suited for whiteboard development.

I’ve seen very different mail forum posts about this or that algorithm, and it was always PITA to read Java code out of an email, perhaps wrapped at 80 characters.

Not so in really expressive languages!

Coming back to the pattern mismatch mistake above:

I detected this problem when I refactored a good bunch of code from Java pre-5 while loops to the Java 5 foreach loop.  In many many cases it was easy to exchange the loops. But I detected more than one place, where the loop construct was slightly different, and replacement did not work.

The point is:  I was not aware of this differences, because browsing over the code, all loops seemed equally expressing the standard iteration concept of  get iterator, while hasNext, elem = next.

Only the refactoring revealed the locations where the looping concept indeed differed.
Expressive?  Or truth hidden by word flood?

So when talking about Java’s verbosity and new concepts for Java 7 or 8 or whatever, first remember the faculty example and cogitate if the new ideas don’t express abstract concepts more explicitly and thus clearer than the verbose forms, you considered being more “clear and directly” before.

June 26, 2008 Posted by thedetdev | Design, Java, Language | | No Comments Yet

How not to use annotations

Since Java 5, the markup of code stuff with so called ‘annotations’ has been expanded to further use.

While before Java 5 tagging was mainly used for javadoc and to mark a method as deprecated, since Java 5 everyone is able to define her own meta-language to annotate her code.

As annotations per se may be useful, the way to create and use them in Java 5 seems to have led to some form of usage which leaves the boundaries of OO style, changing Java programming into a kind of declarative programming style.

To talk about annotations, we first have to divide them into different categories:

  • Compile time processed vs. Runtime processed
  • System defined (say: by Sun JDK or a tool vendor) vs. User defined (say: in application development)

Annotations are ‘meta tags’, which means they provide information about the code on a higher level. The problem is, what is considered a ‘higher level’.

So let’s have a look at compile time processed annotations first:

Compile time annotation means, the annotation provided by the programmer in her source code is recognised by the compiler, when it does its work to transform the source code to byte code.

The three most commonly known annotations are: @Override, @Deprecated and @SuppressWarnings

These three just give a good example where the problem in the meta-debate is:

@Deprecated is a good example of a meta-information, which does not tell us something about the code itsself, the algorithms, the class hierarchy or other parts of our coded problem solution. Instead it informs us about plannings, about conception, specifically about a feature life-cycle.
It simply tells us, that this so marked feature will not be available in a future version, so its usage in applying code is currently not wrong, but is not recommended any more.

This annotation does not change the created byte code in any way, neither the code which is annotated, nor the code who calls that so tagged feature. It is only a hint to an application programmer about what may be happen in the future if she really uses that feature.

@SuppressWarnings is also a good example of a meta-information, as it does not say anything about the implementation and the algorithm or the structure or else, but is communication with the compiler. It tells the compiler, that a warning, created by the following feature, is indeed expected and is assumed to be of no interest.

The annotation’s existence does not change the result of the compilation in any way, but only the way the compiler works with the input it.

@Override is indeed a bad example for such a meta-information. It tells us, that a specific method is assumed to override a method with the same signature in a super class. While this may be considered a meta-information as it does not tell anything about the methods implementation itsself but our assumptions about that method, it is in fact an addition to the code, not a meta-information about it. It is in the same category like the public or the final modifiers, for example.
They all do not change the algorithm in any way, but tell the compiler our assumptions about its application. It communicates our software conception. That is, what code is about. So public means: may not be called from outside. Final means: May not be reassigned. And override means: Shall correspond to a method with same signature in super class.

Override gives a concrete information about the inheritance structure.
I think Martin Odersky thought the same when he decided to make override a keyword in Scala.

The same can be said about runtime annotations, i.e. annotations which can be analysed at runtime, so changing or controlling the systems behaviour.

While this may be a good idea, e.g. when writing test code using a testing framework (test methods get the annotation @Test instead of being detected by name prefix), this can easily be abused when applied to control application logic.

Even in the mentioned test framework, recognising the test methods by annotation is in my opinion more a hint to a design flaw in the underlying programming language (say: Java) than a feature. Obviously it is not possible to code this configuration with language inherent features, at least not in a satisfying, clear and concise way, making the framework developers falling back to reflection and annotation use.

At first, I was not unhappy with the convention over configuration approach, assuming all test methods to start with the prefix ‘test’. But beside that I suspect that there are more elegant solutions in languages that provide functions resp. closures as first-class citizens.

Beside the example above I stumbled over a question in the Groovy user list, where a validation solution in a Java programm, based on annotations, should be transformed to Groovy. The current lack of inner classes led to me doubting the proper use of annotations for that application per se.

The solution had a generic validation method which analysed a given object for annotated properties and called a further validation method for that property based on the specific annotation.

The object to be validated was an anonymous inner object created especially for that purpose, so being a form of configuration.

Example:

someMethod() {
    Object checkObject = new Object {
        @SomeAnnotation
        String myProperty = someValue;
        public getMyProperty() ....
        // other properties of that kind, with different annotations ...
    };
    validate ( checkObject);
}

While this approach seems at first a good application of runtime annotations (as the user of the validate method can “easily” configure the concrete applied checks in a declarative way) and indeed OO style (as creating the specific configuration as anonymous inner class seems OO), it indeed hides the fact that the annotation provides no real meta-information about the properties, but is used for runtime flow control.

I do not know the validate() method, but assume it to be more or less in an imperative style, assembled of reflective access to get the annotations and some if-else which calls the corresponding validate method for any annotation with the respective data value to be validated.

So we take a look at the Groovy solution to the above problem.

First, we move the validate() method to a class Validator. This class provides also all the specific validation methods for each annotation (perhaps such a class just existed for the Java solution).

class Validator {
    def checkOne(data) { ... }
    def checkTwo(data) { ... }
    def validate(c) {
        c.delegate = this
        c()
    }
}

Now, assuming we have one instance validator of class Validator, we do the configuration, formerly done in the inner class object, with a closure:

someMethod() {
    validator.validate { checkOne(someValue) ; checkTwo(someOtherValue) }
}

Voíla, the closure put into the validate method is our configuration of what checks shall be applied to what values.

Instead of annotating properties in a class, then analysing the annotations to know which test method to call, we simply call that methods with the values. Instead of implementing what can be done, than declaring what shall be done, we simply do.

Back to our testing framework: Instead of annotating test methods and doing reflective access afterwards, we could also create a test method and give it a test closure:

test("name of test") {
    // test code
}

The point is: we are totally inside the programming language, not on a pseudo meta-level.

April 14, 2008 Posted by thedetdev | Design, Java | | No Comments Yet

How not to use static class members

Recently I came across a new experience which I consider a good example of “How not to use static class members”.

Static class members are members (attributes and methods) which are shared between all instances of a class.

I.e.: If one instance changes the value of a static attribute, all other instances know this new value immediately.

Static members -particularly attributes- are shurely useful for configuration purposes, where all instances share a really really common knowledge with each other.

Static members are also indeed necessary for patterns like Singleton or Factory.

They are absolutely necessary to declare constants.

BUT: Static members are fatal if their usage include a runtime aspect.

I experienced that, when I inherited some code which extended the JUnit Framework to do validation on a loaded Model. Each validation was declared as test method of a so called “ValidationCase”. As JUnit implicitly creates new instances for each test method to be called as test case.
So when running a specific test class, there are a bunch of instances of this class. For the validation now they had to share the model element to be tested.

The quick answer to this problem was: put it into a static member, all instances will know it then. Advantage: The location where these instances were created was inside the JUnit framework and didn’t need to be touched.

BUT:
The error in this notion was: Not all instances of a test class share this model element. (As there are more model elements which are tested later and before by the same test class).

So the rule is: Only all instances of the test class which exist at a given time share this knowledge. At other times the share contains other information, shared by all instances actually existing then.

It worked well as long as only one model element was validated at a time.
The problem of this approach occured when once the validation system was extended to call a validation of one model element out of a validation of the other.

Now there were two groups of instances, one for element A, one for element B. But when B was under test, all instances shared the reference to B. And the reference to A was lost. Overwritten at a point in time.

Even this worked, as long as the validation of B happened to be the last action in the test of A, and the A reference was never needed afterwards.

But it was obvious that this card house once would collapse….

So: Everytime you introduce a static variable into a class, check carefully if its value is really valid for all instances of this class, even over time.
Avoid using static members out of well known pattern (like constants, Singleton, Factory …).

March 5, 2008 Posted by thedetdev | Design, Java, Language | | No Comments Yet