I have been growing fond of this trendy Go programming language lately. We use it at Glassy Media to build services over HTTP and command line. So when we needed a Amazon Mechanical Turk interface I thought why not use Go for that too? I found an existing library in Go for interacting with Amazon Web Services. But its Mechanical Turk component is incomplete. So I dove into the source code and started patching to make it work.
A weekend of coding later, I still haven't finished. Then I realised what I was doing. I was building a cool solution but not actually solving the problem at hand. This might have been beneficial for a capable company to help contribute back to the open source community. But not where I'm at -- a new startup that's stretching thin on resources. We simply couldn't afford to lose focus at this phase. So I switched over to good ole Python. The boto Python interface to AWS worked just fine. The result was that there were no "I did this in Go" blog post to write about but our problem was solved and we moved on to the next task.
This sense of building cool solutions just for the sake of it seem common in tech. Just last week at a Go meetup, someone spoke about Using Reflections in Go. Even Rob Pike, the man himself, wrote that reflection "should be used with care and avoided unless strictly necessary". Somehow that was taken as a challenge.
I am guilty of glorifying new technologies and putting down on tried and true solutions too. On more occasions than I dare to admit at data conferences, I participated in bashing at SQL databases with the attendees. I can't speak for others, but for me it was due to ignorance. I used SQL a few times before but was put off by the data warehousing aspect of it. Having gotten more familiar with MySQL in particular over the past couple years, SQL can be simple and beautiful too. I have actually come to prefer it in some cases. Use the right tool for the right task, right?
An example of focusing on solving the problem. Here is one of the distilled tech specs we have for a component.
- A webpage for users to view a dataset of their private contacts
- Sorting capabilities on some of the data fields
- Expected number of contacts per user is several hundreds
- Limit to no more than 10 - 20 users at beta launch
Most of the efforts went into distilling our problem to make it as easy as possible. Like letting the user edit the data? Nope. UX design? Not until we figure out what data to surface. Because the problem specs are concise, solving this is almost trivial. Our current technical stack to solve this is embarassingly simplistic:
- Go for REST-based backend on Heroku; and
- Google Spreadsheet as database.
Nothing fancy. Yes, we didn't even bother with spinning up a database.
People build more complicated things in a hackday than this. That's because the real problem we have is that we think this is needed with no real proof yet. Perhaps all they need is just having CSV files emailed to them? We tried that too. We want to get this out to our customers as soon as possible for them to use and give us feedback. What is the task that this component is doing for our customers in the scope of our product experience? Abstract problems like these are not trivial and validating them is why we are building things in a startup. Not the other way around.
As I was reminiscing earlier this year, effective problem solving is more about defining a clear problem than coming up with a smart solution. "A problem well stated is a problem half-solved." In a pursuit of the latest and greatest, I sometimes find myself swung too far in the pendulum towards glorifying the solution rather than appreciating the effectiveness of clarifying the problem. Sometimes the best solution is to realise not to do something.