My cute little car came with a serious muffler problem; noisy at the best of times, its engine note became a head-shaking, resonating roar when going up hills or otherwise working the engine. The eBay-sourced replacement arrived a couple of days ago, dropped on the doorstep as a six-foot-long lump of oddly-shaped bubblewrap. I met up with Adam over at the Rocket Factory this afternoon and got to work on the installation. The job went more smoothly than either of us expected: an hour after putting the car up on jacks, we had hung the new muffler-exhaust-catalytic-converter system, replaced all the bolts, and fired up the engine – which is now so quiet it feels positively civilized. Success! We celebrated with a round of beer at Hale’s. Now I’m back home and it’s time to do some laundry.
February 28, 2009
February 24, 2009
My car is equipped with its original 1987-vintage stereo, which no longer works. I don’t need a stereo when driving around in town, but I sure would like to have one by my next road trip. The car stereo I want to buy, however, almost certainly doesn’t exist: all I want is a plain black panel with a volume knob and a USB jack. No buttons, lights, colors, labels, logos, video panels, pop-out-folding-media-player navigation devices, or any other such flappery, please – just let my iPod fill the car with music.
February 21, 2009
This rant, Why Should I Ever Use C Again, is a funny, irreverent, spot-on critique of a certain strain of micro-optimized thinking about software performance. Samples:
Okay, C is fast. But C is not the only fast language. It’s not even the fastest. If speed was everything, we would be (1) on a race track (2) using assembly. The C-is-fast-so-use-C crowd doesn’t know there is a clan that says the same for assembly. But, in 1980, it was clear that _slower_ C made more sense than _faster_ assembly.
Computers are really good at automating repetitive work. Every decade or so it becomes clear that it has come time to delegate to the computers some entire category of task which programmers have spent years sweating over. When this happens, it’s not because the computer can suddenly do a better job than a clever human being could, on a one-by-one comparison – it’s because the computer can do an adequate job a billion times a day without breaking a sweat. Computers keep getting faster, and for any problem there comes a point where the run-time cost of an automatic solution disappears against the development-time cost of human brainpower.
Programming language compilers themselves are an early example of this process in action. People take the notion of a high-level language for granted now, enough so that nobody uses the term “high-level language” anymore, but writing entire applications in assembly language was once routine. When I was beginning my programming career the need to think in terms of machine instructions was still common enough that every serious development tool offered some way to embed “raw” assembly instructions in your C or Pascal or Basic code. Nobody does that anymore, at all; you could still probably beat the compiler if you worked very hard at it, but it simply is not worth your time to bother.
A similar change occurred with the rise of Java, which pushed the idea of automatic memory management into the mainstream. You youngsters may not believe this, but paying careful attention to the lifetime of every last scrap of data was once a normal part of programming practice. Nobody would design such a language now: memory management is complex, error-prone, and amenable to automatic analysis – therefore it makes no sense to waste any more human brainpower on the problem. We delegate that task to the computers, which will do it in a simple-minded but utterly reliable way, and move on to more interesting things.
We’re about to see another of these shifts. As always, it’s going to start out looking like a nerf toy. How can you get any real work done with something like that, people will wonder? Where’s the go-faster button? Where are the sharp edges? The answer, as always, is that when you have a button, you have to decide whether, and when, to press it. We will choose to give up another layer of fine-grained control in exchange for the opportunity to spend our brainpower solving more interesting problems.
This generational shift is being driven by the ubiquity of multi-processor computing. Everyone has a dual-core machine now, and in two years everyone will have a quad-core machine. Meanwhile, the really big problems are being solved on server farms with thousands of networked processors. The tools we use today leave control of concurrency largely in the hands of the programmer: so programmers have to solve the same set of concurrency design problems over and over. This situation is just begging for automation. In the next few years we will see a new level of abstraction come to prominence: we will choose to give up a few old familiar tools, and in exchange we will be able to delegate the concurrency problem to our new tools.
I think I know what the recipe for this new style will be, and I’m convinced enough to spend a lot of my free time building a working example, but the details are less important than the process. A new generation of candy-coated, dumbed-down, kid-stuff programming tools are about to come down the pike. They will look limited and faintly embarrassing, but get ready to jump on board anyway: those limitations are the key to the future.
February 20, 2009
I love discovering a band I really like that’s been around for a while, then slowly eating up their back catalog. I’m listening to Psycraft’s “New Moves” at the moment, and it’s making me very happy.
New gloves arrived today, from Fox Creek Leather. The roads have been clear lately but the air is still very cold, and my hands have been getting pretty chilly in my summer gloves (I lost one of the winter pair). These are very nice, with long cuffs that pull back over the ends of my jacket sleeves.
Whistler ski trip is only two weeks away. I’m looking forward to it: I hope to go up after work on Friday, ski as many of the next nine days as I can, and come back late Sunday the 15th. This winter has been pretty much a bust as far as local snow is concerned, so I’m planning to ski hard and get all my runs in at one go.
February 19, 2009
February 17, 2009
I rode my bike to work today, for the first time since the blizzard in December. It was cold, of course, and I’d be more comfortable with heavier gloves, but with a sweater under my jacket it really wasn’t bad. I had a new chain and rear tire installed last week, and the whole machine feels smooth and happy.
February 9, 2009
This PDF slideshow introduces a concept the author calls “gradual typing” for Python. I’ve been pursuing a similar notion of typing in Radian. You can think of the notion of “type” as the information we have about a value. “Static type” is the information the compiler has about a value, and “dynamic type” is the information the running program has about the value.
From this perspective, one can see the ubiquitous ‘assert’ statement as a supplementary typing system, evaluated at run time. I frequently assert that various parameters are non-null, or that the objects in those parameters are related in some standard way; the C++ language may not include this information in its notion of a type system, but those attributes are very much part of my concept of the types I expect the method to receive. When you look at a type system in these broader terms, little islands of dynamic typing start to show up even in the most “static” languages like C++ and Java.
Wouldn’t it be nice if those ad-hoc assertions I place in my code by habit could be as much a part of the language, and have as much of an effect on the compiler’s knowledge about the values I am working with, as the built-in parameter and variable type annotations?
The Radian type system approaches something much like the linked presentation’s “gradual typing” from the opposite direction. It starts with a completely wide-open type system, where any value could have any type, then allows the programmer to limit the range of options by making assertions about values. Each assertion functions as a guard, or checkpoint; in order to continue, the given conditions must hold.
We then rely on dataflow analysis, constant propagation, and constant folding to resolve as many of these assertions as possible at compile time. The compiler can use the resulting knowledge about the content of each value to produce more efficient code specialized for that type. Each assertion condition can be resolved as either known true, in which case the assertion has been satisfied at compile time and can be omitted from the output, known false, in which case the compiler knows that the assertion cannot succeed and can report an error, or unknown, in which case the assertion will be compiled into the output and checked at run time.
Let’s make the compiler do all the tedious bookkeeping work! That’s what it’s there for. The result, I hope, will be a language which allows programs to start small, simple, and generic, then specialize over time for safety and efficiency – thus gaining the advantages of both “dynamic” and “static” typing.
February 6, 2009
My creative energy is all going into Radian lately. I’m having a ball, working deep in the plumbing – thinking about tuples, monads, type inference, garbage collection, dataflow analysis, and concurrency – but the tool itself is a long way from doing anything useful, and there’s not much to talk about here.
In the meantime, here’s a neat article which shows how to set up a makefile that automates most of the annoying dependency management. Those of you building executables on unix systems will appreciate this.
I want a portable computer and I am thinking about getting one of those cute little “netbooks”. I had to send my Macbook back when I left Real, and got a Blackberry phone as a substitute. It works fine for email and light web browsing, but I’m still stuck in my bedroom whenever I want to write code, which has become a significant fraction of my free time. I want something sleek, light, quiet, and cheap, running Linux (preferably not nerfed), with a comfortable keyboard, a solid-state drive, and reliable wireless networking. I don’t need to play videos or even music; I just need to check email, do some casual web browsing, and edit lots of source code. Anyone out there tried one of these little portables? I’d love a recommendation.