31 August, 2005

Let's Hold Each Other to a Higher Standard

Rant Alert!

Last year, I signed up for a year-long membership at St. Louis Workout on Union St. in St. Louis, MO. I paid my $200 and signed a contract. At the end of the year, I didn't go back; I didn't really dislike the gym, but I found another that I liked better. A couple of weeks after the end of the year contract, however, I thought I'd better make sure everything was cleaned up, so I called the gym. "No problem," the lady said, "just come in by the 15th and we'll clear everything up for you." I came in on the 13th and signed some paperwork declaring my intent to leave the gym; part of the paperwork was an "amount due" field, about which the gentleman at the gym said, "just put '$0' since you prepaid your year membership."

Two weeks after that, I got a bill from the company stating that I owed "$23.66 per month" [for two months after the year membership] and late fees totaling $50. I called them to sort it out. My argument was as follows:

  1. They were perfectly within their right to collect on this amount due, since I had signed a contract stating that I would give them advance notice of my termination
  2. I had made my intentions clear by a) pre-purchasing the year membership rather than enrolling in a repeated-billing process and b) not visiting the gym after the membership had ended
  3. Two representatives of the gym had both told me that there would be no problems in closing my account
  4. Therefore, they should work out some deal with me so they come out as the good guys, willing to help out their customers in the case of an unintentional error

The "gentleman" on the phone disagreed, stating that he "had nothing further to say to me." So I wished him a good day and hung up. I will send the check. They will cash it.

But I have learned my lesson: I no longer have any faith in corporations to "provide a service to their customers." From now on I will treat them as an enemy whose only purpose is to take my money. I will not sign devious contracts.

And I will hold myself to a higher standard: read all fine print.

29 August, 2005

Things that Should Exist

  1. Dream Recorder

    So according to physics, anything that's an engine is also a generator. (Just run it in reverse, dummy.)

    Well, I know almost nothing about the human brain, but it would be pretty cool if we could apply the generator/engine model to the visual center of the brain in order to record dreams. This, of course, relies on figuring out where dream visions differ from real visions; that is, clearly you don't just dream about the backs of your eyelids (at this point, half my audience closes their eyes to see what the backs of their eyelids look like - admit it), so somewhere between cone/rod and the innermost processing a misfire has to take place. If it originates really close to the outside world in the optic nerve, then we've got some potential!

    Now we just need to do some research and then find test subjects who will let us put wireless transmitters on their optic nerves.

  2. MP3 Tagger

    I'd like to be able to put little digital sticky notes on my mp3s. A note could attach to a whole song or just a few seconds. Then, you could send all the notes to a friend as a file, and the friend's reader would pop the notes up when the song is played. Like the little notes in MS Word, but for music. It's important that they be able to be restricted to a small portion of a song, since, for example, I may not like the whole song, but want to point out a "really cool drum solo" or something. This software would have nothing to do with music piracy, since it's dependent upon you both having copies of the same song. Unfortunately, if you want the stickies to be applied automatically, you'd need to use a music format that has track information (ID3, for example); if not, you'd have to apply the stickies manually.

  3. Filesystem URL Symlinks

    Unix, Linux, Mac, etc. all have a great feature called symlinks - basically virtual copies of a file. They come in two versions: "hard" symlinks act as full copies of the file, but don't have the original content, while "soft" symlinks act like really thin wrappers so you can basically call a file by two different names (great for directory shortcuts and the like).

    Now that OSs like OSX are starting to come with webservers preinstalled, I'd like to see a third category: URL symlinks: things that act like files but are really handled by the web server. The following example should illuminate: I've got iTunes, which uses an XML file for its library data. But let's say I'd like to have it use a database instead (maybe to do reporting, or in the hopes that it does lookups faster), or have it use a web url (so all my computers use the same library file, say). I could have my local web server take over the responsibility for the "file" /Library/iTunes/library.xml or whatever. It would accept reads and writes just like any other file (so long as I enabled those permissions), but would actually forward the requests to a servlet. I see this as the next evolution in web servers. We're almost there with wikis, but not quite.

25 August, 2005

Specialization

Today I will venture into a few areas that I see as related:

  1. Appreciation for and learning of good writing has declined over the past 100 years in America
  2. Time marches ever forward (ignoring, for the moment, those realities in which it does not)
  3. The Liberal Arts education

1.

I repeatedly hear those in my grandparents' generation complaining that, "kids these days can't read or write." There are certainly many possible reasons for this being true, including

  • a) Linguistics - grammars and vocabularies are ever-shifting, so generation Y will sound nothing like the Depression-era folks' speech, and thus each will think the other doesn't speak the language correctly.
  • b) The Failure of No Child Left Behind (and the American education system in general) - in my opinion, the situation of reading and writing in America was going downhill well before President Bush took office, but this policy, while well-intentioned, was poorly implemented. It certainly isn't helping. Fully Federalizing education has failed spectacularly for the last 40 years, so I'm all fore giving the states and local communities more power, but they need more money, too.
  • c) There's more stuff to learn - seriously. Kids 100 years ago didn't have to master the internet and learn the history of the Iraq war. Admittedly, there is material that they learned that has gone by the wayside, but for the most part, we just keep increasing the amount of stuff kids have to learn by the time they're 18. This is a direct by-product of #2, above.

This essay is not the place to debate the first or second reason for the change (I say decline, but 1a above argues against that) in the reading and writing of American students. I am interested in the effects of 1c.

2.

That means stuff accumulates over time. There's never less of it than there was.

3.

The theory of a Liberal Arts education is that it produces a well-rounded academic. This is a wonderful goal. I make my living writing computer code, but I wouldn't want my life or learning limited to that; I would go insane. Well-roundedness has another benefit: more connections. Invention, creativity, problem solving - all the stuff where the gears in your head are really chugging - are basically the synthesizing of ideas. The more fields with which you have experience, the more connections and styles of thought you have. Some argue, "why should I have to take 4 semesters of psychology if I know I want to go into Gothic Architecture?" This is a good point; taken to the extreme, the idea of "more classes is better" would mean never graduating. So we need to find a balance.

But even if we find a good balance today, won't it have to shift with time? There will be more classes necessary to learn all about Gothic Architecture since eventually there will be the Neo-Gothicists and the Post-Neo-Gothicists, and ... There will also be new fields not yet imagined - fields about which "any intelligent person" ought to know at least a little. So if all fields tend to expand in volume at about the same rate, the ratios won't shift, but we'll all end up spending longer in school.

Let's hope those working to lengthening life expectancy maintain their focus.

22 August, 2005

CSS as JSP

The Problem

I've been working on refactoring a project from tables to a table-less design with CSS. The stated benefit (with which I agree wholeheartedly) is that using tables for layout of non-tabular data (that is, using tables to position blocks of text) is improper because it is using the wrong tool for the job. Any artisan (woodworker, metalsmith, sculptor) would tell you this is a huge no-no, but in web design, it's gone unchallenged for virtual centuries (i.e. a few years). But the "it's-just-bad-art-and-bad-zen" argument isn't the whole story: alternative browsers (cell phones, audiobrowsers for the deaf, etc) have no idea what these tables mean, and will therefore confuse their users. The problem is that though CSS is standardized, some broswers (most notoriously, IE) don't conform to the standard.

The Established Solution

So far, people have been adding hacks to their CSS to get around browser differences. Things like the star html hack and the mac backslash hack are ingenious, but they impede development. They're hard for future programmers to understand (even with liberal comments), and they're logically messy. (No self-respecting C++ programmer would write

  width = 100;
  callBackSetWidth(120);  //Linux platforms before
                          //1997 don't support this,
                          //so they get the value 100
It's just ugly.)

My Solution

I came upon my solution by accident. I have been using the .jsp extension for my CSS files for a while now for the sole purpose of being able to use the <c:url> tag. If I use an image for a background, I don't want the link to have to reference my project name - epecially since the context may change to root at deployment.

Because the CSS files were already dynamically generated, I thought of doing browser dependency with tags. I've got
<c:set var="user_agent" value="${headerValues['user-agent'][0]}" />

<c:choose>
  <c:when  test="${fn:startsWith(user_agent, 'Mozilla/5.0')}">
    <%-- Firefox 1.0, Gecko, etc --%>
    <c:set var="firefox" value="${true}" />
    <c:set var="ie" value="${false}" />
    <c:set var="app_width" value="760" />
  </c:when>
  <c:otherwise>
    <%-- IE 6 --%>
    <c:set var="firefox" value="${false}" />
    <c:set var="ie" value="${true}" />
    <c:set var="app_width" value="762" />
  </c:otherwise>
</c:choose>
at the top of the file. You could easily have more cases if you need to support more browsers. Notice first the "ie" and "firefox" variables. These can be used by tags later for browser-specific settings. Also notice the global variable app_width; this is a nice way of promoting reuse (constants are our friends - it'd sure be nice to be able to make 'em final in the page scope, though) while allowing differences between browsers.

The Dangers of Globalization

The Premise

The Diane Rehm Show hosted Barry Lynn today to discuss his book, End of the Line: The Rise and Coming Fall of the Global Corporation. Lynn was a globalization consultant for many business, and, over the years, came to believe that as our economy has become more global for the sake of efficiency (which all economists will agree is a benefit), this efficiency has come with increased risk. He gives examples such as computer manufacturers relying on chips from Taiwan, and we are thus importing their political instability in the form of component-reliance. Lynn's solution is to use the US Government to force diversification and backup, such as a law stating "no one foreign country can supply more than 25% of a given product."

My criticism

Such a law would probably have the intended benefit - political disturbances in Taiwan would have less of an effect on our economy because businesses would be forced to also use Brazil.

(Opponents who still accept that this is a problem would argue that the US Government should be giving tax credits to companies doing manufacturing and sourcing within our borders so as to decrease dependence on foreign goods and services overall. This has some merit, but strikes me as a little heavy-handed. It's basically substituting tax money for efficiency, which smacks of socialism. This doesn't work.)

I, however, like to think of Government as the solution only when we can't come up with a free-market solution. Therefore, I began to brainstorm some ideas that will help alleviate future problems due to dependence on unstable resources. (By the way, people who study computer science will be smacking their foreheds and saying, "duh," throughout this whole article, because we're constantly trying to limit dependence upon unstable resources.)

Some ideas

  1. A company that offers foreign-instability-insurance. If you've got a $10B business that relies on information stored in Bangalore, we'll give you money when Bangalore falls into the ocean or erupts into civil unrest . . . for a price. This has the benefit of being immediately profitable (we're not making payouts until something bad happens, and we're taking in premiums from the get-go), but the actuaries are going to complain a lot because they've never seen a problem like this.
  2. A company that offers goods/services backups. Creating domestic copies of Dell's offshore data is quite easy, but how do you create a backup chip manufacturing or chemical processing plant? A backup textile factory? Perhaps the company could have a branch that specializes in really fast construction and buy up land in cheap areas to be used at a moment's notice. Clearly location isn't important, since the plants are now 8000 miles away.
  3. (as a little bonus, Company #1 could offer discounts to businesses that employ the services of Company #2 - now we've got a risk-reducing empire on our hands!)
  4. A company that stops natural disasters. You'd just call them up and say, "hey, in case there's an earthquake about to hit India, I'd rather it didn't." Technical specs to be hashed out later.

16 August, 2005

The Business Experiment

The Business Experiment is trying to create an open-source-style business. I like the idea (and am a member), but I have some reservations. Some critics worry that people won't be willing to share their ideas for fear of losing out on the rewards. I'm perfectly happy to take that risk, because from all the startups I've tried to start, I know that the odds of actually getting your idea going is close to nil, so it's a worthwhile trade. I love the idea of collective wisdom (which is oddly kind of the opposite of groupthink) - the anecdote that really hits home with me is that of the M&Ms in the jar:

If you put out a jar of M&Ms and ask everybody to guess how many there are in the jar, with the person guessing closest getting a prize, the average guess will be very close to dead-on, even if no single guess is.

So I really like the idea, but I do have some worries. One of them is how to split up revenues among those "running" the business. Also, are the people signed up on the site employees? Or one collective CEO? If the former, we'll need to have some sort of payscale. For either, there will have to be some determination of how much each person contributed (or simply divide by #users, which, to some, would seem very unfair).

13 August, 2005

Consumating

"Tell me about your mother," Consumating asked. And so I responded, but, as mentioned in the postscript, I told a lie. My mother has, in fact, never climbed Mt. Kilimanjaro.

11 August, 2005

Businesses are Foolish

So many eBusinesses out there subscribe to the same, dumb model. They make you create an account to do the smallest thing, like email them a question. Buy.com just lost a sale because I could not email them a question. (Granted, the question was whether they would match, or even come close to a competitor's price.)

I imagine companies require all sorts of registration so they can collect information on their customers in order to better market. If I want specials emailed to me, though, I would just want to submit my email address to a "specials newsletter" form. I still wouldn't want to go through the whole signup process. If I don't end up purchasing from them, my account is just wasting space on their server; if I do end up purchasing, they've got all that information from the order form.

There is another possible reason for all these registrations: the programmers aren't smart enough to figure out a way to do what the business analysts want without logins. Just a tiny bit of thinking outside the box (and not all that outside the box) yields elegant solutions for many of these issues. Let's say you want to make sure that the email address submitted to the "specials newsletter" wasn't somebody else's; you simply send them a confirmation email first. Now, what about when the person wants to unsubscribe? Simply having an email daemon (they're FREE from Apache's Jakarta project, for goodness' sake) that listens for "unsubscribe" emails accomplishes this.

Now, don't get me wrong: sometimes, an account on a site - even an eMarketplace - can be a Good Thing(TM). (Side note: I'm really not sure why we say "Good Thing(TM)," but I'm pretty sure that's how it's done now.) If I want to view order history, view order tracking, not have to reenter my billing address, ... I'm all for it. But what if I don't want any of that?

So in the end: making people sign up for accounts that don't really do anything just pushes customers away.

03 August, 2005

Being understood

I just reread my Plea 1, and was reminded of what happened this weekend. I had asked my friend Chelsey to come over and help me clean. She agreed, but by "help" she meant "heckle." This actually was fine, since just having someone around to keep me on task works wonders. Bonus point one for CMR.

But to the point: at one point I had mentioned that I tend to listen to music without listening to the lyrics (much to the annoyance of an ex girlfriend). Later, I tried to explain Schenkerian theory of pivot chords and pivot notes (hence the relevence to Plea 1) and my music thesis. After twenty minutes of doing complete injustice to the theory, Chelsey says, simply, "now I see why you don't pay attention to lyrics." It was the highlight of my summer; I haven't felt understood in a long time. So bonus point two to CMR.

Java notes

The best way to iterate (pre java 1.5)

for (final Iterator iter = myCollection.iterator(); iter.hasNext(); ) {
  //code
}

Benefits:

  • forces iter to have the right scope
  • puts looping logic on one line (unlike while, or wose yet, do...while)

A gripe

javadoc should be able to translate < and > into &lt; and &gt; automatically. For actual html tags, you can just write <li> or whatever, but you can't put List<Dog> in a javadoc comment. Javadoc should be able to tell the difference between html tags and parameterized types (not to mention mathematical logic, like myNum < .5). I just think "@param dogs a List&lt;Dog&gt; that are available for sale" looks ugly.

Use Business-Level Helpers

In Better Faster Lighter Java, Tate and Gehtland discuss breaking dependencies (pp 54 ff). They describe the "train wreck" that can happen when you have things like "store.getAddress().getCountry().getState().getCity() or ... address.country.state.city ... [especially when the code] reaches into many different packages." They suggest adding helper methods that do the reaching for you from the top layer so that clients of Store don't need to know about the intermediary classes.

I suggest an alternate solution: the use of very specialized helper classes. Such a class might have only one method: City getCity(Store store). They are even more useful when doing calculations rather than simple accesses. A class like this allows you to change the internal structure of Store without affecting its clients. If you later want to use database lookups or web-service lookups, or send an SMS to a guy that sits in your office to do lookups, you can simply replace the code for the helper. (Note that these helpers should NOT be Singletons, or you're going to create quite the bottleneck!)