Skip to main content

Meta Coinage - Role of Syntactic Sugar

Posted by brucechapman on March 19, 2009 at 2:23 AM PDT




Some Meta thoughts on Project...


Some Meta thoughts on Project Coin's Small Language Changes


Java (the programming language) is Turing complete so no new language feature can enable us to solve a problem with Java that would be unsolvable without the language feature. Therefore any new language feature is at best a convenience to those reading and writing the code.

Such features of convenience are not to be lightly dismissed, as they allow developers to increase the signal to noise ratio of our source code. Some people might use the phrase "essence over ceremony" to mean the same thing - though we probably disagree with them about whether explicit types are signal or ceremony.

There are a range of mechanisms available for increasing the signal to noise ratio of common programming idioms.

At one end of the spectrum is simply writing a better API. Some people are calling this fluent APIs because they are APIs that are designed to be fluent to speak to.  Anyone can write an API, and quite a few people can do quite a good job of it. It is an easily accessible mechanism and is also quick to roll out, It is generally relatively easy to change your mind about the details and doesn't lock you out of trying different concepts later however it is restrictive in terms of what can actually be achieved.

At the other end of the spectrum is a language change. Very few people can do an adequate job of this, and even fewer can do a great job. It is slow, often taking several years to get something from concept to being available for the masses. Having made a decision you must live with it forever and it can have a negative influence on later changes. However it is very powerful in terms of what can be achieved.

Reading posts to the project coin mailing list, you could be forgiven for thinking that these are the only two options. I want to point out two other mechanisms that lie more centrally on this spectrum. I am mentioning these because they may well be better alternatives for addressing some of the needs implicit in various project coin proposals.

The first alternative mechanism is to have the compiler generate boilerplate code for you using an annotation processor. For an example of this see My prototype "no closures" implementation. I have also implemented mixins using this mechanism, and delegates can be given a similar treatment. Also multiline string and XML literals are possible using this mechanism (and that is just a sampling from my own work). While these don't get rid of quite as much noise as a language change could, neither do they have all the negative aspects of a language change. Often they are good enough to be fit for purpose.

The second alternative to API or language changes is to move syntactic sugar out of the language itself. Although this might seem strange, contemporary technology is very close to doing just this, its just that no-one seems to have noticed. The idea is not new, and indeed can be traced back at least a decade, however at that time it was probably impractical. The difference is that now I believe the time is right.

Here are the Slides from a 10 minute talk I did last year at The Wellington JUG backgrounding this idea.

In a nutshell, the idea is to treat syntactic sugar as a view of the desugared java code. The IDE can do this. The developer works with either the sugared or desugared version at their discretion (much like code folds at present) and can type in sugared form and have it desugared in the model (and simulaneously " code folded' back into sugar form in the view). The model is the file that is saved and the file that is compiled. The compiler (and language spec) work with the (desugared) model, and the developer works with the (optionally sugared) view.

Eclipse (via plugin) and IntelliJ Idea already have the sugaring part of this to represent anonymous inner classes in a closure like syntax.

There are many details to work out in order to make this easily accessible, but long term I see developers relatively easily defining a two way sugaring/desugaring transformation (jackpot is a good start for how this might be done), trying them out, evolving them and sharing the good ones with colleagues and the community. The advantages of this are almost the same as for a language change, without the disadvantages. The very best could become ubiquitous and then form the basis of an actual language change if necessary to get rid of any remaining "noise" not possible with this approach.

For a sneak preview of how this concept might feel in practice this Netbeans Module is a (barely functional) prototype for Properties using this approach.















Related Topics >>

Comments

The problem with this argument is that one of the joys of Java is its the ability of the compiler/IDE to check what you are doing. While Java might be Turing complete, I do not think that it addresses problems with that joy. In particular current annoyance with Java (and the reason for my Coin proposal of LightWeight Properties) is in areas like Beans Binding Frameworks and the JPA Criteria API which both require field names to be passed as Strings. Another place that needs this is a PropertyChangeSupport objects, which again take a String as the field name. While one could modify the compiler and IDEs to have special knowledge that this particular string has to be the name of a field in a particular object, and one could possibly even use Annotations to do that (especially with the new rules for Annotation placement that are being considered for Java-7), it is not a real solution to the problem. The JPA Criteria problem is part of a much larger problem, that of validating SQL inside a Java source program. Criteria does the work of sorting out the SQL syntax, but the field(column) names still have to be hand coded. The basic problem is finding a way of getting (in a compiler checkable way) from a class/field combination to the Field object that defines the field (or an error if the combination is wrong). So being able (using # to be an operator which either returns a Field object, or a Property object) to say with an Object foo of class Foo which contains a field bar of class Bar which contains a field ali of class Ali:- foo#bar#ali which would produce either a Field object, or a Property object depending on which proposal you follow). This can be checked, while "bar.ali" which is the string you would pass to a Bean Binding framework can not. So yes, the language is complete, and I can express everything that is needed using it, but the compiler can not be sure that I have done it right. I do not think that this problem can be addressed by annotation processing (even of the sort that does naughty things behind the compiler's back) - but if you can suggest a way I would be very glad to hear of it. I am human, I make mistakes, and I value Java because with a decent IDE (I happen to use Eclipse, but I am sure that NetBeans does the same) most of the silly mistakes I make, either by spelling things wrong or later when I come to change something and forget to make the all the necessary changes, get flagged and therefore fixed. David -- David, I agree completely. I was pointing out that there are more than two ways to skin the cat. Knowing this helps to evaluate various coin proposals against each other. I hope to blog more about that soon, (but then again I have 5 part written coin proposals unpublished yet - and they probably deserve more attention). Field, method and type literals have high utility value because they would allow tidy solutions (APIs, code generators, or views) to many problems, not just one. Bruce