Wednesday, June 12, 2002

If you insist on using Internet Explorer, this thing rocks: AdShield Banner Ad Blocker. Get one of the benefits of Mozilla without Mozilla. Really easy. Really effective.

( privacy | cool | software )

Saturday, February 01, 2003

I am seriously considering deploying new weblog software. I don't have the time to maintain my half-assed stuff between my job and the taupe sekrit projecktz. I am currently looking at Drupal, Nucleus, and Grey Matter. I am not considering Movable Type because of its restrictive license. The aforementioned packages are all GPL, which is what I would prefer (although BSD, MPL, and other OSI-approved licenses would be fine too). Conveniently I need to play with some of these packages to do some research for work. No doubt there are others out there that would serve my needs, but those look to be the most fully-featured and flexible. Ideally the source would be in Perl or PHP so I can pretend that I would actually read it at some point.

( software )

Monday, May 03, 2004
Opera has this great feature called "fast forward" (or "rewind," depending on direction) where it guesses the next page you want. I don't know how well that works in general, but one thing where it works really well is the directory of images (such as this directory of Rhapsody screenshots). Instead of the standard index -> image 1 <- index -> image 2 <- index etc. loop, you go to the first image and then keep hitting the fast-forward button (or Shift-X) and it goes to the next image. Pretty nifty.

( software )

Software engineering in a nutshell*.

( funny | software )

Tuesday, May 11, 2004

I've had the idea kicking around in my head for some time for a blending of Free Software and commercial software development. While I feel that the standard models of intellectual property are inherently flawed, fixing them is a utopian ideal that can only be reached in tiny, incremental steps over a long period of time. Realistically, there has to be a bridge. I think the GPL is great, but the free redistribution to anybody aspect is a stumbling block. I understand and agree with the other freedom arguments, but I don't see how that contributes to a user's freedom.

The Walled Garden License (WGL, or "wiggle") is dirt simple. Take the GPL. Add the restriction that redistribution is limited to the community of users that you, the software developer, have defined. Voila. Within the garden, you have all the freedom of the GPL. Anybody can write and distribute patches. Everybody gets the source. Nobody is held hostage by the original developer. Nobody gets in for free (unless you want). And membership is irrevocable.

This opens up some interesting possibilities. Once someone enters the community, they can compete with the original developer for customers. The community is not tethered to the original developer; if they neglect their duties or take development in an unpopular direction, the community can still survive. Beyond providing an insurance policy for the customers, it also gives an impetus to the original developer to continue progressing. A conventionally-licensed software package is really better viewed as a monopoly of one. Microsoft Word theoretically competes in the word processing market, but the switching costs are so high that the word processing market is really a collection of monopolies. With a license like the WGL, on the other hand, not only would those switching costs be reduced, but the monopoly of one would crumble into a real market.

There are many ways one could expand on the idea, but those are just details. The essence is to gain the practical benefits and the higher ideals of free software without the revenue-destroying sharing clause. I don't expect I would actually use a license like this (for one thing I don't see myself being an independent software vendor), but it's possible. Nor do I expect that this would be anything but a temporary state of affairs; I see this as being more of a transitional mode before the rise of patronage.

Eventually, we are going to move to a patronage model. Rather than buying software/books/music/etc. per unit like they are widgets, the emphasis will shift to paying for something to exist, like a collaborative bounty. Freeloaders just aren't a problem with digital goods in that environment. That's the future. In a lot of ways, actually, that is the present, but filtered through inefficient, opaque mechanisms such as software licensing and market research. Current licensing models will eventually disappear. It will probably take decades to happen, and it won't ever achieve a complete victory. The WGL is just an intermediate stepping stone from the standard of today to that future. Each mechanism performs the same task of converting need, effort, and money into useful software, but each one does it better than the previous one. It is inevitable that the market will evolve to these better ways.

( software )

Monday, May 17, 2004
It has been pointed out to me by someone without a web page that the Walled Garden License is a lot like a co-operative. The distinction I would make is that in a co-op, the payment (whatever form it may take) for entry into the co-op is given to the co-op itself, while in the WGL model, the payment is given to the original software developer. Similar, but different.

( software )

Monday, March 07, 2005

You may have heard the term enterprise software before. Generally, they sell big software to big business. There'll be a team of dedicated sales people that works on a client for months, even years, doing demos, sales pitches, hammering out terms, etc. for and with the executives at the customer. The customer has a list of features they want that they use to narrow down the possible solutions. Eventually, if all goes well, the customer signs a contract and writes a big check. Then the professional services consultants descend, adapting the product to the customer's needs and existing business systems. After a while, there's another version of the software and the cycle repeats. There are a lot of software companies in Austin that follow the model. Tivoli was one. Motive was another. So's ROME. And that's just the companies that I've worked for.

Note that I haven't mentioned said anything about what the customers and the product do. That's because it doesn't matter. Look at the model described above and think about what sorts of behaviors it creates incentives for. There are a few biggies. First of all, you want a product that looks impressive. That's not the same thing as useful. Often those things coincide, but often they don't. When push comes to shove, the one that brings money in the door is the one that wins. Many times, sales people will demo something that doesn't actually exist. Secondly, there is no incentive to make the product simple. After all, the more complex the product, the more time it takes to install, and the more billable hours your services people rack up. Third, once you get the check, the customer no longer matters. All you have to do is a good enough job that the customer won't sue. Maybe, if you're especially forward-looking, you'll try to maintain a decent relationship so you can sell them the next version a couple of years later. Even that has a hook; you can implement a feature well enough that you're not lying when you say you can do it, but not so well that customers can actually use it. That's the next version, which is available for the low low price of $1.5 million. You can generally get away with a lot, as the people who use the software aren't usually the people who use it.

Naturally, this type of focus has an impact on development. Sales will scream for some feature they need to sell a particular client. Or they may have already sold the client on that feature and it needs to be designed, developed, tested, and documented by the end of the quarter. Services will scream that some part of the product is buggy or unusable. What matters is building something that vaguely resembles what was sold as soon as possible. Everything else is secondary. Quality is an afterthought. A well-designed architecture is too much work. One could even argue that it's bad business to focus on quality. I can't help but think that kind of business is living on borrowed time. The customers tolerate that model, and in some cases even insist on it, but I can't see a future in a company whose best customers write a seven figure check and never use the product.

So, after all that, you're probably wondering why I put up with it. Well, the easy answer is, I thought that's how the industry worked. I thought I was just being naive and idealistic. Turns out I was wrong, though, so I'm not going to have to deal with it anymore. My new job is at Works. They were one of the early dot-com cliches, selling office supplies online. 7 years and two business plans later, they have a pretty nifty product for managing payments in various organizations. The model is different. Works is what is known as an "application service provider" (ASP). The product is hosted on their servers and accessed through the web. The most well-known ASP is Salesforce.com, but you could argue that web mail is the quintessential ASP. Works gets no real money when they sign a customer. Instead, they only get paid as customers use the product. If the product isn't useful, efficient, or reliable, the customer doesn't use it and Works gets no money. The model is built from the ground up in a fundamentally different fashion that aligns their interests more closely with the customers' interests. That's the theory, at least, and what I've seen so far confirms it.

I really wanted the ROME job to work, as I've had more than my fill of employment volatility. I did my best to improve things, but there was only so much I could do, and only so much frustration I was willing to deal with. To be fair, things aren't that bad, but given the opportunity for something that is better in nearly every respect, how could I possibly turn it down? It's quite possible that the enterprise software model has many profitable years ahead of it. It's quite possible that I'm turning my back on lots of money, but it isn't 1999 anymore; options are nothing more than lottery tickets. What matters more is a demonstrably sustainable business and a positive environment. Baby needs cash and a content father.

( software | (un)employment )

Tuesday, April 19, 2005
I hit upon the idea of making the Umapuma blogger files PHP instead of HTML so I could embed, well, whatever I wanted. All I'm using it for right now is the age counter, so the front page can automatically calculate Uma's age. It's really easy to do; I'm sure I'm going to come up with all kinds of ways to abuse this.

( web | software )

Tuesday, May 17, 2005

I found a more useful use for Blogger with PHP. The standard <BloggerArchives> tag prints out the archive links in ascending chronological order, i.e., oldest first. I'd rather have them in descending order, but I couldn't figure out if I could reverse the order with the standard Blogger tag. So I did this instead:

<?
    $archiveLinks = array(
        <BloggerArchives>
            "<$BlogArchiveURL$>" => "<$BlogArchiveName$>",
        </BloggerArchives>
    );
?>

<ul class="archive-list">
<ArchivePage><li><a href="<$BlogURL$>">Current Posts</a></li></ArchivePage>

<?
foreach (array_reverse($archiveLinks, true) as $link => $name)
{
    ?>
    <li><a href="<?= $link ?>"><?= $name ?></a></li>
    <?
}
?>
</ul>
And that's that.

( web | software )

Thursday, May 19, 2005
If you want an image editor for Windows that's superior to the bundled Paint but doesn't actually cost money, try Paint.NET. It's free, open source, reliable, and a lot easier to use than the GIMP.

( software )

Monday, June 13, 2005
I just wrote my first Greasemonkey script. Greasemonkey is an extension for Mozilla and Firefox that allows you to attach arbitrary behavior to the web pages you load. I've installed scripts that make the NY Times front page links go straight to the single page articles, to disable annoying Intellitxt keyword ads, to eliminate links that force a new window, and other pet peeves. The script I wrote is for fixing the footnotes of the book Practical Common Lisp. The footnotes for each chapter were at the bottom of the HTML page, making it a pain to scroll down and back. My script will grab the footnote text from the bottom and make them hidden text elements that appear when I mouse over the footnote marker. For the work that went into it, it's of rather limited use, but far more important is that I know how to do this now. This isn't something you should attempt if you don't know how to write code, sadly. Greasemonkey makes it easier, but not easy. There is a project called Platypus that works with Greasemonkey to allow interactive clicky-clicky editing of a page, but I haven't used it so I don't know how well it works.

( software )

Monday, July 25, 2005

I've been reading Joel on Software for a few years now. I've found his writing on both the business and technical aspects of software development to be insightful and informative. His most recent essay takes the cake for his most brilliant idea yet:

... duplication of software is free. That means that the cost of programmers is spread out over all the copies of the software you sell. With software, you can improve quality without adding to the incremental cost of each unit sold. Essentially, design adds value faster than it adds cost.
Emphasis his. Maybe I just like that because it massages my ego (assuming I'm as good as I think I am). It also makes sense, though. It dovetails nicely with that essay I've been writing for 2 or so years on why India isn't going to eat our lunch in software.

( software )

Tuesday, October 04, 2005
Released today are Fiona Apple's "Extraordinary Machine" and Franz Ferdinand's "You Could Have It So Much Better." In three weeks, Civilization IV comes out. Not sure how I'll find the time to play that, though.

( music | software )

Wednesday, October 19, 2005

It may surprise you to know that I'm not a very good programmer 1 I can't keep track of many things at a time. I have trouble multi-tasking. I don't have a very good memory, neither short-term nor long. I am lazy. I have little tolerance for repetitive tasks. Certain simple things can occasionally baffle me. My understanding of the intricacies of some computing concepts is not what it could be. In other words, I'm never going to be the guy who figures out how to prune 6 cycles from malloc on Athlon64s by using a vector add instead of a scalar multiply.

It turns out that these handicaps are not so crippling after all. They've made me into a maniac for simplicity, clarity, and elegance. I make my methods and functions simple and contained, so that they do exactly one thing. That makes it easier to keep track of the moving parts and easier to pick up where I left off. I give all of the entities verbose, descriptive names, because I'm not going to remember what they're for otherwise 2 . I try to stick to the "don't repeat yourself" principle because that means I don't have to deal with tedium. Those things are all valuable no matter how good a programmer you are, but many programmers are never forced to learn them because they never work on projects that exceed their natural abilities. Since my natural abilities are meager, most meaningful projects challenge my abilities. To make a (possibly poor) analogy, no matter how tall you are, at some point you'll be in over your head. Then it's a good time to know how to swim. Once you know how to swim, you may realize that swimming is useful even when your head is above water.

It can be even worse, though. The earlier you are forced to learn something, the better you internalize it. The longer you go without getting prodded into learning it, the harder it will be for you to learn it. Indeed, the harder it will be for you to realize that there even is something there to be learned. Many programmers never learn these things because there are a lot of ways to badly write a program that still technically works 3 .

To take the tall metaphor in a different direction... Suppose you're a 7' high school senior. You dominate the basketball court. Once you're in college, though, things are different. You can't really shoot. Your ball-handling skills aren't all that. Your physical fitness is sub-par. Compare that to the 6' point guard you overpowered in high school; he's had to lean all of those things to compete with you. The kicker is, he's going to get better and better, but you're as tall as you're going to get. Not only that, since you've gone so long without developing those skills, you don't even know where to start to learn them.

As it so happens, a lot of applications programming isn't fundamentally hard stuff when you get down to the nuts and bolts. Theoretical computer science and half a century of experience have done a pretty good job of figuring out what can is possible and practical. Most of us just aren't trying to go to the moon anymore 4 . As a result, it's not too hard to figure out some way to solve a problem. That issue has receded in importance. Even performance isn't the be-all end-all that it used to be in many cases 5 . What matters far more is choosing the appropriate solution, and implementing it simply, elegantly, and clearly 6 . What's aesthetically pleasing often has more tangible benefits.

As a result, I've gained a substantial amount of confidence in my ability to develop software. Being a really good programming in the small has diminishing value over time as compilers get smarter, institutional and industry knowledge matures, and computational resources continue to grow. I've developed a good nose for bad code. I might not be great at finding and fixing bugs, but having a good feel for the design aspects makes it less likely that I will create bugs in the first place. My code may have lots of little bugs, but its bones will be strong.

1 Although some of you have seen my code, so it might not be a surprise.
2 What's important isn't describing what the code is doing; if you know the language (or a similar one), that should be obvious. What should be clear is your intent; it's not about what the code is doing, but why it's doing it, or why it's doing it in that particular way.
3 Of which the Daily WTF is a reminder.
4 Which could be depressing from a certain perspective, but it's about replacing one kind of hard with another. Still, I'm happy that Google is out there, because they have shown that tackling really hard problems is worth it.
5 Performance is basically binary: either it's fast enough or it isn't. On the other hand, this philosophy can lead to the death of a thousand cuts, but I think that's just a result of misapplying the principle.
6 That's part of the reason I've been paying a lot more attention to Lisp lately. In general, you should write code for other humans to read, and only incidentally for a machine to understand. The skill of a good developer isn't in translating from human to machine, but rather in translating from human to algorithmic math, and then letting a tool get from there to machine code. A language like Lisp makes it much easier to succinctly express what you are trying to do in a way that is readily comprehensible to other (Lisp-proficient) humans, without sacrificing the ability to be compiled into efficient machine code.

( me | software )

Friday, January 13, 2006
I've been using Opera as my primary browser at work for a couple of months now. I've really grown to like it. The key features for me are performance, stability, and session persistence. I am a massive, massive abuser of tabs, on the order of dozens open in a single window, with half a dozen windows open at once. The only thing that keeps me from opening more is that even Opera starts to crawl at this level, but it's still better than Firefox. Secondly... Opera has crashed maybe 3 times on me. Firefox would crash on me on average once a day. That was especially annoying because Firefox does not save your tab session. Opera does, which makes it easy to restart the application to flush out memory leaks (which both Opera and Firefox have), and also to restart in the rare case of a crash (would work for system crashes and power problems too, of course). I still haven't gotten completely used to Opera, and some things still annoy me, like how it switches you to the last used tab when closing a tab rather than the adjacent one like Firefox. Opera also doesn't have nearly as many extensions as Firefox either. Even so, I find the benefits greatly outweigh those inconveniences now that Opera is free. Give it a shot. You may like it. Ironically, the performance and stability issues are much less of a concern for me now that I am getting on the del.icio.us and RSS reader bandwagons. Still, better is better, right?

( software | web )

Thursday, January 19, 2006

I don't do New Year's resolutions. I don't believe in them 1 . Consider that people generally come up with these resolutions well before the New Year, but delay implementing them until that time. Why is that? Surely, if the resolution is a beneficial change in their lives, they would benefit most from implementing it as soon as they decided to do it. Then there's all the baggage that comes with calling it a New Year's resolution. That's just asking to fail, because nobody keeps their resolutions. In those apparent contradictions are the answer. People make New Year's resolutions for things they think they should do but don't actually want to do. Waiting till the New Year delays doing something they don't want and allows them to join a crowd of people all failing at once, reducing their guilt. It's win-win; they get the satisfaction of trying to do something positive without actually having to do it or feel bad about not doing it.

All of that is a long-winded, roundabout way of saying I have resolved to do a new thing, but this resolution is not of the New Year's kind. The main thing I took away from Paul Graham's latest essay was the idea that one should constantly be producing something. I've spent a lot of time thinking about various ideas, but little time in either following through on them or laying the groundwork for doing so at another time. I find it very easy to let a day go by without having accomplished anything productive (code-wise), and it's similarly easy to let a single wasted day become a wasted week. I won't have that luxury if I'm on my own; days and weeks like that could be fatal to an attempt to go independent. As a result, I've resolved that I must write some useful code every day. Always Be Creating 2 . It could be for my day job. It could be for some noodling around on my own. What doesn't matter so much as long as it happens.

There are several clear advantages to doing this:

  1. Self discipline and good work habits.
  2. Being a doer, not a dreamer. I've spent a lot of time thinking about things I could do and very little time actually following through.
  3. Experience and knowledge beyond what I might get through my job. This is especially important because the languages and technologies that will be most useful for me aren't ones I use at work. For example, if I want to create a client-side application, C# looks to be the best language to use. For building many kinds of web applications, the Java that I know is useful, but I suspect a more dynamic language such as Python will be better suited for the scale of what I'm more likely to attempt.
  4. Building a library of useful parts from which I could build other things. When the time comes to go off to try whatever fool idea I seize upon, I cannot allow myself to start from scratch. I need to have all my building blocks and tools ready. Otherwise, I just won't have enough time or energy. 90% of most software projects is plumbing, and most of that is the same with similar projects.

1 Which is to say, I don't agree with them, not that I deny their existence.
2 "First prize is a Cadillac Eldorado. Anybody want to see second prize? Second prize is a set of steak knives. Third prize is you're fired."

( me | longshot | software )

Monday, April 09, 2007
A lot of websites use Javascript auto-focus to save you the click to put your input cursor into the right form field. The problem is that you might have already gotten there if the site load is slow. That's because the Javascript to set the focus usually runs only when the page has completely loaded. As the page is loading, you click your mouse pointer on the input field and start typing. When the page finishes loading, the script runs and moves the pointer to the input field where you're already typing. Sometimes this will delete what you've already typed, while other times you may end up typing the second part of your input in front of the first part. Either way, the fix is simple: don't set focus if the value in the input field has changed.

( software | web )

Wednesday, May 30, 2007

I'm sure I'm not the first person to notice the growing similarity between Google Earth and the program of the same name in "Snow Crash." It's no coincidence; it's a inevitable application and a logical interface. It's still funny, though.

( software | books )

Tuesday, June 12, 2007

After my scare last month with almost losing a few years of photos, I set up Jungle Disk to back up my important files over the Interweb. Jungle Disk uses Amazon's Simple Storage Service (S3) to store arbitrary amounts of data at multiple geographically separate data centers1. It's a lot more reliable than anything I could piece together myself, and it's trivially easy to set up. Of course, uploading 20-odd gigs over my simple Road Runner connection means I'm not going to have a full backup completed until, oh, next Wednesday, but after that...

1 I wish I could work on something that cool at my job.

( software )

Wednesday, August 29, 2007

4 ME! 4 LOLPUMA! 4 HOLE FAMLEE! 4ALL!

GIMMEH LOLCODE! I wonder if Bank of America will buy me the book:

LOLCODE

Anything's possible if EBSCO has it.

( lolcat | software )

Friday, March 28, 2008

In software, there are two processes for making software support different languages. One is "internationalization," which is where you make the software look up the various phrases and words from external sources (dictionary files, etc.) rather than having them embedded in the source code. That makes the software merely capable of supporting other languages. The other is "localization," where you actually produce the files with the text for Swiss German or whatever and package a version of the software containing them. Some people decided that the words "internationalization" and "localization" were too long. Rather than abbreviate them the way normal people would, they abbreviated them as "i18n" and "l10n," meaning "'i' then 18 letters then 'n'" and "'l' then 10 letters then 'n'" respectively. I figure I can follow that model and abbreviate my name as "k3n g9r" (and put it on my license plate?), pronounced "Ken Gee-Niner." Kieran would be "k4n," and Uma would of course be "u1a."

( ideas | software | me | names )

Friday, April 11, 2008

Suppose you're given a list of people and the languages they speak. How do you find the three (or two or four or...) languages such that you're able to communicate with the most people? You can't just pick the most popular languages. Suppose you have 90 of 100 people speaking Finnish, 85 out of 100 speaking English, and 10 of 100 speaking Tamil, and you want to choose the 2 languages that will enable you to communicate with the most of the 100. If the 85-English speakers are all Finnish speakers, then there's no point in trying English; it won't get you any more listeners. Even though Tamil is the least popular, it's more useful than English. This problem is the a version of the one with 6 billion people and thousands of languages that I suggested a 5-language solution for the other day.

My intuition suggests to me that the general version of this problem is a variation on a well-known problem in computer science called the Knapsack problem. That problem is about how to fit the most of a number of objects into a single bag. It's in a class of problems called "NP-complete." These are (roughly) problems that get exponentially harder to solve as the number of objects you're dealing with increases, but it's relatively easy to check a candidate solution for correctness. NP-complete problems are something theoretical computer science spends a lot of time on. The knapsack problem is probably one of the most readily understood one to the lay person. The canonical example is called the "travelling salesman problem:" given a list of cities, find the route that visits each of them while travelling the least total distance. An interesting characteristic of NP-complete problems is that a method to efficiently 1 solve one of them can solve all of them.

If my intuition is correct, then figuring out the optimal languages to learn would actually be pretty hard to do. A problem where the difficulty scales exponentially over a data set of 6 billion would probably take longer than the expected lifetime of the universe to solve 2. That's of course assuming you could get a list of all the people in the world and the languages they spoke. You could probably come up with very good but not guaranteed best solutions based on the fact that language knowledge isn't distributed randomly; most people in Sweden speak Swedish, but not many people in Kenya do. I wasn't intending to give a primer on deep problems in computing, but it struck me as interesting that a simple question I had out of the blue could very well could be one of these unsolvable (realistically) problems.

1 And precisely; there are numerous methods for finding good but not guaranteed best solutions.
2 Wild-ass guess.

( software )