Wednesday, August 20, 2008

We're moving!

You heard it here first. We're moving back to New Jersey. Beth's getting a new job, but since there hasn't been a bona fide offer, I won't say anything just yet. I'm keeping my job with Google, I'll just change where I do what I do. Also, we're keeping the dog.

If Beth's job is settled as we expect, she will leave Los Angeles a couple of weeks before me. I will drive with the dog across the country. Whereas last time I drove cross-country over twelve days, this time I don't plan to stop for a couple of days in each city, since I'm currently employed and also because Maggie is not much of a sightseer.

We're still working out dates, but rest assured, by Halloween, we'll be gone.

Tuesday, August 12, 2008

Stick with Draft Blogger

I like the recently updated Blogger in Draft. It contains many long-anticipated features, including a nifty new editor, something I desperately wanted. Don't be fooled by the word draft, it's in good shape.

There's one small problem, though: even though I can create new posts using the draft editor, you're still led to the original editor when selecting edit links straight from the blogroll. That can actually cause some formatting problems, since both editors interpret HTML a little differently.

So for the short term, I wrote a small Greasemonkey script that mutates the anchor tag. Have fun with it.

Sunday, August 10, 2008

Watch your return values

Preface - This post was going to be a one-sentence comment to a post by Jeremy Zawodny, but then I remembered my professor, and it went from there.

I had a professor for two semesters that required that all our assignments were written in C. This was his assignment submission policy:
1) Run lint on all your code.
2) All code must have zero warnings from lint, with no exceptions.
3) Any use of strcpy resulted in a zero for the assignment.

#3 was my first lesson about buffer overflows. (We all used strncpy.)

One of the lint warnings pertained to unused return values. For instance, the method signature for printf is
int printf(char *format,...)
How often is printf's returned value given attention? It represents the number of characters written to the stream, or a negative number on failure.

Our linter complained about unused return values for typical uses of printf like:
printf("--done.");
We were required to either accept and process the return value, or explicitly disregard it:
(void) printf("--done.");
This was one of my earliest impressions of studying defensive programming.

In Java, the method java.io.InputStream.skip has a contract that requires you to pay attention to the return value, and the reason may surprise you:
public long skip(long) throws IOException
The skip method may, for a variety of reasons, end up skipping over some smaller number of bytes, possibly 0. This may result from any of a number of conditions; reaching end of file before n bytes have been skipped is only one possibility. The actual number of bytes skipped is returned. If n is negative, no bytes are skipped.
So, you supply a distance to skip, and you likely expect the same value back, at least, most of the time. What amazes me is that the documentation even addresses the common expectation: sure EOF is one way skip(n) != n, and then says, twice, that there may be a "variety of reasons" and a "number of conditions." The author is trying to make up for a troublesome API with special javadoc.

Forget that oftentimes there's no documentation and hence, no contract, you still can't expect that documenting unexpected behavior is going to result in proper use of the API.

Present day, Java has Findbugs, The Lint Of Java (zero results, you saw it here first!) Java's classfile format and FindBugs' semantic analysis makes it much more powerful than lint, it can identify this issue with java.io.InputStream.skip(). From the description as Findbugs reports it:
This method ignores the return value of java.io.InputStream.skip() which can skip multiple bytes. If the return value is not checked, the caller will not be able to correctly handle the case where fewer bytes were skipped than the caller requested. This is a particularly insidious kind of bug, because in many programs, skips from input streams usually do skip the full amount of data requested, causing the program to fail only sporadically. With Buffered streams, however, skip() will only skip data in the buffer, and will routinely fail to skip the requested number of bytes.
That's great, but there's a problem, and that comes with expanding the API. If I build my own API with its own nuances, someone needs to write a FindBugs detector. (Hint: be careful writing a clever API!)

It seems draconian to enforce a policy of "always address return values" with Java outside academia since there's no easy way to mimic the explicit cast to void. Otherwise you wind up with unused local variables, which becomes yet another code smell.

In the end all tools like FindBugs and lint only augment the human analysis that accompanies development.

I hope students today are being told that they cannot turn in any Java assignments without running FindBugs.

Saturday, August 09, 2008

One year ago

Part one: the past

My mother died one year ago, or just over one year ago, depending how you look at it.

Last July 21 was a Saturday. My wife and I spent the day at my company's rather successful summer picnic. Beth and I had a wonderful afternoon socializing, playing with adults and children, and feeling generally pretty good. We left the party around 5PM, and I was still a little drunk. This was no issue since we planned to spend the evening watching a movie on TV. At home we ordered some take-out Chinese food, and settled down with our new dog, Maggie, who we finally became accustomed to, and she, thankfully, to us.

Some time around 6PM my brother called to say that mom had collapsed. Her boyfriend discovered her on the floor, and she was at the hospital. He didn't know anything else. I said "I'll get on a plane right now." but he told me to wait. Ten minutes later he called back: "It's a cerebral hemorrhage." Still, no more details. I told him I would come home, but he impatiently told me to just wait. He called again after ten more minutes: "You have to come home right now. The doctors say she's not going to leave the hospital alive."

So Beth and I managed to get me packed, get a plane ticket, and out the door in short time. Only one plane ticket was purchased; Beth was incapable of leaving until the following day. Maggie, who was by now generally happy and comfortable with us, felt all our stress and would not stop barking and meddling. It was very tense.

But we had a pending issue: our other brother was nowhere to be found and we needed to find him as quickly as possible. After several phone calls we discovered he was in Albany, but didn't have any contact information. Everyone we spoke with helped us collect some data, and also said they would do whatever we needed. Luckily, one of them is the most reliable person I know for just such an issue, so when I said: "Steve, here's what I need: find Peter." we all knew that the job would be done. And he got the job done.

Getting through the airport that Saturday night was a breeze. Although there were long lines, every staff member treated me like I was beyond first class when I explained the situation. I was intentionally terse: "I'm the guy who bought his plane ticket 30 minutes ago because he has to go home for a family emergency." Not "I'm the guy" as in, "I'm the guy you just spoke with" but rather, "I'm the general profile of that customer." I was moved to the front of every single line.

At about 10:15PM I settled in to my window seat for the red eye home. It was during the pre-flight security briefing, when there was nothing else to keep me occupied that I finally broke down. I cried quietly but uncontrollably. The flight attendant brought me a box of tissues.

A stewardess came around to deliver the first round of drinks. This was an overnight flight, there was no more food to be served. I hadn't eaten since before the holiday party ended, and was coming off a couple too many drinks to boot. I prepared a long message on my handheld phone so that I would not have to speak over the passengers. The note was also crafted to fit on one screen so the flight attendant would not have to figure out how to scroll the screen. She arrived and I showed it to her: "Going home for a family emergency. Got my ticket last minute, and had no dinner. Is there anything more substantial than peanuts? Also, OJ no ice please." (This, it turns out, was early training for Twitter.) She returned five minutes later with a microwaved Chicken Parmesan sandwich. I'm positive they store these for just such an emergency. It made me feel taken care of.

Two days later, on July 23, the doctors turned off the life support system to my mother and she died. She was buried two days after that. In those intervening two days I took care of calling almost all the friends and family. Mom's red address book is still sitting at my computer, where it's remained, untouched, for at least 11 months. Also I wrote a eulogy, which I presented at the funeral. I worked very hard on it, and I'm not ashamed to say that the hard work paid off. I've considered sharing it several times on this blog, but its consideration caused me to discover that there are just some things best kept private.

This intervening year was very difficult. The first three months back at work were unsurprisingly unproductive, and I was sullen and unfriendly, particularly to my wife. The following three months were also unproductive, but now they were surprisingly so -- I was not getting back on track. However, I was much nicer to my wife. It was only the following six months when I was able to function at full steam and resume feeling good about myself.

Of course Beth was a big factor in my recovery, but what neither of us expected was how important our new dog, Maggie, was in our mutual recoveries. We poured all our love and attention in to her, and we're still just crazy about her. As I admitted in last year's post about Mom's death, Beth and I used to confess to each other "If mom died I don't know what I'd do." Now we confess to each other "If Maggie dies I don't know what I'd do."


Part two: the recent past

My mother died one year ago, or just over one year ago, depending how you look at it.

This past July 23 came and went, and while I recognized that a Gregorian year had completed, it surprisingly remained a fairly non-day. But I did speak to my brother, which is not something I do every day, and it was on his mind too.

The following week I noticed something: when faced with a trauma that gets easier with time, you go through phases. During the first phase, you think about it all the time. During the second phase you think about it every day. During the third third phase, you don't think about it every day. That week I discovered a phase in between the second and third: you think about it every day, but you're not completely sure.

Seven days ago another significant day passed: the day of the annual company summer picnic. Was that the acknowledgment that a year had passed? No, though once again, it was on my mind.

Four days ago Mom's condo sale completed, and three days ago, her estate dissolved. The majority of the work to get this done fell on my two brothers, since I live so far away.

Tonight was the start of Yartzeit - the mark of one year according to the Jewish calendar.
Sidebar: why don't Jewish calendar days match up with Gregorian calendar days? That's well covered elsewhere. Suffice it to say that both calendars operate like a rolling cylinder with a weight attached to the inner side; sometimes one is ahead, sometimes the other.
This the last of the four events that could mark the passing of a year: the Gregorian calendar, the company picnic, the chronologically convenient end of Mom's estate, and Yartzeit. It is on this last day that I choose to acknowledge her passing, and so tonight I lit a memorial candle, and wrote this, and continue to think about her.


Epilogue

I said I would not share the eulogy I wrote for Mom. It will continue to be kept private, but I'll make one part public -- my favorite, in fact. It contains a superb tactical edit from my dear friend Mark. It's written as if I were talking directly to her:
You should know that Teddy is responsible for telling me that you love getting flowers. Boy this make acknowledging you on Mother's Day, or really, any day, very very easy, and whenever you called to thank me and describe the flowers, it made me feel like I hung the moon.
Mom, you've been gone for a year and while I miss you all the time, you still make me feel like I hung the moon.