Monday, October 19, 2009

Pretend you are your own customer.

Our talk in August at Eclipse Day at the Googleplex focused on what it's like to support a large number of users in an enterprise. Dwelling in this question got me thinking about what kind of Eclipse user I might have been five years ago, and so I looked up the first message I ever posted to our internal mailing list for Eclipse users.

I have been a Google employee for just over five years, and have only spent the latter three supporting Eclipse for my colleagues. At the time of this dialogue, I'd been at Google for less than two months, and my Eclipse experience was limited to about 18 months of mostly untrained use.

Before you bother reading it, please do not waste time troubleshooting the problem -- that's not the point if this post. This is a five year old issue, after all.
Robert Konigsberg
to <eclipse mailing list>
Subject: Problem with Eclipse 3.0 installation
10/10/2004
Hi all,

This afternoon I was working pretty happily in my Eclipse environment. All of I sudden I got a message telling me that I ran out of heap space, and advised me how to change my heap space. It offered to shut down Eclipse. I said "no". saved some work and quit myself.

When I tried to restart Eclipse I got all sorts of odd stuff. I can open Eclipse, but if I try to open the Java perspective, I get the error, "Problems opening perspective 'org.eclipse.jdt.ui.JavaPerspective'. Restarting my machine didn't help. When I try to edit Java preferences, I get similar errors.

Thoughts? Steve, is it Upgrade-To-3.0.1-Day for me?
Cedric Beust
to Robert Konigsberg, <eclipse mailing list>
Re: Problem with Eclipse 3.0 installation
10/11/2004
What does your .log say?  Is it running out of heap space at each launch? In which case, I suggest to launch Eclipse with more heap:

eclipse -vmargs -Xmx600M
Robert Konigsberg
to Cedric Beust
cc <eclipse mailing list>
Re: Problem with Eclipse 3.0 installation
10/11/2004
Don't know which .log I'm looking for. Note below (edited for readability)

~/.eclipse$ find . -name "*.log" -ls
1556 Sep 29 18:20 ./org.eclipse.platform_3.0.0/configuration/org.eclipse.update/install.log
1008 Sep 29 18:20 ./org.eclipse.platform_3.0.0/configuration/org.eclipse.update/error_recovery.log
~/.eclipse$ cd ../workspace/
~/workspace$ find . -name "*.log" -ls
1319 Sep 10 18:17 ./.metadata/.plugins/org.eclipse.tomcat/catalina.2004-09-10.log
1319 Oct 10 10:50 ./.metadata/.plugins/org.eclipse.tomcat/catalina.2004-10-10.log
1017 Oct 10 16:48 ./.metadata/.plugins/org.eclipse.help.base/browser.log
~/workspace$ find . -name "*.log" -exec vi {} ";"
Cedric Beust
to Robert Konigsberg
cc <eclipse mailing list>
Re: Problem with Eclipse 3.0 installation
10/11/2004
Sorry, should have been more specific...

The .log file is in your ${eclipse-workspace}/.metadata directory.
I've removed the rest of the dialogue. Suffice it to say that it was probably a JDT index corruption issue that was resolved by removing the workspace-root/.metadata/.plugins/org.eclipse.core.resources/.root directory.

Here's the point: it's a little embarrassing to see that while I've attained some expertise in this domain, even I had no idea where the workspace log was. Also, I called it the "Eclipse environment" which is kind of a little wrong.

I appreciated both the memory and the mild feeling of humiliation that came with pulling up this old email.

Monday, October 12, 2009

Story Time with Google Collections

Note: this post in no way suggests that Google Collections is wasteful. Quite the opposite, it's spectacularly awesome. If you haven't used it yet, go get it, play with it, discover appropriate uses of its power, and go rock your project.

Several months ago there was a discussion on one of the mailing lists at work about preference of part of the Google Collections API over an imperative equivalent. Specifically, using Iterables.transform to translate a List<X> into List<Y> by creating a Function that translates X into Y. In other words, which was better?

This:
Function<X, Y> function = new Function<X, Y>() {
  public Y apply(X from) {
    return X.asY();
  }
};
List<Y> listOfY = Lists.newArrayList(
    Iterables.transform(listOfX, function));

Or this:
List<Y> listOfY = Lists.newArrayList();
for(X x : listOfX) {
  listOfY.add(x.asY());
}

There was this argument about the value of the functional style over the imperative style, and frankly, I found it all rather confusing. All things being equal, the former was just too damn much. And that's the key here: all things being equal. If we were using a language with proper closures, or if there was a host of Function instances available to substitute for function, I might have (and have had) a different opinion.

To illustrate my point, I submitted this story to the mailing list.
Me: Kevin, tell me a story.
Kevin: Seriously. Go away.
Me: TELL!!
Kevin: OK. Once upon a time there was a programmer. He wanted a List. of Strings. But unfortunately, he had a List of Another Type.
Me: What type?
Kevin: Doesn't matter.
Me: WHAT TYYYYYPE!
Kevin: DOESN'T. MATTER.
Me: Ice Cream?
Kevin: Ice Cream. Fine Ice Cream. So the programmer...
Me: How much ice cream?
Kevin: What?
Me: How MUCH?
Kevin: Well, let me put it this way: if it was a List of ice cream, it would be A LOT of ice cream.
Me: Eeeeeeee!
Kevin: (pause) So... this programmer decided to take the list and return a New List. He decided to transform his list by creating a magical function that converts Another Type ... I mean ... _ice cream_ into Strings. And that Function has a method called 'apply'. Apply takes things of type ... sigh ... _ice cream_ and converts it to strings. It does this by calling its callStringMethod. The End.
Me: Wha?

--- REWIND
Kevin ... it would be A LOT of ice cream.
Me: Eeeeeeee!
Kevin: (pause) So... this programmer created a new, empty list. A place to store the Strings. And then he went through every _ice cream_ element in the old list, called its callString Method, and added it to the new list. And then he returned that list. The end.
Me: *sob* that is so awesome. What happened to the ice cream?
Kevin: I think Josh has it. Hurry up before he eats it.
Nobody here is saying that functional programming is bad or wrong. But sometimes it's not really all that awesome to be cutting edge.

Update: What I mean to say, that my colleague said in much fewer words, is that the primary concern in coding should be making your intention as plain as possible.

Thursday, October 01, 2009

A Blatherberg Poem about C++

C++
I don't understand all the fuss
If you want a scoped pointer
Find a lady and anoint her
with watching your mem-o-ree!
Oh I want -- to -- go -- back -- to -- C.
With its malloc and its free
I just get so confused with delete and new
And what deletes who
And comparing an int to a boo-lee-an
I won't ever write a for loop
Thanks to Bjorne Stroutroup
And Alexander Stepanov
And I'll bet you've had enouv
of this poem.

Tuesday, September 29, 2009

The Java language feature I want: Exception Sugar

I've enjoyed observing all the discussion around the new features to make it in to Java 7. All this time I've had an idea about a language feature which I've occasionally mentioned to colleagues, and it's around the domain of exceptions.

Before I discuss the problem, or my proposed solution, let me be frank: I'm no language expert. I have no expectations that a suggestion such as this has a chance of getting in to Java 8 if they can't even get multi-line strings into Java 7. I don't even care about the impurities brought up by this proposal. What I do care about is discussing a more graceful way of dealing with exceptions.

I'll agree with some of the fundamental concerns Misko Hevery brings up around the domain of checked exceptions. People often don't know what to do with them. Sometimes people just throw Exceptions into RuntimeExceptions and propogate them up the call stack. People also tend to overuse existing exception classes when one more specific to the a class or API domain would do. As is well documented in Effective Java (2ed) Item 61: Throw Exceptions appropriate to the abstraction. However, this all too often requires an undesirable amout of boilerplate code, and I do mean boilerplate. How many Exception classes have you written that look like this?
class MyException extends RuntimeException {
  public MyException() { super(); }
  public MyException(String message) { super(message); }
  public MyException(Throwable cause) { super(cause); }
  public MyException(String m, Throwable c) { super(m, c); }
}

Unless all your methods throw Exception, or if you only throw RuntimeException, IllegalArgumentException, and AssertionError, the answer is: you've written them plenty of times, and unless you're building an API to be consumed by the tens of thousands of engineers, you're probably not creating abstraction-appropriate exceptions often enough, directly against the advice of Effective Java.

What I propose is lowing the barrier for creating an exception class, which I'm calling Exception Sugar. Again, being no language maven, with no regard to syntax or grammar, I humbly propose:
exception className extends baseClass;
which serves as syntactic sugar for creating a subclass of baseClass named className that also, and here's the nasty part, "inherits" the base class's constructors. Yes, I know damn well that constructors aren't methods; they don't have instance scope, and there's really no such thing as constructor inheritance. I read Jeremy Manson's blog, and he even talks about the worthlessness of constructors. I get it. I couldn't care less. I just want to make it easier to write exception classes. To avoid the term inheritence I'll call it constructor propagation.

Maybe you don't like the proposed syntax. What about:
class className extends baseClass { propogate_ctors(); }
or
@ExceptionSugar className extends baseClass {}
Did you hear that? That, my friends, was the sound of a thousand shattering coffee cups from Java programmers whose grips loosened uncontrollably from the awful syntax. Relax, girls and boys. I'm not trying to sell syntax. I'm just trying to sell an idea. Get over the syntax, and mop up your coffee.

Q: Why can't you write your own exception class?
A. I might get it wrong. And I want to do it a lot. I want to make creating a domain-specific exception class even easier than creating a class for the domain.

Q: How could you use Exception Sugar to create subclasses that have additional attributes, or slightly different constructors?
A: I don't have any illusion of doing so. It seems to me that 99% of the time, people want to subclass Exception or RuntimeException, and even then, they only define just one constructor instead of all four.

Q: Why can't constructor propagation be applied to non-exception classes? Why should exceptions be the, ahem, exception?
A: Ha ha nice one. They don't have to be, but I'm not interested in easily propagating for classes outside the exception hierarchy. But if I'm pressed, constructor propagation in non-exception classes is almost certainly a Bad Idea, but am not going down that path tonight.

Q: Why not focus on something more valuable, like properties?
A: Properties sounds like a good idea. Go for it. The reason I bring up this particular idea is because I don't see anyone else thinking about it. That isn't to say I haven't brought it up before. I even mentioned it to Alex Buckley at last year's EclipseCon. Poor Alex, it was 1:30AM, and he and I somehow managed to win the party that evening, and so he had to suffer listening to yet another armchair language designer. But I will say, when I mentioned exceptions, he thought I was referring to catching multiple exception types. At least he was surprised, which means the idea might be awful.

Or awfully brilliant!

To be fair, Alex described some of the details that demonstrate the difficulty of this idea, but the combination of many drinks and the late hour made it impossible to understand. (Sorry, Alex.)

But getting back to the value of such a proposal: if people can propose literals with underbars and the Elvis operator, I can talk about this, too. (Don't get me wrong, I very much want the Elvis operator.)

As a conclusion of sorts, I'm about 95% confident there's a technical reason for prohibiting Exception Sugar, and about 99% confident it would never make it in to Java. I'd be honored if someone with an understanding greater than mine of Java and language design would be willing to comment on this idea, and provide some thoughts about the technical issues, if at least to educate.

Thanks for reading. Thanks to David Mankin for his feedback.

Eclipse toString generator magic

In June I made some general comments about Eclipse contributions, using the poor toString generator as my target. Fundamentally I still think Cay Horstmann's arguments are valid, but also, sometimes a partially complete solution is better than no solution at all.* and I realize this is one of those times. Today I needed to generate a toString method merely for the benefit of giving a nice view while debugging my application. In such a case, the toString generator came through like a charm, generating a nice, simple, clean implementation. Neat. Thanks, Mateusz.

* Sometimes a partially complete solution is worse than no idea at all.

Thursday, September 03, 2009

Slides and videos now available for Eclipse Day at the Googleplex

Hi all,

The videos and slides from Eclipse Day at the Googleplex have been published.. You can find the slides on the Eclipse Foundation's wiki and the videos on the Google Open Source Program's blog.
Thanks again to everyone who organized or attended the event.