Thursday, December 6, 2007

Hi, Folks

Since this blog's still getting around 20 hits a day (and, mind you, that's 20 Javascript-enabled hits a day), I have no desire to retire it. I may end up moving my online publishing activities in general to craptome.org, a great domain that I just bought, though. Stay tuned for more details.

Wednesday, September 26, 2007

The Problems With My Startup

Preface
I'm typing this up in order to collect my thoughts, in hopes of eventually showing them to my coworkers. It's here because I'm interested in the commentary of passers-by and because I figure people might find it interesting. I'm initially going to type this in a single sitting, so if I have further thoughts later I'll probably make an addendum section for them.

If you are one of my coworkers and you've stumbled across this prior to my relating these ideas to you, congratulations—you've found my secret blog. Knock yourself out.

A Bit of Background
The startup (I use the term loosely) I work for is composed of four guys—myself (programmer/sysadmin/general technical hotline), two designers (one of whom designed most of our site and one of whom also does Flash programming and did a couple applets on our site), and an people/phone calls/ideas guy. We've been working on our project for over a year, and we provide free basic services and a number of premium, for-pay services. It's largely Web-based, and is not a social network, though it integrates with the big social networking sites, excluding Facebook.

1. Focus and Direction (and Hiring)
When we started our project, we had a single goal. We figured no one was doing our idea, exactly, so why not give it a shot. So we did. And soon we came up with a twist or two to throw in to make the project even more original, namely a client-side application that syncs with our site. But, in my estimation, here we committed two mistakes. First, although we had not yet finished working on our original feature set, we embarked on developing this application simply because it seemed like a great idea. I'll explain the significance of this in a bit. Driven largely (and unconsciously) by desperation to churn this great idea out, we committed our second mistake, which was to enlist a friend of ours, an individual who was intelligent, busy, long-distance, and marginally qualified to develop our application (in particular, as regards Java experience, which he had little of and we needed). This was great for a while; it freed me up to work on core site features. We soon found, however, that communication with our coder was difficult, as we couldn't count on him to meet deadlines even when he set them, and that his idea of quality control didn't match ours. So we said, "Enough is enough," and told him so. At that point the software he had developed was mediocre at best.

So, what to do when the dream isn't panning out? Ask yourself, "What is everyone else doing?" So we did. (Technically, this was sometime during Java application coder's time with us, not after.) And it turned out that Bigger Fish X (code name, of course) was involved in the same sector of business as we were and was providing a service we didn't have to thousands of users of the same ilk as ours. So, why not clone their feature and offer it in addition to our core service? So we did. Another coder (another friend, this time local, thankfully) was drummed up and he began work on the feature. A few months later, we had something that mimicked some of what Bigger Fish X's site did, although many features were missing. And we made a few sales with this feature (to be exact, 10 to date).

Sometime after our web coder finished the Bigger Fish X feature mimick, and I say "finished" in the sense that the barebones functionality was present, he began to drop off the radar. It became apparent that he didn't want to work with/for us—some form of compensation would be required, preferably in the form of pay, and failing that, equity and share in future profits. The latter was not an option amongst the more opinionated among us, who believed that he should prove himself (e.g. dedication, ability to meet schedules, communication, etc.) before being given part ownership of the project/company.

At some point (I'm thinking it was around our startup's half-year anniversary, though it may have been slightly later) we "partnered" with an up-and-coming social networking site catering to a particular niche. The end result was that our services would be advertised to all signups to the social networking site who had an interest in the services we provided (such interest could be determined based upon the type of account they signed up for on the social networking site), and in return our media company would do some audio/visual production work for the site. Our signups increased immensely. I estimate that to date 75% of our signups have been referred by this site. One problem, however, was that these users largely did not have the money to afford our premium services, and thus the "partnership" has not delivered what we hoped.

Over the course of what I've described thus far (around eight months) many, many ideas were thrown onto the table, largely by our idea guy, who has an knack for noticing a random Bigger Fish and suggesting we copy something they are doing. Many ideas were shot down. Some were not, and went onto the drawing board. We gained, notably, a hackish SMS interface (because we couldn't afford an SMS short code; more on that later) that we immediately tried to beta test with several of our more loyal and vocal users, with disappointing results.

Because I'm our only coder for all intents and purposes (we did hire a new Java guy, but he teaches college and has a family and thus makes slow progress), my responsibilities include fixing site bugs, whether in code I wrote or code our late coder wrote, sysadmin tasks, and new feature development. Between bug fixes and new features that we "just had to have" I never had the time to test our core functionality and make sure it was really robust. This is coming back to bite us. Just recently we became aware of a huge deficiency that will need some coding attention and will prevent large clients from using our services effectively until we get it fixed. It's something I wanted to look into more at the beginning, but couldn't because other features were going to make us way more money. Or so some said.

Lately, we've actually gotten the attention of a Big Fish that might want to sponsor a group of people to use our site. This is great, except that it means three months, possibly more, of work to implement features they want that we don't have.

To sum up my issue with our focus I'll attempt to write in generalities. I could go on and on about how our focus has gone wrong. Our "people person" guy preoccupies himself constantly with our startup, although he is a full-time schoolteacher. I would estimate that 50%, possibly more, of my conversation with him involves him telling me about a new feature he's been thinking about lately. Now, mind you, he's probably told me about it before but he's telling me about it again because he's given it further thought and is just this much more convinced that it's largely the key to amazing profits and I know he can't wait until it's implemented. Problem is, I'm our lone coder. I'm working on fixing our current features or fixing a bug discovered by a client or a new feature that's actually work-in-progress, not a few-months-in-the-future maybe. Sometimes I just want to scream, "SHUT UP!"

I see this as probably our biggest problem, and I could go on and on with examples of us allowing ourselves to get tied up doing things that could conceivably be complimentary to our core services, and hopefully will make us money, but at the moment at which they are commissioned are little more than wishful thinking.

2. Innovation
Put briefly, there's little room for it. Sure, I've gotten to write some nifty code, and I was able to put some time into rewriting a particularly key component in our system and tailoring it specifically to our needs, replacing what our Web framework provided. But innovation that will make us money? Innovation that will make our users say, "Wow, that was easy. I love this site!" Nope, we're moving too fast for that. If it works, let's test it for a few days and put it live and cross our fingers. Somehow, we forgot that you can't just copy Random Bigger Fish—you have to be better, and in a way that users notice.

3. Funding/Pay
We knew close to nothing about seeking funding for our startup when we started. We hardly know any more now. The one person who probably knew something about it, because he took the time to research it, was our Web coder friend who declined to work anymore for free. The rest of us wouldn't have known what angel investors or funding rounds were if they smacked us upside the head. One member of our team likes to consider himself business-minded; he once told me that he's a "business geek." Well, you could have fooled me. We never sought any funding, and have never taken any.

Because we were friends when we started, we all worked for free, hoping to share in the rewards of success. Such does not work so well when you're trying to get someone who doesn't see the project's "obvious" merits and potential for success.

If we'd had venture capital, even a little, we could have employed more coders, and they would have wanted to work for us, because money generally has that effect. And who knows, three coders working full time (instead of myself, largely, working when I could) might well have gotten us to where we are now in...dare I say four months?

And then there are growing expenses, like an SMS vanity short code. If we had one, and a bit of money to subsidize messaging costs until the feature began to pay for itself, our SMS feature would not be dead in the water. And it's not like the people who've beta'ed our SMS feature can't tell that something's not right about it. For starters, we're asking people to text to an email address.

If we'd had the money to do so, we could have done press releases as we rolled out our half-baked features, thus at least exposing ourselves to potential users and hopefully, Big Fishes who might possibly sponsor numerous users. Furthermore, in our sector, a press release is a near necessity. Incidentally, press releases are still on the perpetual drawing board, for a later date when we've more money to throw around.

4. Public Relations
As I've mentioned before, our PR guy is a full-time schoolteacher. This means that he doesn't have enough time to call users, to do tech support for users, to answer feedback, to call potential Big Fishes, as is necessary for us to even maintain any momentum we had at the end of the summer.

5. Information Presentation
I believe that when people hit our front page, it's not immediately obvious to them why they need our service. Sure, perhaps they'll come back and check it out on the weekend when they have time to poke around, but our front page does not outline what we do and why people should at least try out our services in a succinct and simple manner. Instead, it's wordy and cluttered and we over-explain (or is that over sell) everything we offer. But we've gotten feedback asking, "Uh, so, what is it you guys actually do?"

This is by no means a jab at our designer. First off, I don't think it's his fault, and second he's been working on a simplistic redesign that gets down to the essentials, but he's being pulled off that by tangential projects that are pulling in some money but are not letting him focus on our core service.

Conclusion
In summary, we suck at staying focused on one idea. If you don't see the merit in that, look no further Flickr.

We suck at hiring (or enlisting) help on our project, and we've blown off a few feet in our desperation.

We suck at allowing ourselves to make something that's actually good and that people will want to use on its own merits. That might be a bit strong, but I'm referencing the innovation thing.

We suck at even understanding how Web business works today, but we don't have enough time to educate ourselves.

We suck at having enough time to respond to the questions, comments, and concerns our current clients, and time to pursue new clients and new venues of acquiring clients.

We suck at explaining to potential users exactly what we provide and why they should use our service.

This is stuff I've been batting around in my own mind for quite a while. Some of it has slipped out in conversation at the office, some has not. I have really enjoyed working on this project, I love the guys I work with, and I think our idea has potential, but I am becoming increasingly disillusioned with where we think we're going, how we plan on getting there, the process through which we decide either of the two previous items, and the manner in which my concerns are often dealt with. Sometimes when I hesitate about something at the office, some part of what I've mentioned runs through my head. I've put it all down here so that I can present it in a comprehensive manner soon.

Saturday, September 15, 2007

September

It's September, and I've nearly forgotten about this blog. I'm going to do my darnedest not to abandon it.

In other news, Aaron Swartz's new project, Jottit, has been officially released. Cool.

Monday, August 6, 2007

Rails Tip: TinyMCE, Unicode, and encodeURIComponent

Here's something I learned today: when sending input from a TinyMCE editor back to your Rails application, Prototype's encode() function will fail you if your TinyMCE'd textarea contains Unicode characters (in my case, they were "curly" quotes, probably generated by Word). Use Javascript's encodeURIComponent() instead. In other words, where you might have written something like this:

function mailSave() {
  <%= remote_function(:url => { :action => 'save' },
    :before => 'tinyMCE.triggerSave(true,true)',
    :with => "'subject=' + encode($('descr').value)
      + encode($('tiny_mce').value)") %>;
}


Instead, use this:

function mailSave() {
  <%= remote_function(:url => { :action => 'save' },
    :before => 'tinyMCE.triggerSave(true,true)',
    :with => "'subject=' + encodeURIComponent($('descr').value)
      + encode
URIComponent($('tiny_mce').value)") %>;
}


One of our bigger clients needed to send a mailing and was going to switch services if this bug wasn't fixed by 5:00 this afternoon, so plenty of bullets were sweat while I figured this out. Many thanks to Firebug, as usual.

Sunday, August 5, 2007

Darn It, Amazon!

Interesting article about Amazon's new FPS. I like what I've been hearing about FPS, particularly because I've experienced Paypal's annoying API and bad customer service firsthand. Plus, I always hated the inane requirement that customers be given the option to use Express Checkout in lieu of your payment form, should they desire. I'm hoping to see Paypal taken to task by a market that demands better.

But darn it, Amazon, why unveil FPS just when we've got Authorize.Net and a merchant account working?!

Saturday, August 4, 2007

How to Install Xmonad on Gentoo

Please Note:
This post is presumably severely dated. I no longer use Xmonad (viva la Stumpwm), so I have not tried to keep this updated. Should you wish to install Xmonad on Gentoo, this is probably not the tutorial to follow. Still, though, you might glean something useful from it.

So, you've heard good things about Xmonad, the minimalistic, tiling window manager for X, and you'd like to give it a try on your Gentoo box. Here's how to do it, and get a respectable Haskell development environment in the process.

Note: This tutorial assumes you want to do things the Gentoo way, i.e. by using Portage. Another option is to build the Haskell compiler, required libraries, and Xmonad from source, and if you'd rather follow this method, the Xmonad site has the details. This tutorial also assumes that you know your way around Gentoo, and know what you're doing, or you are good at pretending you do. Since you're installing things, you will probably need to be root for this.

Step 0: Important!
Since I wrote this, changes to the Haskell overlay, etc., may have occurred. I highly advise you to read the post's comments so that you can "interpret" anything you read here in light of them.

Step 1: Install the Haskell Overlay
First, you need to install the Haskell Portage overlay, which contains newer Haskell-related packages than those found in Portage. If layman, the overlay manager, is not installed, you should first emerge it and update its overlay list.

# emerge layman
# layman --fetch


Once layman is installed, your next task is to enable Darcs-based overlays, which, not surprisingly, require the Darcs distributed source code management system to be present. Here a chicken-and-egg problem arises, as Darcs is written in Haskell and thus requires GHC and the core Haskell libraries. However, you want to avoid installing Haskell until after the overlay is installed, in order to avoid having to upgrade Haskell and friends later. My solution is to use a statically-linked Linux binary provided by the Darcs project.

# wget http://www.pps.jussieu.fr/~jch/software/files/darcs-1.0.7-i386-linux.gz
# gunzip darcs-1.0.7-i386-linux.gz
# mv darcs-1.0.7-i386-linux /usr/bin/darcs
# chmod +x /usr/bin/darcs


You now have a working darcs command, which layman will use to pull in the Haskell overlay, after which you may remove the darcs binary.

# layman -a haskell
# rm /usr/bin/darcs


If this is the first overlay you have installed (in other words, if you emerged layman above), you will need to add a line to your /etc/make.conf. This is necessary to keep Portage happy.

# echo "source /usr/portage/local/layman/make.conf" >> /etc/make.conf

Step 2: Install GHC and Friends
Your next task is installing GHC, the Glorious Glasgow Haskell Compilation System, and its partners in crime. The following lines need to be added to your /etc/portage/package.keywords file to ensure that GHC and friends build from the Haskell overlay:

dev-lang/ghc
dev-haskell/mtl
dev-haskell/regex-base
dev-haskell/regex-compat
dev-haskell/regex-posix
dev-haskell/cabal
dev-haskell/filepath


An addition to /etc/portage/package.use is also necessary to pull in the binary GHC package, as opposed to bootstrapping it.

# echo "dev-lang/ghc binary" >> /etc/portage/package.use

You're now ready to emerge GHC!

# emerge dev-lang/ghc

Step 3: Install Darcs
In view of the possible future in which you become a Haskell fanboy or fangirl, and decide that Darcs is the perfect tool to manage your projects, you need to install Darcs. It's also necessary because you are going to pull the very newest Xmonad sources from a Darcs tree in Step 4. This time you'll build Darcs from source. Add the following to /etc/portage/package.keywords:

dev-util/darcs
dev-haskell/quickcheck
dev-haskell/html


Then, emerge darcs. I got an error when I did this.

!!! Digest verification failed:
!!! /usr/portage/distfiles/darcs-1.1.0pre1.tar.gz
!!! Reason: Filesize does not match recorded size
!!! Got: 1116180
!!! Expected: 1112362


Because Portage pulled the distfile directly from the Darcs site, I assumed it was safe, and used the ebuild command to update the Manifest file for Darcs, and emerged the package again:

# cd /usr/portage/local/layman/haskell/dev-util/darcs
# ebuild darcs-1.1.0_pre1.ebuild digest

# emerge darcs


Step 4: Install Xmonad
Now that everything is in place, it's time to install Xmonad! First, add the following lines to your /etc/portage/package.keywords:

x11-wm/xmonad-darcs
dev-haskell/x11
dev-haskell/x11-extras-darcs


Next, you'll need to add a line to /etc/portage/package.use in order to instruct Portage to build Xmonad with the "extensions" USE keyword, which will enable a variety of layout algorithms and other nifty things you may want at some point.

# echo "x11-wm/xmonad-darcs extensions" >> /etc/portage/package.use

It's now time to emerge xmonad-darcs. After doing so, you need to specify xmonad-darcs as your window manager, using whatever mechanism you currently use. For me, that meant updating my .xinitrc with an "exec xmonad-darcs" line.

Step 5: Install dmenu and dzen (optional)
Xmonad has two pals it gets along well with: dmenu, a lightweight program launcher, and dzen, a status bar program. You don't have to install them, but they're useful, and you won't be inducted into the Church of Xmonad unless you do.

dmenu installation is as simple as running emerge dmenu. After adding a line to /etc/portage/package.keywords, dzen installation is just as simple.

# echo "x11-misc/dzen" >> /etc/portage/package.keywords

Conclusion
If you have followed this tutorial, and assuming I didn't goof up horribly, you should have a functional Xmonad system. Head over to the Xmonad overview to find out more about what you can do with Xmonad.

Monday, July 30, 2007

Moo

Greetings, plebeians.