Archive for March, 2004

Properties: Groovy or not?


Mike is at it again
and this time, Groovy Properties are taking a beating…

I can only admire Mike’s thoroughness, he certainly researches his subjects
before posting about them, and everybody ends up more enlightened after reading
his posts.  However, his conclusions are sometimes…  questionable :-)

First of all, I notice that of the twenty-one listings in his entry, only few
of them actually expose a flaw that deserves to be studied.  More
precisely:

  • Listings 1-6, 8, 10, 12, 13, 14, 15, 20, 21 are working as expected.
  • Listings 7, 9 show bugs in the parser (which shouldn’t be newline-sensitive).
  • Listings 16, 17 work as expected but admittedly with a gotcha (you need
    to keep your types consistent, more on this below).
  • Listings 18, 19 show some behavior that will look odd unwil we come up
    with clear specification of the unboxing behavior (not an easy topic, even
    for JDK 1.5 which still hasn’t come out with a final word on it).

Listing 11 is the one that really got my attention, until I realized that the
rules to get it right are simple and they already exist:  JavaBeans. 
As long as you follow the JavaBeans rules, everything makes sense.

Anyway.  I think we could dissect Mike’s examples one by one and argue
over them for days, but it’s way too early to do that.  Instead, I’d like
to take a step back and discuss Groovy Properties in general.

At this early stage of Groovy’s existence, there are three possible scenarios
for Properties:

  1. Keep the current design and write a thorough specification to
    disambiguate all the corner cases that Mike uncovered.

    I agree with Mike:  Groovy Properties need to be improved, so I won’t
    spend too much on this option.
     

  2. Modify the current design.

    As part of the improvements, Mike and

    Merrick
    suggested adding one ore more new keywords: "property", "rw",
    etc…  I have to say I find Mike’s fix quite curious, since he
    complains about the magic of the current design (declaring a public field
    will cause the generation of the proper accessors, which can then be used in
    your code) and then proposes to fix it with a keyword "rw" which also
    magically generates accessors (even worse:  you are forced to use this
    accessor to read or write the field!).
     

  3. Come up with a brand new design.

    Since the JSR just started, I think we should explore this option seriously.

After reading Mike’s detailed analysis, I was struck by a very simple
realization:  C# got it right.


The way C# implements properties
addresses pretty much all the concerns that
Mike voices, including that of redundancy (if you spelled out the property once,
you shouldn’t have to declare it a second time), and arbitrary complexity
(declaring a simple property is very terse, but you can insert more logic in the
accessors at any time without breaking anything).

Whatever ends up in Groovy, I think the most crucial point is that of uniform
access.  If my property is called "firstName", I should be able to refer to
it as "person.firstName".  I don’t care if it’s going to be a direct field
access or if more complex logic is going to happen undercover.

After all, why would I care, as long as it returns the right value?

Mike on Groovy

  • Mike just posted a
    very thorough analysis of Groovy’s syntactic flaws.  Here are a few
    comments on some of the points he made:

    In general, now that I’ve looked into the Parser code in depth, I am deeply
    distressed by how often the parser looks at newlines as being semantically
    meaningful. To put this in the strongest possible terms, WHITESPACE
    SENSITIVITY IS JUST PLAIN WRONG IN A LANGUAGE LIKE GROOVY
    .

    I think the problem is not exactly there.  The rule of thumb is: 
    if spaces are not semantically meaningful, then neither tabs nor newlines should
    be.  Groovy is clearly violating this principle, and this needs to be
    fixed, but I think that instead of replacing the existing closure syntax with
    the one Mike’s proposing (sorry Mike, I’m still not crazy about the "closure"
    keyword), it would be better to simply fix the parser so that closures can
    remain as they are and be absolutely space/newline/tab neutral.  The
    resulting grammar will most likely not be LALR(1), but that’s a problem for
    James and his fellow developers, not users…
     

  • I like the way Python makes spaces meaningful, but I am afraid that in the
    presence of closures, such indentation is doomed to fail.
     
  • I also like the idea of doing away with parentheses altogether. 
    It looks quite alien the first time you do it, but it grows on you very fast. 
    After all, who cares if "person.firstName" refers to a field or to a method
    call, all you know is that it returns a string representing the first name.

    That being said, if you go that way, the syntax for invoking methods with
    parameters become harder to parse when you read the code, especially in the
    presence of named parameters, although once again, this is something you might
    eventually get used to as well.

My overall feeling on all these issues is that when it comes to writing code, the
developer’s options should
be limited to spaces, newlines and tabs.  In other words, the language
should let me format my code that way I want it, but there should be just one
way to write syntactically correct statements.  Therefore, Groovy should:

  • Impose semi-colons everywhere or not impose them at all.
  • Require parentheses for method calls everywhere or never require them.

Most of the flaws depicted in Mike’s posting are nothing more than signs of a
very young language.  James and his team are experimenting with various
ideas but haven’t had the time to really consider all the syntactic and semantic
implications of their ideas, which further obviates the necessity of a JSR to
fix these problems.

It will be the
Experts Group responsibility to keep the language in check, both syntactically
and semantically, and make sure that Java developers can adjust to it very
quickly while still retaining the power that Ruby and its siblings offer to its
community.

The Lisp dilemma

I like Lisp.  I really do.  I learned it in college about fifteen
years ago and during my PhD, I was happily hacking emacs Lisp on a regular basis. 
When the OOP trend hit, I was ecstatic to be able to combine the power
of Lisp and objects in Common Lisp and also some other variants, such as Scheme, CAML, or Haskell.  They’re all fascinating tools for the mind and they
definitely change the way you look at programming.

That being said, there is something I don’t quite like about Lisp:  its
users.

Lisp is a language that never really made it in the mainstream, and this
failure has caused a profound trauma in its followers.

The Lisp community
suffers from a severe case of "underdogness" which manifests itself as acute
short-sightedness, persistent bitterness and ravaging delusion, which I also like to refer to as the "Luke
Skywalker syndrome", where you feel you are part of the resistance against
a bigger and ruthless power (I once suffered from this syndrome when
I was the proud — too proud — owner of an Amiga).

Lisp fanatics are an amusing crowd, really, and what prompted this post is precisely
the amusement that this introduction to Haskell procured me.

This page starts by giving an implementation of Quick Sort in C and then in Haskell:

qsort []     = []
qsort (x:xs) = qsort elts_lt_x ++ [x] ++ qsort elts_greq_x
where
elts_lt_x   = [y | y <- xs, y < x]
elts_greq_x = [y | y <- xs, y >= x]

which is then described as:

Functional programs are often easier to understand. You should be able
to understand the program without any previous knowledge of either Haskell or
quicksort. The same certainly cannot be said of the C program.

What a gem.

I also liked:

In particular, strong typing means no core dumps!

The assumption here being that Haskell is strongly typed, a claim that
would be enough to start an all-out flamewar on comp.lang.* that lasts for
months, but the core dump
argument really takes the cake.  Are you convinced to convert to
Haskell yet?

Lisp users do have a sense of humor, though, so make sure you visit
Paul Graham’s collection of Lisp
quotes
.

 

The lost art of bookmarking

I am not a big bookmark fan.  Ever since Google came along, I have felt
my need to bookmark drop to the point that my bookmark folder is close to empty. 
I do use the toolbar of my browser, though, and the Litmus test to decide if a
site is toolbar-worthy or not is:  am I going to click this link several
times a day?

If the answer is "yes", then I drag the link to my toolbar, otherwise, the
site falls into oblivion and I rely on my memory and Google to be able to return
there if I ever decide to one day.

With that in mind, I have been reading about the growing enthusiasm for
delicious with quite a lot of skepticism. 
The funky URL notwithstanding, I saw very little interest in a centralized
bookmark manager since Google is already working quite well for me. 

Nevertheless, I gave delicious a try and I have to admit that I found
the implementation pretty neat and very intuitive.  It’s a good showcase
for the power and simplicity of REST but it’s also well thought out and adding a
bookmark to your delicious page requires hardly a couple of clicks more
than bookmarking the page in your browser. 

Some of the nice touches
include:

  • Bookmarks can be added in a pop-up window.
  • The bookmark form is pre-filled with the information read from the
    current page, so adding the bookmark is typically just a matter of clicking
    on "Okay", unless you want to add an extra description or a set of tags.
  • Textual tags allow you to categorize your new entry quickly.
  • When you are done, you are taken back to the page you just bookmarked in
    case you are not using the pop-up.

delicious also provides an RSS feed for your own entries (to give to
friends) as well as another RSS feed for all the entries posted on the site. 
It will also tell you how many other people have bookmarked a certain entry
(both quantitatively and with a color code), which gives you an instant
measurement on the freshness and the popularity of your latest finding (hint: 
bookmark your own Web site and see if other people like you :-) ).

In short, delicious is a model in usability.

However, no matter how positive this first contact was, I was left with a
clear sense of  "It’s not for me".

Until I realized something.

Web sites can be sorted by order of interest to me:  sites that I…

  1. Never hear of.
  2. Hear of but don’t bother going to.
  3. Read and then forget right away.
  4. Read and want to save for possible future reference.
  5. Read and want to save for certain future reference.
  6. Read and want to save and reread several times a day.

Obviously, categories 1, 2 and 3 are quite uninteresting, but I thought I’d
mention them for completeness.

Category 4 is typically addressed by your browser "Bookmark" menu.

Category 5 can be addressed by either the "bookmark" menu or the browser
toolbar.

And finally, sites that belong to category 6 are clearly toolbar material.

From this crude break down, it looks like delicious is a good fit for
category 4 (and possibly 5).  But why is it a win over the "Bookmark" menu
of your browser?

The first obvious answer that comes to mind is its distributed aspect. 
I bet many of you are surfing the Internet from various places and different
browsers, probably all of them with a different set of bookmarks.

But I thought of a few more subtle reasons:

  • Timestamps.  Maybe in a few years, I will have the curiosity to go
    through my old webroll (you read that term here first) and see what I was
    reading back then, although in all likeliness, many of these links will have
    stopped working by then.
     
  • When I was still using bookmarks and I happened to read an interesting
    site, I remember being hesitant adding that site to my Bookmarks folder. 
    I didn’t want to make it too crowded and it was also sometimes hard to
    decide whether it was as important as some other Web sites I had in there. 
    In short, I was trying to limit my bookmark folder to contain only sites
    satisfying a certain criterion, but I was never really able to phrase this
    criterion in a way that would make it obvious to me what belonged there and
    what didn’t.

    As I start to use delicious more, I realize that I no longer have
    this hesitation and I happily bookmark away without thinking too much about
    it.
     

  • Finally, there is the public aspect of delicious, akin to some
    sort of e-voyeurism.  What better way to see what people bookmark than
    randomly checking out the delicious front page a few times a day?

Let’s see how the experiment goes and if I am still maintaining my webroll in
a month from now, but until then, I am promoting the delicious front page
to category 1 in an attempt to encourage its use. 

Welcome to my toolbar.

Groovy's -> and . operators

I need to take back a few things that I said in my previous entry.  I
have been thinking a bit more about Groovy’s "." and "->" operators and I am
realizing that not only is my comparison with C/C++ and automatic unboxing
unfair, but that these operators can actually be quite useful.  Allow me to
expand.

The problem I have with the C/C++ version of these operators is that they
give you the illusion of choice.  The reality is different:  at any
time, there is only one operator that is valid, and using
the wrong one will result in a compilation error.  Therefore, I find it
stupid to put the burden of getting it right on the developer when the compiler
could infer the right operator itself.

Similarly, my comparison with auto unboxing is unfair in the sense that
automatic unboxing happens behind the scenes.  There is no obvious pointer
being dereferenced and receiving a NullPointerException will undoubtedly confuse
developers for quite a while.

Things are very different with Groovy’s operators and they are actually the
manifestation of a fundamental design decision when you write your code: 
is it okay to have a null pointer here or not?

In Java, you make this decision by using the code

String name = null;
if (null != customer) {
  name = customer.getName();
}

or

assert null != customer : "Customer shouldn’t null"
String name = customer.getName();

I don’t know about you, but I make these design decisions all the time in my
code, and nested null tests can indeed become very confusing and hard to read. 
And this is the part I was not getting:  Groovy’s operators are simply
syntactic sugar on top of a design decision.  You remain in control and
once you’ve made your choice, you are pretty much guaranteed to write your code
in the most concise way possible.

I guess it means I like it after all.

 

Groovy wish list

Mike describes his experience with
Groovy
, and he makes a lot of good points.  The comments that followed
brushed on some other aspects of Groovy, such as the operators "." and "->".

Mike’s understanding is:

Oh, and ‘.’ vs. ->: I believe ‘->’ guarantees that you don’t get nullpointer
references, so you can say foo.stuff()->bar.hincky()->bat.fly(), and if foo,
bar, or bat are null it’s a NOP.

which is also what I inferred from the documentation I read (which I can’t
find any more, go try to Google for something like "." or "->"…).  This
is also my understanding, but this behavior scares me.

We were confronted to the same problem in JSR 201 when trying to define the
behavior of unboxing in the presence of a null pointer.  The initial draft
specified that the default value for the unboxed type should be returned, but
after careful examination (read:  dozens of emails), we decided that hiding
a NullPointerException was a far worse offense.  We decided overwhelmingly in
favor of throwing a NullPointerException, a decision which even now is still
controversial with the community (to the extent that we might actually decide to
do away with automatic unboxing altogether).

Groovy’s "." and "->" operators suffer from the same problem.  I really
can’t think of a compelling reason to have both, but maybe someone will prove me
wrong.

As a side note, I do have some history with these two operators, and it dates
way back.  When I received my first CS classes, I remember asking the
following question to my compilation teacher:  "Why does the developer have
to remember which one of . or -> she should use?  Can’t the compiler infer
it based on the type of the lvalue?".  I don’t remember ever receiving a
satisfying answer to that question, even when C++ appeared and admittedly
muddied the water with its feature of operator overloading (note that you can
redefine "->" but not "."…).

In summary, here is what I’d like to see modified in Groovy:

  • Get rid of ->, keep "." and throw an NPE if necessary
  • Either require parentheses for method invocations or not, but don’t
    allow both

I am not quite sure I care as much about semicolons (or lack thereof) as Mike
does, nor do I see a compelling reason to modify the way accessors are defined,
but I challenged him to come up with a proposal so let’s see what he has in mind.

Show us the money, Mike!

Strong Bad's 100th

I am a big fan of Strong Bad.

Strong Bad has been stuck at his 99th email for a while now, and I was very
much looking forward to reading the 100th.  Since it was still not
appearing on the main page, I just went ahead and
typed the URL myself
Surprise… what you see looks like a 404, but don’t be too quick to close the
window and put your headphones on.

Finally, yesterday, the 100th email "officially" appeared on the main page
and it is called "Flashback". 
Fortunately, they didn’t use the same URL, so both emails are still available.

Happy anniversary, Strong Bad, keep up the good work.

 

Groovy JSR: I doubt it

The announcement of Groovy being submitted as a JSR has caused a maelstrom of
reactions from people asking all kinds of questions:

  • Who will lead the JSR?
  • Who will be part of the Experts Group?
  • Who will write the TCK?
  • Where will the source be kept?
  • etc…

Those are all good questions which will need to be answered in time, but
until then, I notice that everybody is making a very important assumption: 
that JSR 241 will be accepted by Sun.

This outcome is far from being guaranteed.

Actually, I am pretty sure that Sun will refuse this JSR, for a number of
reasons.  Maybe the justification will be technical (the language is too
young, community is too small, it looks like Java but it’s not quite Java,
etc…) but I believe the real reason is strategic.

Simply put:  Groovy is a very real threat to Java.

Do you remember how five years ago, C++ users used to laugh at the simple
idea that Java might one day displace C++ in enterprise applications? 
Well, for all I know, maybe in five years from now, Groovy (or another
"scripting" language) will have become mainstream and we will be wondering how
can Java programmers not be disgusted by the complexity of their language of
choice.

Don’t get me wrong:  I am a Groovy fan.  Ruby used to be my
scripting language of choice and over these past years, I have accumulated a
certain number of Ruby scripts that are working really well, but right now, I
can’t think of any reason to use Ruby when I have Groovy.

Groovy does everything Ruby does, with three additional points:

  • Its syntax is Java-like.
  • It has access to the entire Java objectscape.
  • It can compile to .class files.

For all you know, the next ejbgen.jar that I ship could be written half in
Java and half in Groovy.  You won’t notice.  My regression tests won’t
notice.  And the version after that might be 100% Groovy.

And this is precisely what should worry Sun.  And why I think Groovy
will not be accepted as a JSR.

But I wish good luck to James and I sincerely hope I’m wrong.

 

Stroustrup on elegance

It’s always interesting to get a chance to look inside Bjarne Stroustrup’s
mind.  Even though I am more and more distressed to see him entrenched
in positions that are not easy to justify, such as "C++ is simple" and "Java
is a bad language", he is a pragmatist at heart, and it’s a quality I
appreciate a lot.

This time, Bjarne is being
interviewed
by Bill Venners.  Here are a few things that made me react.

I find it interesting that when asked what "simple" or "elegant" means for a
program, Bjarne answers:

Bjarne Stroustrup: "Elegant" and "simple" are very related words.
"Understandable" is another word in that area. What do they mean? It comes to
down to: you can apply tools to your program. You can optimize it. You can
maintain it. You can port it. If you can logically identify something, you can
deal with it. If it’s just a bunch of code scattered throughout a large program,
you can’t do a thing with it.

This is vastly different from what I would have answered myself:  a
program is simple if I can read it and understand it right away. All these other
desirable features that Bjarne enumerates are a consequence of simplicity, but
they do not define simplicity.  I suspect that Bjarne is trying to redefine
the term "simple" so it applies to C++, which is quite a challenge in my opinion :-)

I also notice that Bjarne doesn’t seem to be a big fan of YAGNI:

Bill Venners: How do we do that? How do we design for situations we
can’t imagine?
Bjarne Stroustrup
: You listen to a lot of people and then you aim for
generality.

I also agree wholeheartedly with his laziness principle:

I keep telling my students that they should be lazy. I reject programs that
are too long, because when students get to do real work, they won’t have time to
write that much code. A lot of the things I call elegant you’ll find are short
compared to alternatives.

However, the following quote:

One of the things that amazes people is when you compare good C++ code to
good code in other languages, the C++ code tends to be shorter. C++ code is
shorter when it’s written in terms of things like the standard library or other
good libraries, because you can express ideas very succinctly.

shows his bias, as he is obviously comparing C++ with C, not with Java, where
I am willing to be that equivalent programs are shorter in Java because of its

  • Extensive libraries.
  • Simpler syntax.
  • Automatic memory management.

As a matter of fact, Bjarne manages to avoid talking about Java completely in
this interview…

I wonder if in five years from now, Gosling will be giving a similar
defensive interview while Groovy has become the de facto standard to write
enterprise applications :-)

 

Blocking Flash

I have just discovered this awesome extension of FireFox called
adblock, which is filling a gap I have
been complaining about for a long time now.  Blocking images coming from a
particular server is already a very useful feature, but as you may have noticed,
Flash ads are slowly becoming the norm in advertisement, and unfortunately,
FireFox (or Mozilla) doesn’t let you block them.

Nor does it allow you to add Web sites manually to the "blocked" lists, so
the only solution is to view the source, locate the URL of the ad (not always
easy) and alias it to "localhost" in your hosts file.

These days are gone.  adblock does all this and will let you specify any
arbitrary filter on the URI you want.  No more unwanted animated GIF’s or
Flash.

The Web the way it’s supposed to be.