29 Jul 2011

Walking on water

There's a Boat Show going on in Darling Harbour.  On my way to work, I thought I'd go check it out.  Only after I entered, I realized that the hundreds of boats that had gathered in there were for sale!  The cheapest one I found was for $73,000.  Most others were much more expensive.  (E.g. "sail-away deal" for a big boat was $499,000).  Looking at all the big boats, I realised that I wouldn't want to own one, even if I could afford the price.  The boats are so big, even imagining owning one doesn't feel good :)

But what I did like was that I was walking on water.  Not literally, of course.  There was a really long platform floating on water for us to walk on.  There's a subtle difference in the way once balances oneself walking on a float like that compared to walking on the ground.  The difference is mild, but it's kinda fun.  The few minutes I was on water renewed my desire to go on a cruise -- basically to be on water for a few days.  Hope I get to do that sometime this year!

23 Jul 2011

Mysskin and me

I saw first two movies of Mysskin and liked them both.  I added him to my "watch list".  When he was making his third movie, I happened to see his interview on TV for a minute or so.  He was saying that a movie is basically a story, and songs obstruct the flow of the story.  Loosely, his view was that songs should not be part of movies.

I saw his third movie Nandhalala this morning.  The movie had almost no songs.  He had apparently asked Ilaiyaraja to compose 5 or 6 songs and later decided not to use most of them in the movie because he thought songs were not appropriate in his story.  So, it looks like he did manage to try his approach to movie making.  Personally, I hated the movie because it was full of extremely unlikely incidents and characters.

Then I saw Yudhdham Sey, his fourth movie.  This movie was kinda liked by some of my friends.  "It's mostly like Anjaadhey (his second movie).  It's not a great movie, but don't miss it" was the advice I got.  While the movie was tolerable, it had its own share of stupid characters and very unlikely incidents.  I hear the movie managed to make some money for the producers, but I wonder if Mysskin himself is happy with the way the movie has turned out to be.

**********

Being the egotist I am, I could see myself in Mysskin.  He looked at other people's work and said they were all doing it wrong.  He rose to make a few movies in the "right way" to show to the world what movie making is, but ended up making movies that are arguably worse.

Same with me.  Every time I look at legacy code I scream.  Everything is in one humongous class?  I scream that one component does too many things.  There are quite a few classes?  I scream that the code is overengineered.  And I know the code I write myself is not any better either.  I am trying to make it better, but I know it's not there yet.

I guess the real lesson for me is this: it's easy to mock legacy.  It's easy to call all our predecesors stupid.  Wise it is to understand that the world is not, and probably never will be, ideal, and do what best we can do.  Life is too short for negative thoughts and feelings.

18 Jul 2011

Feeling sad for no reason

For years I have felt sad without knowing the reason.  Some nights, I'd feel very bad.  A feeling of missing something essential, though I wouldn't be able to pinpoint a thing that I miss.  I'd sometimes discover something as the cause for my worries.  Once such a discovery has happened, I can then consciously think about that and worry deeply.  It has never helped much.

Only a few weeks ago I found out that I don't know the reason for my worries because there's no real reason.  Because I was never worried.  I was only feeling tired and/or sleepy.  Just letting myself relax and rest would bring my happiness back.  Mind is a wretched thing that rejoices in its own tears!

15 Jul 2011

Mistakes

I can correct my brother's spelling/grammar/factual mistakes in public and he's cool with that (although he doesn't always correct me in public).  When I was a kid, I was even told that I am allowed to correct my teachers if/when they're wrong.

Having grown up with people like that, I took the liberty to correct people when I thought they were wrong.  Not many people took it well, especially when they were not close friends with me.  I learned from my experiences and now I don't always say it when I find something wrong.  I mostly assume that they don't care if they are right or wrong; they just want to say what they think/feel.

But I really wish everyone were like my brother.  I also wish everyone told me when they thought I was wrong.

Conditionals and code complexity

Let's say we have a function that takes the name of a city and returns the city's current weather.  More details about the implementation:
  • The user might misspell the city name.  The function will use a spell checker to correct any spelling errors we may find.
  • Even with spell correction, we may not find the city.  We will throw an exception if we can't find any city.
  • There can be multiple cities with the same name.  For example there is a Hyderabad in India, and one in Pakistan.  In such cases, we will arbitrarily pick one.  If we get the wrong city, user has to refine the query.
  • We may not be able to get weather data.  If the weather service we are relying on fails, we return null.  (You would probably throw an exception here as well, but this is just a fabricated example.)
  • You don't always want real weather data.  Most of the time, you are working on different parts of the app; you don't care if the weather you get is accurate or not.  You want to use fake weather data if you are running the app for development/testing.
I am going to use Java in this post because that's what I have been writing these days.  First, I present the dreaded conditionals version:
Weather getWeatherFor(String cityName, boolean mayCorrect) throws CityNotFoundException {
  if (AppConfig.useFakeWeather()) {
    return AppConfig.getFakeWeather();
  } else {
    try {
      List<Location> locations = locationService.findCity(cityName);
      if (locations.size() > 0) {
        Location locn = locations.get(0);
        return weatherService.getCurrentWeather(locn);
      } else {
        if (mayCorrect) {
          for (String name : spellCheckService.getCorrectionsFor(cityName)) {
            Weather weather = getWeatherFor(name, false);
            if (weather != null) {
              return weather;
            }
          }
          throw new CityNotFoundException(cityName);
        } else {
          throw new CityNotFoundException(cityName);
        }
      }
    } catch (WeatherException e) {
      return null;
    }
  }
}
Sure, you can read this code and understand what's going on.  But how easy is it to find a bug in this?  And how easy it would be to fix that bug?

The problem with this code is that it uses way too much branching.  An if-else is essentially one statement.  What I mean by that is, when you change something in the middle of an if-else, you should keep the entire if-else in mind.  The condition (weather != null), for example, is 3 levels down a decision tree.  Before you can touch that part of this function, you should have worked out all 3 paths of the decision tree in your mind; otherwise your change might introduce a bug.

Now, the same code written in a way I like:
Weather getWeatherFor(String cityName, boolean mayCorrect) throws CityNotFoundException {
  if (appConfig.useFakeWeather()) {
    return appConfig.getFakeWeather();
  }

  List<String> candidates = new ArrayList<String>();
  if (mayCorrect) {
    candidates = spellCheckService.getCorrectionsFor(cityName);
  }
  // Actual input must be the first search we do; insert it
  // as the first item in the list.
  candidates.add(0, cityName);

  Location locn = findCity(candidates);
  try {
    return weatherService.getCurrentWeather(locn);
  } catch (WeatherException e) {
    return null;
  }
}

Location findCity(List<String> nameCandidates) throws CityNotFoundException {
  for (String candidate : nameCandidates) {
    List<Location> locations = locationService.findCity(cityName);
    if (locations.size() > 0) {
      return locations.get(0);
    }
  }
  return new CityNotFoundException(nameCandidates.get(0));
}
In this version, the decision tree is only one level deep at any given point.  (for and try are not necessarily "conditionals", but even if you include them, nesting is only two levels deep.  Which of these two versions would you change confidently?

If you have been writing code for a while, you will know that what starts like the second version would eventually end up like the first version over time: by changes that happen one line at a time.  As you make code changes, check how deep your decision trees get; if it's anything more than two, it's time to restructure the code to simplify it.

12 Jul 2011

Parking cars

I just realised today that my brain has started trusting my subconscious driving skills.  This is like leaving phase 1 and entering phase 2.  I don't have to focus to stay on one lane, to brake before hitting the car before me, and so on.

Because I don't think much about the fundamentals anymore, now my brain can focus on other things.  Now I am learning to park.  Parking straight, I found in the first few days (of this Mountain View trip) that I can do much easier than before.  Now I am learning to park in reverse.

Well, I am not the kind that would try those things just like that.  I am too scared to experiment with cars or bikes :)  One day I missed the only parking space available and went past it.  Instead of going back all the way and returning to the same place again to park, I tried to park in reverse.  I was surprised how easy it was, and I called my brother Saravanan to ask if I was doing something wrong.  Apparently parking in revers is easy.  He gave me a tip as well: instead of using the rear-view mirrors or looking through the windows, looking through the rear wind shield gives you a better idea of where the car is going.

So I tried that today.  First time I parked the car fairly decently; second time was terrible.  But the point is I am now consciously experimenting.  That's a progress.  I'm happy :)

10 Jul 2011

Web layout: how not to do it

We didn't have stupid issues like this when we used tables for layout.

8 Jul 2011

T-Mobile and me

I go to a T-Mobile store to buy a prepaid SIM card.  I look at the options they have, and choose a plan that only gives data connectivity with no voice calls or text messages.  A few days later, I need to make voice calls.  I look around their web site, but there's no way to add voice support on the phone.  So I go to the store again and ask them to add voice support to my phone.  "Oh that's not possible.  Do you want to buy a new SIM?"

Annoyed, but left with no other option, I buy a new SIM with $10 credit for voice calls.  When I put the SIM on the phone, it won't connect to the Internet.  The storekeeper had said that I can get a "day pass" data connectivity by paying around a dollar and a half.  I have already paid $10, so they should deduct from that credit for the day pass, right?  Turns out they won't do that either.  I have to buy it separately.

So I open T-Mobile's web site, and there's no link or option that would let me buy that damned day pass.  I would have to go to the shop again tomorrow to buy it.

I'm glad I don't live in the US.