Sie sind auf Seite 1von 56

Lessons

Learned
From 13
Failed
Software
Products
Andy Brice
By

Issue 3  August 2010


LET’S GET

SOCIAL
5.2
30,000
influence
*

programmers & startup founders

Advertise
with us

To advertise with Hacker Monthly,


drop us an email at ads@hackermonthly.com.

*Circulation number is based on the average number of digital downloads and print purchases for each issue.
Curator
Lim Cheng Soon
Curator’s Note
Contributors
Andy Brice
Jason L. Baptiste
Jason Schuller

I
Hillel Cooperman
Scott Edward Walker
n every new issue, I try something different. This issue, I
Xavier Shay
have included more technical articles, based on suggestions
Nikos Moraitakis
from our programmer-heavy readership. I have also taken
Dave Pell
a big risk by including longer (up to 10-page) articles, bumping
Matt Might
our total pages to a whopping 56 pages — a 16-page increase
Brian Carper
from the usual issue. Another new experiment is the ‘Tech
Alan Skorkin
Jobs’ section (huge props to Zach Epstein, who suggested it)
Daniel Spiewak
where companies can post programming and other technical-
John D. Cook
related jobs. You might notice most of the URLs in this issues
are shortened under hn.my. It is Hacker Monthly’s own URL
shortening service. 
Proofreader Design-wise, the font is slightly (1pt) smaller in this issue
Ricky de Laveaga
with a wider leading. I’ve combined the use of left-justified and
left-aligned paragraphs instead of choosing one style for the
entire issue. This issue also marks the first time a real person
Illustrators (Andy Brice, who wrote and edited the fantastic featured
Jaime G. Wong
article) has made it onto the front cover.
Hacker Monthly is slowly taking shape, one issue at a time. I
need your feedback the most at this stage in particular. Reach
Printer me directly at cheng.soon@hackermonthly.com. n
MagCloud
— Lim Cheng Soon

Advertising
ads@hackermonthly.com

Contact
cheng.soon@hackermonthly.com

Published by
Netizens Media Hacker Monthly is the print magazine version of Hacker
46, Taylor Road, News — news.ycombinator.com — a social news website wildly
11600 Penang, popular among programmers and startup founders. The submis-
Malaysia. sion guidelines state that content can be “anything that gratifies
one’s intellectual curiosity.”
Every month, we select from the top voted articles on Hacker
News and print them in magazine format.
For more, visit hackermonthly.com.

On The Cover: Andy Brice


Photo: Andrew Fosker (http://www.secondsleft.co.uk/)

4  
Contents

FEATURES

06  Lessons Learned From


13 Failed Software Products
By andy brice

16  How To Become A


Millionaire In Three Years
By jason L. Baptiste

STARTUP PROGRAMMING
22  How I Monetized My Passion 32  Advanced Programming Languages
By Jason Schuller By Matt Might

26  How I Almost Ignored Our Single 36  Emacs Isn’t For Everyone
Best Source For Customer Feedback By Brian Carper
By HILLEL COOPERMAN
38  What Every Developer Should Know
36  What Are The Biggest Legal About URLS
Mistakes That Startups Make? By ALAN SKORKIN
By Scott Edward Walker
42  Understanding And Applying
Operational Transformation
By Daniel Spiewak

SPECIAL 53  Math Library Functions That Seem


21  Why I Quit A Six Figure Job Unnecessary
By xavier shay By John D. Cook

25  What Kind Of Girl Do You Think I Am?


By NIKOS MORAITAKIS
54  TECH JOBS
30  Say Hello To My Little Friend
By DAVE PELL

Illustration: Jaime G. Wong (http://retrazos.pe/)

 5
FEATURES

Lessons Learned
From 13 Failed
Software Products
By Andy Brice

“ No physician is really
good before he has killed
one or two patients.”— Proverb
S oftware entrepreneur
culture is full of stories of
the products that suc-
ceeded. But what about
the products that failed? We rarely hear
much about them. This can lead to a
very skewed perspective on what works
and what doesn’t (survivor bias). But I
believe that failure can teach us as much
as success. So I asked other software
entrepreneurs to share their stories of
failure in the hope that we might save
others from making the same mistakes.
To my surprise I got excellent 12
responses, which I include below along
with one of my own. It is a small sample
and biased by self-selection, but I think
it contains a lot of useful insights. It is an
unashamedly a long post, as I didn’t want
to lose any of these insights by editing it
down.

6  FEATURES
CASE #1 • It is difficult to capture the subtleties CASE #2

DRAMA CleanChief
of the design process in a structured
form.
• A bad hire. If you hire the wrong
DRAMA (Design RAtionale MAnage- CleanChief was to be ‘The easy
person, you should face up to it and
ment) was a commercialization of a management solution for cleaning
get rid of them. Rather than keep
University prototype for recording organisations’. Managing assets, employee
moving them around in a vain attempt
the decision-making process during schedules, ordering supplies, you name
to find something they are good at.
the design of complex and long-lived it CleanChief handled it. Essentially it
• We took a phased approach, starting
artefacts, for example nuclear reactors was light weight accounting software for
with a single-user proof of concept
and chemical plants. By recording it cleaning companies.
and then creating a client-server ver-
in a structured database this informa-
sion. In hindsight it should have been
tion would still be available long after Why it was judged a commercial failure:
obvious that not enough people were
the original engineers had forgotten it, A small number of copies were sold.
actively using the single-user system
retired or been run over by buses. This No one is actively using it at pres-
and we should have killed it then.
information was believed to be incred- ent. Once I realised that it wasn’t a
Time/money invested: At least 3 man
ibly valuable to later maintainers of the complete product and that additional
years of work went into this product,
system, engineers creating similar designs development was required I moved on
with me doing most of it. Thankfully I
and industry regulators. The develop- to other product ideas. I had basically
was a salaried employee. But the lack
ment was part funded by 4 big process run out of enthusiasm for the product.
of success of this product contributed
engineering companies. What went wrong:
to the demise of the part of the
• I am not an accountant.
company I was in.
Why it was judged a commercial failure: • I have never run a cleaning company.
Current product status: The product is
Everyone told us what a great idea • I developed it for more than two years
long dead.
it was, but no-one bought it. despite without getting feedback from real
Any regrets? It was a fairly painful
some early funding from some big cleaning companies. I was arrogant
experience. I would rather have spent
process engineering companies, none enough to think that I knew what they
all that money, time and energy on
of them put it into use properly and wanted (or could work it out on my
something that someone actually used.
we never sold any licences to anyone own). Or maybe it was that I was just
But at least I learnt some expensive
else. where I was most happy and comfort-
lessons without using my own money.
What went wrong: able – writing software. Talking to real
Lessons learned:
• Lack of support from the people who users was new and to be honest a bit
• Creating a new market is difficult and
would actually have to use it. There scary for me.
risky.
are lots of social factors that work • A successful cleaning company
• Changing people’s working habits is
against engineers wanting to record operator, a friend of a friend, offered
hard.
their design rationale, including: to become involved for a 30% share.
• Social factors can make or break a
»»The person taking the time to record This was a gift from the heavens,
product. The end-users didn’t see
the rationale probably isn’t the exactly what I needed. I refused.
anything in it for them.
person getting the benefit from it. • In a way, even though I spent so long
• If the end-users don’t like a product,
»»Extra work for people who are on the product, I gave in too soon, I
they will find a way not to use it, even
already under a lot of time pressure. was just getting feedback from real
if their bosses appear to be enthusias-
»» It might make it easier for others to users, just getting my first batch of
tic about it.
question decisions and hold compa- sales when I decided to move on.
• Talk is cheap. Lots of people telling
nies and engineers accountable for • I developed the application in VB6
you how great your product is doesn’t
mistakes. even though I knew it was outdated
mean much. You only really find out
»»Engineers may see giving away this technology when I started the project.
if your product is commercially viable
knowledge as undermining their job This meant there was no ‘cool factor’
when you start asking people to buy it.
security. when discussing it with other develop-
• Problems integrating with the other ers, I told myself it didn’t bother me,
Contributor: Andy Brice
software tools that engineers spend but it probably did.
(http://successfulsoftware.net/)
most of their time in (e.g. CAD pack- Time/money invested: I worked on it at
ages). This would probably be easier night and weekends for about 2 1/2
with modern web-based technology. years. I paid for graphic design work,

 7
“ Go for it, maybe you win,
maybe you fail, but you will
grow and get tons of useful
knowledge on the way.”

purchased stock icons and images. I I learned so much more in my two Case #3

ChimSoft
probably spent a couple of thousand and a half years of trying to develop
Australian dollars in total and an awful CleanChief than I did in the two and
lot of time. a half years prior to that, during which
ChimSoft – Software for Chimney
Current product status: I moved on to time I really wanted to start a software
Sweeps.
other products that have gone much business but didn’t take any action.
better. My newer products were Lessons learned: Hearing or reading
Why it was judged a commercial failure:
released in months rather than years some piece of advice is totally dif-
I believe this failed for two reasons:
and I looked for real feedback from ferent to living it. Here are some of
• Focusing on too small of a niche
real users from day one. They are: the ideas that I always agreed were
• Me not being able to work full time
• QueryCell – an Excel add-in making true but didn’t fully understand the
on it.
SQL in Excel easy. implications of until I had lived them
I don’t consider it a complete
• QuizNightChief – the easy way to out:
failure because I sold two copies when
organise a quiz Night. • Force yourself to get out and talk
it retailed for $2k, and maybe 10-15
• CustomerCradle – The easiest way to people. Ask their advice. Almost
more copies when I lowered the price
to record and report on where your everyone will help if you ask them for
to $200. Those sales proved that I
customers come from. feedback.
wasn’t completely off base in thinking
I do occasionally ponder returning • Force yourself to cold call a few busi-
there was a market for the software,
to CleanChief and trying to raise it nesses in your target market.
but the cost of customer acquisition
from the ashes. • Create a plan of how to market your
and the size of the market were too
Any regrets? No. Looking back I learned product.
small. Customers wanted to have a
a few lessons from a huge amount of • Try and use your product as much as
bunch of phone calls, face-to-face
time and work, it was a very inefficient possible as you build it.
etc… the type of stuff you only see
way to learn those lessons. But when • Get out of your comfort zone from
with much more expensive software.
you are new to something like starting day one.
The problem was that for a niche this
a business or creating useful software • Do not have the mind set that the day
small we had to charge a lot of money
being inefficient at learning lessons is you release version 1.0 is the finish
to make it worthwhile for us, but
the best you can do, it’s a thousand line, it’s the starting line, so hurry up
the customers were small businesses
times better than not learning lessons and get there.
where this is a major investment, so
at all.
the fit was never right. The other issue
Contributor: Sam Howley
was the people that did buy it were
(http://oakfocus.net/)
not super tech-savvy, so there was a

8  FEATURES
high cost of support that made even a Case #4 Case #5

PC Desktop Smart Diary


$200 product not worth it.
What went wrong:

Cleaner Suite
• Having all partners who were not full-
time, and had equal equity. I ended
up doing most of the work and this is
PC Desktop Cleaner. Simple software Smart Diary Suite.
the main reason I didn’t force success
that cleans your desktop and archives
is I felt I was in it alone.
your files. Why it was judged a commercial failure:
• Focusing on too narrow of a niche.
It sells and the profits cover current
The plan all along was to expand for
Why it was judged a commercial failure: investments in the product, but there
all service industries, but it was much
My goal was to sell 10 units per is little left over on top of that.
harder to make that move than we
month. I’ve sold less than 1 unit per What went wrong: If I had a chance to
expected.
month. do anything differently:
• Not researching pricing more, we
What went wrong: • Take it seriously from day one.
knew small businesses made major
• I think that the product concept is • Never stop developing and supporting.
purchases for things that really helped
not useful enough. It’s not a thing that • Invest as much as possible in market-
their business, but I think it would
people would pay for. ing early on.
have been better to have a cheaper
• The market exists (some people buy) • Don’t stop believing in your creation.
product with wider appeal than
but it’s too little or difficult to reach. Time/money invested: Up to this point,
an expensive product with narrow
• I didn’t do any market research. I just I have spent 13 years on Smart Diary
appeal.
got in love with the idea and did it. Suite and a lot of money went into
Time/money invested: I invested maybe
Later, I’ve learnt to use “lazy instantia- buying hardware, software, hosting,
a year of time and $3k into the
tion marketing” and have trashed a lot marketing, etc… All of that money
company. I did not take any huge risks
of embryo projects. :-) came from my day job, but at this
on it, so there were no big negative
Time/money invested: I think I wasted point SDS has recovered all of that
outcomes.
near $500 in development tools and back and is now making a small profit.
Current product status: The company
some freelancers. Not too much. The actual amount is hard to calculate
folded in 2007, I refocused my efforts
Current product status: I’m still selling (over the 13 year span), but we would
on my existing companies (AUsedCar.
it. I’ve thought about other products, be talking in tens of thousands of US
com and BudgetSimple.com) and both
but not really decided yet. dollars.
have been doing well enough that I
Any regrets? No, it was a lot of fun and Current product status: For a while it
quit my day job.
I learnt lot of things. In my “day job” may have seemed like SDS was not
Any regrets? I don’t regret it entirely, I
I own a small firm that sells software going to be successful, but that’s prob-
think I learned several valuable lessons
for production scheduling. I learnt a ably my fault – I stopped believing for
about working with other people,
lot about SEO and AdWords in the a little while. Now I am back, starting
small business sales, trade-shows and
DesktopCleaner project that I’m now again and this time I’ll make sure it
software development.
using with great results. doesn’t fail.
Lessons learned:
Lessons learned: Go for it, maybe you Any regrets? I do not regret doing it. I
• Pick partners wisely. Don’t try to be
win, maybe you fail, but you will grow regret allowing myself to stop working
even-steven with equity. Use restricted
and get tons of useful knowledge on on it, basically bailing out on it for a
stock to ensure everyone does their
the way. while – that is my biggest mistake.
part.
• Know what your customers expect
Contributor: Javier Rojas Goñi Lessons learned: If you want a successful
(24/7 phone support?) to determine
(http://tekblues.com/) product – believe in it and let others
if you can do this while working a day
know that you believe in it.
job.

Contributor: Dennis Volodomanov


Contributor: Phil Anderson
(http://smartdiarysuite.blogspot.com/)
(http://www.startupdetails.com/)

 9
“Develop something which you find useful,
instead of second guessing others.”

Case #6 pain points are and what extra features Case #7

Highlighter R10Clean
could be added.
Time/money invested: I would guess a
couple of months of evening/weekend
Highlighter. A utility to print neatly R10Clean. A data cleaning and manipu-
development time. Financially there
formatted, syntax highlighted source lation tool.
was little spent, except that I offered
code listings.
the option of a printed manual and
Why it was judged a commercial failure:
CD for an extra charge. One customer
Why it was judged a commercial failure: In the 18 months or so it’s been on the
took me up on the offer, so I had to
I earnt a grand total of £442.52 (about market I have sold 6. It has been £199,
get 100 manuals printed and 99 of
$700 in todays money) in just over £99 and £19 – with no effect on sales!
them went in the bin.
two years, so I guess it paid for itself if What went wrong: Not sure what I did
Current product status: I moved on to
you exclude my time. wrong? The product is maybe too
another product which has sold over
What went wrong: Since it was my first techie?
£50,000 and a third which has earnt
product I was very green about both Time/money invested: No effect finan-
even more than that. Not enough to
marketing and product development. cially as at the time I was in a strong
retire on but considering I only do this
I suggest the following would have financial position.
part-time it must work out at a great
made things better: Current product status: I still have it for
hourly rate. There’s a lot to be said for
• Get feedback from potential users sale but do not market it at all. I have
not giving up…
about the product (e.g. from the ASP other products.
Any regrets? Nope. I figure every failure
forums). Some parts of the program Any regrets? I don’t regret it as it saved
in life teaches you valuable lessons.
where probably too option-heavy and me a ton of time when I was working
Of course if I’d made a large financial
geeky. with legacy databases, as a commercial
investment I may feel differently, but
• Diversify. If people didn’t want to product it has been raved about
that’s one of the big advantages of
print fancy listings, maybe they would (once!) and received a good review
software over physical product sales.
have wanted them formatted in from the Kleper report, but has failed
HTML. totally.
Lessons learned: Just to reiterate –
• Better marketing. I’m not sure this Lessons learned: Advice to others? Just
develop something which you find
would have saved it, but all I knew in because you need it personally, don’t
useful, instead of second guessing
those days was uploading to shareware assume the rest of the world does too.
others.
sites. I never even sent a press release.
I figure it failed simply because Contributor: Steve Cholerton
Contributor: Mike Sutton
it was a product nobody wanted. (http://lonelyhacker.net/)
(http://www.rudabet.com/)
Actually, more importantly than that,,
it was a product *I* didn’t want to use,
but it developed from a larger product
I was working on, on the assumption
I could earn some money on the side
from part of the code. Since then I’ve
stuck to products which I’ve actually
wanted to use myself. There’s a lot to
be said for dogfooding, not just for
debugging, but for knowing where the

10  FEATURES
“Domarket
not get scared of an overly populated
segment.”

Case #8 applications and AV developers were Any regrets? It’s not a total failure as I

nBinder
reluctant to whitelist files created with did make some money out of it with
nBinder. You can imagine it that it was no investment, so I don’t regret start-
enough for an AV such as Kaspersky or ing it, but it could have been much
nBinder, packs multiple files into a stand
Norton to pick my files as malware for better.
alone executable with over 50 advanced
a day and customers would be affected Lessons learned: Words of advice for
output and file unpack options, condi-
and not use my product any more, others trying to make money from
tional run and commands.
especially that it took about 3 days for software development:
AVs to remove the false positive. • Study the market and the current
Why it was judged a commercial failure:
• Infrequent updates. Due to lack of trends very well.
It was the first product I began selling.
time I only updated the product once • Before deciding to take on large
It sold to 300+ customers in 4 years.
or twice a year and this affected the competition make sure you have
But for about a year the sales began
product a lot. something better (at least from one
to go down and have finally stopped
• No marketing. I decided that I didn’t point of view) than the competition
completely.
want to invest money in marketing so, (for example you might not have the
What went wrong:
except for a short AdWords campaign, same features but you have a better
• The biggest problem was that because
I invested no money in marketing. GUI and general presentation).
it was a packer intended for people
• My decision to develop 3 products • Do not get scared of an overly popu-
that wanted to pack their products
instead of concentrating on one or lated market segment. For example
(software or games) into a single pack-
two affected development time and with nBinder I picked a segment with
age (compressed and encrypted) many
quality. I have worked on 3 products very little competition but also few
have used it for creating malware by
simultaneously instead of concentrat- possible users and the results were not
binding malware files to legit files
ing on making a single good one. The so great (I didn’t have many users).
and then distributing the output so
reason I worked on 3 is because I With nCleaner I went head-to-head
it isn’t detected by antivirus software
enjoyed developing different software with lots of already established
(although it would be detected at
in different categories. I didn’t start products but also the market is very
runtime). Because of this I had lots of
this for money but for the fun of big. Although nCleaner is free it has
problems with antivirus companies
development. had the most success because there are
that flagged files create with nBinder
Time/money invested: I invested almost so many potential users (anyone with
as malware. This was of course
no money (except for hosting costs). a PC actually), so it had over 2 mil-
affecting legit users as their files would
Time invested I can’t really say exactly, lions downloads and I still receive lots
be falsely marked as malware. I used
but not too much as I only worked on of mails regarding it, even if the last
virustotal.com to see which antivirus
nBinder in short bursts like 6 hours a update was in 2007. So it is possible
detected it and contacted the antivirus
day for a week or so before releases. to have success in a market with lots
manufacturer as soon as I detected the
Current product status: Still for sale. My of competition with no investment
problem. In most cases they would
other products are: but it’s hard to reach the level of more
remove it from their definitions. But it
• nCleaner – a free system cleaner that established products.
was an uphill battle because it would
has gone quite well (over 2 million
appear again in a matter of weeks.
downloads). Contributor: Boghiu Andrei
Some small AV companies didn’t
• nMacro – an automation tool that has (http://www.nkprods.com/)
event bother to reply to my emails to
seen some limited success (bought by
fix the problem. Others were using
over 100 customers in a year or so).
heuristics to flag files create with my

  11
Case #9 would make it attractive for more Case #10

Net-Herald HabitShaper
prospective clients.
• This kind of software is not sold over
the Internet. Rather it needs very
Net-Herald – a monitoring application HabitShaper – set and track daily targets
active sales people that nurture clients
for water supply companies. It was a for your goals (weight loss, quit smoking,
over a rather long period of time.
complex client server application that jogging, writing, etc…).
• All these facts indicate that software
would receive monitoring data from
like this should not be developed by a
specialized hardware and store that Why it was judged a commercial failure:
one man show.
data inside a SQL database. The client I sold a few copies, but not enough
Time/money invested: The development
displays that data in different graphs, to make back the time I invested in it
time for the first sellable version was
provides printable reports or sends alarm and my conversion numbers and traffic
maybe about 9 months. I didn’t have a
messages via SMS if a monitored value is are below average.
job income at that time, but got fund-
not within its specified limits. What went wrong:
ing due to government support for
I developed Net-Herald as a perfect • Did not do enough pre-production
small start-up businesses. So I didn’t
fit for that specialized hardware that is research (talking to customers, etc).
drain our family’s personal finances.
provided by a local manufacturer. That • Did not do a large enough beta to
But I did of course invest a great deal
way, so I hoped, I could profit from their make up for lack of initial research.
of time and sweat.
sales leads and would find a smoother • Ignored gut-feeling that my product is
Current product status: Now, I have
way into these water supply companies. better suited to being web-based and
drawn a line and stopped active
The downside of course, was that my multi-platform (incl. mobile).
development of Net-Herald. I still do
software would only work with their • Did EVERYTHING myself (logo, web
some custom extensions for my first
hardware. design, video, software, AdWords, etc).
clients. But I no longer market the
Time/money invested: I worked on it
software. I have instead focused on my
Why it was judged a commercial failure: two years, part-time, while doing
consulting services. I also develop and
I sold a first license fairly soon after Masters/PhD in Physics. It had no
sell my cross-platform drag-and-drop
I had a sellable product, although it impact on my finances (very little
product Simidude.
took the customer nearly a year until money invested) or circumstances.
Any regrets? I didn’t succeed yet selling
they finally bought. But since then I Current product status: I am relaunching
my own software (which is still my
sold only one more license within the as a web-based product this summer.
goal) but I do not regret doing it. I
last 4 years or so. Any regrets? Not in the least! I learned
developed Net-Herald using (Java)
What went wrong: about as much from making Habit-
technologies that now give me lever-
• I didn’t do my own marketing and the Shaper as I have from my MSc thesis
age at my consulting gigs. All in all it
hardware guys weren’t really con- and PhD work.
was a heavy ride. But it was fun and I
cerned with selling my software. Lessons learned:
would do it again.
• Water management companies have a • Most important: PAPER prototypes,
Lessons learned:
terribly long sales cycle. Other vendors minimum viable product, and iterate.
• My biggest mistake was the lack of
monitoring applications usually cost • Don’t be afraid to launch early.
market analysis. I trusted the word of
tens of thousands and are geared • Launch a little bigger than you’d
the hardware manufacturer without
toward large suppliers. Whenever a expect (it’s harder to find those initial
verification.
supplier buys into such a product he customers than you think).
• I have written more about the above
is unlikely to change within the next • Don’t be afraid to change directions,
and some other failures on my blog.
decade or more. I tried to position my especially early on.
software towards small suppliers but • Doing things yourself is a great
Contributor: Torsten Uhlmann
even then most of them were already learning experience, but if you want
(http://www.agynamix.de/)
locked into another vendor’s solution. to get your product out to customers
• My software only worked with a as fast as possible, don’t be afraid to
specific hardware. That narrowed the invest money and outsource your
market down substantially. weaknesses.
• In the end the software became too
complex for one poor mortal to Contributor: Adriano Ferrari
maintain. Because the software didn’t (http://blog.habitshaper.com/)
produce any substantial income I had
to stop adding new features which

12  FEATURES
“Launch a little bigger
than you’d expect.”

Case #11 Current product status: I will still Case #12

BPL Anonymous
address support issues with this prod-
uct for registered users, but I don’t
actively sell it. I’ve open-sourced the
BPL – Batch Programming Language A time tracker.
program and it still really isn’t seeing
Interpreter.
heavy use.
Why it was judged a commercial failure:
I was more successful with other
Why it was judged a commercial failure: Because it is not my primary income. I
products. I have a few retired products
I sold about 10 copies. have about 150 customers in one year.
that saw some good bulk-purchase
What went wrong: What went wrong:
deals (command-line DUN HangUp,
• I didn’t really do enough research to • No marketing.
command-line scheduler) and I still
find out if the target market was in • No real thought into features.
sell the following (for Windows):
existence. I was hoping that network • I don’t spend any time on it.
• MailSend – Command-line SMTP
admins and support staff members In my defense, the reason I do not
mailer.
would find it easier to use than batch spend much time on it is that the
• MailGrab – Command-line POP3
files and less complicated than any market became saturated with ‘me
reader.
of the free scripting language options toos’ right after I released, which
• CMD2EXE – Packages up a batch file
available. So, I just rushed to get the was quite expected. In fact, as I was
into an EXE.
MVP (Minimum Viable Product) out looking for users, I got an email from
• ScreenKap – Command-line screen
the door. a competitor suggesting that I don’t
capture.
• I never did provide a compiler that enter the market because they are
All of the above still bring in a
would build a stand-alone EXE. I working on the same thing! I don’t
modest passive income.
think that might have met with more know what I would do differently.
Any regrets? Not at all. “Nothing
success. Maybe spend more time on it? I think
ventured,…”
• I didn’t do much as far as advertising the law of diminishing returns applies
Lessons learned: Had I not attempted to
the existence of the product. quite early in this space so I am not
bring the BPL product to life, I might
Time/money invested: I only spent a sure.
still be sitting here wondering “what
few weeks coding and documenting Time/money invested: Since inception
if?” I think it was very beneficial for
it in my spare time. Support issues (Nov 2008), I’ve spent close to 250
me to invest the time to try out this
sometimes took a whole evening, hours total. Total cash outlay was
idea.
but nothing major. It did not have something like $500.
any impact on my finances as I had Current product status: I never tried to
Contributor: Jim Lawless
invested nothing but my time. make it succeed, to be honest. It was
(http://www.mailsend-online.com/blog/)

  13
01 02 03

04 05

only a learning experience for me. Case #13 Time/money invested: At least £2000

ScreenRest
What I probably need now is to go all was spent on the project, including
in. Quite frankly, if I double the sales software licences and additional
for this product, I can quit all consult- hardware. The product and website
ScreenRest - a consumer software prod-
ing work. But I really do not think it were created over roughly 12 months
uct that reminds users to take regular
is a good idea to work on this app full by myself and my wife Lindsay, some
rest breaks while using their computer.
time as it is too simple. during spare time, then part-time and
Any regrets? Definitely not. finally full-time so it is difficult to
Why it was judged a commercial failure:
Lessons learned: determine the total number of hours.
ScreenRest failed commercially
• Do it! Working part-time and then full-time
because we built a product without
• Solve a problem people know they on ScreenRest caused a significant
having a clearly defined market.
have. impact on our finances. Although
This was compounded by it offering
• Don’t invest too much time and right from the beginning we saw
prevention, not a solution. ScreenRest
money at the beginning. this as in investment for building a
continues to regularly sell a small
• Don’t be wedded to a particular idea. business.
number of licences but not in suf-
• Don’t only listen to your custom- Current product status: Once the
ficient quantity to justify further
ers. Listen to yourself. After all, you product was complete and we started
enhancements. The conversion rates
created the idea which attracted the learning SEO it became all too
are good, but there are simply not
customers. apparent that organic search traffic
enough visitors to the website.
• Never promise a feature for a sale. I’ve for related keywords was going to be
What went wrong:
never done it but the pressure is really insufficient. Research into PPC then
• Not doing market research first.
great. My stock response is always: revealed that the price point was too
• Creating a prevention rather than
“While such a feature may be available low to support purchasing medical
solution product – people generally
in the future, I recommend that you terms. Planned features for ScreenRest
wait until they have a problem and
only use current features when decid- have been put on hold and no further
then look for a solution.
ing on your purchase.” marketing is planned. We continue to
• Creating a product with medical
• Do use Google to your advantage. support new and existing ScreenRest
associations – the SEO and PPC
customers and plan to do so for the
competition for related keywords is
Contributor: Anonymous foreseeable future. Rather than create
prohibitive for a product with a low
another software product we chose
purchase price.
to use what we had learned about

14  FEATURES
06 07

1. ScreenRest
2. ChimSoft
3. nBinder
4. BPL
5. Smart Diary Suite
6. PC Desktop Cleaner
7. R10Clean
8. HabitShaper

08

marketing, copywriting and SEO to Conclusion A big thank you to everyone who ate
create a series of websites targeting a Analysing the above (admittedly small a large slice of humble pie and submitted
range of topics (often known as niche and self-selected sample) it is clear that the above. I hope we can prevent other
sites). The most successful of these by far the commonest causes of failure budding software entrepreneurs making
sites we are expanding in value and were: the same mistakes. Even if you don’t
functionality to fill gaps not serviced • lack of market research succeed, you will learn a lot. n
by the competition. • lack of marketing
Any regrets? No. ScreenRest suc- With the benefit of 20/20 hindsight it Andy Brice is a UK-based software developer
ceeded in every way intended, other seems blindingly obvious that we should: with over twenty years of professional expe-
than commercially. Creating it was • spend a few days researching if a rience. He runs a one-man software product
a rewarding learning exercise that product is commercially viable before company at www.perfecttableplan.com, blogs
started us down a path to finding the we spend months or years creating it at www.successfulsoftware.net and provides a
one-day consulting package to other small soft-
intersection of our skills, experience • put considerable effort into letting
ware companies interested in improving their
and market opportunities. people know about the products we
marketing and usability.
Lessons learned: create
• Start with market research – creating a Yet, by my count, a whopping 6 out
high-quality product you believe in is of 13 of us admitted to failing to do each
not enough on its own. of these adequately. Probably we were
• Make sure you can identify a specific too busy obsessing over the features and
target market, that you can reach that technical issues so beloved of developers,
market and that it is large enough to which actually contributed to far fewer
support your financial goals. failures.
It is also noticeable that, despite the
Contributor: Derek Pollard failure of these products, there are few
(http://www.kimotaprime.com/) regrets. Important lessons were learned
and no-one lost their house. Many of
us have gone on to develop successful
products and the others will be in a
much stronger position if they do decide
to try again.

Reprinted with permission of the original author. First appeared in http://hn.my/softwarelesson/.

  15
Illustration by Jaime G. Wong (http://retrazos.pe/)

16  FEATURES
How To Become A Millionaire
In Three Years
By Jason L. Baptiste

“ I move forward the only direction


Cant be scared to fail in search of perfection ”
— Jay-Z, On To The Next One

I ’m going to go ahead and replace 3 years with a “short time frame”.


Some things to focus on:

Market opportunity
A million dollars is not a lot
Leverage skills you know
You can go into new fields
the obscure and unsexy. Don’t
make that mistake. If your
Charge for something
Building a consumer property
in the grand scheme of things, such as say Finance, but goal has primarily monetary dependent upon advertis-
but it certainly is a lot if the make sure you’re leveraging motivations, look at the ing has easily made many
market opportunity is not something you already know unsexy. One example would millionaires, but it isn’t the
large enough. Even if you put such as technology and/or be email newsletters, which surest path. It takes a lot of
Bill Gates and Steve Jobs as product. Someone wanted I’ve profiled before. time and scale, which due to
founders in a new venture to start a documentary with cash-flow issues will require
with a total market size of 10 me. I said that would be Surround yourself with smart large outside investment
million, there is no way they fun, but it would be my first people probably before you are a mil-
could become too wealthy documentary regardless of Smart people that are success- lionaire. Build something that
without completely changing what happened. There was ful usually got there by doing you can charge for. That’s
the business (i.e. failing). a glass ceiling due to that. If the same and have an innate how business has worked for
I do something leveraging a desire to help the people thousands of years prior to
Inequality of information skill I know, I’m already ahead surrounding them achieve the the 1990s. Make something,
Find a place where you know of the game. same success. It’s the ecosys- charge for it, repeat it. DHH
something that many under- tem that’s currently happen- explained this really well at
value. Having this inequality Look in obscure places ing with the PayPal mafia and Startup School 08.
of information can give you We’re often fascinated with can be traced all the way back
your first piece of leverage. the shiny things in the inter- to Fairchild Semiconductor.
net industry. Many overlook

  17
Information products are Go with your gut and do not If it’s a mass market “trend” Get out and be social
valuable care about fameballing that’s all over the news, it’s Even if you’re an introvert,
E-Books, screencasts, and Go with what your gut says, too late being around people will give
anything that can teach others regardless of how it might This means the barriers to you energy. I’m at my worst
to be good at something is look to the rest of the world. entry are usually too high at when I’m isolated from people
a very lucrative business. Too often we (I) get lost in this point to have the greatest and at my best when I’ve at
Look at guys like PeepCode... caring about what people possible chance of success. least spent some time with
they’re killing it. There are think. It usually leads to a Sure you could still make a close friends (usually who I
also things like Parrot Secrets wrong decision. Don’t worry lot of money in something don’t know from business.)
that make 400k a year. Bonus about becoming internet like the app store or the
points if the information famous or appearing on teh Facebook platform, but the Make waves, don’t ride them
helps a person make money maj0r blogz. Fame is fleet- chances are significantly There was a famous talk
(directly or indirectly) or ing in the traditional sense. less than they were in the Jawed Karim gave from
improves their self image. Become famous with your summer of 08 or spring of YouTube. He described the
FYI, this doesn’t mean sell customers. They’re the ones 2007. You can always revisit factors that made YouTube
snake oil ebooks. That may that truly matter. What they past trends though. Peter take off in terms of secondary/
get you a somewhere in the 5 think matters and they will Cooper and I clarified some enabling technologies. I think
figures, but word will spread ultimately put their money of the semantics about what they included (1- broadband
that your shit smells. where their mouth is. is a trend over here. in the home 2- emergence of
flash, so no codecs required

“Ifdollar
Your primary metric 3- proliferation of digital cam-
shouldn’t be dollars eras 4- cheap hosting 5- one
If you are going after a big
enough market and charging you do focus on a click upload 6- ability to share
embed). Find those small
a reasonable amount, you can
hit a million dollars. Focus on amount, focus pieces and put them together
to make the wave. That’s what

on the first $10,000.”


growth, customer acquisition YouTube did imho. The other
costs, lifetime value of the guys really just rode the wave
customer, and churn. they created (which is okay).

Get as many distribution If you do focus on a dollar Say NO way more than you
channels as possible Be an unrelenting machine amount, focus on the first say YES
There is some weird sense Brick walls are there to $10,000 I bet almost every web
that if you build something show you how bad you want This usually means you’ve entrepreneur has encountered
they will just come. That a something. Commit to your found some repeatable this: You demo your product/
few “like” + retweet but- goals and do not waver from process/minimal traction, explain what you’re doing and
tons and emails to editor@ them a one bit regardless of i.e. if you’re selling a $100 someone suggests that you do
techcrunch.com will make what else is there. I took this product, you’ve already “X feature/idea”. X is a really
your traffic explode + grow approach to losing weight and encountered 100 people who good idea and maybe even
consistently. It fucking won’t. fitness. I have not missed a have paid you. From here you fits in with what you’re doing,
Get as many distribution single 5k run in over a year. can scale up. It’s also a lot but it would take you SO
channels as possible. Each (I profiled this in my article easier to take in when you’re FAR off the path you’re on. If
one by itself may not be large, “Hacking Calories” if you’re looking at numbers. Making you implemented X it would
but if you have many it starts interested). It did not matter 1 million seems hard, but take a ton of time and morph
to add up. It also diversifies if I had not slept for two days, making $10,000 doesn’t seem what you’re doing. It’s also
your risk. If you’re a 100% traveling across the country, so hard, right? really really hard to say no
SEO play, you’re playing a or whatever else. If your goal when it comes from someone
dangerous dangerous game. is to become a millionaire, Be a master of information well respected like a VC or
You’re fully dependent you need to be an unrelenting Many think it might be waste- famous entrepreneur. I mean
upon someone else’s rules. If machine that does not let ful that I spent so much time how the fuck could they be
Google bans you, you will be emotions make you give up/ on newsyc or read so many wrong? Hell, they might even
done. You could easily replace stop. You either get it done tech information sites. It’s not, write me a check if I do what
the SEO example with: App with 100% commitment or it’s what gives me an edge. I they say!!!!! Don’t fall for that
store, Facebook, etc. you don’t. Be a machine. feel engulfed. trap. Instead write the feed-
back down somewhere as one
single data point to consider

18  FEATURES
amongst others. If that same Look for the accessory great deal of money. Giving Make sure you’re robbing a
piece of feedback keeps ecosystem you a 20-30% cut is worth it, bank
coming up AND it fits within iPod/iPhone/iPad case manu- when the opposite is making When Willie Sutton was asked
the guidelines of your vision, facturers are making a fortune. no money at all. why he robbed banks, he
then you should consider it Armormount is also making said because that’s where the
more seriously. Weight sugges- a killing by making flat panel Productize a service money is (Thanks to edw519
tions from paying customers wall mounts. WooThemes If you can make what might for this quote). Make sure
a bit more, since their vote is makes millions of dollars a normally be considered a ser- whatever you’re going after
weighted by dollars. year (and growing) selling vice into a scaleable, repeat- is where the money actually
Wordpress themes. There are able, and efficient process that is, i.e. a customer that will
Be so good they can’t ignore tons of other areas here, but makes it seem like a product pay you. Consumer markets
you these are the ones that come you can make a good amount are tough, especially with
I first heard this quote from to mind first. If there’s a huge of money. In some ways, I feel web based products. People
Marc Andreessen, but he stole new product/shift, there’s this is what Michael Dell did expect everything to be free.
it from Steve Martin. Just be usually money to be made in with DELL in the early days. Businesses are usually your
so good with what you do that the accessory ecosystem. Putting together a computer best bet.
you can’t be ignored. You can is essentially a service, but he
surely get away with a boring put together a streamlined Don’t be emotional
product with no soul, but method of doing things that Emotions can let you make
being so good you can’t ignore it really turned it into a stupid decisions. It can make

“Ifeveryone
is much more powerful. you not walk away because
you’re attached to some-
Always keep your door/inbox
open this was easy then thing. Most importantly it
will lead to indecision and a
You never know who is going
to walk through your door + would be a loss of confidence. Put your
emotions into your product

millionaire.”
contact you. Serendipity is a or save them for your lover,
beautiful thing. At one point family, friends,etc.
Bill Gates was just a random
college kid calling an Albu- Don’t leave things up to
querque computer company. Stick with it product. On a much smaller chance
Don’t give up too fast. Being scale, PSD2XHTML services People feel that things will
Give yourself every broke and not making any did this. It’s a service, but the just work out due to carpe
opportunity you can money sucks + can often end result + what you pay for diem. They usually don’t.
I use this as a reason why make you think nothing will really feels like a product. People can be unreliable, deals
starting a company in silicon ever work. Don’t quit when can fall through, and shit will
valley when it comes to you’re down. If this was easy Look for something that is always happen. Prepare for
tech is a good idea. You can then everyone would be a required or subsidized by law multiple scenarios and contin-
succeed anywhere in the millionaire and being a mil- Motorists are required to have gencies. You can mitigate this
world, but you certainly have lionaire wouldn’t be anything insurance, public companies by working with smart AND
a better chance in the valley. special. Certainly learn from have to go through sarbox reliable people.
You should give yourself your mistakes + pivot, but laws, doctors get tens of
every opportunity possible, don’t quit just because it thousands of dollars for
especially as an entrepreneur didn’t work right away. EHR systems, etc. Look for
where every advantage counts. something that is required
Make the illiquid, liquid by law and capitalize on
Give yourself credit I realized this after talking that. Usually things that are
This is the thing I do the least to a friend who helps trade required and/or subsidized by
of and I’m trying to work on illiquid real estate securities. law are mind numbing with
it. What may seem simple A bank may have hundreds of complexities. Find a way to
+ not that revolutionary to millions of assets, but they’re simplify that process.
anyone ahead of the curve actually worth substantially
can usually be pure wizardry less if they cannot be moved.
to the general public, whom If you can help people make
is often your customer. Give something that is illiquid,
yourself more credit. liquid they will pay you a

  19
“Reward yourself a
little bit, but live as
frugally as possible.”

Raise revenue, not funding Look for those who are Companies spend just as he finds out what specifically
Everyone is always so damn comfortable much or more on services as led to their success.
fixated on getting funded Who is comfortable in a they do on software
because it’s the cool thing to certain industry? Go in Paying for the ERP, CRM, or Last, but not least: Learn how
do. Focus on getting people and knock them off their custom built system is just to filter
to pay you at first and then hammock so they spill their the first step. Then there’s I just wrote upwards of 2,200
scale things outwards with mojitos on themselves. the maintenance, training, and words. Some of the points
funding IF and WHEN you This can also be considered service contracts. are even contradictory. Start
need it. If your goal is to stagnation. Industries often adding in other sources of
make a million dollars in mature and people get com- Keep the momentum going information and you will feel
three years, funding probably fortable keeping the status I’ve had projects where like you’re being pulled in a
isn’t the way to go. VCs quo. Stagnation is the mid- things were moving a million five million directions. You
won’t let you take a salary life crisis for a former trend. miles an hour, then BOOM, will then become indecisive.
of ~300k per year. Selling This is usually a good point to they just lost a lot of momen- Take in information and then
a company in < 3 years is a come in with something. tum. That is the worst filter the good bits while
crapshoot. The lifespan of an possible thing you can have synthesizing them to be a part
investment is usually about 7 Don’t skimp on the important happen. Keep moving the of your overall plan. What
years from what I’ve read. things ball everyday. works for person A doesn’t
When it comes to things that always work for person B. n
Don’t get comfortable need to be reliable such as Listen (or read the transcrip-
You will probably get infrastructure, delivery, or tions of) to every Mixergy Jason L. Baptiste, is currently the
comfortable somewhere even your own personal tech interview you can co-founder of Cloudomatic, which
around 200k, maybe less or equipment - don’t skimp Most of my audience will provides an easy to integrate affili-
more, but it will certainly be out. These are the tools that probably know about Mixergy, ate engine specifically made for
before 1 million dollars. If ensure reliability and your but I can’t let a single reader SaaS and web app developers.
He is also on the board of the MIT
you get comfortable you start product being delivered. leave without making sure
Enterprise Forum of South Florida.
getting off balance and having You can skimp on the office they know it exists. It is by far
You can learn more about Jason at
the hunger to move forward. space, the desks, coach airfare, the most practical resource on jasonlbaptiste.com.
Reward yourself a little bit, budget motel in mountain the Internet if your goal is to
but live as frugally as possible. view, etc. do well. Andrew has inter-
I have friends who have made viewed entrepreneurs from
some okay money, but blow all walks of life and levels of
it all away on stupid shit success. Most of them had
because they got comfortable. real business models and boot-
strapped. Most importantly,

Reprinted with permission of the original author. First appeared in http://hn.my/millionaire/.

20  FEATURES
Why I Quit A Six Figure Job
By Xavier Shay

I had the best job in the world. My


immediate team of ten people were
all world class, and everyday I was
able to work on hard and interesting
challenges with them. Hours were flex-
find ways to fill that space. A job is a TV
that takes up even more time.
A job allows you to work on large
challenges. The type and scale of
problems you are able to work on in IT
A job means you have to show up.
Forty hours of every week were sold to
someone else. That’s a huge opportunity
cost. I couldn’t put everything on hold
for a few days to chase a new idea. I
ible—many of us worked seven to four at a big company are totally different to couldn’t use the burst of energy I get
(by choice!)—and there was virtually those you have the opportunity to attack often when I had a great idea late at
never any overtime. It wasn’t unheard of flying solo. It was a fantastic experience night, because I had to be up early the
to have our end of week review down at working on these projects, but I’m no next day.
the pub. I was paid a six figure salary. longer feeling inspired by them. A job is working on someone else’s
After six months, I quit. A job allows you to work with smart dream. This isn’t necessarily bad —
I need to be working for a reason. people. This is actually the primary helping people achieve their dreams is
Salaried work isn’t necessarily a bad reason I accepted the job. The opportu- fantastic — but those dreams didn’t align
thing, but the benefits it provided me nity to work in such a high calibre team with my own.
weren’t benefits I actually wanted. in such an environment was one that A job is selling your time. When
doesn’t come up often outside of salaried I’m working by the hour, there is an
The Up positions. There are many other smart economic incentive to take longer to
A job is easy money. This is the obvious people I will get to work with outside of complete a task, but a professional one
one. The easiest, most comfortable way a job, but I will have to work harder to to be efficient. I don’t want competing
to get money is to work for someone else. make that happen. motivations. Why are the hours spent on
I currently have enough assets to sustain They’re pretty fantastic benefits, and a task even relevant? I want to sell value
me for about two years, and there’s noth- I don’t regret the last six months in the rather than my time.
ing that I want to buy, so I don’t need slightest. None of them are particularly So what am I going to do? For a large
any more money. relevant to me any more though, and part, I don’t know, and that’s kind of the
A job is low risk. Related to the last when matched with the downsides the point. I have a few projects I’m working
point but worth stating separately. You balance is no longer positive. on — A tour of the US and this blog
get a paycheck every month, whether being two major ones — but now the
or not the company makes money. This The Down biggest benefit is that I’m free to say yes.
risk is shouldered by the owners of the A job is working on someone else’s Yes to projects, yes to schemes, yes to
company, and that’s why they stand to schedule. I was expected to be produc- travel, yes to “let’s stay up on a week-
gain (or lose) a lot more. I can provide tive for eight hours in the middle of night and watch B-grade sci-fi.” I don’t
my own safety net at the moment, I the day, five out of seven days a week. want the best job in the world, I want
don’t need someone else to do it for me. This doesn’t match my natural rhythm. the best life. n
A job fills the time. This isn’t relevant Some days I can work for fourteen
to me, but I’ve heard a few times “Won’t hours, others I just need a day off. If I Since quiting his job, Xavier Shay has taken up
you get bored without a job?” This is so work in the mornings only, I don’t need beat boxing, performed as a life-sized giraffe,
far outside my conceptual space I didn’t a weekend. I’m really keen to explore become a dance teacher, organized a tech train-
even think of it. If you are worried about different modes of working to find what ing tour through the US, and started a blog with
being bored without a job, first try cut- is most productive for me. his brother Jared about personal development
and being more awesome at www.two-shay.com.
ting TV out of your life and see how you

Reprinted with permission of the original author. First appeared in http://hn.my/sixfigure/.

  21
STARTUPS

How I
Monetized
My Passion
By Jason Schuller

J ust over 2 years ago, I was


sitting in what seemed like
an ever-shrinking cubicle at a
major Seattle based company
making updates to websites for upper
management. I suppose I made a decent
(average) living, and my job was secure,
but at the same time I felt that I was
ready for a major change in my life.
Needless to say, I thought about quitting
my job more than once per day (sound
familiar?), but to what end?
There were countless times during my
years at that company when I tried to
make a difference by presenting alterna-
tive ways to implement and manage their
all of these ideas were either dismissed or
put off on the basis that these “alterna-
tives” were unknown, untested and
unsupported open source technologies
such as Joomla, WordPress, etc. I specifi-
cally remember one manager telling me
that my ideas sounded amazing, but a
little “wild and crazy” for the company.
under-challenged, under-utilized and internal network of websites. In the end,

22  STARTUPS
“Idetermined
had a passion for web design and I was
to turn that passion into a career.”

Making the Decision to Change the time as I played around with the Trial and Error
It was pretty much at that point that platform. I spent hours on end every During the first two months of 2008, I
I realized if I didn’t at least try and day working with WordPress, reverse- was able to build enough of a name for
do something different, I would wake engineering themes and tweaking code. myself where I could sustain my income
up one day (years later) in that same WPelements.com gained some traction by doing freelance WordPress design
ever-shrinking cubicle working the same right after I released my first free theme and development work. However, it was
dead end job. I was ready to step up to called “Massive News” which was down- about that same time that I realized that
the plate. loaded a few hundred times within the I still was not quite happy with what I
As much as I wanted to, I knew that I first week. Right after Massive News, I was doing for a living. Basically, it was
couldn’t just walk into work one day and released my first WordPress plugin called the exact same thing I was doing at my
quit on the spot. I had responsibilities – a the “Featured Content Gallery” which previous job, just with clients instead of
wife, a house and bills to pay. With that in was also an instant success. I remember managers. Back to square one. Something
mind, I researched and then approached thinking that this was my ticket into needed to change once again just two
my manager about taking a 2 month something new, a step toward that “big months into my entrepreneurial career.
“sabbatical”…a trial run if you will. change” in my life that I was searching The WordPress community was grow-
Basically a leave without pay, but at least for. Soon after I released Massive News, ing, and I took note of a trend which was
I would still have a job if I needed one at the emails started rolling in from people on the rise… “Commercial WordPress
the end of those two months. Manage- looking for custom WordPress develop- Themes.” Brian Gardner pioneered (or
ment signed off on it (no questions asked) ment services which is how I started my at least was one of the first to pioneer)
and off I went into the unknown. (short) freelance career. the idea of selling commercial WordPress
By the time my two month sabbatical themes in August of 2007 with a theme
Getting Your Feet Wet was up, I was confident enough to walk called “Revolution” (now StudioPress.
My plan was simple… I had a passion back into work and put in my two weeks com). Shortly after Brian, a few others
for web design and I was determined to notice. Actually, what I said was: “I am popped up selling their own themes as
turn that passion into a career. The first prepared to give you two weeks, but if well including Adii with his “Premium
step was to get my name out there, and you can let me go in a week that would News Theme” (now WooThemes.com).
I figured the best way to do that was to be great because I’m really really busy.” To say the least, the idea of creating a
start a blog and begin writing about web theme and selling it as a commercial
design, development and other related product perked my interests. I remember
topics. Please keep in mind that my skills emailing both Brian and Adii about their
as a designer/developer were all self businesses looking for tips on how to
taught to that point (still are actually), so get started. Surprisingly, both of them
I really was not all that confident about already knew about me and what I was
doing this – but I had to try. doing with WPelements.com, and gave
WordPress seemed to be a trendy me the inspiration to try selling some
topic at the time, so in January of 2008 I themes of my own. Let me say that
launched a site called WPelements.com Brian and Adii are some real stand-up
and started blogging about WordPress. guys who I am happy to consider my
Really, all I was doing was writing about friends even though we are each others
things that I myself was learning at competition.

  23
“ Money is not a bad thing,
but it really should not be
your means to happiness.”
Then Success on my hands. Not many theme develop- for recognition, or to brag about what
I had created a site called TrailerFlick. ers (if any) were creating video-centric I consider my own personal success.
com in December of 2007 which never WordPress themes at that particular time, Honestly, I’m sure most of you don’t
became popular, but there was always and I think that releasing a commercial even know who I am or what I do, nor
interest in the site design by random solution for video was the key to growing do you probably care. The whole point
users who just happened upon it one way my business as fast as I did. of writing this article was to share with
or another. I created TrailerFlick.com to At that time, I was still doing freelance you that life is in fact, what you make
provide an alternative method of view- work and blogging about WordPress on of it. If you want to change, there really
ing movie trailers, and the design was WPelements.com, but I finally decided is nothing stopping you from doing so.
simple… just a grid of movie posters that that neither blogging or freelance work That is not to say that change is at all
when clicked would display the trailer in were really what I wanted to do which is easy, or something that will happen
a pop-up window. This was actually the why I designed a simple theme store and overnight. It took me more than 10 years
first live website I had ever built entirely moved all my commercial themes over of working at a company, developing
on WordPress. In February of 2008 I had to Press75.com separating my theme skills, experimenting with different ideas
a client that found TrailerFlick.com and business from my freelance business and and just growing up before I found the
wanted a WordPress theme based on the blog. By August of 2008, I had doubled confidence to really go after my passion.
design for his own movie production my income on Press75.com with only 4 Also, it is my strong belief that if
studio. I spent a week tailoring the theme themes at $50 a piece. This allowed me making money is your only goal in life,
for this client who in the end never paid to completely close the doors on free- you will probably spend the rest of your
up. I decided that this would be a good lance work to focus 100% of my efforts life chasing that goal and never end up
candidate for my first commercial theme, on commercial WordPress themes. where you want to be. I realize that the
so I cleaned up the code, called it “Video Nearly one year and about a dozen title of this article is “How I Monetized
Flick” and threw it on WPelements.com themes later, Press75.com continues to My Passion”, but what I really mean by
for just $5.00 per download. I just want grow and I just launched a second site that is money can sometimes become
to take a second to thank that client for called ThemeGarden.com in hopes to a by-product of chasing your passions.
never paying his tab. expand beyond my own personal brand. Money is not a bad thing, but it really
The interest in Video Flick blew me Needless to say, I could not be happier should not be your means to happiness.
away, and I immediately knew that had with what I do for a living. I get to design When I left my day job two years ago,
something on my hands that I could and create WordPress themes that are money was never my end game, and I
build into a real business. One theme used by thousands of people around the hope it’s not yours when/if you decide
at $5.00 per download was definitely world, and the best part is that the only to make a major change in your life.
not enough to make a living, but it was one telling me what to do and how to do Let your interests and your passions be
good extra cash to throw on top of the it – is me. the driving force behind change in your
freelance work I had at the time. As the life – I did. n
months rolled by, I released two more Let Your Passion Drive You
video-centric WordPress themes (TV Ele- I really don’t consider myself any sort Jason Schuller is a digital creative professional
ments followed by Video Elements) and of talent when it comes to writing, but living and working in Seattle Washington. He
started charging $25 a piece. By June of if you have stuck with this story to primarily designs and builds themes and plugins
2008 I knew there would be no looking this point, a few more minutes aren’t for the popular WordPress publishing platform
back and that I had a substantial business going to kill you. I didn’t write this which can be found on Press75.com.

Reprinted with permission of the original author. First appeared in http://hn.my/passion/.


Photo: Adrià Ariste Santacreu, http://www.flickr.com/photos/manicomi/2537105338/.
Licensed under Creative Commons Attribution 2.0 Generic licence. Full terms available at http://creativecommons.org/licenses/by/2.0/deed.en.

24  STARTUPS
What Kind Of Girl
Do You Think I Am?
By Nikos Moraitakis

D on’t try this at home:

Guy: “If I gave you a million dollars, would you sleep with me?” Consequentialist reasoning suggests that morality is context-
Girl: “A million dollars is a lot of money, and you don’t look sensitive, in the sense that the results of an action have a real effect
that bad, so I guess I would consider it” on our judgment of its morality. Torture is morally reprehensible,
Guy: “Ok, since I don’t have a million dollars, would you sleep but what if torturing one man can give you information to save the
with me for $100?” lives of thousands? In other words, the potential outcomes of an
Girl: (outraged) “What kind of girl do you think I am?” action, i.e. what’s at stake, need to be considered in moral judgments.
Guy: “We’ve already established the answer to that question. The girl of our story is a consequentialist kind of girl. (if it
Now we’re just negotiating the price” bothers you that the difference between the options is just a bit
more money, consider a case where instead of a million dollars
Without the million-dollar question, moral choice is easy for she was offered the formula for a drug that will cure cancer for
this girl. Yes, she won’t sleep with someone for $100 and that all humanity – and consider whether she should feel equally or
doesn’t take a lot of thinking. She’s just not that kind of girl. The less “dirty” for sleeping with the guy to get it as with the $100)
million-dollar question is interesting because it forces her to really Categorical reasoning on the other hand suggests that the moral-
decide what kind of girl she is. ity of action is independent of results. The morality of exchanging
If a principle is subject to revision past a price point, then this sex for money is the same regardless of the amount. We can debate
is no longer a question of principle, but a question of finding the if it’s good or bad, moral or immoral, but we would not be prepared
price point. Surely not $100, but possibly less that a million. to revise our moral judgment based on what’s at stake. In other
How many business decisions have you taken without the words the girl should happily take the $100 assuming that this is
privilege of considering the million-dollar option, and its moral a fair value for the time she will spend on the activity.
consequences? If you’re like most people, it’s happened to you The philosophical debate is in no way decided (it wouldn’t be
several times and you weren’t even aware of it. a philosophical debate otherwise) and that is really why making
I think of this little anecdote every time a cost/benefit question decisions generally sucks. In each case, we have to first decide
comes up at work. It’s not uncommon in business to be faced with whether we are a consequentialist or a categorical girl, whether
the opportunity to do something that is against your standards and we will always be that kind of girl, or whether we will take some
professional practices, but would bring in some extra revenue. In decisions categorically (and set up “commandments”, “golden rules”
such circumstances, it’s typical for the people involved to debate and “honour codes” to defend from consequentialist creep) while
whether it’s “worth” doing X or not. And, inevitably, the “worthi- allow for consequentialist thinking in others (and use methods
ness” of the action is measured in dollars. Sure, no big company will such as “cost-benefit analysis” and “risk valuation” to determine
put its reputation or professional standards at stake for $10,000 our moral inflection point).
(if they’re at all serious about their business) but for an amount I find it helpful, before I consider a dilemma, to at least debate
that has an actual impact on its bottom line, morality gets fuzzier. whether I’m in that girl’s situation, and what kind of girl I’m going
So here’s a handy tool that may, in some cases, bring more to be for this particular question. Imagining different stakes for the
clarity to your decision-making: available options is perhaps one of the easiest ways to abstract any
1. Would it be easier/harder to decide if the amounts at stake business decision to a level where the consequentialist/categorical
were dramatically lower/higher? dichotomy is obvious. n
2. If so, then what kind of girl are you?
Legislators and moral philosophers have invented fancy terms for Nikos Moraitakis is vice president of business development at Upstream.
the two possible answers to the “what kind of girl are you”question. Follow him on Twitter at @moraitakis.
Reprinted with permission of the original author. First appeared in http://hn.my/girl/.

  25
How I Almost Ignored
Our Single Best Source
For Customer Feedback
By Hillel Cooperman

B ack in mid-2009 when we were building A


Story Before Bed a children’s books online
service for its eventual launch in the fall of
2009 we had a talk about how to support our eventual
customers. I remember reading a blog post (which I
was very nice. She was dedicated to our product. And
I could chat with her over IM, even when she was on
call (to which I could listen in on). Her attitude was
just wonderful, but there was no way she could know
the product the way I did. She also couldn’t know how
can’t find now) about how putting an 800 number much we cared about making our customers happy.
on your website made people much more willing to One day I discussed with her when to give a refund.
give you their credit card numbers. We decided that I told her we had a no questions asked 7 day refund
having free 1-800 tech support for our site was going policy. She asked what to do if the person wanted a
to be a differentiator for us. It’s not often you find a refund on day 8? I told her to go ahead and give it
consumer website these days that provides that level anyway. There were a lot of situations like this that
of support. Typically if there even is a phone number had to be spelled out. To the letter.
it’s buried under layers and layers of FAQs, knowledge We launched, and she handled calls. She definitely
bases, and e-mail forms. It often seems like companies did her best, and it was great to know that our custom-
will do anything possible to avoid actually speaking ers had someone they could rely on. And while we
to a customer. I’ve experienced this many times as a didn’t have a huge number of customers, we woefully
customer and I know how it makes me feel. Like crap. overestimated how many support calls they would gen-
And yet, as a business owner, I read all this reluctance erate. It’s not that our product was perfect. It definitely
as an indicator of how costly and time consuming it wasn’t. It’s just that while the 800 number may have
is to provide person-to-person customer support. I made people feel comfortable using the site, for the
was nervous. most part, they didn’t use it. My rough calculations
At first I suggested that the 1-800 number would show about one support call out of every 100 registered
ring my cell phone. This wasn’t some altruistic desire users, if that. After a couple of months of paying an
to connect with customers, but me being cheap. My incredible amount of money to handle the handful of
partner Walter laughed at me. He pointed out this calls we decided to bail and go back to the original plan.
would not be a good use of my time as we would no We set up a new 800 number that rings straight to my
doubt be inundated by calls, and I had lots of other stuff cell phone. Caller ID lets me distinguish between my
to do. I was a little embarrassed, but he’s annoyingly mom calling and a customer needing help. And now,
right almost all of the time. I spent months looking for every few days, I get a phone call from a customer who
firms to which I could outsource our phone support. has a question about our service.
I finally found one in the Philippines. Our operator

26  STARTUPS
“When customers call, their
questions and feedback are
essentially a free focus group.”

When I used to work at a large software company, may be obvious to many of you reading this post, but
I couldn’t imagine many jobs worse than being a tech even if I understood them intellectually, I didn’t *really*
support person. Perhaps it was my own interaction with understand them, at an emotional level. It’s still early,
support folks stuck supporting products they almost but it looks like answering calls may not only not be
never had control over, and often didn’t have enough a drag on the bottom line, but a boost.
expertise in. Or maybe it was all the effort that compa- And while the frequency of calls is on the rise as
nies make to avoid being on the phone with customers our site gets more popular, for now, handling the calls
in the context of support that made me assume it’s isn’t just ‘not a problem’ it’s something I look for-
something to be avoided. It turns out that answering ward to. It makes me understand why Craig’s (a.k.a.
our support calls has been an incredibly productive Craigslist Craig) main job is customer support. From
experience as well as potentially a profit center. When my perspective, there’s no better way to understand
customers call, not only am I in a great position to help what my customers are thinking. Analytics can tell me
them as I understand the product inside and out, but what they’re doing, but not why. When the calls are
their questions and feedback are essentially a free focus frequent enough to impact my other responsibilities, I
group. We always have a list of improvements we need honestly wonder which of my tasks I’ll delegate. More
to make to the product, but sometimes prioritizing can and more I think that someone else might be flying
be a crapshoot. Vocal customers tell me quickly which to New York to sign up new publishers, and I’ll stay
work items need to move to the top of the list. I can focused on answering calls and e-mails.
only imagine how many customers of ours experience A Story Before Bed. This is Hillel. How may I help
the same frustration as these callers but don’t bother you? :) n
picking up the phone. I think of our support callers as
unelected representatives of our customer population. Hillel Cooperman is one of the founders of Jackson Fish Market,
Each of them represents a non-trivial number of users a bootstrap startup from Seattle. They have shipped sev-
who (understandably) didn’t have the time to call us. eral consumer experiences for the web and mobile devices
Not only do I get great information that I can empa- including A Story Before Bed (www.astorybeforebed.com) that
thize with from these customers, but recently I’ve lets parents and grandparents record a video of themselves
reading a digitized children’s book, and lets kids play it back
started finding out how effective our marketing is – “Do
in the web browser or on the iPad or iPhone synchronized to
you mind me asking where you heard about A Story
the pages of the book.
Before Bed?” and turning each support call into a gentle
sales call – “Did you know about our subscription offer?
It could save you a lot of money.” I realize these things

Reprinted with permission of the original author. First appeared in http://hn.my/feedbacksource/.

  27
What Are The Biggest
Legal Mistakes That
Startups Make?
By Scott Edward Walker

M y buddy and I are coding up a new


site and we will be ready to launch
the beta in about a month. We have
a couple of angel investors who are interested, and
we don’t want to screw anything up. What are the

Place of Incorporation. Some entrepreneurs
make the mistake of incorporating the company
in the wrong state. You should incorporate in Delaware
– that’s what investors generally require. You should
then qualify the company to do business in California
biggest mistakes that you’ve seen guys like us make? and/or any other State in which it is “doing business.”
Here are ten quick ones (in no particular order): I discuss this issue in paragraph 1 of my blog post
regarding formation issues (part 1).
IP Ownership. Some entrepreneurs make the
➊ mistake of creating IP for their new venture Vesting Restrictions. Some startups make the
while they are still working for someone else. They ➍ mistake of issuing stock to co-founders without
then quit and launch their startup, not realizing that imposing vesting restrictions. Then, one of the found-
the IP is actually owned by their prior employer. This ers ends-up leaving in a few months and keeps all
is a tricky issue, and you should carefully review all of his or her equity. You should make sure you and
employment-related agreements to determine if there your co-founder execute a restricted stock purchase
are any provisions that may inhibit your new venture, agreement with reasonable vesting schedules (typically
including IP ownership. I discuss this issue in detail in four years) upon the issuance of the company’s stock.
paragraphs 2 and 4 of my blog post regarding formation I discuss this issue in detail in my blog post “Founder
issues (part 2). Vesting: Five Tips for Entrepreneurs.”

Choice of Entity. Some entrepreneurs make the Securities Law Issues. Some startups make
➋ mistake of forming the wrong entity. Investors ➎ the mistake of not complying with applicable
generally invest only in corporations – not LLC’s or securities laws; for example, they issues shares to
partnerships. You should thus form a corporation – and “friends and family” who are not “accredited investors”
consult with an accountant as to whether you should without proper disclosure documents; or they retain
make an S corporation election (and then convert to a consultant who is not a registered “broker-dealer” to
a C corporation down the road). I discuss the issue sell company stock for a commission. You should be
of choice of entity in detail in my blog post “Choice very careful when issuing any kind of securities; non-
of Entity for Entrepreneurs.” compliance could cause severe consequences, including

28  STARTUPS
a right of rescission for the securityholders (i.e., the would be equal to the purchase price if such stock was
right to get their money back, plus interest), injunctive purchased), with any subsequent appreciation of the
relief, fines and penalties, and possible criminal prosecu- stock being taxed at capital gains tax rates upon its sale.
tion. I discuss these issues in detail in paragraphs 2 and Such an election is made by filing the appropriate IRS
4, respectively, of my blog post “Five Common Mistakes form within 30 days after the grant/purchase date (no
Entrepreneurs Make in Raising Capital.” exceptions applicable). I discuss this issue in detail
in paragraph 3 of my blog post “Founder Vesting: Five
Splitting Equity. Some startups make the Tips for Entrepreneurs.”
➏ mistake of splitting equity equally between or
among the co-founders. The splitting of equity is a Due Diligence. Some startups make the mistake
significant business decision which must be negotiated ➒ of not diligencing the guys or gals on the other
between or among the co-founders based upon their side of the table. Indeed, whether a startup is doing
respective contributions to date and their expectations a financing, a partnering agreement or some other
going forward. Simply dividing the shares equally transaction, it must investigate the other party or par-
may sound fair on its face, but it’s usually not the ties involved. This means determining the reputation
correct decision. I discuss this issue in detail (and the of both the company/firm (if it’s not a marquee name)
various factors to consider) in my blog post “Ask the and the particular individuals with whom it is dealing.
Attorney – Splitting Equity.” Who are these guys? Are they good guys or are they
jerks? Can they be trusted? When they say they
Employment Issues. Some startups make the are going to do something, do they do it? Do they
➐ mistake of not addressing employment-related add value? Remember, in certain deals (such as an
issues with respect to new hires. For example, if an angel or venture capital financing), the startup will, in
employee is hired by a startup, he or she generally effect, be married to the firm and the individuals for
should be required to execute two documents: (i) an a number of years. I discuss this issue in paragraph 1
offer letter and (ii) a confidentiality and IP/invention of my blog post “Five Mistakes Entrepreneurs Make
assignment agreement. The offer letter will set forth in Dealmaking – Part I.”
all of the employee’s respective rights and obligations,
including position, compensation (including stock LegalZoom. Finally, some startups make the
options and/or other incentive compensation), benefits ➓ mistake of using LegalZoom or other sites to
and, most importantly, whether the relationship is “at prepare their legal documentation. Websites like
will.” The confidentiality and IP/invention assign- LegalZoom are not law firms and do not render legal
ment agreement is designed to prevent disclosure of advice; nor are they able to create the kind of sophis-
the company’s trade secrets and other confidential ticated documents that you need to protect yourself
information and to ensure that any IP developed by the and to demonstrate credibility with your prospective
employee is legally owned by the company. I discuss investors. You should retain an experienced corporate
this issue in paragraph 8 of my blog post “Launching lawyer to help you from the legal side. I discuss this
a Venture: Ten Tips for Entrepreneurs.” issue in detail in the FAQ’s section of my website.

83(b) Elections. Some founders make the Conclusion


➑ mistake of not making an “83(b) election” in I hope the foregoing is helpful. I realize it’s a lot of
connection with the restricted stock (i.e., stock subject information to digest; however, I see these mistakes
to forfeiture) issued to them. Section 83(b) of the made by startups all the time. n
Internal Revenue Code permits the founders to elect
to accelerate the taxation of restricted stock to the Scott Edward Walker is the founder and CEO of Walker Corpo-
grant date, rather than the vesting date. As a result, rate Law Group, PLLC, a boutique corporate law firm special-
the founder would pay ordinary income tax rates izing in the representation of entrepreneurs. Scott has built
on the fair market value of the stock at the time of a strong team of lawyers, with offices in Los Angeles, San
the grant (which presumably would be quite low or Francisco and Washington, D.C. You can follow him on Twitter
as @ScottEdWalker or check out his blog.

Reprinted with permission of the original author. First appeared in http://hn.my/legalmistakes/.

  29
SPECIAL

Say Hello to
My Little Friend
How I Became the Tony Montana of the Internet
By Dave Pell

B ack in the early days of the


web I was just a dealer. And I
followed the advice I got from
the movie Scarface: Don’t get high on
your own supply. I used the web as a tool
suckers. But it was a lie.
The other day, after spending my
usual ten to twelve hours in front of this
laptop I decided to restart my machine.
I checked my email. I refreshed my
and how, as I’ve written here before, I
went from using a tool to being one.
A few weeks ago I was hosting my
son’s fourth birthday party at an old
school arcade. We were running short
to be more efficient at achieving goals I Tweetie. I double-checked Facebook. I on quarters, so I went to throw a few
had set for myself in the outside world. I loaded Google Reader to make sure I dollars in the change machine. While I
blogged, I created sites, I worked with a was entirely up to date on all the news waited for my bills to become change, I
bunch of interesting startups. from the latest Afghanistan troop levels pulled my iPhone out of my pocket and
Don’t get me wrong. I dabbled in the to the attempts to stop the gallons of checked my email. It was Sunday morn-
web as a user. But it was always with the crude from bubbling into the Gulf to ing. It was my son’s birthday party.
bigger picture in mind. It was always with the current quotes from the Mel Gibson I often fall asleep to audiobooks. That
a purpose. I was in charge. I was in control. tapes to the latest reactions to Anten- leaves my iPhone on my nightstand.
Those days are over. Like Tony nagate. Finally, after a quick check of my Recently, while my wife and I spent
Montana, I didn’t follow the advice realtime blog stats, I took a deep breath the sunrise hours cuddling and joking
about getting hooked on the product. As and pressed the restart button. with our kids, I heard the vibration of
the realtime, social web has erupted, so Within five seconds, I picked up my an incoming email. I rolled over and
too has my transition from being a dealer iPhone and checked my email. checked it.
to being a dealer and a hardcore user. Suddenly self-aware, I paused. I looked In the last year, I haven’t driven a
I’ve been denying this reality for years. I at my sweat-beaded reflection in the still commute of more than 15 minutes — or
easily convinced myself that I wasn’t the darkened laptop screen and I realized walked more than five — without open-
Nurse Jackie of the internet. I told myself that yes, I am high on my own supply. I ing at least one app on my iPhone.
I was just taking a little taste to make used the next couple minutes of restart Last weekend, everyone in my house
sure I understood the product I was time for some personal reflection about heard what sounded like a deep breath-
serving out to others — the civilians, the the way the internet now controls me ing sound in our kitchen. Then I open

30  SPECIAL
NEED A BOOST TO STAY AHEAD?

HIRE THE HECK OUT OF


PASQUALE D’SILVA.

HE DOES ANIMATION, ILLUSTRATION & NIFTY


IDEAS THAT ARE COOLER THAN ANYTHING
YOU HAVE EVER HEARD OF*.

2010
pasqualedsilva.com/hire
*true facts

the door and I heard it in the backyard worked his way to the top through a updates I habitually check.
too. I started to get nervous. It was the combination of sheer will, toughness When the WiFi went down during the
kind of sound that would provide an and a knack for avoiding chainsaws, official iPhone 4 demo, didn’t you sort of
appropriate backdrop to a horror movie to being the Tony Montana who was wish Steve Jobs would turn to the crowd
that was just about to get scary. I walked unconsciously fantasizing about his sister and say, “You know what, let’s just talk.”
to the front of my driveway. I explored and yelling obscenities to an empty room But that could have never happened.
the garage. I put my ear to heating ducts while soaking neck-deep in a cocaine- We know from his late night email
and water pipes. Everywhere, I heard the fueled bubble bath. exchanges with customers that Steve
sound. Inhale, exhale. Inhale, exhale. I The realtime web has become a habit. Jobs is no longer just a dealer either.
ran back into the house to tell the kids to It’s a twitch. I do it without thinking. Is there a pill for this twitch or a salve
pack a bag, we were getting out of there. More importantly, when I succumb to to slow this reflex? I don’t know. While I
Then my daughter pointed to my pocket. the reflex of checking it every few min- search, I hear the constant repetition of an
I reached in and pulled out my iPhone utes or seconds, I do so at the expense updated version of another Scarface quote.
on which I had inadvertently opened the of thinking. When is the last time you You gotta make the money first. Then
Balloonimals app which makes a blowing stood in line at a bank without checking when you get the money, you get the
noise until you start the game. your iPhone? What about waiting for a power. Then when you get the power,
Suddenly I knew what Tony Montana long stoplight or sitting at a restaurant then you get the women.
meant when he said, “Say hello to my counter? Those moments, now domi- Then you get the iPhone. n
little friend.” nated by the internet reflex must have
At the moment, I felt stupid. But then been used for something else before all Dave Pell writes Tweetage Wasteland, Confes-
I realized that the breathing was real. My this technology climbed into our pockets. sions of an Internet Superhero. He is web entre-
iPhone is alive. I hear it breathing right What were we thinking about when we preneur and investor and lives in San Francisco.
now. Do you hear yours? had all that extra time?
I went from being the Tony Montana I don’t remember. But I’m pretty sure
who came to Miami with nothing and it was more important than all these
Reprinted with permission of the original author. First appeared in http://hn.my/tonymontana/.

  31
PROGRAMMING

Advanced
Programming
Languages
By Matt Might

S tudents often ask for a


recommendation on what
language they should learn
next. If you’re looking for
a job in industry, my reply is to learn
whatever is hot right now: C++, Java and
C# — and probably Python, Ruby, PHP
and Perl too.
entrepreneurship, you need to multiply
your effectiveness as a programmer, and
since you (probably) won’t be working
with an entrenched code base, you are
free to use whatever language best suits
the task at hand.
Here you’ll find descriptions of four
good languages to learn — Haskell, Scala,
niches. To name just a few more, there’s
also D for systems programming; Erlang
or Clojure for concurrency; and Datalog
for constraint programming. Then there
are languages like Smalltalk — alternate
yet fully capable universes that branched
off from mainstream computing long ago.
I encourage my students to never
If, on the other hand, you’re interested ML and Scheme — with a list of my stop learning niche languages. They
in enlightenment, academic research favorite features for each, and pointers expand your modes of thinking, the
or a start-up, the criterion by which on where to learn more. kinds of problems you solve quickly and
you should choose your next language Of course, this short list is by no your appreciation for the meaning of
is not employability, but expressive- means exhaustive. There are many computation.
ness. In academic research and in uncommon languages that excel at

32  PROGRAMMING
Haskell type a is an instance of a lattice, then a
Haskell excels as a language for writing More pragmatically, I have found map from k to a is also an instance of a
a compiler, an interpreter or a static laziness useful in encoding option types, lattice.
analyzer. I don’t do a lot of artificial where utilizing the empty case should As another example, you can easily
intelligence, natural-language processing always nuke the program. In Haskell, you turn the Cartesian product of two lat-
or machine-learning research, but if I can avoid creating an option type and tices into a lattice:
did, Haskell would be my first pick there instead use error to produce the empty
too. (Scheme would be a strong second.) value. Because of laziness, every type in instance (Lattice a, Lattice b) =>
Haskell is the only widely used pure, lazy Haskell automatically has two additional Lattice (a,b) where
functional programming language. values: non-termination and error. Used bot = (bot,bot)
Like Standard ML and OCaml, well, this eliminates much tedious pat- top = (top,top)
Haskell uses an extension of Hindley- tern matching. (a1,b1) <: (a2,b2) = (a1 <: a2) ||
Milner-style type inference, which means My favorite feature of Haskell is type (a1 == a2 && b1 <: b2)
that the programmer doesn’t have to classes. Haskell’s type system allows (a1,b1) `join` (a2,b2) =
write down (most) types, because the the compiler to infer the correct code (a1 `join` a2, b1 `join` b2)
compiler can infer them. It has been my to run based on its type context, even (a1,b1) `meet` (a2,b2) =
experience that it is difficult to get a bug when that type context is also inferred. (a1 `meet` a2, b1 `meet` b2)
through the Hindley-Milner type system. The example of type classes that got me
In fact, experienced programmers excited was bounded lattices. A bounded It’s easy to make the “natural” lifting of
become adept at encoding correctness lattice is a mathematical structure that the lattice operations, relations and ele-
constraints directly into the Haskell type has a least element (bot), a greatest ele- ments to almost any data structure. The
system. A common remark after pro- ment (top), a partially ordered less than end result is that if you use the expres-
gramming in Haskell (or ML) for the first relation (<:), a join operation (join) and a sion bot or the relation <: anywhere in
time is that once the program compiles, meet operation (meet). your code, Haskell can infer, at compile-
it’s almost certainly correct. In Haskell, one can define a bounded time, their “appropriate” meaning based
As a pure language, side effects lattice as a type class: on the type of the expression (which it
(mutations of variables or data structures can also infer).
and I/O) are prohibited in the language class Lattice a where The ML languages have functors to
proper. This has forced the language’s top :: a play the role of type classes, but they
designers to think seriously about how to bot :: a lack the ad hoc polymorphism support
provide such functionality. Their answer, (<:) :: a -> a -> Bool of Haskell’s type classes. Having spent a
monads, enables one to perform side join :: a -> a -> a considerable amount of time program-
effects and I/O inside a safely constrained meet :: a -> a -> a ming in the MLs and in Haskell, the
framework. Naturally, Haskell lets users practical ramifications of inference on
define their own monads, and now the This says that if type a is a Lattice, expressiveness cannot be understated.
programmer has access to monads for then a supports the expected operations.
continuations, transducers, exceptions, What I really love about Haskell is Favorite features
logic programming and more. that it lets the programmer define condi- • Type classes.
Aside from being pure, Haskell is also tional instances of a class; for example: • A rich library.
lazy. That is, an expression in Haskell is • Monads.
not evaluated until (and unless) its result instance (Ord k, Lattice a) => • List comprehensions.
is required to make forward compu- Lattice (Map k a) where • Compact, readable, whitespace-guided
tational progress. Some have argued bot = Map.empty syntax.
that the promised efficiency gains from top = error $ "Cannot be
laziness haven’t materialized, but that’s represented."
not of concern for me. I appreciate lazi- f <: g = Map.isSubmapOfBy (<:) f g
ness for the increase in expressiveness. f `join` g = Map.unionWith join f g
In Haskell, it is trivial to describe data f `meet` g = Map.intersectionWith
structures of infinite extent. Where other meet f g
languages permit mutually recursive
functions, Haskell permits mutually This rule says that if the type k is an
recursive values. instance of an order (class Ord) and the

  33
Standard ML and OCaml
The ML family is a sweet spot in the ran faster than the C++-based model I languages, but they still permit side
language-design space: strict, side-effect- had used as a reference, with just 10% of effects, they make a nice stop on the way
able and Hindley-Milner type-inferred. the code. to learning Haskell. In Haskell, program-
This makes these languages practical The functor system in SML, while mers not yet well versed in functional
for real-world projects that need high more verbose than Haskell’s type class program design may find they repeatedly
performance and stronger guarantees of system, is more flexible. Once you code themselves into a corner, where
correctness. The ML family has gained instantiate a type class T for a kind/ they don’t have access to the monad
traction with aerospace engineers (for type k in Haskell, you can’t instantiate that they need. The MLs keep the side
its support of bug-free code) and with that type class again for that kind/type. effects “escape hatch” open to patch
programmers in the financial industry With functors, each instance gets its own over incomplete design, which prevents
(for the same reason). Standard ML was name, so you can have multiple instances projects from coming to a sudden,
the first functional language I learned of a given functor for the same type. It’s unexpected “refactor-or-abort” decision
well, so I still remember being shocked rarely been the case that I needed such point. One useful measure of a language
by its expressiveness. expressiveness, but it has been nice in is how well it tolerates a bad or incom-
Today, OCaml seems to be the those cases where I have. plete design for the software system,
popular ML to learn, but there is at least The other modern branch on the ML since design is something that inevitably
one convincing argument in SML’s favor: family tree, OCaml, is good to know changes as a program evolves. In this
MLton. MLton really delivers on the because there is a large community regard, the MLs still have the upper hand
thesis that functional languages offer the invested in it, which means that there are over Haskell.
best opportunities at optimization. As a lot of libraries available. The OCaml
a whole-program optimizing compiler, tool-chain is also rich, with interpreters, Favorite features
I’ve yet to see another compiler match optimizing compilers and byte-code • Flex records. (SML only)
its performance. I once created OpenGL compilers available to the developer. • Pattern matching.
bindings for MLton to toy around with Because the ML languages are more • Structures and functors.
3D graphics, and the resulting program expressive than all the mainstream

Scheme
Scheme is a language with a pure core Consequently, the programmer can In Scheme, during any point in the
(λ-calculus and the theory of lists) and reconfigure Scheme to reduce the computation, the program can capture
a design mandate to maximize freedom impedance mismatch between the the current continuation as a procedure:
of expression. It’s untyped, which makes language and the task at hand. Combined invoking this procedure returns the
it ideal for web-based programming and with support for first-class continuations, program to the evaluation context that
rapid prototyping. Given its Lisp heri- it is even possible to embed alternate existed when the continuation was cap-
tage, Scheme is a natural fit for artificial programming paradigms (like logic tured. Programming with continuations
intelligence. programming). feels like traveling back and forth in time
With its support for arbitrary-preci- For example, in the code: and shifting between parallel universes.
sion numerics, Scheme is also my first Ultimately, Scheme is so minimal and
choice for implementing cryptographic (let ((x (amb 3 4 5)) extensible that there’s not a whole lot to
algorithms. [For examples, see my short (y (amb 6 7 8 ))) say about it, except that Scheme allows
implementations of RSA and the Fermat (assert (= (+ x y) 12)) the programmer to extract from the
and Solovay-Strassen primality tests in (display x) language whatever the programmer is
Scheme.] (display y)) willing to put into it.
By far, the most compelling reason
to use Scheme is its macro system. It is possible to write an amb macro Favorite features
All of the macro systems available that “chooses” the right argument to • S-Expressions as syntax and data.
for Scheme, including the standard make a subsequent assert statement be • Hygienic macros.
syntax-rules and syntax-case systems, are true. (This program prints 4 and then 8.) • Continuations.
Turing-equivalent. • Higher-order functions.

34  PROGRAMMING
Scala
Scala is a rugged, expressive, strictly access to the entire Java library as well. You can imagine implicits as an API for
superior replacement for Java. Scala is This means you can get real work done the error-recovery phase of the type-
the programming language I use for tasks in Scala. checker. In short, when the type checker
like writing web servers or IRC clients. In As I started using Scala, I became needs an X but got a Y, it will check to
contrast to OCaml, which was a func- impressed by how tightly the functional see if there’s a function marked implicit
tional language with an object-oriented and object-oriented worlds had been in scope that converts Y into X; if it finds
system grafted to it, Scala feels more like blended. In particular, Scala has a power- one, it automatically applies the implicit
a true hybrid. That is, object-oriented ful case class/pattern-matching system function to repair the type error.
programmers should be able to start that addressed annoyances lingering Implicits make it possible to look
using Scala immediately, picking up the from my experiences with Standard ML, like you’re extending the functional-
functional parts only as they choose to. OCaml and Haskell: the programmer can ity of a type for a limited scope. For
I learned of Scala from Martin decide which fields of an object should example, suppose you want to “add” an
Odersky’s invited talk at POPL 2006. At be matchable (as opposed to being escapeHTML() method to type String.
the time, I saw functional programming forced to match on all of them), and You can’t modify the definition of
as strictly superior to object-oriented variable-arity arguments are permitted. String, but with implicits, you can make
programming, so I didn’t see a need for a In fact, Scala even allows programmer- it so that when type-checking fails on
language that fused functional and object- defined patterns. myString.escapeHTML(), it will look for
oriented programming. (That was probably I write a lot of functions that operate an implicit function in scope that can
because all I wrote back then were compil- on abstract syntax nodes, so it’s nice to convert a String object into a type that
ers, interpreters and static analyzers.) match on only the syntactic children, supports the escapeHTML() method.
The need for Scala didn’t become while ignoring fields for annotations or Implicits also allow cleaner domain-
apparent to me until I wrote a concur- source location. specific embedded languages (DSELs) in
rent HTTPD from scratch to support The case class system lets one split Scala, since they allow you to transpar-
long-polled AJAX for yaplet. In order the definition of an algebraic data type ently map Scala literals (like 3 or “while”)
to get multicore support, I wrote the across multiple files or across multiple into literals in the DSEL.
first version in Java. I don’t think Java is parts of the same file. Scala also sup-
all that bad, and I can enjoy well-done ports well-defined multiple inheritance Favorite features
object-oriented programming. As a func- through class-like constructs called traits. • JVM support.
tional programmer, however, the lack of And, Scala allows operator overloading; • Intelligent operator overloading.
terse support for functional programming even function application and collection • Extensive library.
features (like higher-order functions) update can be overloaded. Used well, this • Case classes/pattern matching.
grates on me. So, I gave Scala a chance. tends to make my Scala programs more • Extensible pattern matching.
Scala runs on the JVM, so I could intuitive and concise. • Multiple inheritance via traits.
gradually port my existing project into One feature that turns out to save a • Rich, flexible object constructors.
Scala. It also means that Scala, in addi- lot of code, in the same way that type • Implicit type conversions.
tion to its own rather large library, has classes save code in Haskell, is implicits. • Lazy fields and arguments.

Resources available on the original post


http://hn.my/apl/. n

Matt Might is a professor of Computer Science


at the University of Utah. His research inter-
ests include programming language design,
static analysis and compiler optimization.
He blogs at http://matt.might.net/articles/ and
tweets from @mattmight.

Reprinted with permission of the original author. First appeared in http://hn.my/apl/.


Emacs Isn’t For Everyone
By Brian Carper

C has Emerick recently posted


the results of his State of Clo-
jure survey. It turns out that
the (self-selected) group of Clojure-using
respondents happen to prefer Emacs as
habits and forming new ones. And you’re
trying to do this at the same time you’re
undertaking another, even harder task:
writing programs. And if you’re a new
Clojurist, and you’re learning Emacs and
integration, Emacs’ funky regex syntax
for search/replace, Emacs’ bizarre kill
rings and undo rings, the list goes on.
These things are very flexible in Emacs,
which is a great thing, but it’s also an
their IDE of choice, eclipsing all other Clojure from scratch at the same time, impediment to learning how to configure
editors by a large margin. well, get the headache medication ready. and use them. There’s no getting around
Chas then has this to say: As a programmer and someone who the time investment.
sits in front of a computer 12+ hours a And it’s not just a matter of learning
“I continue to maintain that broad accep- day, I consider myself pretty flexible and some new keyboard shortcuts. There’s a
tance and usage of Clojure will require capable of picking up a new user inter- new vocabulary to learn. You don’t open
that there be top-notch development face. As someone who had been using files, you visit them. What’s a buffer?
environments for it that mere mortals Vim for years prior to trying Emacs, I What’s a window? (Not what you think it
can use and not be intimidated by...and considered myself more than capable is.) What’s a point? What’s a mark? Kill?
IMO, while emacs is hugely capable, I of learning even a strange and foreign Yank? “Apropos”? Huh? C-c M-o means
think it falls down badly on a number of interface. I’d done it once before. what exactly? My keyboard doesn’t have
counts related to usability, community/ But learning Emacs still hurt. Oh how a Meta key. Yeah, you can use CUA mode
ecosystem, and interoperability.” it hurt. I blogged while I was learning and get your modernized Copy/Cut/
it, and you can see my pain firsthand. I Paste shortcuts back, but that’s the tip of
As an avid, die-hard Vim and Emacs sometimes hear people say “I tried Emacs the iceberg. It’s hard even to know where
user for life, I’m going to agree. for a whole month and I still couldn’t get to begin looking for help.
it”. Well, it took me over a year to be able Yeah, Emacs came first, before our
Mere mortals? to sit down at Emacs and use it fluidly more common and more modern
Emacs isn’t difficult to learn. Not in the for long periods of time without tripping conventions were established, and that
sense of requiring skill or cleverness. It over the editor. explains why it’s so different. That
is however extremely painful to learn. I To be fair, I’m talking here about using doesn’t change the fact that Emacs today
think there’s a difference. Emacs as a programming environment. is a strange beast.
The key word is tedium. Learning Using Emacs as a Notepad replace-
Emacs is a long process of rote memori- ment could be learned in short order. Community and ecosystem
zation and repetition of commands until C-x C-f, C-x C-s, or use the menus, Personally I find the Emacs community
they become muscle memory. If you’re there you go. Using it comfortably as a to be a pretty nice bunch. In the highest
smart enough to write programs, you full-fledged IDE is significantly harder tradition of hackerdom and open source
can learn Emacs. You just have to keep and requires you to touch (and master) software, Emacs users seem to be eager
dumping time into the task until you many more features. Syntax highlight- and willing to share their elisp snippets
become comfortable. ing, tab-completion, directory traversal and bend over backwards to help other
Until you’re comfortable, you face the and cwd issues, enabling line numbers, people learn the editor. I got lots of help
unpleasant task of un-learning all of your version-control integration, build tool when I was struggling and learning Emacs.

36  PROGRAMMING
The Emacs wiki is an awesome The wealth of options of ways to do every day. I learned Emacs because I love
resource. The official documentation is so things in Emacs is simultaneously a good programming and I love playing with
complete (and so long) that it leaves me thing, overwhelming and confusing. If all toys, and Vim or Emacs are as nice a toy
speechless sometimes. And there are a you want is something that works and as I could ask for. (I love programming
million 3rd-party scripts for it. Whatever gets out of your way, too many options enough to form strong opinions and
you want Emacs to do is generally a short can be worse than one option, even if write huge blog posts about text editors.)
google away. that one option isn’t entirely ideal. For me, productivity was a beneficial
If there’s anything wrong with the Emacs’ Java interop, I know nothing side-effect.
Emacs community, it’d be people who about. Almost certainly, Emacs can come There are only so many hours in a
take Emacs evangelism overboard. The close to a modern Java IDE for fancy day. There are a lot of other challenges
answer to “I don’t want to have to use features like tab-completion and docu- to conquer, some of which offer more
Emacs to use your language” can’t be ment lookups and project management. tangible benefits than Emacs mastery
“Be quiet and learn more Emacs,” or But how long is it going to take you to would get you. Mastering an arcane text
“If you’re too dumb to learn Emacs, go figure out that tab-completion is called editor isn’t necessarily going to be on the
away.” In some communities there is hippie-expand in Emacs? That and a top of the list of everyone’s goals in life,
certainly some of that. But thankfully I million other surprises await you. especially when there are other editors
don’t see it much in the Clojure commu- that are easier to use and give you a
nity. Let’s hope it stays that way. What’s my point? significant subset of what Emacs would
There was a pithy quote floating around give you. We have to pick our battles.
Interoperability on Twitter a while back (I think quoting So I understand when people say
Once someone spends the time to write Rich Hickey): they don’t want to learn Emacs. I think
a suitable amount of elisp, Emacs can maybe so many Clojurists use Emacs
interoperate with anything. I think so “One possible way to deal with being right now because we’re still in the early
many people use SLIME for Clojure unfamiliar with something is to become adopter stage. If you’re using Clojure
development precisely because it familiar with it.” today, you’re probably pretty enthusi-
interoperates so darned well with Lisps. astic about programming. You’re likely
SLIME is amazing. You probably can’t That’s true, and you could say that invested enough to be willing to burn the
beat Paredit either, and Emacs’ flex- of Emacs. I strongly believe that when required time to learn Emacs.
ibility is precisely what makes things like it comes to computers, there’s no such If Clojure becomes “big”, there are
Paredit possible. thing as “intuitive”. There’s stuff you’ve going to be a lot of casual users. A casual
The problem is the amount of time already spent a lot of time getting used user of Clojure isn’t going to learn
you have to spend to get that interoper- to, and there’s stuff you haven’t. Emacs. They’re going to silently move
ability set up and to learn how to use But certain things require more of a on to another language. And I really
it. After two years of using Emacs and time investment than others. Could I think that new blood is vital to the
Clojure together, every once in a while I learn Clojure if all the keywords were in strength of a community and necessary
still find myself bashing my face on my Russian or Chinese instead of my native for the continued healthy existence of a
desk trying to get the latest SLIME or English? Sure, but it’d take me a long programming language.
swank to work just right, or trying to get time. I’d certainly have to have a good So Clojure does need alternatives.
a broken key binding fixed, or tweak- reason to attempt it. I’ll stick with Emacs myself, but there
ing some other aspect of Emacs that’s I learned Emacs partly because it was should be practical alternatives. I’d
driving me crazy. One day, curly braces hard. I saw it as a challenge. It was fun, encourage the Clojure community to
stopped being recognized as matched yet painful, but more pain, more glory. continue to support and enjoy Emacs,
pairs by Paredit. Why? No idea; I fixed it, Mastering it makes me feel like I’ve but don’t push it too hard. n
but it was a half hour of wasted time. accomplished something. I’d encourage
Emacs is good at integrating with Git other people to learn Emacs and Vim Brian is a professional programmer and hobbyist
too. So good that there are four or five too. I think the benefits of knowing them text-editor enthusiast. He writes about these
different Emacs-Git libraries, each with a outweigh the cost and time investment topics at http://briancarper.net.
different interface and feature set. I gave of learning them.
up eventually and went back to using But I didn’t learn Emacs with the
the command line. (You can embed a goal of being productive. I learned it for
shell / command line right in Emacs. the same reason some people build cars
There are three or four different libraries in their garages, while most people just
to do that too.) buy one and drive it to and from work
Reprinted with permission of the original author. First appeared in http://hn.my/emacs/.

  37
What Every
Developer Should
Know About URLs
By Alan Skorkin

I have recently written about the value of fundamentals in


software development. I am still firmly of the opinion that
you need to have your fundamentals down solid, if you
want to be a decent developer. However, several people made
a valid point in response to that post, in that it is often difficult
The Structure Of A URL
This is easy, starts with HTTP and ends with .com right :)?
Most URLs have the same general syntax, made up of the
following nine parts:

to know what the fundamentals actually are (be they macro <scheme>://<username>:<password>@<host>:<port>/<path>;
or micro level). So, I thought it would be a good idea to do an <parameters>?<query>#<fragment>
ongoing series of posts on some of the things that I consider to
be fundamental – this post is the first installment. Most URLs won’t contain all of the parts. The most common
Being a developer this day and age, it would be almost components, as you undoubtedly know, are the scheme, host
impossible for you to avoid doing some kind of web-related and path. Let’s have a look at each of these in turn:
work at some point in your career. That means you will inevi-
tably have to deal with URLs at one time or another. We all • scheme – this basically specifies the protocol to use to access
know what URLs are about, but there is a difference between the resource addressed by the URL (e.g. http, ftp). There are
knowing URLs like a user and knowing them like a developer a multitude of different schemes. A scheme is official if it has
should know them. been registered with the IANA (like http and ftp), but there
As a web developer you really have no excuse for not know- are many unofficial (not registered) schemes which are also
ing everything there is to know about URLs, there is just not in common use (such as sftp, or svn). The scheme must start
that much to them. But, I have found that even experienced with a letter and is separated from the rest of the URL by
developers often have some glaring holes in their knowledge of the first : (colon) character. That’s right, the // is not part of
URLs. So, I thought I would do a quick tour of everything that the separator but is in fact the beginning of the next part of
every developer should know about URLs. Strap yourself in – the URL.
this won’t take long :).

38  PROGRAMMING
• username – this along with the password, the host and the • query – these on the other hand are very common as every
port form what’s known as the authority part of the URL. web developer would know. This is the preferred way to
Some schemes require authentication information to access send some parameters to a resource on the server. These are
a resource this is the username part of that authentication key=value pairs and are separated from the rest of the URL
information. The username and password are very common by a ? (question mark) character and are normally separated
in ftp URLs, they are less common in http URLs, but you do from each other by & (ampersand) characters. What you
come across them fairly regularly. may not know is the fact that it is legal to separate them
• password – the other part of the authentication information from each other by the ; (semi-colon) character as well. The
for a URL, it is separated from the username by another : following URLs are equivalent:
(colon) character. The username and password will be sepa-
rated from the host by an @ (at) character. You may supply http://www.blah.com/some/crazy/path.html?param1=foo
just the username or both the username and password e.g.: &param2=bar

ftp://some_user@blah.com/ http://www.blah.com/some/crazy/path.html?param1=foo
ftp://some_user:some_path@blah.com/ ;param2=bar

If you don’t supply the username and password and the • fragment – this is an optional part of the URL and is used to
URL you’re trying to access requires one, the application you’re address a particular part of a resource. We usually see these
using (e.g. browser) will supply some defaults. used to link to a particular section of an html document.
A fragment is separated from the rest of the URL with a #
• host – as I mentioned, it is one of the components that (hash) character. When requesting a resource addressed by a
makes up the authority part of the URL. The host can be URL from a server, the client (i.e. browser) will usually not
either a domain name or an IP address, as we all should send the fragment to the server (at least not where HTTP is
know the domain name will resolve to an IP address (via a concerned). Once the client has fetched the resource, it will
DNS lookup) to identify the machine we’re trying to access. then use the fragment to address the relevant part.
• port – the last part of the authority. It basically tells us what
network port a particular application on the machine we’re That’s it, all you need to know about the structure of a URL.
connecting to is listening on. As we all know, for HTTP the From now on you no longer have any excuse for calling the
default port is 80, if the port is omitted from an http URL, fragment – “that hash link thingy to go to a particular part of
this is assumed. the html file”.
• path – is separated from the URL components preceding
it by a / (slash) character. A path is a sequence of segments Special Characters In URLs
separated by / characters. The path basically tells us where There is a lot of confusion regarding which characters are
on the server machine a resource lives. Each of the path safe to use in a URL and which are not, as well as how a URL
segments can contain parameters which are separated from should be properly encoded. Developers often try to infer this
the segment by a ; (semi-colon) character e.g.: stuff from general knowledge (i.e. the / and : characters should
obviously be encoded since they have special meaning in a
http://www.blah.com/some;param1=foo/crazy;param2=bar/path.html URL). This is not necessary, you should know this stuff solid –
it’s simple. Here is the low down.
The URL above is perfectly valid, although this ability of There are several sets of characters you need to be aware
path segments to hold parameters is almost never used (I’ve of when it comes to URLs. Firstly, the characters that have
never seen it personally). special meaning within a URL are known as reserved charac-
ters, these are:
• parameters – talking about parameters, these can also appear
after the path but before the query string, also separated ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","
from the rest of the URL and from each other by ; characters
e.g.: What this means is that these characters are normally used
in a URL as-is and are meaningful within a URL context (i.e.
http://www.blah.com/some/crazy/path.html;param1=foo; separate components from each other etc.). If a part of a URL
param2=bar (such as a query parameter), is likely to contain one of these
characters, it should be escaped before being included in the
As I said, they are not very common. URL. I have spoken about URL encoding before, check it out,
we will revisit it shortly.

  39
The second set of characters to be aware of is the unreserved (they shouldn’t be encoded) and when they are part of a URL
set. It is made up of the following characters: component (which means they should be encoded). Lastly you
should never try to double encode/decode a URL. Consider
"-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" that if you encode a URL once but try to decode it twice and
one of the URL components contains the % character you can
The characters can be included as-is in any part of the URL destroy your URL e.g.:
(note that they may not be allowed as part of a particular
component of a URL). This basically means you don’t need to http://blah.com/yadda.html?param1=abc%613
encode/escape these characters when including them as part of
a URL. You CAN escape them without changing the semantics When encoded it will look like this:
of a URL, but it is not recommended.
The third set to be aware of is the ’unwise’ set, i.e. it is http://blah.com/yadda.html?param1=abc%25613
unwise to use these characters as part of a URL. It is made up
of the following characters: If you try to decode it twice you will get:

"{" | "}" | "|" | "\" | "^" | "[" | "]" | "`" http://blah.com/yadda.html?param1=abc%613


Correct
These characters are considered unwise to use in a URL
because gateways are known to sometimes modify such http://blah.com/yadda.html?param1=abca3
characters, or they are used as delimiters. That doesn’t mean Stuffed
that these characters will always be modified by a gateway, but
it can happen. So, if you include these as part of a URL without By the way I am not just pulling this stuff out of thin air. It is
escaping them, you do this at your own risk. What it really all defined in RFC 2396, you can go and check it out if you like,
means is you should always escape these characters if a part of although it is by no means the most entertaining thing you can
your URL (i.e. like a query param) is likely to contain them. read, I’d like to hope my post is somewhat less dry :).
The last set of characters is the excluded set. It is made up
of all ASCII control characters, the space character as well the Absolute vs Relative URLs
following characters (known as delimiters): The last thing that every developer should know is the differ-
ence between an absolute and relative URL as well as how to
"<" | ">" | "#" | "%" | '"' turn a relative URL into its absolute form.
The first part of that is pretty easy, if a URL contains a
The control characters are non-printable US-ASCII char- scheme (such as http), then it can be considered an absolute
acters (i.e. hexadecimal 00-1F as well as 7F). These characters URL. Relative URLs are a little bit more complicated.
must always be escaped if they are included in a component A relative URL is always interpreted relative to another URL
of a URL. Some, such as # (hash) and % (percent) have special (hence the name :)), this other URL is known as the base URL.
meaning within the context of a URL (they can really be con- To convert a relative URL into its absolute form we firstly need
sidered equivalent to the reserved characters). Other characters to figure out the base URL, and then, depending on the syntax
in this set have no printable representation and therefore of our relative URL we combine it with the base to form its
escaping them is the only way to represent them. The <, > and absolute form.
“ characters should be escaped since these characters are often We normally see a relative URL inside an html document. In
used to delimit URLs in text. this case there are two ways to find out what the base is.
To URL encode/escape a character we simply append its 2
character ASCII hexadecimal value to the % character. So, the 1. The base URL may have been explicitly specified in the
URL encoding of a space character is %20 – we have all seen document using the HTML <base> tag.
that one. The % character itself is encoded as %25. 2. If no base tag is specified, then the URL of the html docu-
That’s all you need to know about various special characters ment in which the relative URL is found should be treated
in URLs. Of course aside from those characters, alpha-numerics as the base.
are allowed and don’t need to be encoded :).
A few things you have to remember. A URL should always
be in its encoded form. The only time you should decode parts
of the URL is when you’re pulling the URL apart (for whatever
reason). Each part of the URL must be encoded separately, this
should be pretty obvious, you don’t want to try encoding an
already constructed URL, since there is no way to distinguish
when reserved characters are used for their reserved purpose

40  PROGRAMMING
Once we have a base URL, we can try and turn our relative Here are some examples of applying the above algorithm:
URL into an absolute one. First, we need to try and break our 1)
relative URL into components (i.e. scheme, authority (host, base: http://www.blah.com/yadda1/yadda2/
port), path, query string, fragment). Once this is done, there are yadda3?param1=foo#bar
several special cases to be aware of, all of which mean that our relative: rel1
relative URL wasn’t really relative.
final absolute: http://www.blah.com/yadda1/yadda2/rel1
• if there is no scheme, authority or path, then the relative
URL is a reference to the base URL 2)
• if there is a scheme then the relative URL is actually an base: http://www.blah.com/yadda1/yadda2/
absolute URL and should be treated as such yadda3?param1=foo#bar
• if there is no scheme, but there is an authority (host, port), relative: /rel1
then our relative URL is likely a network path, we take the
scheme from our base URL and append our “relative” URL final absolute: http://www.blah.com/rel1
to it separating the two by ://
3)
If none of those special cases occurred then we have a real base: http://www.blah.com/yadda1/yadda2/
relative URL on our hands. Now we need to proceed as follows. yadda3?param1=foo#bar
relative: ../rel1
• we inherit the scheme, and authority (host, port) from the
base URL final absolute: http://www.blah.com/yadda1/rel1
• if our relative URL begins with /, then it is an absolute path,
we append it to the scheme and authority we inherited from 4)
the base using appropriate separators to get our absolute base: http://www.blah.com/yadda1/yadda2/
URL yadda3?param1=foo#bar
• if relative URL does not begin with / then we take the relative: ./rel1?param2=baz#bar2
path of the base URL, discarding everything after the last /
character final absolute: http://www.blah.com/yadda1/yadda2/
• we then take our relative URL and append it to the resulting rel1?param2=baz#bar2
path, we now need to do a little further processing which
depends on the first several characters of our relative URL 5)
• if there is a ./ (dot slash) anywhere in a resulting path we base: http://www.blah.com/yadda1/yadda2/
remove it (this means our relative URL started with ./ i.e. ./ yadda3?param1=foo#bar
blah.html) relative: ..
• if there is a ../ (dot dot slash) anywhere in the path then we
remove it as well as the preceding segment of the path i.e. final absolute: http://www.blah.com/yadda1/
all occurrences of “<segment>/../” are removed, keep doing
this step until no more ../ can be found anywhere in the path Now you should be able to confidently turn any relative
(this means our relative path started with one or more ../ i.e. URL into an absolute one, as well as know when to use the
../blah.html or ../../blah.html etc.) different forms of relative URL and what the implications will
• if the path ends with .. then we remove it and the preceding be. For me this has come in handy time and time again in my
segment of the path, i.e. “<segment>/..” is removed (this web development endeavours.
means our relative path was .. (dot dot)) There you go that’s really all there is to know about URLs, it’s
• if the path ends with a . (dot) then we remove it (this most all relatively simple (forgive the pun :)) so no excuse for being
likely means our relative path was . (dot)) unsure about some of this stuff next time. Talking about next
time, one of the most common things you need to do when it
At this point we simply append any query string or fragment comes to URLs is recognise if a piece of text is in fact a URL, so
that our relative URL may have contained to our URL using next time I will show you how to do this using regular expres-
appropriate separators and we have finished turning our rela- sions (as well as show you how to pull URLs out of text). It
tive URL into an absolute one. should be pretty easy to construct a decent regex now that we’ve
got the structure and special characters down. Stay tuned. n

Alan Skorkin is a developer and aspiring software craftsman from Mel-


bourne, Australia. He is often found causing controversy on his blog
skorks.com, while sharing his thoughts about hacking, the software devel-
Reprinted with permission of the original author. First appeared in http://hn.my/urls/. opment profession and the people who work in it.

  41
Understanding and Applying
Operational Transformation
Algorithm Behind Google Wave and Google Docs
By Daniel Spiewak

A lmost exactly a
year ago, Google
made one of the
most remarkable
press releases in the Web 2.0 era. Of
course, by “press release”, I actually
mean keynote at their own conference,
and by “remarkable” I mean potentially-
caret position, the conversation title
and a host of other things. An example
document following the Wave message
schema might look something like this:

<body>
<line/>Test message
<line/>
XML with some ancillary annotations.
As far as the Wave server is concerned,
you can stuff whatever data you want
in there, just so long as it’s well-formed.
It just so happens that Google chose to
implement a communications tool on
top of this data backend, but they could
have just as easily implemented some-
transformative and groundbreaking. I am <line/>Lorem ipsum dolor sit amet. thing more esoteric, like a database or a
referring of course to the announcement </body> windowing manager.
of Google Wave, a real-time collaboration The key to Wave is the mechanism
tool which has been in open beta for the (assuming the following annotations): by which we interact with these docu-
last several months. • style/font-weight -> bold ments: operational transformation. Wave
For those of you who don’t know, • style/font-style -> italic actually doesn’t allow you to get access
Google Wave is a collaboration tool • link/manual -> http://www.google.com to a document as raw XML or anything
based on real-time, simultaneous editing even approaching it. Instead, it demands
of documents via a mechanism known You will notice that the annotations that all of your access to the document
as “operational transformation”. Entities for style/font-style and link/manual be performed in terms of operations. This
which appear as messages in the Wave actually overlap. This is perfectly accept- has two consequences: first, it allows for
client are actually “waves”. Within each able in Wave’s document schema. The some really incredible collaborative tools
“wave” is a set of “wavelets”, each of resulting rendering would be something like the Wave client; second, it makes
which contains a set of documents. Indi- like this: it really tricky to implement any sort of
vidual documents can represent things Wave-compatible service. Given the fact
like messages, conversation structure Test message that I’ve been working on Novell Pulse
(which reply goes where, etc), spell (which is exactly this sort of service),
check metadata and so on. Documents Lorem ipsum dolor sit amet. and in light of the fact that Google’s
are composed of well-formed XML with documentation on the subject is sparing
an implicit root node. Additionally, they The point of all this explaining is to at best, I thought I would take some
carry special metadata known as “annota- give you at least a passing familiarity time to clarify this critical piece of the
tions” which are (potentially-overlap- with the Wave document schema so that puzzle. Hopefully, the information I’m
ping) key/value ranges which span across I can safely use its terminology in the about to present will make it easier for
specific regions of the document. In the article to come. See, Wave itself is not others attempting to interoperate with
Wave message schema, annotations are nearly so interesting as the idea upon Wave, Pulse and the (hopefully) many
used to represent things like bold/italic/ which it is based. As mentioned, every OT-based systems yet to come.
underline/strikethrough formatting, links, document in Wave is actually just raw

42  PROGRAMMING
Operations For example, we can encode the example 1. retain(8)
Intuitively enough, the fundamental document from earlier as follows: 2. deleteCharacters(’m’)
building block of operational transforms 3. insertCharacters(’M’)
are operations themselves. An operation 1. openElement(’body’) 4. retain(38)
is exactly what it sounds like: an action 2. openElement(’line’)
which is to be performed on a document. 3. closeElement() Instead of adding content to the docu-
This action could be inserting or deleting 4. annotationBoundary(startKeys: ment at ever step, most of this operation
characters, opening (and closing!) an [’style/font-weight’], startVal- actually leaves the underlying document
XML element, fiddling with annotations, ues: [’bold’]) untouched. In practice, retain() tends to
etc. A single operation may actually 5. insertCharacters(’Test message’) be the most commonly used component
perform many of these actions. Thus, 6. annotationBoundary(endKeys: by a wide margin. The trick is that every
an operation is actually made up of a [’style/font-weight’]) operation must span the full width of
sequence of operation components, each 7. openElement(’line’) the document. When evaluating this
of which performs a particular action 8. closeElement() operation, the cursor will start at index
with respect to the cursor (not to be 9. annotationBoundary(startKeys: 0 and walk forward through the existing
confused with the caret, which is specific [’style/font-style’], startValues: document and the incoming operation
to the client editor and not at all interest- [’italic’]) one item at a time. Each XML tag (open
ing at the level of OT). 10. openElement(’line’) or close) counts as a single item. Charac-
There are a number of possible 11. closeElement() ters are also single items. Thus, the entire
component types. For example: 12. insertCharacters(’Lorem ’) document contains 47 items.
13. annotationBoundary(startKeys: Our operation above cursors harm-
• insertCharacters — Inserts the speci- [’link/manual’], startValues: lessly over the first eight items (the
fied string at the current index [’http://www.google.com’]) <body> tag, the <line/> tag and the string
• deleteCharacters — Deletes the speci- 14. insertCharacters(’ipsum’) ’Test ’). Once it reaches the ’m’ in ’mes-
fied string from the current index 15. annotationBoundary(endKeys: sage’, we stop the cursor and perform a
• openElement — Creates a new XML [’style/font-style’]) mutation. Specifically, we’re using the
open-tag at the current index 16. insertCharacters(’ dolor’) deleteCharacters() component to remove
• deleteOpenElement — Deletes the 17. annotationBoundary(endKeys: the ’m’. This component doesn’t move
specified XML open-tag from the [’link/manual’]) the cursor, so we’re still sitting at index
current index 18. insertCharacters(’ sit amet.’) 8. We then use the insertCharacters()
• closeElement — Closes the first 19. closeElement() component to add the character ’M’ at
currently-open tag at the current precisely our currently location. This
index Obviously, this isn’t the most stream- time, some new characters have been
• deleteCloseElement — Deletes the lined way of referring to a document’s inserted, so the cursor advances to the
XML close-tag at the current index content for a human, but a stream of end of the newly-inserted string (mean-
• annotationBoundary — Defines the discrete components like this is perfect ing that we are now at index 9). This is
changes to any annotations (starting or for automated processing. The real utility intuitive because we don’t want to have
ending) at the current index of this encoding though doesn’t become to retain() over the text we just inserted.
• retain — Advances the index a speci- apparent until we look at operations We do however want to retain() over the
fied number of items which only encode a partial document; remainder of the document, seeing as
effectively performing a particular muta- we don’t need to do anything else. The
Wave’s OT implementation actually tion. For example, let’s follow the advice final rendered document looks like the
has even more component types, but of Strunk and White and capitalize the following:
these are the important ones. You’ll letter ‘m’ in our title of ‘Test message’.
notice that every component has some- What we want to do (precisely-speaking) Test Message
thing to do with the cursor index. This is delete the ‘m’ and insert the string ‘M’
concept is central to Wave’s OT imple- at its previous location. We can do that Lorem ipsum dolor sit amet.
mentation. Operations are effectively a with the following operation:
stream of components, each of which
defines an action to be performed which
effects the content, the cursor or both.

  43
Composition Transformation Unfortunately, if we naïvely send A’s
One of Google’s contributions to the Here’s where we get to some of the operation to B and B’s operation to A,
(very old) theory behind operational really interesting stuff and the motiva- the results will not converge:
transformation is the idea of operation tion behind all of this convoluted • ’got’ + (retain(2); insertCharacters(’a’)
composition. Because Wave operations representational baggage. Operational = ’goat’
are these nice, full-span sequences of Transformation, at its core, is an optimistic • ’goa’ + (retain(2); insertCharacters(’t’)
discrete components, it’s fairly easy to concurrency control mechanism. It = ’gota’
take two operations which span the allows two editors to modify the same Even discounting the fact that we have
same length and merge them together section of a document at the same time a document size mismatch (our opera-
into a single operation. The results of without conflict. Or rather, it provides tions each span 2 indexes, while their
this action are really quite intuitive. For a mechanism for sanely resolving those target documents have width 3), this is
example, if we were to compose our conflicts so that neither user intervention obviously not the desired behavior. Even
document operation (the first example nor locking become necessary. though our server may have a sane con-
above) with our ’m’-changing operation This is actually a harder problem cept of consistent ordering, our clients
(the second example), the resulting than it sounds. Imagine that we have the obviously need some extra hand-holding.
operation would be basically the same following document (represented as an Enter OT.
as the original document operation, operation): What we have here is a simple one-
except that instead of inserting the step diamond problem. In the theoretical
text ’Test message’, we would insert 1. insertCharacters(’go’) study of OT, we generally visualize
’Test Message’. In composing the two this situation using diagrams like the
operations together, all of the retains Now imagine that we have two editors following:
have disappeared and any contradicting with their cursors positioned at the end
components (e.g. a delete and an insert) of the document. They simultaneously
have been directly merged. insert a t and a character (respectively).
Composition is extremely important Thus, we will have two operations sent
to Wave’s OT as we will see once we to the server. The first will retain 2 items
start looking at client/server asymmetry. and insert a t, the second will retain 2
The important thing to notice now is items and insert a. Naturally, the server
the fact that composed operations must needs to enforce atomicity of edits at
be fundamentally compatible. Primarily, some point (to avoid race conditions
this means that the two operations must during I/O), so one of these operations The way you should read diagrams like
span the same number of indexes. It will be applied first. However, as soon as this is as a graphical representation of
also means that we cannot compose an either one of these operations is applied, operation application on two documents
operation which consists of only a text the retain for the other will become at the same time. Client operations move
insert with an operation which attempts invalid. Depending on the ordering, the the document to the left. Server opera-
to delete an XML element. Obviously, text of the resulting document will either tions move the document to the right.
that’s not going to work. Wave’s Composer be ’goat’ or ’gota’. Both client and server operations move
utility takes care of validating both the In and of itself, this isn’t really a the document downward. Thus, diagrams
left and the right operation to ensure problem. After all, any asynchronous like these let us visualize the application
that they are compatible as part of the server needs to make decisions about of operations in a literal “state space”.
composition process. ordering at some point. However, issues The dark blue line shows the client’s
Please also note that composition is start to crop up as soon as we consider path through state space, while the gray
not commutative; ordering is significant. relaying operations from one client to line shows the server’s. The vertices of
This is also quite intuitive. If you type the other. Client A has already applied these paths (not explicitly rendered)
the character a and then type the its operation, so its document text will are points in state space, representing
character b, the result is quite different be ’got’. Meanwhile, client B has already a particular state of the document.
than if you type the character b and then applied its operation, and so its docu- When both the client and the server line
type the character a. ment text is ’goa’. Each client needs the pass through the same point, it means
operation from the other in order to have that the content of their respective
any chance of converging to the same documents were in sync, at least at that
document state. particular point in time.

44  PROGRAMMING
So, in the diagram above, operation a Coming back to our concrete example, It is very important that you really
could be client A’s operation (retain(2); we can finally solve the problem of ’goat’ understand this process. OT is all about
insertCharacters(’t’)) and operation b vs ’gota’. We start out with the situation the transform function and how it
could be client B’s operation. This is of where client A has applied operation a, behaves in this exact situation. As it turns
course assuming that the server chose B’s arriving at a document text of ’got’. It out, this is all that OT does for us in and
operation as the “winner” of the race con- now receives operation b from the server, of itself. Operational transformation is
dition. As we showed earlier, we cannot instructing it to retain over 2 items and really just a concurrency primitive. It
simply naïvely apply operation a on the insert character ’a’. However, before doesn’t solve every problem with col-
server and b on the client, otherwise we it applies this operation (which would laborative editing of a shared document
could derive differing document states obviously result in the wrong document (as we will see in a moment), but it does
(’goat’ vs ’gota’). What we need to do state), it uses operational transformation solve this problem very well.
is automatically adjust operation a with to derive operation b’. Google’s OT One way to think of this is to keep in
respect to b and operation b with respect implementation will resolve the conflict mind the “diamond” shape shown in the
to a. between ’t’ and ’a’ in favor of the server. above diagram. OT solves a very simple
We can do this using an operational Thus, b’ will consist of the following problem: given the top two sides of the
transform. Google’s OT is based on the components: diamond, it can derive the bottom two
following mathematical identity: sides. In practice, often times we only
1. retain(2) want one side of the box (e.g. client A
2. insertCharacters(’a’) only needs operation b’, it doesn’t need
In plain English, this means that the 3. retain(1) a’). However, OT always gives us both
transform function takes two operations, pieces of the puzzle. It “completes” the
one server and one client, and produces You will notice that we no longer have diamond, so to speak.
a pair of operations. These operations a document size mismatch, since that last
can be applied to their counterpart’s end retain() ensures that the cursor reaches the Compound OT
state to produce exactly the same state end of our length-3 document state (’got’). So far, everything I have presented has
when complete. Graphically, we can Meanwhile, the server has received our come pretty directly from the white-
represent this by the following: operation a and it performs an analogous papers on waveprotocol.org. However,
series of steps to derive operation a’. contrary to popular belief, this is not
Once again, Google’s OT must resolve enough information to actually go out
the conflict between ’t’ and ’a’ in the and implement your own collaborative
same way as it resolved the conflict for editor or Wave-compatible service.
client A. We’re trying to apply opera- The problem is that OT doesn’t really
tion a (which inserts the ’t’ character at do all that much in and of itself. As men-
position 2) to the server document state, tioned above, OT solves for two sides
which is currently ’goa’. When we’re of the diamond in state space. It only
done, we must have the exact same docu- solves for two sides of a simple, one-step
ment content as client A following the diamond like the one shown above. Let
application of b’. Specifically, the server me say it a third time: the case shown
document state must be ’goat’. Thus, the above is the only case which OT handles.
OT process will produce the operation a’ As it turns out, there are other cases
consisting of the following components: which arise in a client/server collabora-
tive editor like Google Wave or Novell
Thus, on the client-side, we receive
retain(3) Pulse. In fact, most cases in practice are
operation b from the server, pair it with
insertCharacters(’t’) much more complex than the one-step
a to produce (a’, b’), and then compose
diamond.
b’ with a to produce our final document
Client A applies operation b’ to its
state. We perform an analogous process
document state, the server applies opera-
on the server-side. The mathematical
tion a’ to its document state, and they
definition of the transform function
both arrive at a document consisting of
guarantees that this process will produce
the text ’goat’. Magic!
the exact same document state on both
server and client.

  45
For example, consider the situation Remember, OT only solves for the This scheme has some very nice
where the client performs two operations bottom two sides of the diamond given advantages. Given an operation (and
(say, by typing two characters, one after the top two sides. In the case of the first its associated parent hash), we can
the other) while at the same time the operation (a), the server had both top determine instantly whether or not we
server performs one operation (originat- sides (a and c) and thus OT was able to have the appropriate document state to
ing from another client). We can diagram derive the all-important a’. However, in apply said operation. Hashes also have
this situation in the following way: this case, we only have one of the sides the very convenient property of converg-
of the diamond (b); we don’t have the ing exactly when the document states
server’s half of the equation because converge. Thus, in our one-step diamond
the server never performed such an case from earlier, operations a and b
operation! would be parented off of the same hash.
In general, the problem we have here Operation b’ would be parented off of
is caused by the client and server diverg- the hash of the document resulting from
ing by more than one step. Whenever applying a to the initial document state
we get into this state, the OT becomes (and similarly for a’). Finally, the point
more complicated because we effectively in state space where the client and server
need to transform incoming operations converge once again (after applying their
So we have two operations in the (e.g. b) against operations which never respective operations) will have a single
client history, a and b, and only one happened! In this case, the phantom hash, as the document states will be syn-
operation in the server history, c. The operation that we need for the purposes chronized. Thus, any further operations
client is going to send operations a and of OT would take us from the tail end of applied on either side will be parented
b to the server, presumably one after a to the tail end of a’. Think of it like a off of a correctly-shared hash.
the other. The first operation (a) is no “bridge” between client state space and Just a quick terminology note: when
problem at all. Here we have the simple server state space. We need this bridge, I say “parent hash”, I’m referring to the
one-step diamond problem from above, this second half of the diamond, if we hash of the document state prior to
and as well know, OT has no trouble are to apply OT to solve the problem of applying a particular operation. When I
at all in resolving this issue. The server transforming b into server state space. say “parent operation” (which I probably
transforms a and c to derive operation will from time to time), I’m referring to
a’, which it applies to its current state. Operation Parentage the hash of the document state which
The resulting situation looks like the In order to do this, we need to add some results from applying the “parent opera-
following: metadata to our operations. Not only tion” to its parent document state. Thus,
do our operations need to contain their operation b in the diagram above is par-
components (retain, etc), they also must ented off of operation a which is parented
maintain some notion of parentage. We off of the same hash as operation c.
need to be able to determine exactly
what state an operation requires for Compound OT
successful application. We will then use Now that our operations have parent
this information to detect the case where information, our server is capable of
an incoming operation is parented on a detecting that operation b is not par-
state which is not in our history (e.g. b on ented off of any state in its history. What
receipt by the server). we need to do is derive an operation
For the record, Google Wave uses a which will take us from the parent of
Ok, so far so good. The server has
monotonically-increasing scalar version b to some point in server state-space.
successfully transformed operation a
number to label document states and Graphically, this operation would look
against c and applied the resulting a’ to
thus, operation parents. Novell Pulse something like the following (rendered
its local state. However, the moment we
does the exact same thing for compat- in dark green):
move on to operation b, disaster strikes.
ibility reasons, and I recommend that
The problem is that the server receives
anyone attempting to build a Wave-
operation b, but it has nothing against
compatible service follow the same
which to transform it!
model. However, I personally think that
compound OT is a lot easier to under-
stand if document states are labeled by a
hash of their contents.

46  PROGRAMMING
Fortunately for us, this operation is Google’s careful definition of operation the server: any operation received by the
fairly easy to derive. In fact, we already composition, this is guaranteed to server must be parented on some point
derived and subsequently threw it away! produce the same operation as we would in the server’s history. Thus, the server
Remember, OT solves for two sides of the have received had we applied OT in two would have rejected operation b in our
diamond. Thus, when we transformed separate steps. example above since it did not branch
a against c, the resulting operation pair The final state diagram looks like the from any point in server state space. The
consisted of a’ (which we applied to our following: parent of b was a, but the server didn’t
local state) and another operation which have a, it only had a’ (which is clearly a
we discarded. That operation is precisely different point in state space).
the operation shown in green above. Of course, simply rejecting any diver-
Thus, all we have to do is re-derive this gence which doesn’t fit into the narrow,
operation and use it as the second top one-step diamond pattern is a bit harsh.
side of the one-step diamond. At this Remember that practically, almost all
point, we have all of the information we situations arising in collaborative editing
need to apply OT and derive b’, which will be multi-step divergences like our
we can apply to our local state: above example. Thus, if we naïvely
rejected anything which didn’t fit into
the one-step mold, we would render our
collaborative editor all-but useless.
The solution is to move all of the
heavy lifting onto the client. We don’t
want the server to have to track every
single client as it moves through state
Client/Server Asymmetry space since there could be thousands (or
Technically, what we have here is enough
even millions) of clients. But if you think
to implement a fully-functional client/
about it, there’s really no problem with
server collaborative editing system.
the client tracking the server as it moves
In fact, this is very close to what was
through state space, since there’s never
presented in the 1995 paper on the
going to be any more than one (logical)
Jupiter collaboration system. However,
server. Thus, we can offload most of the
while this approach is quite functional, it
compound OT work onto the client side.
At this point, we’re almost done. The isn’t going to work in practice.
Before it sends any operations to the
only problem we have left to resolve is The reason for this is in that confus-
server, the client will be responsible for
the application of operation c on the ing middle part where the server had to
ensuring those operations are parented
client. Fortunately, this is a fairly easy derive an intermediary operation (the
off of some point in the server’s history.
thing to do; after all, c is parented off of green one) in order to handle operation
Obviously, the server may have applied
a state which the client has in its history, b from the client. In order to do this, the
some operations that the client doesn’t
so it should be able to directly apply OT. server needed to hold on to operation a
know about yet, but that’s ok. As long
The one tricky point here is the fact in order to use it a second time in deriv-
as any operations sent by the client are
that the client must transform c against ing the intermediary operation. Either
parented off of some point in the server’s
not one but two operations (a and b). that, or the server would have needed
history, the server will be able to trans-
Fortunately, this is fairly easy to do. to speculatively retain the intermediary
form that incoming operation against
We could apply OT twice, deriving an operation when it was derived for the
the composition of anything which
intermediary operation in the first step first time during the transformation of a
has happened since that point without
(which happens to be exactly equivalent to a’. Now, this may sound like a trivial
tracking any history other than its own.
to the green intermediary operation point, but consider that the server must
Thus, the server never does anything
we derived on the server) and then maintain this sort of information essen-
more complicated than the simple one-
transforming that operation against b. tially indefinitely for every client which it
step diamond divergence (modulo some
However, this is fairly inefficient. OT is handles. You begin to see how this could
operation composition). In other words,
fast, but it’s still O(n log n). The better become a serious scalability problem!
the server can always directly apply OT
approach is to first compose a with b and In order to solve this problem, Wave
to incoming operations, deriving the
then transform c against the composi- (and Pulse) imposes a very important
requisite operation extremely efficiently.
tion of the two operations. Thanks to constraint on the operations incoming to

  47
Unfortunately, not all is sunshine and Note that we were able to send a do this, we add another bit of metadata
roses. Under this new regime, the client immediately because we are preserving to the operation: a locally-synthesized
needs to work twice as hard, translating its every bit of data the server sends us. We unique ID. This unique ID will be
operations into server state space and (cor- still don’t know about c and d, but we do attached to the operation when we send
respondingly) server operations back into know that the last time we heard from it to the server and preserved by the
its state space. We haven’t seen an example the server, it was at the same point in server through the application of OT.
of this “reverse” translation (server to state space as we were (the parent of a Thus, operation a’ will have the same ID
client) yet, but we will in a moment. and c). Thus, since a is already parented as operation a, but a very different ID
In order to maintain this guarantee on a point in server state space, we can from operations c and d.
that the client will never send an opera- just send it off. With this extra bit of metadata in
tion to the server which is not parented Now let’s fast-forward just a little bit. place, clients are able to distinguish their
on a version in server state space, we The server receives operation a. It looks own operations from others sent by the
need to impose a restriction on the into its history and retrieves whatever server. Non-self-initiated operations (like
client: we can never send more than one operations have been applied since the c and d) must be translated into client
operation at a time to the server. This parent of a. In this case, those operations state space and applied to the local
means that as soon as the client sends an are c and d. The server then composes c document. Self-initiated operations (like
operation (e.g. a in the example above), and d together and transforms a against a’) are actually server acknowledgements
it must wait on sending b until the the result, producing a’. of our currently-pending operation. Once
server acknowledges a. This is necessary we receive this acknowledgement, we
because the client needs to somehow can flush the client buffer and send the
translate b into server state space, but pending operations up to the server.
it can’t just “undo” the fact that b is Moving forward with our example,
parented on a. Thus, wherever b eventu- let’s say that the client receives opera-
ally ends up in server state space, it has tion c from the server. Since c is already
to be a descendant of a’, which is the parented on a version in our local
server-transformed version of a. Literally, history, we can apply simple OT to
we don’t know where to translate b into transform it against the composition of a
until we know exactly where a fits in the and b and apply the resulting operation
server’s history. to our local document:
To help shed some light into this
rather confusing scheme, let’s look at an After applying a’, the server broad-
example: casts the operation to all clients, including
the one which originated the operation.
This is a very important design feature:
whenever the server applies a trans-
formed operation, it sends that operation
off to all of its clients without delay. As
long as we can guarantee strong ordering
In this situation, the client has in the communication channels between
performed two operations, a and b. The the client and the server (and often we
client immediately sends operation a to can), the clients will be able to count on
the server and buffers operation b for the fact that they will receive operations
later transmission (the lighter blue line from the server in exactly the order in
indicates the buffer boundary). Note which the server applied them. Thus,
that this buffering in no way hinders the they will be able to maintain a locally-
application of local operations. When the inferred copy of the server’s history.
user presses a key, we want the editor to This also means that our client is going
reflect that change immediately, regard- to receive a’ from the server just like
less of the buffer state. Meanwhile, the any other operation. In order to avoid
server has applied two other operations, treating our own transformed operations
c and d, which presumably come from as if they were new server operations, we
other clients. The server still hasn’t need some way of identifying our own
received our operation a. operations and treating them specially. To

48  PROGRAMMING
Of course, as we always need to keep Once we have this operation (whatever Building the Bridge
in mind, the client is a live editor which it is), we can compose it with e and get We can maintain this bridge by compos-
presumably has a real person typing a single operation against which we can ing together all operations which have
madly away, changing the document transform d. been synthesized locally since the point
state. There’s nothing to prevent the where we diverged from the server. Thus,
client from creating another operation, at first, the bridge consists only of a. Soon
parented off of c’ which pushes it even afterward, the client applies its next
further out of sync with the server: operation, b, which we compose into the
bridge. Of course, we inevitably receive
an operation from the server, in this case,
c. At this point, we use our bridge to
transform c immediately to the correct
point in client state space, resulting in
c’. Remember that OT derives both
bottom sides of the diamond. Thus, we
not only receive c’, but we also receive a
new bridge which has been transformed
The first thing to recognize is that the against c. This new bridge is precisely the
inferred bridge (the green dashed line) green dashed line in our diagram above.
is going to be composed exclusively of Meanwhile, the client has performed
client operations. This is logical as we are another operation, e. Just as before, we
This is really getting to be a bit of attempting to translate a server opera- immediately compose this operation
a mess! We’ve only sent one of our tion, so there’s no need to transform onto the bridge. Thanks to our bit of
operations to the server, we’re trying to it against something which the server trickery when transforming c into c’, we
buffer the rest, but the server is trickling already has. The second thing to realize can rest assured that this composition
in more operations to confuse things and is that this bridge is traversing a line will be successful. In other words, we
we still haven’t received the acknowl- parallel to the composition of a and b, know that the result of applying the
edgement for our very first operation! As just “shifted down” exactly one step. To bridge to the document resulting from
it turns out, this is the most complicated be precise, the bridge is what we would c will be precisely the document state
case which can ever arise in a Wave-style get if we composed a and b and then before applying e, thus we can cleanly
collaborative editor. If we can nail this transformed the result against c. compose e with the bridge.
one, we’re good to go. Now, we could try to detect this case Finally, we receive d from the server.
The first thing we need to do is figure specifically and write some code which Just as with c, we can immediately
out what to do with d. We’re going to would fish out a and b, compose them transform d against the bridge, deriving
receive that operation before we receive together, transform the result against c, both d’ (which we apply to our local
a’, and so we really need to figure out compose the result of that with e and document) as well as the new bridge,
how to apply it to our local document. finally transform d against the final prod- which we hold onto for future server
Once again, the problem is that the uct, but as you can imagine, it would be a translations.
incoming operation (d) is not parented mess. More than that, it would be dread-
off of any point in our state space, so OT fully inefficient. No, what we want to do
can’t help us directly. Just as with b in is proactively maintain a bridge which
our fundamental compound OT example will always take us from the absolute
from earlier, we need to infer a “bridge” latest point in server state space (that
between server state space and client we know of) to the absolute latest point
state space. We can then use this bridge to in client state space. Thus, whenever we
transform d and slide it all the way down receive a new operation from the server,
into position at the end of our history. we can directly transform it against this
To do this, we need to identify con- bridge without any extra effort.
ceptually what operation(s) would take
us from the parent of d to the the most
recent point in our history (after apply-
ing e). Specifically, we need to infer the
green dashed line in the diagram below.

  49
With d’ now in hand, the next opera- c, which comes from the server. At this Checkpoint time! The client has
tion we will receive from the server will point, we must somehow transform the performed operation a, which it sent
be a’, the transformed version of our buffer with respect to the incoming to the server. It then performed opera-
a operation from earlier. As soon as we server operation. However, obviously the tion b, received operation c and finally
receive this operation, we need to com- server operation (c) is not parented off of performed operation e. We have an
pose together any operations which have the same point as our buffer (currently operation, a” which will be equivalent to
been held in the buffer and send them b). Thus, we must first transform c against a’ if the server has no other intervening
off to the server. However, before we a to derive an intermediary operation, c”, operations. We also have a buffer which
send this buffer, we need to make sure which is parented off of the parent of the is the composition of a transformed b and
that it is parented off of some point in buffer (b): e. This buffer, composed with a”, serves
server state space. And as you can see by as a bridge from the very latest point in
the diagram above, we’re going to have server state space (that we know of) to
troubles both in composing b and e (since the very latest point in client state space.
e does not descend directly from b) and Now is when we receive the next
in guaranteeing server parentage (since b operation from the server, d. Just as when
is parented off of a point in client state we received c, we start by transforming it
space not shared with the server). against a” (our “in flight” operation). The
To solve this problem, we need to resulting transformation of a” becomes
play the same trick with our buffer as we our new in flight operation, while the
previously played with the translation resulting transformation of d is in turn
bridge: any time the client or the server used to transform our buffer down
does anything, we adjust the buffer another step. At this point, we have a
accordingly. With the bridge, our invari- new a” which is parented off of d and
ant was that the bridge would always a newly-transformed buffer which is
be parented off of a point in server state parented off of a”.
space and would be the one operation Once we have this inferred operation, Finally, we receive a’ from the server.
needed to transform incoming server c”, we can use it to transform the buffer We could do a bit of verification now to
operations. With the buffer, the invariant (b) “down” one step. When we derive c”, ensure that a” really is equivalent to a’,
must be that the buffer is always par- we also derive a transformed version of a, but it’s not necessary. What we do need to
ented off of a point in server state space which is a”. In essence, we are anticipat- do is take our buffer and send it up to the
and will be the one operation required ing the operation which the server will server. Remember, the buffer is parented
to bring the server into perfect sync with derive when it transforms a against its off of a”, which happens to be equivalent
the client (given the operations we have local history. The idea is that when we to a’. Thus, when we send the buffer, we
received from the server thus far). finally do receive the real a’, it should be know that it is parented off of a point in
The one wrinkle in this plan is the fact exactly equivalent to our inferred a”. server state space. The server will eventu-
that the buffer cannot contain the opera- At this point, the client performs ally acknowledge the receipt of our buffer
tion which we have already sent to the another operation, e, which we operation, and we will (finally) converge
server (in this case, a). Thus, the buffer immediately compose into the buffer to a shared document state:
isn’t really going to be parented off of (remember, we also composed it into
server state space until we receive a’, at the bridge, so we’ve got several things
which point we should have adjusted the going on here). This composition works
buffer so that it is parented precisely on because we already transformed the
a’, which we now know to be in server buffer (b) against the intervening server
state space. operation (c). So e is parented off of c’,
Building the buffer is a fairly straight- which is the same state as we get were
forward matter. Once the client sends a we to apply a” and then the buffer to the
to the server, it goes into a state where server state resulting from c. This should
any further local operations will be sound familiar. By a strange coincidence,
composed into the buffer (which is a” composed with the buffer is precisely
initially empty). After a, the next client equivalent to the bridge. In practice, we
operation which is performed is b, which use this fact to only maintain one set of
becomes the first operation composed data, but the process is a little easier to
into the buffer. The next operation is explain when we keep them separate.

50  PROGRAMMING
The good news is that, as I mentioned Resources
before, this was the most complicated • To obtain Google’s OT library, you must take a Mercurial clone of the wave-
case that a collaborative editor client ever protocol repository:
needs to handle. It should be clear that
no matter how many additional server $ hg clone https://wave-protocol.googlecode.com/hg/ wave-protocol
operations we receive, or how many more
client operations are performed, we can • Once you have the source, you should be able to build everything you need by
simply handle them within this general simply running the Ant build script. The main OT classes are
framework of buffering and bridging. And, org.waveprotocol.wave.model.document.operation.algorithm.Composer and
as when we sent the a operation, sending org.waveprotocol.wave.model.document.operation.algorithm.Transformer.
the buffer puts the client back into buffer Their use is exactly as described in this article. Please note that Transformer does
mode with any new client operations not handle compound OT, you will have to implement that yourself by using
being composed into this buffer. In prac- Composer and Transformer. Operations are represented by the
tice, an actively-editing client will spend org.waveprotocol.wave.model.document.operation.DocOp interface, and can be
most of its time in this state: very much converted into the more useful org.waveprotocol.wave.model.document.operation.
out of sync with the server, but maintain- BufferedDocOp implementation by using the
ing the inferred operations required to get org.waveprotocol.wave.model.document.operation.impl.DocOpUtil.buffer method.
things back together again.
All of these classes can be found in the fedone-api-0.2.jar file.
Conclusion
The OT scheme presented in this article • Google’s Own Whitepaper on OT: http://www.waveprotocol.org/whitepapers/
is precisely what we use on Novell operational-transform
Pulse. And while I’ve never seen Wave’s • The original paper on the Jupiter system (the primary theoretical basis for Google’s
client code, numerous little hints in the OT): http://doi.acm.org/10.1145/215585.215706
waveprotocol.org whitepapers as well • Wikipedia’s article on operational transformation (surprisingly informative): http://
as discussions with the Wave API team en.wikipedia.org/wiki/Operational_transformation
cause me to strongly suspect that this is
how Google does it as well. What’s more, Daniel Spiewak is a software developer based out of Wisconsin, USA. Over the years, he has worked
Google Docs recently revamped their with Java, Scala, Ruby, C/C++, ML, Clojure and several experimental languages. He currently spends
word processing application with a new most of his free time researching parser theory and methodologies, particularly areas where the field
editor based on operational transforma- intersects with functional language design, domain-specific languages and type theory.
tion. While there hasn’t been any word Daniel regularly writes articles on his weblog, Code Commit (www.codecommit.com), including his
from Google on how exactly they handle popular introductory series, Scala for Java Refugees.
“compound OT” cases within Docs, it
looks like they followed the same route
as Wave and Pulse (the tell-tale sign is
a perceptible “chunking” of incoming
remote operations during connection lag).
None of the information presented
in this article on “compound OT” is
available within Google’s documentation
on waveprotocol.org (unfortunately).
Anyone attempting to implement a
collaborative editor based on Wave’s OT
would have to rediscover all of these
steps on their own. My hope is that this
article rectifies that situation. To the
best of my knowledge, the information
presented here should be everything you
need to build your own client/server
collaborative editor based on operational
transformation. So, no more excuses for
second-rate collaboration! n
Reprinted with permission of the original author. First appeared in http://hn.my/ot/.

  51
Photo: João Trindade, http://www.flickr.com/photos/joao_trindade/4363154158/.
Licensed under Creative Commons Attribution 2.0 Generic licence. Full terms available at http://creativecommons.org/licenses/by/2.0/deed.en.

52  PROGRAMMING
Math Library Functions
That Seem Unnecessary By John D. Cook

T his post will give several


examples of functions include
in the standard C math library
that seem unnecessary at first glance.
to a large number, then the relative error
in the answer doesn’t matter. But if you
multiply the result by a large number,
your large relative error becomes a large
absolute error as well.
some values of x, yes, this is true. But if
x is large, erf(x) is near 1, and the code
1 - erf(x) may return 0 when the result
should be small but positive. As in the
examples above, the naïve implementa-
Function log1p(x) = log(1 + x) tion results in a complete loss of preci-
The function log1p computes log(1 + x). Function expm1(x) = exp(x) – 1 sion for some values and a partial loss of
How hard could this be to implement? Another function that may seem unnec- precision for other values.
essary is expm1. This function computes
log(1 + x); ex – 1. Why not just write this? Functions Γ(x) and log Γ(x)
The standard C math library has two
Done. exp(x) - 1.0; functions related to the gamma func-
But wait. What if x is very small? If x tion: tgamma that returns Γ(x) and lgamma
is 10-16, for example, then on a typical That’s fine for moderately large x. For that return log Γ(x). Why have both?
system 1 + x = 1 because machine preci- very small values of x, exp(x) is close to Why can’t the latter just use the log of
sion does not contain enough significant 1, maybe so close to 1 that it actually the former? The gamma function grows
bits to distinguish 1 + x from 1. (For equals 1 to machine precision. In that extremely quickly. For moderately large
details, see Anatomy of a floating point case, the code exp(x) - 1 will return arguments, its value exceeds the capacity
number.) That means that the code 0 and result in 100% relative error. As of a computer number. Sometimes you
log(1 + x) would first compute 1 + before, for slightly larger values of x the need these astronomically large numbers
x, obtain 1, then compute log(1), and naïve code will not be entirely inaccurate, as intermediate results. Maybe you need
return 0. But log(1 + 10-16) ≈ 10-16. This but it may be less accurate than needed. a moderate-sized number that is the ratio
means the absolute error is about 10-16 The solution is to compute exp(x) - 1 of two very large numbers. In such cases,
and the relative error is 100%. For values directly without first computing exp(x). you need to subtract lgamma values rather
of x larger than 10-16 but still fairly small, The Taylor series for exp(x) is 1 + x + than take the ratio of tgamma values.
the code log(1 + x) may not be com- x2/2 … So for very small x, we could just
pletely inaccurate, but the relative error return x for exp(x) – 1. Or for slightly Conclusion
may still be unacceptably large. larger x, we could return x + x2/2. The standard C math library distills a lot
Fortunately, this is an easy problem of experience. Some of the functions may
to fix. For small x, log(1 + x) is approxi- Functions erf(x) and erfc(x) seem unnecessary, and so they are for
mately x. So for very small arguments, The C math library contains a pair of some arguments. But for other arguments
just return x. For larger arguments, functions erf and erfc. The “c” stands these functions are indispensable. n
compute log(1 + x) directly. for “complement” because erfc(x) =
Why does this matter? The absolute 1 – erf(x). The function erf(x) is known John D. Cook is an applied mathematician. He
error is small, even if the code returns as the error function and is not trivial lives in Houston, Texas where he works for M. D.
a zero for a non-zero answer. Isn’t that to implement. But why have a separate Anderson Cancer Center. His interests include
OK? Well, it might be. It depends on routine for erfc? Isn’t it trivial to imple- numerical analysis and Bayesian statistics.
what you do next. If you add the result ment once you have code for erf? For

Reprinted with permission of the original author. First appeared in http://hn.my/math/.

  53
TECH JOBS

Ruby/Rails Engineer Systems Administrator apps is great but not required, Senior Systems
Backupify (http://backupify.com) Berklee College of Music an eye for great design and Architect
Cambridge Mass (exceptional (http://www.berkleemusic.com) user experiences, and ability MySpace (http://www.myspace.com)
candidates may work remotely) Back Bay, Boston, MA to communicate within a Beverly Hills
We’re looking for kick ass, Berklee College of Music’s close-knit team. The Systems group is looking
agile friendly, Hacker News online extension school is To Apply: Email jobs@bu.mp. for a hacker architect. You
reading, Rails developers who looking for a sysadmin to join have autonomy to do awe-
are passionate about coding, their Operations team to sup- some things. Your C#/C/
not afraid of the command port our server infrastructure. Software Engineer C++ is masterful, but you
line, and love working with Position requires knowledge XIA LLC (http://www.xia.com) use Ruby/Powershell/Python
emerging technologies. of Linux, Amazon AWS, stor- Bay Area where it makes sense. Same
Backupify is venture-funded age systems and deployment We make processing electron- goes for assembly. You are
and you’ll enjoy working on of high availability websites. ics for x-ray and gamma-ray equally comfortable in front
a loaded MacBook Pro with a Off-hours support required. detectors and our software of a whiteboard or windbg/
solid team. This is a full-time To Apply: Send resume controls precision instru- gdb. Flexible hours, good pay
position. and cover letter to ments. Things we like: C, and free food. Will relocate.
To Apply: Send links of past work@berkleemusic.com. C#, F#, Ruby, Lisps, Emacs, To Apply: 6362656c6c406d797
projects to jobs@backupify.com. hg, flexible work hours and 3706163652d696e632e636f6d
Hacker News. Don’t get
Security Researcher too hung up on the specific
Software Engineer Harris Corp – Crucial Security languages: we are looking for Awesome Java
ExtraHop Networks Programs (http://www.harris.com/csp) skilled developers and are Developer
(http://www.extrahop.com) Various/US always open to using new Dubit Limited
Seattle Security Researcher: User languages in our projects. (http://dubitplatform.com)
About You: You’re a good & kernel-mode C/C++ x86 To Apply: Resume and cover Leeds, Yorkshire, United Kingdom
programmer. You’re skilled assembly, reverse engineering, letter to jobs@xia.com. We’re looking for a multi-pur-
or interested in some or all debugging, & os internals; pose, penknife of a developer,
of the following: networking, automated executable analy- who can handle maintaining
systems programming, C sis, virtualization, emulation C++ or Java Developer our server side technology and
programming, Python pro- engines; pen testing; research; Capital Markets Placement integrate it with our Flex front
gramming, UI/UX design, and low-level SW protection (http://www.CMP.jobs) end. You’ll need to be experi-
problem solving. You enjoy a methods & executable New York, Chicago and enced in Java, with a comput-
startup environment, which dissection algorithms; writing Washington, DC ing related degree, and you’ll
means getting things done, for highly technical audience; Several investment banks, need to know what wait/notify
not being specialized, and not security components & debug one hedge fund, one pub- are for too. Any experience
attending many meetings. tools; malware, rootkits, pro- lishing and one interactive with socket programming or
To Apply: Please send us an tection schemes, & virtualiza- client company. Hiring very servlets is a plus.
email at jobs@extrahop.com. tion theory; Clearable. actively C++ or Java develop- To Apply: Send your CV and
To Apply: ers. C++ positions paying covering letter to
kirsten.renner@harris.com. $100-$250k base, depending thomas.williams@dubitlimited.com.
PHP Developer on background and in lieu
Altruja GmbH (http://www.altruja.de) with prior compensation
Munich, Germany Android Developer numbers, for example trading
We are looking for a PHP Bump Technologies, Inc. systems will be compensated
Developer, who should have (http://bu.mp) to the max. For Java $90-
experience developing Web- Mountain View, CA 140k, with Spring/Hibernate
Applications (LAMP, MVC, Design and build the next and Javascript.
Symfony). Knowledge of generation of Bump's Android To Apply: Either apply
(X)HTML/CSS/JS would be app and API. Requirements: directly through website or
good, too. We’re a Start-Up with Expert in Java (Python and contact boris@cmp.jobs with a
funding and offer a nice work C/C++/Obj-C are a plus), resume or questions.
environment and a great team. experience developing native
To Apply: jobs@altruja.de. Android apps or other mobile

54  TECH JOBS


Linux Systems Sr. Java Software Freelance Front End Senior Software
Administrator Engineer Web Developer Engineer
Simply Hired Clearspring Technologies Butchershop Creative Democratic National Commit-
(http://www.simplyhired.com) (http://www.clearspring.com) (http://butchershopcreative.com) tee/Organizing for America
Mountain View, CA McLean, VA San Francisco, CA (http://www.barackobama.com)
Simply Hired is seeking a We’re looking for an Butchershop, a San Francisco Washington, DC
great Linux Sys Admin to extremely talented engineer marketing and creative agency The Democratic National
help take our production to help us tackle some of is looking for an imaginative, Committee is seeking a
environment to the next the largest-scale data pro- innovative, visual, organized, talented software engineer
level of stability, scalability, cessing challenges around. self-motivated individual to empower communities
automation, and transparency. Clearspring’s tools are seen to help with the following: across the country. The Senior
Experience in high scale web by over 1 billion people Design, Color, Typography, Software Engineer will build
site operations; Linux/Unix / across the web every month. Composition, Illustration, UI/ and maintain a variety of
open-source, Perl or Python; From that data, you’ll be UX, HTML, CSS, JavaScript. open, scalable web services
x86 servers, switches, routers; unraveling the mysteries of Bonus if you have used that will be critical pieces of
LAMP/Java/open-source web-wide social behavior and Python or PHP. party infrastructure.
stacks. delivering powerful insights To Apply: Email To Apply: Email
To Apply: to publishers. info@butchershopcreative.com. techresume@dnc.org.
http://hn.my/simplyhired To Apply: jobs@clearspring.com.

Senior Developer Senior Software


UI and Software Freelance Cake Baker youDevise, Ltd. Engineer
Engineers FlickEvents (https://dev.youdevise.com) F5 Networks (http://www.f5.com)
Meetup (http://www.meetup.com) (http://www.flickevents.com) London, England Seattle
New York, NY (Soho) Internet or Singapore 60-person agile financial Interested in taking your
Meetup is fast-growing, FlickEvents is a startup in software company in London software engineering career to
venture capital-backed, just- Singapore that focuses on committed to learning and the next level? Ever wonder
turned-profitable + a great tools that make life easier quality (dojos, TDD, continu- what 100 Gb/s of TCP traffic
place for top talent to do for event organizers, and to ous integration, exploratory looks like? In GDB? We are
their best work. We’re hiring make this tradtionally boring testing). Under 10 revenue- looking for top engineers with
exceptional engineers (QA, industry a little bit more affecting production bugs last system-level C, networking,
UI, Software & Systems) with bearable. We are looking for year. Release every 2 weeks. protocol and kernel exper-
web experience to work on a a freelance developer who Mainly Java, also Groovy, tise. Join our team of super
product that’s already helped does CakePHP 1.2 and above, Scala; no prior knowledge of smart engineers working in
millions of people find + build and who understands design any language needed. a fun and fast-paced highly
local community worldwide. patterns, SimpleTest or TDD To Apply: Send CV to technical environment where
To Apply: practices, and Git. jobs@youdevise.com. your ideas become part of the
http://www.meetup.com/jobs To Apply: job@flickevents.com. solution!
To Apply: http://hn.my/f5

To post a job:

http://hn.my/jobs/ $59
Hacker Monthly is an independent project by Netizens Media and not affiliated with Y Combinator in any way.

Tell us what you think


Let us know what you liked, and what we need to work on.
Please share your thoughts so we can improve the coming issues.
hackermonthly.com/feedback/

Das könnte Ihnen auch gefallen