The West Coast Mobile Office

Writing software is a lot like writing anything else. I think that's why so many computer programmers are unhappy working at companies that expect to see them typing away furiously for 8 hours a day, 40 hours a week. With any creative endeavor, inspiration tends to happen in bursts. In programming, these bursts tend to take the form of the 18 hour caffeine-fuelled marathon sessions that come to mind when you think of Internet startups. One of the (very few) things that those companies got right in the late 90s was to recognize this work pattern and find ways to accommodate it. (Unfortunately, most companies accommodated it by setting up pinball machines right in the middle of the dev space, thus wiping away any potential productivity gains in a sea of noise).

Anyway, back to the point at hand, the key to keeping up productivity as a developer is to find ways to foster these inspired bursts of creativity. With this in mind, we packed up the truck and left rainy, dismal Portland behind for a while. 20 hours south, we set up shop in Bishop, one of the most inspiring spots that the US has to offer. High alpine wilderness, tons of amazing rock climbing and Bouldering, pleasant secluded camping, and, amazingly, good EVDO coverage. Everything a climber/geek could want!

Free from the distractions of the city, we'd pull out the laptops in the morning, sipping espresso and knocking out new functionality until well after lunch. Thus creatively spent, we'd pull out the rock boots and head up the hill in search of Boulder problems on the amazing granite that Bishop is famous for.

What a week. What a place. we'll be back.

exampleCode != productionCode

Take a look at this little piece of code. It looks pretty innocuous, like it was taken straight from "Teach Yourself ASP.NET in 21 Days". Pull a list of Trips out of the database for a given user, and bind it to a select list. Nothing fancy. Teaches you a little bit about ADO.NET and databinding all in one place.

Figure 1., Book Sample

public class ExampleCode : System.Web.UI.Page
    protected HtmlSelect selTripID;

    private void Page_Load(object sender, System.EventArgs e)
        if (!IsPostBack)
            DataSet ds = new DataSet();
            SqlConnection connection = new SqlConnection(
            SqlDataAdapter adapter = new SqlDataAdapter(
                "select * from Trip where UserID=" 
                + Request["UserID"], connection);

            selTripID.DataSource = ds;
            selTripID.DataTextField = "TripName";
            selTripID.DataValueField = "TripID";
Imagine my surprise, however, when I walked in to a small software shop recently and found a whole project written with code like the above. What were these guys thinking? Are they seriously relying on this fragile, unmaintainable mess in a real software product?

And then it dawned on me. Maybe nobody had ever told them that the little examples in the book are just that: Little Examples. For teaching purposes. Never intended for use in the real world. Come to think of it, it doesn't even tell you that in the book. It aught to be in block capitals across the cover of the book:


Somehow, it seems that this message never got through to a substantial portion of the software industry. Every time I see a "Senior Developer" writing ad-hoc SQL or referencing a hashtable with a string I just want to cry.

So what do we do about it? I guess we try to get the message out. Here is some code I copied out of the Blogabond source that is functionally equivalent to the above:

Figure 2., Production Sample

public class ProductionCode : System.Web.UI.Page
    protected HtmlSelect selTripID;
    private int _userID;

    private void Page_Load(object sender, System.EventArgs e)
        if (!IsPostBack)
            _userID = StringConvert.ToInt32(
                Request[User.Columns.UserID], 0);
            if (_userID != 0)
                // bail gracefully...

    private void PopulateTripList()
        selTripID.DataSource = Trip.GetByUserID(_userID);
        selTripID.DataTextField = Trip.Columns.TripName;
        selTripID.DataValueField = Trip.Columns.TripID;
Short and to the point. And obviously only the tip of the iceberg. This bit of code goes deep, but we can learn a few things just by looking at it:
  1. We're using a Data Layer of some sort. Somewhere in the back end lives a class that is wrapping a stored procedure for me. There's a ConnectionFactory back there someplace that knows to hand me a connection to the Production database because of a server setting.

    The code that's handing me the DataSet I'm binding to can be reused by any page in the project, so I know that little select statement is only living in a single place. In fact, everything that touches that table is sitting in a single class back there. So if something changes in the schema I won't have to go hunting through the client code to fix it.

    Best of all, because we've separated the database code out into its own place, we can drop all the boilerplate CRUD into CodeSmith templates and let it auto-generate itself from the database schema. In the case of Blogabond, I can flip a switch and watch as 50k lines of boilerplate C# and SQL in our backend gets blown away and recreated in about 30 seconds. And since it's also generating all the boilerplate Unit Tests for all that code, we can be sure that the datalayer and the database line up correctly. So if junior dev Jimmy comes by and unchecks a not-null constraint in Enterprise manager, we'll see the continuous build fail on an integrity check a few minutes later.

  2. We're using Enums instead of inline strings to reference our column names. This may not sound like a big deal, but it buys us a couple things. First, we've abstracted out the concept of the Typo. There is simply no way we can misspell "TripID", because the compiler will catch it for us. It will sit there underlined in red if we even try. We don't even have to remember what columns we have available, since Intellisense will tell us when we hit ctrl+space.

    Second, and bigger, is that we buy the freedom to monkey with our tables and never worry that we're causing runtime errors someplace. I can rename the column "TripName" to "BlogName" if I want, re-generate the database wrappers, and watch as the project fails to compile until I fix the references. That is some powerful stuff. And what happens if I forget to re-generate the wrappers for that table? The continuous build will fail in about 5 minutes, since the unit tests that check to make sure the wrappers match the schema will fail.

Where do we go from here?

Copy and paste code reuse is bad. Everybody knows that. Ad-hoc SQL is bad. Everybody knows that. Inline strings are bad. Everybody knows that.

At least that's what I thought. But you know what? They don’t. And they should. And it's our job to tell them.

New stuff at Blogabond

Just pushed a few new features to Blogabond today. Most visible is the ability to embed your maps into external web sites, blogs, and wherever else you might want to stick a map of your travels:

Groovy, eh? You can try it out on your own blog by running through the Trip Builder, and copying out the code it gives you when you're done. Along the way you'll need to sign up for an account and name your trip, but it's still pretty quick to get a map up and running on your own site.

For the curious, here is the code you'd need to drop onto your page to display the map above:

<script src=""></script>


Two Weeks Vacation is only a Recommendation, not a Rule

How much vacation time did you take last year? If you're like most workers in the States, it was probably less than 3 weeks. That's all your company will give you, right?


3 weeks is the amount of PAID vacation your employer will compensate you for. The actual amount you take has nothing to do with that number. In practice, the amount of vacation time you can take is directly related to your value to the company. And let me give you a little hint: You are a lot more valuable to your employer than they are to you.

I stumbled across this idea early in my career, and didn't even realize it. I was about 3 years out of school, working as an environmental engineer at a big consulting firm. It was the mid-90's, at the height of the downsizing era. Morale was low and people were leaving the company fast.

One day, I was looking at a little backpack I owned and it occurred to me that I could probably fit enough in that pack to live on for 3 months if I wanted to. Hmm… I hear the climbing in Southern France is pretty good. Maybe I'll look into a flight…

Two days later, ticket in hand, I strolled into the office of my department head. I caught the flash of exasperation on his face before he greeted me (he was fielding about one resignation a week at this point, so he probably expected the worst). "Don't worry," I said. "I'll be coming back in August."

That was it. No begging, pleading or anything. Just a bit of shuffling to make sure my plate was clean before heading out, and that was that. Life at the company didn't skip a beat, and 3 months later I picked up where I left off just like I would have after a week in Cancun.

At first, I figured that this must have been a special case. The company was in tough shape, and I was in a unique position to take advantage. Turns out though, that I kept finding myself in this position of advantage time and again over the years. So much so, that it finally dawned on me just how valuable a good employee really is to an organization.

Cut to 3 years later, and I'm on a small, tight programming team for a little dot-com startup. I've been there for almost a year, and it's time for a bit of R&R in Central America. 6 weeks off should just about do it. So I sit down with the boss, and start listening to the old "yeah… we're kind of in crunch mode right now… I'm not sure we can spare you for even 3 weeks, let alone Six…", so I just cut it short:

"Well, I'd really hoped I would be able to come back when I was done. I really like this company, and it's too bad to hear that I'll have to be leaving…"

And that was that. The tone of the meeting turned on a dime, and the next day I had a 4-week leave of absence approved and tacked on to my 2 week vacation request.

So here's the one thing you need to take away from this:

You are more valuable to your employer than they are to you.

It is nearly impossible to hire a good developer. Talk to anybody that's ever had to do any hiring in this industry and they'll tell you that there are simply no good candidates out there. It will take at least 6 months effort to hire a developer that can find his arse with both hands. If you are already in the door and delivering code, you can be assured that your company does not want to lose you. Sure, they'll do their best to make it sound like they don't care about you. They might even utilize the industry standard "Layoffs Are Coming!!! Panic NOW!!!" motivational techniques. But believe me, if push comes to shove, they'll find a way to keep you.

Tell them you're planning to take 2 months off. Don't ask. Tell them. Make it clear that you're going to go regardless of whether there's a job waiting when you get back. They'll accommodate you. Trust me.

A few Caveats to the above:

  • You're not going to get paid for those 2 months off. You'll get the first 2 weeks or whatever paid for, but from there on out it's just a leave of absence. You'll need to save up a pile of cash ahead of time. If you've dug yourself so far into debt that you can't float along a measly 2 months without pay, I guess you're out of luck.

  • This only works once every couple years. Don't get into the habit of storming into the boss's office every 3 months demanding another month off. You'll soon find yourself with all the free time you need.

  • This only works if you are actually good at what you do. Take a quick self assessment first: Can you code your way out of a sack? Honestly? Cool, go for it then.

  • This only works if you are prepared for the possibility that your employer will call your bluff. You may very well end up without a job as a result of doing this. If the prospect of having to look for work is that scary to you, then you should probably just sit tight and book that 5 night package holiday to The Bahamas. But then, if the idea of unemployment is really that scary, it's likely that you were fibbing a bit on that self assessment above. Jobs are plentiful for the truly skilled.

How Google killed Search

It's official. It is now completely impossible to find things on the web using a search engine. Try this out. Go to Google and see if you can find a

cheap hotel in new york

What comes up? Any hotels? Not really. Just page after page of spammy affiliate sites that promise to find you great deals, but will really just send you off to other affiliate sites. Click along and you'll fall down this black hole of non-content and Google Ads with no hope of ever finding a real website where you can book a cheap hotel in New York.

I blame this phenomenon on Google's Pagerank algorithm and its reliance on link counts. The quickest way to get to the top of the rankings is to produce tons of empty pages all across the web, all linking back to your thing. So you get this huge global competition to see who can produce the most useless content and shove it out onto the web. Everybody knows it's not really content, but the game is to fool the search engines into indexing it anyway. Let this strategy play itself out for a few years and you get the Internet in its current state. 21,800,000 pages all wanting to tell me about cheap hotels in New York. Only 1 of which is (and it's not in the top 30.)

It's a lot like the state of professional boxing in the '80s. You had this kid who could fight, so you'd put him in against some guys you thought he could beat and he'd get some ranking points for himself. Then you'd find some highly ranked fighters who were on their way out and let him fight them, boosting his ranking some more. Then you'd get some other kids that weren't really all that good to start with, but you'd boost their rankings in the same way until they had enough points to put in against your guy. He'd beat them easily and get even more points for himself.

This would go on for a few years, with your kid steadily climbing the rankings without ever really fighting anybody good, since everybody you put him in against had had their ranking inflated by the same means. Finally, there comes the day when he's earned himself a title shot. What happens? Mike Tyson knocks him out in 18 seconds and that's the last you ever hear about him. (And Don King pockets another $20 Million.)

So maybe that's what Google needs, the SEO equivalent of the Tyson fight. If your site manages to weasel its way into the top 5 for a given keyword, you get some real people to put eyes on the thing and see if it can hang with the competition. That way, people like you and me would never have to sift through search engine results from just because they managed to link spam their way up the rankings.

ps. I'm in no way guilt free in this area. Before writing this today, I spent the morning trolling around and picking up a couple high-ranking domains from them ( and, which I am now using for shady SEO practices...

pps. Check out the new changes to the World Browser at Blogabond!

6 things that killed Waifmail

With all the success stories about Expat Software and Blogabond that I've been telling lately, you might get the impression that it's all blue skies every day here. I thought it would be good for balance if I told the story of one of our spectacular failures.

Back in 2004, Waifmail was positioned to be the great Outlook killer. A web based mail client from which you could read all your email from all your myriad accounts, all in one place. All on one screen. It was pretty cool.

Waifmail died before it got off the ground for a number of reasons that are too complex to go into here but… Nah, screw that. it died for 6 specific reasons that I'll outline below. In actuality, it died for one single reason: GMail. But it sounds more interesting if I break it up into a bunch of bullet points instead.

6. Small target audience

As you might know if you've been reading this blog, I travel a lot. As a result, I often find myself in some sweaty little internet café in rural Laos, waiting 20 minutes for Hotmail to load up the "Hey, you have some mail" screen. Followed by another 20 minutes to load the screen where it actually shows you that mail. I have 4 email addresses that I like to keep up with, so every visit to the internet café involves a dozen Internet Explorer sessions open at any given time, all fighting for bandwidth over the single shared AOL connection that the café is using.

My first big mistake was assuming that there was at least one other human being on the planet with my same problem. To be fair, there were probably a few. But they were stuck in some dingy Cambodian internet café, and not likely to find this thing. Especially true due to our...

5. Really sad marketing

To be honest, I can't even remember what our marketing strategy was for this thing. Something along the lines of "Put a link on the Expat Software site and let Google find it." I might have mentioned the site in a few posts to the Usenet, but we never really seriously marketed the thing and certainly never paid for any advertisement. I think it was the classic case of the geek in the basement (or jungle as the case may be) writing his perfect app and then sitting back waiting for the world to find it.

Nobody did.

4. Poor technology choice

I know it's lame to blame your crappy software product on a crappy development platform, but I think we were really hampered by our decision to go with the LAMP stack for this thing. Specifically, PHP.

I'd done a fair amount of PHP development by this point, and had built a set of tools that let me work pretty well from a public internet terminal. My little DHTML IDE and file management utilities worked so well that when I took off on my 9 month road trip, I left the laptop at home.

I did some research before starting development on Waifmail, and it seemed like PHP had a pretty decent mail library built in, and another beefier one waiting to go in PEAR. I come from a Microsoft background, and you can say what you want about Microsoft, but their development tools and libraries are rock solid. If they have a library called System.Web.Mail, you can rest assured that it will actually send emails when you ask it to. Unfortunately, this is not the case with PHP.

First off, the IMAP_whatever functions in PHP simply do not work. It's incredible that there are four separate ways of opening a mailbox and none of them will actually open a mailbox. Check out the documentation over at It's unmitigated comedy, as dozens of developers hand out advice in an attempt to get the library to function at all.

Next up was PEAR, which is at least capable of sending an email message. Too bad it doesn't offer much help in connecting to a mail server and reading your mail. Looking around the PEAR site today, it seems that people have at least been adding to it, so it's possible that there is a functional library in there somewhere. Though in standard PHP fashion, you get multiple semi-redundant libraries piled on top of one-another with no naming standards.

So, as a last resort, I wrote my own IMAP and POP clients in PHP. Not any fun to do, and certainly an unwelcome piece of work since it was the one thing I figured I'd get for free from the platform.

3. Reliance on shared hosting

This was another visionary move that turned disastrous in a hurry. The plan was to rely on constellations of cheap $5/month shared boxes, easily adding more capacity as demand increased. Seeing as how we've gotten about 40 signups in 3 years, we never needed to put this grand scaling vision into place, but it woulda' been cool I tells ya!

The problem with this scheme is that we lost control of the environment. MySql would put out a release, our host would upgrade the servers, and something at Waifmail would randomly break. New versions of PHP would come and go, with different global settings in place, and suddenly we'd be living in the world of "Magic_Quotes_Runtime" and everybody's mail would have slashes all over the place. We'd wake up to find the site on another box that didn't have the PEAR libraries installed, and suddenly mail would stop sending. It became a lot of work just keeping track of this stuff.

Eventually, the whole hosting company got sold and the site ended up on another box with a different configuration. That's about when I gave up paying attention. I'd be surprised it Waifmail were even functional today.

2. Impossible to gain users' trust

This one stopped us dead in our tracks. Try it out some time. Put up a new website and ask people to type in their email address and password! That's really the only way we can log into your mail server to show you your email, but really, who in their right mind would give out this information? Maybe if you're Google you could pull this off, but for an unknown site just starting out, this simply killed us.

I knew it wasn't gonna work the day I tried to demo the site to my sister. I showed here the signup page and told her to put in her email address and password.

Lisa: "My Email address? My company doesn't really like me to give that out."

Me: "But you're not giving it out. You're just using it to read your mail."

Lisa: "Yeah, but still… If they found out I think they'd be mad."

There you have it. We're fucked.


This all happened in the winter of 2004. Now sometime around April of that year, this company Google put out their own email service called Gmail. Perhaps you've heard of it.

Gmail did roughly everything that Waifmail had set out to do with the sole exception of letting you read your Yahoo, Hotmail, and work accounts through their reader. But you knew that was coming soon. And when it did, any little company trying to do the same thing would be out of luck.

Fortunately for us, we had already thrown in the towel.

The Chamonix Branch Office

You're never going to find good clients on the internet. Pay attention, aspiring consultants out there because it's true. You can spend all the time you want at UpWork or scouring Craigslist, and you'll never once bag a client that will keep you fed for more than a month at a time.

You're going to meet your clients the same way you met everybody else you know, through friends and by going out and doing things. You'll buy outrageously overpriced tickets to the Ballet for your girlfriend and the guy sitting next to you will ask what you do for a living. "Hey, what a coincidence! I've got this great idea for a website." And you know this guy is squared away enough to see the project through because he's spending his time (and money) at the Ballet and not on some free classified ad service on the web. Seriously, if you want to completely overload yourself with work, just spend a week flying first class between Los Angeles and New York.

I met Ben at an Italian restaurant in Pasadena. He had this great idea for a site that was a sort of WebMD for Traditional Chinese Medicine. I sent him home with a card and a week later we were at a Starbucks, behaving like those jackasses you always see with tables covered in diagrams and open laptops. Over the next month, I built him a nice little prototype that he could show to potential investors and hopefully drum up some funding to build the whole thing. It was starting to get towards winter, so I soon found myself in Southeast Asia, climbing rocks on the beach and putting some hours into one of my side projects. I sent Ben a postcard, but didn't really expect to hear from him again for a while.

From: Ben
Date: Feb 17, 2006 12:22 PM
Subject: DUDE!

Just got out of a 1 hour phone conference between Jeff Arnold and his VP; the creators of WebMD... not only was it a cool opportunity to just talk with these guys, but they're extremely interested in the project and feel that the strategies in place are ideal!

Investors started calling and Ben had his funding secured within a couple weeks. Now we had to start looking at everybody's schedules and decide on a good time to converge on LA and get this thing started. But hang on, why LA? We'd be pulling in the whole Expat Software team for this job, and we were sort of scattered at that point. And besides, Los Angeles sucks. How about we just pick a spot on the globe where we'd all like to spend some time, and then find a cheap rental house with fast internet access? All in favor? All opposed? Sorted.

At the top of the list was Antalya, Turkey. A couple of us had been there before and we knew that there was good rock climbing nearby. Oh yeah, did I forget to mention that that's a priority? Here's the list of requirements: Good climbing (and/or surfing), cheap accommodation, fast internet access. Turkey met the first two but we never found a big enough place with DSL installed. Kalymnos, Greece and Currumbin, Australia failed for similar reasons, and the island nation of Niue (with its free WiFi coverage of the entire country) was just too far off the map to get any good information about.

In the end, we fell back on the South of France. Besides having the best climbing in the world, the Rhone Alps are a major ski destination during the winter. That means that you can pick up a giant chalet for next to nothing if you show up in July. Our six bedroom rental house in Chamonix ended up costing less than a comparably sized cube farm in LA, including airfare to fly everybody out and back. Something worth thinking about next time you have a major project that needs doing in a hurry!

The two months we spent in Chamonix were among the most productive I've ever known. Each morning I'd wake up to blue skies over the most amazing view of Mont Blanc. I'd brew up an espresso and take my croissants onto the balcony to enjoy another perfect summer morning. I'd boot up and slip into the zone, flowing smoothly and uninterrupted until dinner was served hours later. In the evenings, we'd get the entire team together in the great room; founder, developers, strategists and even a few hangers on to discuss the direction of the project, triage bugs, and flesh out designs for new features. Wine would flow and brie would, uh, smear, and the creative process was let loose to do its thing.

I can't get over how good it was to have the whole team together in one house, cut off from the details of life and left with no choice but to focus on the task at hand. Communication was a simple as dragging the client over to a couch. "Issue 381, what are you trying to accomplish with this?" "Could you draw me a quick sketch of how you want that to look?" Draw up a quick data model for the feature in question, and back to the table to code it up. A couple hours later that new feature would be pushed to the QA server (a laptop nestled amongst the bottles of the wine rack) and ready to hit from anybody's machine.

Weeks flew by, friends came and went, and we got to watch France and Italy battle it out in the world cup, while sitting astride the border between the two countries. Eventually we had to pack up and go our separate ways, finally pushing Continuous Build 310 live as The data-entry minions were set loose back in LA, and Ben went off to promote the site and raise capital for round two.

That was six months ago, and we've just finished a big planning session for the next year of operations. It looks like this thing is actually going to start bringing in revenue earlier than anybody expected. Finances are in place, and soon we'll need to start thinking about another big development push.

I'm already talking to real estate agents in Spain.

Getting it down on paper

A bit of background for those of you that may have stumbled across this. At the end of 2002, I quit my job and bought a one-way ticket to Cape Town. I'd done a fair bit of travel before that, mostly for a couple months at a time, and it always bothered me that I didn't have the time to do it right. So I saved a bit of money and bought a ticket to one end of the world. I figured I could make it to the other end in a year or so, if I moved at a good pace.

Fast forward six months, and I'd made it as far as Istanbul, having done most of that distance by land. The only flight that gained me any real ground was from Nairobi to Cairo, since nobody really wants to be crossing the Sudan in the summer. Hitched through Jordan & Syria with no problems whatsoever, even though we were actively bombing Iraq at the time. Once I hit Europe, it was smooth sailing for a while.

But now comes the interesting part. I'm getting bored. 9 months in, my mind is crying out for stimulation, and sorting out bus tickets is just not providing it. I need to work. Now. I sent off a couple emails, and a week later I had a 3 month contract lined up in the 'States and a roundtrip ticket booked from Bangkok to Los Angeles.

So, it's the top of the year again and I'm off to Southeast Asia to pick up where I left off. This time I had the forethought to pack along a laptop and a small pile of freelance work. Spent the winter on the beach, traveled through China for a while, then hopped the Trans Siberian train to Moscow. I've been back to the US a few times since then, but never for more than a few months at a time. I'm on my third laptop now, and my clients and jobs have grown substantially from the little $1,000 gigs that paid for my beer in Thailand. Now I spend probably half my time working on my own projects, building things that will bring in revenue by themself so that eventually I can ramp down the consulting work and focus on the important things.

Viewing 51 - 58 of 58 Entries
first | previous | next | last

Jason Kester

I run a little company called Expat Software. Right now, the most interesting things we're doing are related to Cloud Storage Analytics, Online Classrooms, and Customer Lifecycle Metrics for SaaS Businesses. I'll leave it to you to figure out how those things tie together.

Subscribe in a reader

Copyright © 2024 Expat Software