if ( document.comments_form.url ) { document.comments_form.url.value = getCookie("mtcmthome"); } Otaku, Cedric's weblog: March 2004 Archives

March 31, 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?

Posted by cedric at 02:50 PM | Comments (5)

March 29, 2004

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.

Posted by cedric at 05:15 AM | Comments (4)

March 26, 2004

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.

 

Posted by cedric at 08:09 AM | Comments (12)

March 24, 2004

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.

Posted by cedric at 07:40 AM | Comments (3)

March 22, 2004

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.

 

Posted by cedric at 09:48 AM | Comments (6)

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!

Posted by cedric at 07:59 AM | Comments (2)

March 19, 2004

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.

 

Posted by cedric at 05:44 AM | Comments (0)

March 18, 2004

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.

 

Posted by cedric at 08:48 AM | Comments (10)

March 17, 2004

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 :-)

 

Posted by cedric at 09:35 AM | Comments (1)

March 15, 2004

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.

 

Posted by cedric at 07:58 AM | Comments (18)

March 14, 2004

Fun with unions

I was discussing with a friend about same-sex marriages the other day (for those of you who don't live in America, there is a big controversy sweeping across the country about whether same-sex marriage should be allowed or not.  It's currently illegal in most states but a movement aiming at making it legal is gaining a lot of momentum).  My friend pointed out that if marriage gets reformed, then maybe we should also consider making polygamy legal as well.

This idea is not the point of this post, although my opinion is that the two debates have nothing in common since the monogamy law doesn't violate the "equal rights" clause of the Constitution.

After this discussion, I did some research on the Internet for "polygamy" to gain some insight.

Sure enough, there is a Web site called polygamy.com, and that's where the fun starts.

First of all, their main page is quick to point out that they endorse the idea of a man having several wives but not the other way around.  Let's leave aside the fact that this idea is anti-constitutional for the reason cited above for the moment and focus on what this Web site has to say:

"Polygamy", as referred to on this site, is meant in its most popular usage, where one husband has more than one wife at the same time. Technically, Webster's Dictionary defines this practice as "polygyny."   Polygamy.com does not support "polyandry", where one wife has more than one husband at the same time.

It seems to me the authors of this Web site were so gung-ho about the idea that they decided to register the name polygamy.com and create a Web site.  Then out of curiosity, they checked the dictionary and to their horror, realized that their understanding of the word "polygamy" was...  inaccurate, to say the least.  It's too late to backtrack, so they go to all these lengths to justify that throughout their Web site, they will be using their own meaning for the word, not even realizing that they are actually undermining their goal for all the readers who won't bother reading their disclaimes.

But it doesn't stop here.

For more fun, check out their explanation why "polygamy (polyandry actually) is good for women".

The Onion would be proud.

 

 

Posted by cedric at 08:43 AM | Comments (2)

March 12, 2004

Named parameters

Dion likes named parameters:

I have always liked named parameters, as I have seen many bugs due to methods such as: doFoo(String acct1, String acct2). Here we have no way to know if someone is passing in the right info (other than via Unit tests).

Named parameters are indeed attractive, but they come at a price.

First of all, method parameters become part of the signature of your method, which means you can't modify them without breaking your users.  It might sound like a minor annoyance but my experience tells me that the least you expose in a public API, thee asier your life will be.

But the best lesson about named parameters comes from C++, again.

Named parameters almost made it into C++.  The proposal had been reviewed several times by the Committee and there was a universal agreement on their good qualities:  easy to explain, easy to implement, not representing any major backward compatibilities issue, etc...

Bjarne was just a little bit concerned about the extra verbosity in the source, which was going to make it harder to search source files, but he agreed that his objection was not strong enough to decline this new feature (we can also notice once again how pragmatic he is.  It's also interesting to point out that this kind of concern is moot now that IDE's provide us with semantic searches).

And then, a few days before the proposal was formally accepted, one of the group experts sent an email to everyone saying "We don't need named parameters, we already have them".  And then he proceeded to demonstrate his point by turning the working example (in Java syntax for readability):

Window w = new Window(x:0, y:0, color:blue)

into

Window w = new Window().x(0).y(0).color(blue);

 

Posted by cedric at 08:57 AM | Comments (17)

March 10, 2004

JAM documentation

Patrick just posted some documentation on JAM, the type abstraction API used in EJBGen and SGen.

The idea behind JAM is to offer a uniform access to the way the Java type system (and more particularly, annotations) are collected.  Right now, JDK 1.4 is supported, 1.5 will be available very soon (source or .class form) and in the future, you can expect more metadata providers to become available.

JAM is shipped as part of the Open Source Apache XMLBeans project but we are considering making it a standalone product (which for now is available directly from Patrick's Web site).

There is a lot of design work currently happening around JAM so now is the time to provide feedback!

 

Posted by cedric at 04:54 PM | Comments (6)

March 08, 2004

Precisions on Canvas and Velocity

I have to say I am surprised by some of the comments I have received about Canvas, and in particular from people who say that the Velocity Template Language (VTL) is a better choice than Groovy because it's not a "real" language, so you are not tempted to mix presentation and business logic.

First of all, the assumption that the generated template is for "presentation" (probably meaning:  a Web page) is a generalization.  Velocity is used for much more than just generating Web pages, so this argument is weak in my opinion.

But if you think the VTL is just a declarative language, you are fooling yourself.  VTL has

  • Control structures (if, while, etc...).
  • Variables.
  • Macros.
  • And worst (or best) of all, it has access to the underlying Java objects.

In other words, I am pretty sure that you can use VTL to write arbitrarily complex pieces of code inside your template, and Sam was quick to point out a perfect example of that.

With that in mind, if we are going to have to deal with a language inside the template, I would rather use one that I like, is powerful and ideally, close to the Java syntax.

There is also another reason why VTL is less than optimal for this, and it has to do with the philosophy behind Velocity templates.

Velocity templates make no distinction between "verbatim text" and VTL.  The only way to identify the pieces of VTL code in your template is by spotting the various syntactic annotations (#, $, etc...).  The problem with this approach is that it makes it pretty much impossible to guarantee the indentation of the generated files, since you can never tell when a space is significant (part or your "verbatim text") or should be ignored (used to indent a VTL expression).

The JSP syntax (or any delimiter-based syntax) makes it obvious what spaces should be preserved and which ones can be ignored for the generation of the final file:

// Canvas template
public class GeneratedClass {
  <%
    for (i in methods) { i.generate() }
  %>
}

From my experience, it is absolutely impossible to get a decent indentation for this very simple example with Velocity...

Posted by cedric at 10:37 AM | Comments (8)

March 07, 2004

Canvas: a Velocity killer

Now that I have your attention :-)

Velocity is a fine product that delivers its promise, but it has a few shortcomings:

  • Velocity is pretty much a dead project.  There has hardly been any activity in over a year and nobody seems to be interested in taking over.  The good news is that from my experience, Velocity is relatively bug free, but it doesn't bode well for its ability to evolve with the increasing demand of modern Java computing.
     
  • It comes with some annoying dependencies, such as log4j or commons.  I am not criticizing the quality of these two packages but Velocity has a rude way of instantiating its loggers that recently gave me quite a headache.  On a related note, if you intend to publish a framework, please think twice before adding dependencies on packages that your users might be using in their own code base.  To add insult to injury, log4j happens to have a perfectly decent equivalent in the JDK itself.  Granted, java.util.logger isn't as powerful as log4j, but in this particular case, I see no reason why Velocity is trying to impose its own logger on pour souls like me who only need a simple generator framework.
     
  • Finally, Velocity offers very little control on the indentation and shape of generated files and I haven't found any satisfying way to solve that problem.

With that in mind, I started thinking about a replacement.  The Velocity API is simple and easy to understand, but I had no desire to implement yet another expression language.  The solution quickly imposed itself to me:  Groovy.

Not only is Groovy a cool language that borrows features from two of my favorite languages, Java and Ruby, it's also extremely easy to embed in a Java application.

With that in mind, it took me just a few hours to put together this quick prototype of a product reusing the Velocity API but using Groovy as its expression language.  The good news is that the dependency is now limited to one jar file:  groovy.jar.

I called this product Canvas and you can read more about it on its home page.

Also, I'd like to take this opportunity to hereby claim the title of the smallest framework ever:  Canvas only has three classes.  You can't get more lightweight than that!

Posted by cedric at 07:02 PM | Comments (26)

March 06, 2004

Anti-spam conference

I just read a very interesting report on the Anti-Spam conference that just took place at the MIT.

It contains some very interesting comments that are guaranteed to keep spam filter developers busy for quite a while, such as:

He found that randomly deleting a few words gave a 3x improvement in accuracy.
or how some servers can be used as "tar pits" to spammers in order to make their life more difficult:
451-Your spam is important to us. Please stay on the line. 451-Your spam is important to us. Please stay on the line. 451-Your spam is important to us. Please stay on the line.
although some other proposals such as:
To simplify a little bit, you use an address until it starts getting spam. As soon as that account gets its first piece of spam, you "lock" it so that anybody who has sent you mail to that address in the past can keep using that address; anyone else gets rejected at the server.
look dubious to me since they don't address the main problem of spam today: how can we protect our existing email addresses from the incoming downpour.

Posted by cedric at 01:51 PM | Comments (0)

March 04, 2004

SGen clarifications

SGen has caused quite a stir, so I thought a few clarifications were in order.

JAM

There is quite a bit of interest about JAM, and rightfully so, so I'll start with this.

JAM is shipped with XMLBeans, so it's an Apache product.  I didn't include it in SGen (although I did include the JAM javadocs), but if you want the whole JAM distribution, just download XMLBeans.  What you won't find in that distribution is the JSR 175 code, though, which I just recently wrote.  I will ship this as part of SGen for now, though, but eventually, it will make it in XMLBeans as well.

The only reason why the SGen distribution is a bit messy right now is that I need to figure out a way to package it with two different jar files (1.4 and 1.5), and I just haven't had the time to do that so far.  Please bear with me.

SGen

Over the past months, I have received increasing requests to make EJBGen extensible.  Since EJBGen is not open source, the only way I could do this was provide an extension API in the same spirit as Eclipse or COM.  As I started factoring this code out of EJBGen, it occurred to me that the framework was actually turning into something fairly generic.  EJBGen was already using JAM back then and it became quite obvious that SGen could become not only a generator framework, but that it would be annotation-neutral on top of that.

From this point on, the other ideas fell in place very naturally.  The concept of separate jars for modules became central to the design of SGen.  Ideally, I want people to download a minimal SGen runtime and then shop around for various jar files (in source form or not) for the various modules they need.  This way, they create their own generator "a la carte" and one single invocation of the generic SGenRunner is all that's needed in their build to generate all the files they need. 

XDoclet

Here is my perception of the XDoclet landscape right now.  Please note that as opposed to the other sections, what follows is admittedly very subjective and I have no doubts that a lot of people will disagree with me.

There is an impressive number of XDoclet plug-ins used in production, and I think it's fair to say that 99% of them are based on XDoclet 1 (since XDoclet 2 is not even alpha, as far as I know).  Of course, anybody who has written a module for XDoclet 1 is very interested in porting their code to XDoclet 2, which offers a very compelling Velocity-based template model, as opposed to the version 1 and its XML language.

XDoclet 2 has been brewing for quite a while, now, but hasn't seen much activity in the CVS depot or the mailing-lists.  This standstill has had a disastrous effect on the landscape:  module authors are hesitant starting working on a pre-alpha version while reluctant to add more code in their v1 plug-in which is going to be obsoleted “very soon”.  My impression is that development of XDoclet modules has slowed down quite a bit because of this.

This realization and the fact that the SGen framework was reaching a decent shape led me to the thought that either SGen would pick up where XDoclet left, or that it would create an electroshock in the XDoclet 2 community, thus reviving it.

Either way, it seemed like a good thing.

SGen and XDoclet

The comparison between SGen and XDoclet is inevitable, and it’s quite justified since SGen is in some way trying to pick up where XDoclet left off.

First of all, I’d like to emphasize that SGen is such a lightweight framework that it could actually be used as a foundation for XDoclet.  All SGen does (besides the JAM part) is to define a formal SPI that modules need to respect when they contribute generators and configuration parameters.  That’s all.

SGen only has one plug-in right now, but it’s a sizable one (EJBGen) and I believe it’s complex enough to serve as a proof of concept.  I don’t think it’s fair to judge the potential of SGen on the number of modules it supports today, since SGen is hardly an alpha release right now. Besides, I don't recall XDoclet 1 or Hibernate getting immediate traction on the day they were announced :-)

I received an interesting comment mentioning two features of XDoclet 2 : “pluggable input source” and “pluggable metadata processor”.

First of all, these ideas look interesting, but I couldn’t find any documentation about them.  Call me picky, but mapping a CVS depot and reading code to understand concepts is not my idea of fun, so if somebody has a URL or a white paper to give me, I would love to take a look.

Nevertheless, the comment is justified.  That’s what SGen and JAM offer, except that we don’t make it possible to plug a metadata processor, we give you one (well, two:  a Javadoc and a JSR 175 processor).  I am not quite sure that a “pluggable input source” is, though, but it sounds cool, so we’ll provide it too :-)

Finally, Merrick made some very interesting comments about JAM, which I will address in a separate post.  I can already give you a hint, though:  I was having this very discussion with the author of JAM just yesterday, so stay tuned, there is more to come in this area as well.

 Present and Future

The SGen release is a bit messy right now.  The source is included, but mostly to satisfy users’ curiosity.  I really don’t think there is much value in the implementation itself, so I am surprised to hear that some people actually tried to build it.  But fair enough, I’ll make that possible.  In the meantime, please focus on sgen.jar and the examples.

My goal by releasing SGen at this early stage is to get the API “out there”.  EJBGen has proved that SGen is already useful in its current form, but I’d like to hear from developers who wrote generators recently -- either XDoclet or others --  to take a look at this API and let me know if it would fit their need.

 

 

Posted by cedric at 08:12 AM | Comments (9)

March 03, 2004

SGen: an XDoclet killer

Now that I have your attention :-)

I am happy to announce the initial release of SGen, a framework that makes it easy to create tools that parse annotations and generate files.  Some of the goals for SGen are:

  • Modules can be developed separately and shipped in individual jar files.  All they need to do is contain at least one SGen module (which is achieved by implementing a certain interface).  For example, you can download ejbgen.jar, drop it in your "modules" directory, point SGenRunner to it and voila, you have added a new generator to your arsenal.
     
  • SGen is annotation-neutral.  It supports both Javadoc and JSR 175 style annotations.  The way the annotations are collected is made transparent to your module through an open-source abstraction layer called JAM.
     
  • SGen doesn't mandate any template technology.  You are free to use Velocity or println if that's what you want.
     
  • SGen is XML-free.  That's right, baby, you won't have to write a single line of XML to use it.

Since the question is most likely going to come up, I don't see SGen as a direct competitor to XDoclet, although they achieve similar goals.  The idea is that if you wrote an XDoclet module, you should be able to factor out all the "business logic" of your generators and make an SGen module out of it.  Then your module can be downloaded by your users and mixed with the other SGen modules they use.

For more details, examples, architecture overview and JavaDoc, please take a look at the SGen home page.

SGen is certainly in alpha stage at this point and as you can see at the bottom of the documentation, more features are coming up, but since the current version works fine for the very demanding EJBGen (which is now an SGen module), I think it is in a good-enough shape for early adopters.

All questions about SGen should go to the SGen mailing-list.

Posted by cedric at 01:11 PM | Comments (15)

The value of free? Not much.

Clemens Vasters wrote a very insightful letter addressed to a young open-source enthusiast:

Do you want to have a car, a house and a family when you are 30? Do you love being a software engineer at the same time? If so, you literally need to get a life. Forget the dream about stuff being free and stop advocating it. It’s idiocy. It’s bigotry.

I couldn't agree more.  Note that Clemens is not saying that open-source software is useless or worse than closed-source one.  His points are much more subtle than this.  It's all about personal achievement, being able to do a work you enjoy and stopping being a bigot.  To paraphrase Clemens' advice:  "If you are not an open-source enthusiast at 20, you have no heart.  If you are still an open-source enthusiast at 30, you're an idiot :-)".

I would push Clemens' argument one step further:  carefully thinking about the kind of license you want for your code is a great way to make sure that not only this software will be maintained, but that working on it might even become your profession.

Very often, open-source enthusiasts go from one extreme to the other:  they release their source as open-source (or worse, GPL), then work on it for a few months, sometimes a few years.  One day, a real job kicks in that is incompatible with their free software and soon thereafter, their project joins the ranks of the thousands of other dead projects on SourceForge.

On the other hand, if from day one, you decide to retain a certain number of rights on your source and that your program is indeed successful, you might very well end up combining the best of both worlds:  keep working on it and making money from it.

At any rate, liking a certain software just because it's open source is not only dumb, "it's idiocy and bigotry".

 

Posted by cedric at 03:23 AM | Comments (17)

March 02, 2004

POGO's

As I confessed earlier, I am a big fan of properties, whether they are implemented in C# or Ruby.  Not a day goes by without me missing them thoroughly in Java land, as I tirelessly write an endless stream of "int m_foo; public int getFoo() { ...};   public void setFoo(int n) { ...}" (actually, my IDE does that for me but it's still a waste of space and it gets in the way of readability).

How come I am not surprised that James found such a neat way to solve this conundrum in Groovy?

James call them POGO's (Plain Old Groovy Objects), and declaring them is as simple as declaring your fields public.  The Groovy compiler takes care of generating the boiler plate accessors without them getting in the way of your published interface.  I think it's important to be able to control the access to your fields, but I also believe it's very important for this access code not to obfuscate your code more than necessary.

Once again, Groovy hits the perfect sweet spot between Ruby and C#.

Well done, James.

Posted by cedric at 06:16 AM | Comments (4)