What I Learned at JavaOne, Part III - Language Design

9:51 PM 0 Comments

This is part of a series explaining what I learned at JavaOne.

Language design was a big topic at JavaOne, and I found myself in several sessions that extolled the virtues of varying languages now running on the JVM as well as new features being added to Java itself.


Embedding Scripting Language into Java, by Paul Thwaite


I'm not sure exactly what I was expecting from this talk, but it was more basic than I had imagined.  It was still good information, but I probably could have gleaned it simply from reading up on JSR 223.

The talk was basically about the introduction of a standard API for evaluating java.next scripts from Java code.  You have probably evaluated Groovy or Javascript in the past from withing a Java program using the Groovy script engine or Rhino; this JSR is to standardize those interactions:


import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("jruby");
scriptEngine.eval("puts 'Hello, World!'");


There are some gotchas around configuring the scripting engine as configuration is not part of JSR 223. This means that if you want to tweak certain aspects of, say, the Groovy Scripting Engine, you will need to invoke it with the Groovy API instead of the javax.script one.

That was basically the extent of the session.

But, what about debugging? Stack traces? Script injection (since you can supply a context object to the script)? Performance? Compilation to binaries? I would have liked to see these covered.

Also, there is the really interesting feature of type inference by method names via the Invocable interface. You can read the Java Scripting Programming Guide for more information. It seems like there are some interesting design patterns that could be derived from that (duck typing?). It would have been nice to delve into that a bit.

Oh, well. Thwaite did a good job making it clear how get started in embedding scripts; I sort of wish we had reached a higher level of discussion, though.

 

Nashorn:  Javascript on the JVM


Nashorn is basically a replacement for Rhino, the existing standard for Javascript on the JVM.  This session was an exciting one for me because we use Rhino for a significant piece of our architecture, and I would be very happy to replace it with something faster, more debuggable, etc.

I suppose the session could be summed up in four words:  It's Rhino, but better.

This session was interesting because it was equipped with in-person testimonials from Twitter and NetBeans folks.  The fellow from Twitter said they were using Nashorn for doing server-side template rendering with mustache.js.  The individual from NetBeans said they were using Nashorn for tool support--code completion and the like.

Nashorn, as of the talk, was 99.99% compliant with ECMA test262.  They anticipated 100% compliance by the end of the week.  We don't do anything particularly complex with our javascript, so this doesn't matter as much to me, but I'm always happy to see organizations give high priority to standards!

Unfortunately, it is being written for JDK 8.  They have plans to backport it to 7, but not to 6 (though the NetBeans guy said that they did some hacking and got it to work with 6).  I would suppose that this is mostly because Nashorn is probably leaning heavily on InvokeDynamic to get high performance and it would be a bear to take all of that out to have it be JDK 6-compatible.  As happens with a number of big companies, we just got onto JDK 6, so it might be a while for us to make the change.

 

Meet the Java Language Team, by Brian Goetz, Joe D'Arcy, Michael Trudeau



While it might sound a bit romanticized, it was great to "sit at the feet" of some real language experts.  Language design is very intriguing for me, and these guys get to do it every day.

The panel didn't have any planned discussion; they just took questions.  Here are a few of the interesting ones:

What is happening with annotations? There are some new annotation APIs, like caching.  Annotations on type parameters is being considered:  List<@NonNull String>, for example.  There is the possibility of specifying a method literal in an annotation.  There might be a change to the rules for annotation inheritance on methods.  The restriction on repeating annotations on a given element is being removed.

Will Java add Union or Intersection types? Probably not right now--it would make the language more complex for very little gain.  JDK 7 does add union typing for try-catch blocks, and it is more a case-by-case approach than adding union and/or intersection types wholesale.

What about Design by Contract? Apparently this was the number one RFE for a while, but has since dropped off the radar for these guys.  C# has added support for it via Spec#, you can use JML if you like.  Apparently, there are some very tricky problems that I don't completely understand regarding object invariance in a multi-threaded environment, but what if I just want to say this method parameter needs to be non-null or have a length greater than 10?

Type inference improvements? Yes.

Could we skirt backwards compatibility for increased velocity, e.g. fork Java? Brian Goetz said, "There is a lot of life in Java without breaking backwards compatibility."  While I would agree with him there, I wonder if that is a big of marginal thinking on his part.  Anyway, other groups have already done what this question proposed, so I'm not sure what this individual wants.

Support for immutability? Yes, though it is tricky to understand what engineers would really use.  For example, there are a number of cases where during object composition, you don't want it to be immutable, but that there is some point at which you would like to "make" the object immutable at runtime.  What is the right way to support that?

Multiple Inheritance? No.  :)

And then there were a couple of comments from the panel that weren't super-related to the questions, but were insightful nonetheless.  One was the idea that there are a number of problems that are introduced in Java applications due to the fact that constructors have full access to the language, and maybe they shouldn't.  Of course, I'm not sure how you could make a backwards compatible change like that.  Another was a brief discussion of project Sumatra, which will allow Java applications to leverage GPUs and APUs for better performance.

 

Intro to Play Framework, by James Ward


This was pretty interesting for being a 101 talk.  The framework has what you would expect--rest support, server-side templates, etc.--which is great because it increases the prospect of using Scala at a broader level than Scala's niche of highly-concurrent applications.  Some nicer features are that it calls Google Closure and minifies Javascript and Coffeescript as part of the build process.  It also comes with its own web container; it leverages this to auto-refresh code in dev mode, give very detailed error information including displaying the code in context of the error in the browser, and make it possible to easily right functional, integration, and unit tests.

It looks intriguing, though I am cautious about one thing:  The controller methods need to be static.  Eww.  I'll bet that makes them harder to test in isolation, no? I suppose I'll have to try it out to see.

Scala Case Study, by Brian Tarbox


This session was much more interesting because of the software than the presenter's actual defense for using converting his software from Java to Scala.

Consider the tale of two Java libraries:  The first is a very popular logging framework, the second a MIDI sound player API.  With the first, you can do things like log.error("Something terrifyingly bad happened").  With the second, you can do things like player.play("E D C D E E E") (Mary Had a Little Lamb, as we all know).  The first is typically either the blessing that helps a developer find the needle-bug in the haystack-application or the cursing that is looking for hours and esoteric messages that previous engineers apparently thought would be helpful.  The second is the source of relaxing symphonies emanating from your JVM.

Now, what would you get if you put these two technologies together? You would get Log4JFugue, of course, or a library that puts your logs to music.

Wow! How cool is that?? Brian's hypothesis is that you can listen to the sound of your car and tell what is wrong, so why not your application? And, since you can code while listening to music, you can suddenly be more efficient, too.  He played a segment of his log files for us, and it was great.

Anyway, I know that most people felt the same way as I because nearly all the questions after the presentation centered around the library as opposed to his choice to port it to Scala.

Since he was trying to make a case for making the jump, though, I should probably say a little bit about that. If I weren't already a huge fan of Scala--the actor model, immutability, currying, tuples, traits, DSLs, and on and on--he would not have convinced me.  Most of his examples were "Look at how much more compact my code is!" which, while a good reason, is certainly only one of many and not the most important for me.  It is true that the fewer lines of code you write, the fewer places you can have an error, but there's usually an API or a compiler for that.

Show me how it scales better (actors), is more secure (immutability), is easier to design code with (BDD), is easier to enhance the language for greater expressiveness (DSLs), and these will be more convincing for me than being able to write code in fewer lines.  The language features and APIs in Scala are definitely persuasive, but when I talk to most enginners at bigger companies, they say, "but the junior developer can't read it!".  I believe that Scala is a good move for enterprise-level companies to make, but it can't be just because the engineers would like to be more terse with their code.

 

Who's More Functional?, by Andrey Breslau


Breslau is a funny guy, which made this talk a pretty enjoyable listen.

His point was basically, "Once Java has closures, all the languages are equally functionally expressive, so can't we all just get along?" This was ironic since he is the lead designer on yet another functional-oo-language-hybrid-language, Kotlin.

He has his reasons, of course.  One of them being that he feels Scala is very good but 1) too complicated to ever give good tool support and 2) too hard to follow with the implicit keyword in place.  While Breslau may be right on the first one (I am more optimistic), I unfortunately like the implicit keyword since it allows me to add methods to String, etc. instead of having a zillion StringUtils classes all over my code.

What I think that Kotlin may need is a feature to differentiate it from the rest.  Maybe they can get traction with the "simplified Scala" approach, but honestly that's what Java seems like to me.  Once Java has closures, what does working with Kotlin buy you? (Actually, before I give my review, I should probably try it out, shouldn't I? :))

Kotlin aside, Breslau made two statements that I would have probably liked him to clarify.  First, he said that no alleged functional language was purely functional because they all had side effects.  This seems to be a pretty debatable topic as several folks see Haskell as a pure functional language even if it does do I/O (as I would suppose all languages must).  I suppose the same could be said for Lisp.  Are all four he was comparing (Java, Kotlin, Scala, Groovy) capable of programming with side-effects? Yes.  However, it might have been a bit of a controversial way to explicate his thinking.

Second, he said that this:

collection.filter().sort()

was backwards from this:

sort(filter(collection))

which I disagree with.  I think that it is probably true that the first one is more readable, but the latter is definitely a composition of functions (think f o g and g o f).  He might have been speaking in pragmatic terms though, not functional ones.

Of course, I think there is room for both.  I think that Breslau gave a good example in the beginning when he showed how the Fibanocci numbers could be evaluated more quickly iteratively than recursively, where recursion is the standard functional approach.

Anywho, I'll have to give Kotlin a shot some time.  I would still say that Scala is way more functional than Java.

 

Annotation Processors, by Ian Robertson


Even though they've been around since Java 5, I somehow had never heard of the Annotation Processor API.  With annotation processors you can:
  •  Add compile time warnings and errors of your own
  • Generate code and other resources 
While I guess auto-generation of DTOs or the like might be cool, I see the potential for adding your own compiler errors as having a lot of potential.

Currently, when we want to enforce a particularly important development need, like using the right class name when naming a logger or not having a Spring-managed bean be final, the best we have are Sonar violations.  While Sonar violations are great from a technical debt standpoint, they aren't a good fit for alerting the developer to when he is doing something that is just not going to work.

Enter Annotation Processors.  The Annotation Processor API basically gives you access to the AST for Java files that your configuration indicates you would like to process.  There are a bunch of rules regarding using Elements vs. Mirrors, which I didn't get a complete grasp of during the discussion, but the essence is that you use the API to analyze each Java file during the compilation phase to see whether it complies.

Robertson gave the example of building two Annotation Processors.  One checks to make sure a POJO annotated with the JPA @Entity annotation has a default constructor.  JPA will not correctly deserialize to this POJO without it.  This was about 30 lines of code, which will save the developer a bunch of time since missing constructors will now be caught at compile time.  The second one checked to see if POJOs using the @OneToMany annotation have the correctly named property referenced in the annotation.  This one was much more complicated being upwards of 200 lines or so.

It sounds very verbose, and it makes me wonder what improvements might be made on it through a DSL and/or case classes since they are a bit more suited to compiler-type logic.

Anyway, I'm very excited to try my hand at it.

Josh Cummings

"I love to teach, as a painter loves to paint, as a singer loves to sing, as a musician loves to play" - William Lyon Phelps

0 comments: