I think the next improvement I should make to my writing is to drastically reduce the number of times I include notes in parentheses. They make reading unnecessarily hard without adding much value.
15 Oct 2012
7 Oct 2012
Bad writing
I was chatting with a friend and remembered something I had blogged about. Naturally, I shared the link to the post. That post was written two years ago, and it wasn’t the best of my writing. After reading, she said I had come a long way from that point and I write much better these days.
I didn’t start writing because I wanted to become better at writing; I have always been a person who likes to write... it’s a way of self-expression for me. English isn’t my first language, but my primary blog (this blog) is in English. God only knows why. My posts from years ago are nothing to be bragged about. They are childish thoughts expressed in an awkward way. Not that I have become a great writer now, but I have improved over time.
The way to improve writing is to exercise bad writing. You know your writing is horrible, and yet you keep on writing. Some day you’ll find yourself writing like a good writer. I don’t know about others, but my takeaway from this is that there isn’t anything inherently good or bad. Everything is equally good and bad.
Going back to writing well. As I said, I like writing. I think good writing should feel like the writer wrote it effortlessly... like words dancing together to make the text, and not like odd components stacked together. If I were to wish, I’d say I want to write like Rob Pike or Bruce Eckel. Those are two authors I loved reading... people from whom I have learned many things.
If you have been trying to become better at something, I think you’d like watching this video. (Source: Daring Fireball)
I didn’t start writing because I wanted to become better at writing; I have always been a person who likes to write... it’s a way of self-expression for me. English isn’t my first language, but my primary blog (this blog) is in English. God only knows why. My posts from years ago are nothing to be bragged about. They are childish thoughts expressed in an awkward way. Not that I have become a great writer now, but I have improved over time.
The way to improve writing is to exercise bad writing. You know your writing is horrible, and yet you keep on writing. Some day you’ll find yourself writing like a good writer. I don’t know about others, but my takeaway from this is that there isn’t anything inherently good or bad. Everything is equally good and bad.
Going back to writing well. As I said, I like writing. I think good writing should feel like the writer wrote it effortlessly... like words dancing together to make the text, and not like odd components stacked together. If I were to wish, I’d say I want to write like Rob Pike or Bruce Eckel. Those are two authors I loved reading... people from whom I have learned many things.
If you have been trying to become better at something, I think you’d like watching this video. (Source: Daring Fireball)
Winning and losing
If you’re not willing to lose, you have a rather slim chance of winning.
29 Sept 2012
Don’t pay for web hosting if you don’t have to
A few months ago, I moved all my websites, including my personal homepage www.manki.in to Google hosting. (That is, some Google product running on my own domain.) However, there was one piece in the puzzle that was still with my web hosting provider: redirecting any requests to the naked domain manki.in to www.manki.in. Once the request reaches www.manki.in, Google would take care of it from there on.
This was the setup of my site for several months, until yesterday. Only yesterday I found out an awesome feature Google Apps has. It can redirect requests to your naked domain to any subdomain you specify. Precisely the one thing I was paying my web hosting provider for! And Google would do this for free because I am on their free Google Apps plan. That amounts to saving more than $50 a year. Very cool!
Essentially, I had to set up DNS A records to point my domain name to Google’s IP addresses and tell Google Apps which subdomain I wanted the requests to go to. Check Google’s help page for detailed step-by-step instructions.
One last thing you need to do is disconnect your domain name from your hosting provider’s IPs so your users are always sent to the right place. Once you have added the A records to map your domain to Google’s IPs, delete all original A records so your domain is not pointing to your hosting provider anymore. When your hosting contract runs out next year, you can simply not renew it :)
This was the setup of my site for several months, until yesterday. Only yesterday I found out an awesome feature Google Apps has. It can redirect requests to your naked domain to any subdomain you specify. Precisely the one thing I was paying my web hosting provider for! And Google would do this for free because I am on their free Google Apps plan. That amounts to saving more than $50 a year. Very cool!
Essentially, I had to set up DNS A records to point my domain name to Google’s IP addresses and tell Google Apps which subdomain I wanted the requests to go to. Check Google’s help page for detailed step-by-step instructions.
One last thing you need to do is disconnect your domain name from your hosting provider’s IPs so your users are always sent to the right place. Once you have added the A records to map your domain to Google’s IPs, delete all original A records so your domain is not pointing to your hosting provider anymore. When your hosting contract runs out next year, you can simply not renew it :)
18 Sept 2012
Error-handling: Java vs Go
FotoBlogr is the first toy I wrote using Go. As a part of FotoBlogr, I also wrote a Flickr client library, an App Engine helper library, (unpublished) Blogger client, and Picasa client, so I got to see some idiomatic Go. One thing I really missed when writing Go was exceptions. Many things that are one-liners in languages with exception support (Java, Python, etc.) become 3 or 4 lines in Go. Let’s take parsing a string as an integer for example. In Java, you’d write:
Fast forward a few months. I had moved to a C++ project where the style guide prohibits using exceptions. Existing code in this project ignored errors in several places, but when I was writing new code I always made sure I did something about errors... at the minimum log it and proceed. I didn’t have to make a conscious effort to do that; writing Go code had trained me to naturally think about error handling. It felt awkward to not check for errors, in fact.
Now, I am fixing a bug in a Java project. This is an old project with design decisions independently made by hundreds of engineer over several years. The change itself is fairly simple: instead of simply sending a request to an RPC server, now we have to first check whether it’s okay to send that request. If this query fails, we’d show an error message to the user. But the complication is this: I’m changing a void method that does not throw any exceptions. (This method in effect promises all its callers that it can never fail!) This method is being called by half a dozen classes, which are being called a few others, and so on. Unless I touch a large number of files to handle the new error, I can’t get the code to compile.
I was discussing this issue with a teammate and what he said was remarkable. He said, “Every method in every class should throw a checked exception irrespective of whether that method can fail or not. If it cannot fail today, maybe it can tomorrow.” He didn’t literally mean that, of course. What he meant was we weren’t using checked exceptions as extensively as we should have. If this method I am changing now threw some checked exception, I could simply use that in my client code without scratching my head too much. This is precisely what Go does. Almost all functions return an error status. You can choose to ignore it, but when someone new to the codebase reads it, it’s obvious you’re ignoring an error. I’m starting to think that Go’s way of error-handling is a much superior way than Java’s and C++’s.
int n = Integer.parseInt(str);and you’re done. If you expect this conversion to fail, you’d catch NumberFormatException, but it’s not mandatory. Compare this to equivalent Go code:n, err := strconv.Atoi(str)Of course, you can choose to ignore the error by using an underscore in the place of err, but it still won’t be as expressive like in Java. For instance, you cannot write return math.Sqrt(strconv.Atoi(str)). You must write that in two different statements:n, _ := strconv.Atoi(str)
return math.Sqrt(n)Of course, this is wrong, and it should actually be something like:n, err := strconv.Atoi(str)
if err != nil {
// Handle this error.
}
return math.Sqrt(n)It was very annoying to get used to writing code this way... almost as if writing dumb code.Fast forward a few months. I had moved to a C++ project where the style guide prohibits using exceptions. Existing code in this project ignored errors in several places, but when I was writing new code I always made sure I did something about errors... at the minimum log it and proceed. I didn’t have to make a conscious effort to do that; writing Go code had trained me to naturally think about error handling. It felt awkward to not check for errors, in fact.
Now, I am fixing a bug in a Java project. This is an old project with design decisions independently made by hundreds of engineer over several years. The change itself is fairly simple: instead of simply sending a request to an RPC server, now we have to first check whether it’s okay to send that request. If this query fails, we’d show an error message to the user. But the complication is this: I’m changing a void method that does not throw any exceptions. (This method in effect promises all its callers that it can never fail!) This method is being called by half a dozen classes, which are being called a few others, and so on. Unless I touch a large number of files to handle the new error, I can’t get the code to compile.
I was discussing this issue with a teammate and what he said was remarkable. He said, “Every method in every class should throw a checked exception irrespective of whether that method can fail or not. If it cannot fail today, maybe it can tomorrow.” He didn’t literally mean that, of course. What he meant was we weren’t using checked exceptions as extensively as we should have. If this method I am changing now threw some checked exception, I could simply use that in my client code without scratching my head too much. This is precisely what Go does. Almost all functions return an error status. You can choose to ignore it, but when someone new to the codebase reads it, it’s obvious you’re ignoring an error. I’m starting to think that Go’s way of error-handling is a much superior way than Java’s and C++’s.
SIDENOTE: The easy and obvious fix is to throw a
RuntimeException and catch it in only the places I like to change now. But that’s a really wrong way to fix a problem like this. First of all, RuntimeExceptions are not meant for cases like this. They are for things like division by zero, dereferencing a null pointer, etc. Things that can happen in any code and thus are impractical to handle specifically. Since they are rare and usually very serious, they are allowed to propagate through deep call stacks. Defining application errors, input errors, etc. as RuntimeException can lead to severe debugging issues over time. You really don’t want that.
Subscribe to:
Posts (Atom)

