This Just In!! Updated Silly Keyword Metrics

It’s this time of the year and we’re repeating the silly metrics keyword count across all of jOOQ‘s code base.

We have a couple of exciting news! public is still one of the favourite keywords (yeah, we’re an API), but return is closing in, as well as final (yeah, we love final).

A bit more surprising:

  • if has surpassed throws and void. Is jOOQ becoming less object oriented, and more imperative?
  • true is still more popular than false. Yeah, we’re thinking positively about life
  • continue has one more instance in our code base. Gotta love the occasional continue!
  • do experienced a 600% increase!
  • … we still try more than we catch
  • … does the rise of char mean that we’re parsing more SQL?
  • … and we’ve removed one instance of volatile
  • … and still no strictfp or native
2013                2014                   
--------------------------------------
Keyword      Count  Keyword      Count     
public       8127   public       9379      
return       6801   return       8079      
final        6608   final        7561      
import       5938   import       7232      
static       3903   static       5154      
new          3110   new          3915      
extends      2111   extends      2884      
int          1822   int          2132      
throws       1756   if           1985      
void         1707   throws       1898      
if           1661   void         1834      
this         1464   this         1803      
private      1347   private      1605      
class        1239   class        1437      
case         841    case         1225      
else         839    else         940       
package      711    package      842       
boolean      506    boolean      623       
throw        495    throw        553       
for          421    for          469       
long         404    long         456       
true         384    true         439       
byte         345    interface    407       
interface    337    byte         397       
false        332    false        396       
protected    293    break        357       
super        265    protected    328       
break        200    super        328       
try          149    switch       197       
switch       146    try          193       
implements   139    catch        167       
catch        127    implements   162       
default      112    default      156       
instanceof   107    instanceof   156       
char         96     char         122       
short        91     short        93        
abstract     54     finally      54        
double       43     abstract     50        
transient    42     transient    45        
finally      34     double       44        
float        34     float        35        
enum         25     while        35        
while        23     enum         31        
continue     12     continue     13        
synchronized 8      synchronized 10        
volatile     6      do           6         
do           1      volatile     5  

Download the free and ASL 2.0 licensed “silly-metrics” program and start counting keywords in your software.

This is the Final Discussion!

Pun intended… Let’s discuss Java final.

Recently, our popular blog post “10 Subtle Best Practices when Coding Java” had a significant revival and a new set of comments as it was summarised and linked from JavaWorld. In particular, the JavaWorld editors challenged our opinion about the Java keyword “final“:

More controversially, Eder takes on the question of whether it’s ever safe to make methods final by default:

“If you’re in full control of all source code, there’s absolutely nothing wrong with making methods final by default, because:”

  • “If you do need to override a method (do you really?), you can still remove the final keyword”
  • “You will never accidentally override any method anymore”

Yes, indeed. All classes, methods, fields and local variables should be final by default and mutable via keyword.

Here are fields and local variables:

    int finalInt   = 1;
val int finalInt   = 2;
var int mutableInt = 3;

Whether the Scala/C#-style val keyword is really necessary is debatable. But clearly, in order to modify a field / variable ever again, we should have a keyword explicitly allowing for it. The same for methods – and I’m using Java 8’s default keyword for improved consistency and regularity:

class FinalClass {
    void finalMethod() {}
}

default class ExtendableClass {
            void finalMethod      () {}
    default void overridableMethod() {}
}

That would be the perfect world in our opinion, but Java goes the other way round making default (overridable, mutable) the default and final (non-overridable, immutable) the explicit option.

Fair enough, we’ll live with that

… and as API designers (from the jOOQ API, of course), we’ll just happily put final all over the place to at least pretend that Java had the more sensible defaults mentioned above.

But many people disagree with this assessment, mostly for the same reason:

As someone who works mostly in osgi environments, I could not agree more, but can you guarantee that another api designer felt the same way? I think it’s better to preempt the mistakes of api designers rather than preempt the mistakes of users by putting limits on what they can extend by default. – eliasv on reddit

Or…

Strongly disagree. I would much rather ban final and private from public libraries. Such a pain when I really need to extend something and it cannot be done.

Intentionally locking the code can mean two things, it either sucks, or it is perfect. But if it is perfect, then nobody needs to extend it, so why do you care about that.

Of course there exists valid reasons to use final, but fear of breaking someone with a new version of a library is not one of them. – meotau on reddit

Or also…

I know we’ve had a very useful conversation about this already, but just to remind other folks on this thread: much of the debate around ‘final’ depends on the context: is this a public API, or is this internal code? In the former context, I agree there are some good arguments for final. In the latter case, final is almost always a BAD idea. – Charles Roth on our blog

All of these arguments tend to go into one direction: “We’re working on crappy code so we need at least some workaround to ease the pain.”

But why not think about it this way:

The API designers that all of the above people have in mind will create precisely that horrible API that you’d like to patch through extension. Coincidentally, the same API designer will not reflect on the usefulness and communicativeness of the keyword final, and thus will never use it, unless required by the Java language. Win-win (albeit crappy API, shaky workarounds and patches).

The API designers that want to use final for their API will reflect a lot on how to properly design APIs (and well-defined extension points / SPIs), such that you will never worry about something being final. Again, win-win (and an awesome API).

Plus, in the latter case, the odd hacker will be kept from hacking and breaking your API in a way that will only lead to pain and suffering, but that’s not really a loss.

Final interface methods

For the aforementioned reasons, I still deeply regret that final is not possible in Java 8 interfaces. Brian Goetz has given an excellent explanation why this has been decideed upon like that. In fact, the usual explanation. The one about this not being the main design goal for the change ;-)

But think about the consistency, the regularity of the language if we had:

default interface ImplementableInterface {
            void abstractMethod   () ;
            void finalMethod      () {}
    default void overridableMethod() {}
}

(Ducks and runs…)

Or, more realistically with our status quo of defaulting to default:

interface ImplementableInterface {
          void abstractMethod   () ;
    final void finalMethod      () {}
          void overridableMethod() {}
}

Finally

So again, what are your (final) thoughts on this discussion?

If you haven’t heard enough, consider also reading this excellent post by Dr. David Pearce, author of the whiley programming language

Silly Metrics: The Most Used Java Keywords

Tell me…

  • Haven’t you ever wondered how many times you actually “synchronized” something?
  • Didn’t you worry about not using the “do {} while ()” loop structure often enough?
  • Are you an expert in applying “volatile”?
  • Do you “catch” more often than you “try”?
  • Is your program rather “true” or rather “false?
  • And how did that “goto” make it into your source code??

Here’s a bit of a distraction among all the other, rather informative posts I’ve written recently. An utterly useless ranking of the top Java keywords in jOOQ. I mean, after all, useful metrics can already be reviewed at ohloh, or collected with FindBugs and JArchitect

Now, you can figure it out. Here’s the ranking!

Keyword      Count
public       8127
return       6801
final        6608
import       5938
static       3903
new          3110
extends      2111
int          1822
throws       1756
void         1707
if           1661
this         1464
private      1347
class        1239
case         841
else         839
package      711
boolean      506
throw        495
for          421
long         404
true         384
byte         345
interface    337
false        332
protected    293
super        265
break        200
try          149
switch       146
implements   139
catch        127
default      112
instanceof   107
char         96
short        91
abstract     54
double       43
transient    42
finally      34
float        34
enum         25
while        23
continue     12
synchronized 8
volatile     6
do           1

Curious about your own Java keyword ranking? I’ve published the script to calculate these values on GitHub, under the ASL 2.0 license. Check out the sources here:

https://github.com/lukaseder/silly-metrics

Use it, and publish your own rankings! And feel free to provide pull requests to count keywords from other languages, or to calculate entirely different silly and useless metrics.

SQL in Scala, where jOOQ could go

I have recently blogged about how simple it is to integrate jOOQ into Scala. See the full blog post here:

https://lukaseder.wordpress.com/2011/12/11/the-ultimate-sql-dsl-jooq-in-scala/

I’m more and more thrilled by that option, as Scala is one of the fastest emerging JVM languages nowadays. The plain integration of a Java library in Scala leaves some open questions. jOOQ knows the “val()” operator or method, to create bind values. See the manual here:

http://www.jooq.org/manual/JOOQ/BindValues/

This operator cannot be used in Scala, as Scala declares “val” as a reserved word. I’ve had similar issues in Java before, when trying to use “case” or “else” in the API, which is not possible either. The path of least resistance is to overload or re-name those methods. “val” was overloaded as “value” in jOOQ 2.0.1. “case” and “else” were re-named a long time ago as “decode” (from Oracle’s DECODE function), and “otherwise” (as in XSL).

So for a full-fledged integration in Scala, jOOQ should be wrapped in a new API called scOOQ ;-). This new API should take Scala’s language features into account in order to make working with jOOQ a lot easier. This could be the chance to re-engineer some of the API and make all API methods uppercase, as is usual with SQL. With Scala’s ability of omitting syntax elements, such as “.” and “()”, the API could then declare one-word methods, such as in this Java example:

MERGE().INTO(MY_TABLE)
       .USING(SOURCE_TABLE)
       .ON(MY_TABLE.ID.equal(SOURCE_TABLE.ID))
       .WHEN().MATCHED().THEN().UPDATE()
         .SET(ID, 1)
         .SET(DATA, "Data")
       .WHEN().NOT().MATCHED().THEN().INSERT(MY_TABLE.ID, MY_TABLE.DATA)
       .VALUES(1, "Data")

While in Java, this looks quite nasty and verbose, in Scala it could be very nice! The below statement should compile in Scala if the API was declared as such:

MERGE INTO MY_TABLE
      USING (SOURCE_TABLE)
      ON (MY_TABLE.ID equal SOURCE_TABLE.ID)
      WHEN MATCHED THEN UPDATE
        SET (ID, 1)
        SET (DATA, "Data")
      WHEN NOT MATCHED THEN INSERT (MY_TABLE.ID, MY_TABLE.DATA)
      VALUES (1, "Data")

Convinced? Contributions very welcome! :-)