The Calculus of Risk

The other day a nice gentleman who had a hold of my business card contacted me with an idea for a web site that he wanted me to help develop and run. He thought it could be the next Craig’s list or the like: and while the idea was an interesting one, I told him that I wasn’t interested in working on a web site.

I’m sick of web site development. If my time at Yahoo! has taught me anything, it’s that web site development sucks. Or rather, the “constant iteration” that Yahoo! practices and that I’ve read elsewhere about how web sites “should” be developed sucks, as “constant iteration” really translates (at least at Yahoo!) to “management can’t get its shit together and plan things in a reasonable way, so you’re expected to constantly be on call because no-one can plan more than 15 minutes in advance.” I don’t mind “plans are subject to change without notice because of new information that came in during execution.” I do mind “we changed our minds because we have no clue what we’re doing.” Especially when events were easily foreseen.

But I digress.

Part of what I tried to convey to this person is my own take on how I would evaluate the risk/reward of my getting involved in a new project–and that, mathematically speaking, for me to get involved in a project like his would be expensive. And I mean “oh, shit, you’re kidding!” sorts of expensive.

So let me break down my own thinking about money–and let’s put some numbers to this, shall we?

I’m a software developer with 20 years of professional experience, and I think I’m one of the best programmers out there. (Do I have an ego? Probably. But it doesn’t change the numbers.)

Let’s assume my salary is around $150,000/year. Probably not far off for someone with 20 years of professional experience in Los Angeles, when you factor in bonuses and stock options and the like.

Okay, now say I’m going freelance. Well, when you add in corporate social security matching (which is really just a hidden tax), insurance, unemployment and the like–you need to add another 25% to that number. So this brings the amount to $200,000/year. That is what I would have to bring in as a freelancer in order to match my salary.

Now lets assume I’m freelancing. (And I used to freelance, so I can attest to the following numbers.) If I’m doing real well, I should expect only about 60% of my time to be billable time. Why? Well, I’ll want to spend some time on vacation–four weeks a year cuts the number of billable hours by almost 10%. And the rest of my time will be spent searching for more freelance work–since, really, the reward of a job well done is being patted on the back and shown the door.

This translates into a base hourly rate of $200k/1200hrs or $160/hr.

Suppose I want to put together a web site for someone as an investment. Say it will take six months to assemble the web site. Well, the amount I would charge to do this as a consultant is easy: $160 * 24 weeks * 40 hours/week = $153,600.

Now this is where things get interesting. Suppose, for example, that you want me to build this web site for you, but you want me to do it at a discount in exchange for a share of the resulting internet company. So suppose you want me to build the web site for (say) $50,000. This means that I have, in effect, invested $103,600 to your project. Now suppose it takes 3 years for the company to develop, and after my initial investment in time I have no involvement at all in the company–and after 3 years, there is a 1 in 20 chance that the company will become “successful”–that is, you’ll convince Yahoo! to buy you out.

What should my return on this be?

Well, that’s simple. Currently T-Bills are getting about 5%/year. So if I were to have taken my $103,600 and instead put it into T-Bills, that would have grown to about $120,000. (The reason why I’m using T-Bills is because there is zero risk to that investment. In other words, I’m not interested in what I may be able to get for that $103,600–I’m interested in what I would get if I had taken no risk. Because any return above that amount would involve some risk–and any return below that amount means either my risk didn’t pan out or I’m an idiot.)

Using Bayesian math I can say that if my risk is 1/20 that I will get a payout and 19/20 that I won’t, then the potential reward that I would have to receive for taking a risk that 19 out of 20 times your web site will not return anything would be $120,000 * 20 or $2.4 million.

In other words, if I don’t see an upside of $2.4 million on my six months of work if there is only a 1 in 20 chance of success, I’m better off on the average keeping my day job. And, more importantly, this is the “break even” point for a web site that only has a 1 in 20 chance of success–in order to motivate me, I should receive more. In other words, we can work this math backwards–and when we do so, every $100,000 in potential reward 3 years from now is only worth around $4300 today. So if you entice me with a potential $3 million reward in 3 years–and remember, this is assuming that I am not involved at all for the 2 and a half years between completing my work and the ultimate payout; if I’m involved, this number can go up dramatically–that would be the same as if I swapped jobs and got a 15% pay raise.

Why such a large number? Because there is risk involved. And for every success story we heard about in Silicon Valley, there are dozens who found themselves screwed one way or another. It’s easy to concentrate on the successes, but we ignore the failures–after all, we think we won’t fail; we’re smarter than everyone else. In mathematical terms, we think the chances of success is like 1 in 2 or 1 in 3–not 1 in 20. Thus, we misestimate the potential for downside. We also fail to properly estimate what we are worth–that is, how much we could make if we took no risks–which is why in many cases I’ve seen people walking away having negotiated a present-value contract that earns them less than minimum wage: out of their ignorance they put themselves in a worse position than if they’d went to flip hamburgers part-time at McDonald’s.

Now me, I will factor in my abilities–and I know that I can reduce the probability of failure simply because for many companies, they fail simply because they fail to release a product. Millions in invested money later and all they have to show for it is a roughly written demo and the PowerPoint they gave the venture capitalists. So I may internally tweak the numbers: for me, it may be 1 in 15 chance of success. And of course there are more outcomes than “jackpot!” and “failure”, and sometimes even failure gets us where we want to go. After all, very few businessmen succeeded the first time out.

But ultimately this is the mathematical analysis I will apply if someone asks me to quit my day job to put together their web site. Of course the salary numbers are just numbers I pulled out of my ass–and I may factor in other intangibles, such as the potential upside in the event of failure. But don’t be surprised if I don’t quit my day job at Yahoo! simply because you think you have the next great idea and want to cut me in for 10% of your ten million-dollar idea.

(Note: The numbers above have been changed to protect the innocent. No numbers were harmed in the writing of this essay. Your mileage may vary.)

Cool.

One of the things that makes me happy about my alma matter is that they do not award honorary degrees. The highest award given is the “Distinguished Alumni” award, which, naturally enough, only go to alumni.

At some point I’ve realized that the best professional social circles revolve around one’s alma matter–and given that they’re just down the street from me, there is no reason for me not to get involved.

Heh.

Two used G4-based Mac Minis: $550.
One 17″ monitor: $180
Cheap keyboard and mouse: $30
Two resistors to enable the G4s to run headless: $1.90 (for two packs, one at 270ohms, one at 120ohms).

Instant testbed environment to permit simultaneous debugging MacOS X software for v10.3, v10.4 and v10.5 compatibility: Priceless.

Frustration.

One of the must frustrating things in the world is having what you believe is a brilliant idea for a startup company and a strong drive to create a startup–yet having no-one you know who you think you can approach to go in with such a project.

Bah!

Computer Languages and Entry Points

Every computer language has what I would call an “entry point”: a set of things which you need to ‘grok’ in order to understand that computer language. They’re fundamental assumptions made about the shape of the universe which is just “off” enough that you’ll forever be confused if you don’t get them. (Or at least they’re things that confused me until I got them.)

Here are a few languages I spent time learning and the ‘pivot points’ around those languages.

LISP
* It’s all about recursion. Learn to live by, and love, recursion.
* Because there is no real natural ‘syntax’ per se, pick a ‘pretty print’ style and stick with it.
* There is no such thing as a single “program”; applications just sort of ‘jell’. This is unlike C or Pascal programs, which definitely have a beginning, middle, and end to development. (This fact made me wonder why, besides Paul Graham, no-one used LISP for web development.)

Pascal and C
* The heap is your friend. Understand it, appreciate it, love it.
* The heap is your enemy; it is a mechanism designed to kill your program at every opportunity if given a chance.

C++
* Objects are your friends. Instead of telling the program the steps to accomplish something, you describe the objects which are doing things. To someone who is used to thinking procedurally, this is a really fantastic brain fuck.
* While a->foo() looks like a pointer to a method, it is really a reference to a vtable which happens to hold a pointer to a method with an invisible argument. If you’re used to thinking about C as a glorified portable assembly language (and can even remember which form of a++ for a pointer a translates into a single assembly instruction on a 680×0 processor), vtables help bridge the gap from “talking to bare metal” to “abstract object oriented programming.”
* Resource Acquisition Is Initialization.

Java
* The package hierarchy is like a parallel “code-space” file system.
* When learning Java, also learn the run-time library. Love it or hate it, but you should first learn the java.lang package, followed by java.util, java.io, and then java.net. All the rest is icing.

Objective C
* Learn to love the Smalltalk-like syntax. For someone who cut their eye-teeth on LISP, C++ and Java, the Smalltalk-like syntax leaves you wondering what to call a method; after all, every language except Smalltalk has just one name for a function and like any good language based on math, the name prefixes the parameters. Not Smalltalk, nor Objective-C.
* If you cut your eye-teeth on the rules for addRef()/release() in Microsoft’s COM environment, the retain/release rules are fucking odd. With Microsoft, the rule was simple: if something hands you a pointer to an object, you own it; you release it. If you pass a pointer to an object, you must increment the reference count on the object because you pass the object means you’re passing ownership.

Not Objective C, which in adding ‘autorelease’ has made the rules a little bit more complicated. Now the rules seem to be:

(1) If you are handed a pointer to an object, you must explicitly retain it if you are holding it.
(2) If you pass an object to another object, it will retain it, so you need to do nothing.
(3) If you create an object out of thin air, you own it–and if you don’t need to hold it, you must autorelease it so it gets released.

Now (3) gets real tricky: basically, there is a naming convention which tells you if you ‘created an object out of thin air.’ Basically, if the name of the method you called starts with ‘alloc’ or ‘new’ or contains the word ‘copy’, you own it, and you have to let it go with autorelease. (Why not ‘release’ instead? Because ‘release’ causes it to go away now, while autorelease causes it to go away “eventually.”)

I long for the simplicity of COM, even though it creates additional verbage in your code. Though I’d much rather have the garbage collection of Java or LISP: just drop the damned thing, and it’ll go away on its own.

Multi-threaded programming

While not strictly a language, it does impose its own rules on the universe, and there are a few key things to ‘grok’ to get it:

* There really are only a few “safe” design models for building multi-threaded code. You have thread pools, single-threaded event pumps, and re-entrant data structures (which can be as simple as using a semaphore to grant exclusive access to as complicated as using read/write locks on a complex data structure)–and that’s it. In other words, you either have units of work which can be isolated into a single object and worked in parallel (because they’re unrelated)–good for a thread pool–or you have a process (such as a user interface) where you shove all your parallelism into a queue which is operated on in a single thread (as is done in most UI libraries), or you have a specialized case where you have a re-entrant data structure which was designed from the ground up to be multi-thread ready.

And that’s it.

Anything else is a bug waiting to be discovered.

* If you need to create a re-entrant data structure that is more complicated than a semaphore-protected object, you really really need to remember to avoid deadlocks by making sure you use a consistent locking order.

* Oh, and it is quite helpful to create a semaphore object or a locking object wrapper, for testing purposes, which times out (and fails noisily) after some set period, such as five minutes. Preferably blowing up by killing all threads waiting on this object with a complete stack trace.

Internet Development verses Product Development

I used to think developing for the Internet would be no different than any other sort of product development: there would be some sort of software methodology used to write products, which would ship on a given timetable, with features reduced and a complete QA cycle done prior to releasing a product. The only difference here is what “product release” means: for an Internet company it means uploading your software to a server or bank of servers, while for product development it means pressing a CD master and sending it off for duplication.

In many ways I thought Internet development would be easier than Product development: you only have to make sure your software works on one server rather than thousands (or millions) of individual computers, each with their own quirks and oddities. And while various operating systems go out of their way to help isolate your product from other software running on the same system, various ‘hacks’ tend to burrow into the operating system, creating unpredictable features which may or may not break whatever API you are using.

What I didn’t appreciate is how different Internet development is to Product development.

At first I thought that somehow management where I work was screwed up: everyone was all into “agile” development (as opposed to “waterfall” where I worked before)–and their implementation of “agile” seemed to borrow all the worst elements without any of the benefits. (Waterfall is also a silly methodology, but at least it implied forcing everyone to a similar timetable so different teams didn’t stomp arbitrarily over other teams, as seems to be the case here.) But now I’m realizing that two features of the Internet make the risk/reward equation such a completely different animal that, aside from the fact that you write code and test it, Internet development and Product development share damned near nothing in common.

The first factor is the fact that you only push your software on one computer, a computer you own. This means that it is possible to push incremental improvements damned near daily.

Yeah, various software update panels (Symantec’s LiveUpdate, Apple’s Software Update panel, Microsoft’s Windows Updater) allow your company to push patches out to your customers. But at best this is a mechanism that can be used quarterly: because you are pushing software to potentially millions of computers, you really only have one chance to get it right, and that sort of testing takes time. And even then, you still run a risk of screwing it up, as Microsoft learned with it’s latest Vista patch.

But if your target system is just one server, a server that you own and control–well, the natural risk to pushing software out is significantly lowered. Sure, large Internet companies put arbitrary barriers to pushing out patches outside of the normal delivery cycle (where I now work, there is a committee which approves such things), because even where I work there is at most 8 server locations with two boxes each, it’s not the same as pushing software down LiveUpdate.

And that leads to the second difference, which puts incredible pressure on extremely short delivery cycles: software bugs are easier to fix and push out to production.

Because the cost of delivering a fix is extremely low (relative to a product update), the threshold for what constitutes an emergency requiring everyone to drop everything and push out a fix is lowered–and thus everything becomes an emergency. And, likewise, because everything is an emergency and fixing it in production is easier, there is pressure to (a) shorten the development cycle, and (b) less pressure to think through a problem to make sure the solution being implemented is the correct one.

In the systems I’ve worked on, the code quality is (from my perspective, with four and a half years creating products and another 9 years consulting) complete crap: there are places where deadlocks are just patched over, and fundamental flaws are ignored. One system I’ve done some work on desperately needs a complete rewrite, and other systems I’ve seen I’d never in a million years engineer that way.

And while it’s easy to chalk these things up to incompetence, I’ve realized that the economics of an Internet company forces these sorts of shortcuts: experiment, get something out the door, and move on–and if it breaks, take a couple of days and upload a fix. We don’t get six months or even six weeks to think through a problem–fix it in six days or else you’re too slow.

I don’t think I like working for an Internet company.

Sadly, what worries me more is that the attitudes people are learning at Internet companies are being brought over to Product companies–and rather than think through problems these new generation of software developers are slapping crap together because they’re more used to a two-week development cycle than a six month development cycle. And God help us if critical software systems (or, for that matter, consumer electronics) are developed on Internet time!

May you live in interesting times and come to the attention of people in power.

Microsoft makes a bid to acquire Yahoo!.

Ballmer’s letter to Yahoo: We want you
Ballmer’s memo to his troops

Which, in a way, is irritating to me: I had planned to write a very long post about the sorts of questions one should ask when one is interviewing at a company–which was going to include a bunch of snide remarks about the hand that is currently feeding me. (Things like asking managers you’re talking to about their plans to promote from within, the types of software methodologies they use–and what to watch out for.) But today: um, I like my paycheck. And the announcement means anyone connected to the purple Y! will probably be receiving extra scrutiny.

Including idiots with tiny little no-nothing blogs like me.

Happy.

I find that I’m spending more and more of my time studying computational algebra, which makes me incredibly happy. When I was a student at Caltech I took an abstract algebra class–which I did miserably at, because the material was presented without motivation. Computational algebra has the advantage of covering much of the same material I didn’t get the first time around–but this time, with a motivating reason which allows me to actually have a model for what the different types of objects really represent.

As a side note, I find it extremely interesting how much a background in object-oriented programming helps in understanding group theory. In a way, a group, a ring and a field are all essentially like interfaces: declarations of objects and operators which observe certain well-defined properties, but with different types of objects that can be plugged into our operators. For example, we could define a ‘group’ as a set of objects and an operator:

template class Group
{
	public:
		virtual Element add(Element, Element) = 0;
};

Then the Group Z of integers is:

class Integer: public Group
{
	public:
		inline int add(int a, int b)
		{
			return a+b;
		}
};

And the group ZN of integers from 0 to N-1 (which represents a finite integral group) could be represented by:

class IntegerN: public Group
{
	public:
		IntegerN(int m)
		{
			fModulo = m;
		}
	
		inline int add(int a, int b)
		{
			return (a+b)%fModulo;
		}
	private:
		int fModulo;
};

Why the Sony Connect Failed.

Simple: no content.

The technical offerings by Sony sucked. The Science Fiction section was small. The other sections may have been fine for all I know–but if they followed the model of these other two sections, they sucked as well.

I have a Sony Reader, and the primary thing I use it for is to view specially formatted RTF and PDF files which I’ve transferred from the ‘net: every time I log onto the Sony web site, I’m disappointed at the lack of content. It could very well be that Sony’s primary deals are with Japanese publishers.

The Sony Reader itself is a wonderful electronic device, and if they had simply made a deal with anyone–even the eReader folks for content–it would have been more successful.

Which is why I think the Amazon Kindle may have a better chance: already on launch Amazon has more content than the Sony Connect site has after a year of being out.