flak rss random

books chapter four

Keep it simple.


Moving back in time, before there was JSON there was JavaScript, invented by Brendan Eich. Before Netscape, he had worked with a number of systems, doing some low level unix work. He makes a great remark that the first time he looked at the implementation of the C preprocessor, it was a “huge pointer stew” which is probably an apt description for a lot of string fiddling code.

With regards to the early development of JavaScript itself, he knew what he wanted to put in the language, but he was also rushed and didn’t have time to think about what he didn’t want the language to be. A lot of software seems to suffer from this problem. We think we’re done when we can answer what is it, but what is it not is an equally important question.

In the context of programming languages, he makes the point that we should consider patterns flaws in the language. An example might be creating namespaces in JavaScript by calling an anonymous function. It gets the job done, and it’s a great demonstration of the power and flexibility of the functional programming influences. But maybe (function(){})() isn’t the best way to spell namespace? I think there’s a balance where you have a small number of simple (? powerful?) concepts that you can combine, which in theory makes it easy to learn everything, but then in practice you discover that reading other people’s code requires learning a whole set of idioms. Applicable to a number of programs. My personal example would be find, which is flexible enough to support many operations, but also results in beginners typing longish arcane sequences by rote. Another perspective on sensible defaults.

On the divide between academia and industry, he compares transactional memory and a simpler share nothing design. Transactional memory is more interesting, and has problems to solve, thus lots of attention. Shared nothing architectures just work, so there’s less incentive to focus on it.

There’s a shoutout to what is now the debugging tool rr. When you’re trying to learn a piece of code, don’t just study it. Run it in a debugger and step through it, see what it does. He’s also a big fan of fuzzing.


Branching out from the Lotus family, we meet Ray Ozzie, who wrote Lotus Notes. Then he founded Groove Networks, which Microsoft bought, and I’m not sure where that went. Notes came about because he observed that while at the time a spreadsheet might only be used by on person at one desk, it was inevitable that as more people used computers, they would have more information to share with each other. Later, after Notes had been adopted within organizations, there existed a similar situation between organizations, hence Groove. Trending towards more connections.

Having decided to build some cloud sync service (based on my understanding, though those were not the words in vogue in 1999), they needed to prove that syncing could work. They spent a long time building and testing a proof of concept in stealth mode, knowing that once they got that part working the rest of the features could be built around it. Do the hard part first, then launch.

Evan Williams founded Pyra Labs, which was supposed to make a bunch of things, but accidentally made Blogger. An interesting time. Blogging was fairly small scale, and mostly restricted to a set of people who each wrote their own scripts for publishing. There was also GeoCities, which made it easy for people to create a web site, but not to publish a stream of articles. So there was this little gap between what was possible and what was easy.

But there wasn’t much money in blogging, and all the employees had to be laid off, leaving only Evan to learn system administration to keep the lights on. An argument to be a technical founder I guess, so when you’re back down to running on fumes you can keep going. Finally, Blogger started making a bit of money by selling not advertising. There were ads on blogs, but they didn’t really bring in much money, but people would pay a decent amount of money to remove the ads. Not my favorite business model, but one that remains lucrative. People seem willing to pay more for something to be not worse than they will for something to be better.


Aristocracy, Democracy, and System Design. And making it all fit together. There was a time when the thing to do in Europe was build giant cathedrals. The largest of them took centuries to build, which meant lots of different architects over time, and changes in fashion, etc. The result is often a strange blend of styles, but the best cathedrals are those where the later architects swallowed their pride and continued new development in the existing style. And so it should be with software.

“I will contend that conceptual integrity is the most important consideration in system design. It is better to have a system omit certain anomalous features and improvemetns, but to reflect one set of design ideas, than to have one that contains many good but independent and uncoordinated ideas.”

In the end, systems are built to be used, and a feature only achieves a net savings in time when you can find it in the manual and understand how to use it.

But is this not totalitarian? Every developer is capable of good ideas, right? So why ignore them? Not necessarily. Those good ideas must simply fit within the existing design. Imposing some constraints on an idea is often a means to make it an even better idea. There’s a nice quote that when the PL/C group at Cornell implemented a compiler for PL/I, they decided to implement the language without modification; otherwise they would have spent all their effort improving the language and not implementing.

Critically, keeping a lid on the design helps testing and integration because everything fits together.


10. Ready, fire, aim... begins the section on tracer bullets. One can aim a gun by making a great many calculations regarding trajectory, wind currents, etc. Or one can shoot first and see where the bullet hits. Even better with a glowing tracer bullet. We can use this approach to build software as well. Specify enough of the problem to build enough to test and gather feedback. At first this sounds a bit like prototyping, but it’s different. The tracer bullet should actually be minimally functional; it may be incomplete but it needs to be real. Instead of an interface that displays fake data, it should display real data, but maybe not support every possible query. It’s like an end to end check, which verifies all the parts are working and can link together.

It’s very important to decide whether one is building a tracer or a prototype. And do that before demoing the throwaway prototype which suddenly gets pressed into service. I liked this point a lot. I write a lot of code using the tracer approach, but have rarely thought about the distinction.

11. On the other hand, sometimes you do want a prototype. You want to see how all the data fits on the screen, without necessarily computing all the data. They give some hints that one might deliberately choose to prototype in a language or system other than that specified for the final product. It’s possible to iterate faster in error checking free perl than C. Just make sure it doesn’t wind up in the product.

12. On the merits of domain specific languages. Move the solution closer to the problem. You have a choice; go big or go small. Be careful going big. You’d rather not let the language run away from you, which is something I’ve seen a few times. Be careful going small. You end up with sendmail.cf. Some of the tradeoff comes from deciding whether a mini language is intended to be used only by the developer of a program, or by end users as well. At some point, internal languages tend to slip out into the world, and it can be tempting to do so without reworking it too much. Just put a new letterhead on the internal documentation. Definitely been there, done that; definitely a mess.

13. Estimating is hard. This refers to development estimates, but also capacity provisioning and many other aspects of programming. Are components engineered to handle the necessary load, but not overengineered? I believe the modern phrasing would be you don’t need Hadoop.


There’s something magic about numbers. Some people write with a pen, some people write with a Kugelschreiber, but we all write 10. Which is a serious improvement over the insanity of Roman numerals. The concept of zero is so useful that the one number system to use it replaced every other.

The zero is pretty important, but for our purposes, what’s really important is that using zero allows the creation of a positional number system. So the number 10 doesn’t actually always have to mean ten. It means one of some number, but that number may as well be eight. Which it may be, if we’re a cartoon character. Neat fact: on planet octal, where cartoon characters live, they too have 10 fingers and 20 fingers and toes. Lobsters, the cleverest of crustaceans, have four (10) pincer prongs, which they use to count 1, 2, 3, 10.

If we carry along in this manner, we get to the point where we have 1 and 0 and that’s it. Which makes for a rather simple addition table and a very simple multiplication table. Math is easy when you only need to count to 1. It also conveniently maps on to all these circuits and switches and lightbulbs we’ve been building; on and off; one and zero.


Learn when to say no. This was very clearly expressed by Brooks, but several other books made similar points in different contexts. Lots of wasted effort spent trying to build everything, usually with disastrous results. It occurs to me that the tracer bullet approach to development can help. It’s easy to add new features to isolated prototypes without considering how it all fits together. Maintaining conceptual integrity requires the ability to see the project as a whole; this is obviously easier if there is a whole to see.

Brooks also made a point about simple vs straightforward, which blends nicely with a discussion of how much sugar to add to JavaScript.

Posted 14 Jul 2017 15:36 by tedu Updated: 14 Jul 2017 15:36
Tagged: bookreview