Showing posts with label software systems. Show all posts
Showing posts with label software systems. Show all posts

October 15, 2009

Computers are not getting faster

When we discuss the inclusion of a feature in Lua, we ask ourselves, "OK, but will it run in a microwave oven?"
--Luiz Henrique de Figueiredo

I recently started working with John Fremlin's TPD2 HTTP server, one of the fastest web servers currently available. TPD2 uses a lot of interesting (at least from a Lisp point of view) techniques to achieve high performance. This reminded me of something I noticed in Masterminds of Programming: both Chuck Moore and the creators of Lua emphasized the tendency of computers to scale down.

When laptops and servers are getting faster processors with larger caches and more cores (which doesn't really help because we don't know even know how to think about writing software for them), it's easy to overlook the fact that we're trying to imbue ever smaller objects with computational intelligence. Moore provided the extreme example of a chip having cores with 64 words of RAM and 64 words of ROM memory each. A less extreme example comes in the form of smartphones.

At the same time use of existing systems is increasing to the point where some people are measuring how much servers they buy by the number of tons of waste their packaging generates. If each of your servers could handle three times as many requests per second, you could fit it on a computer three times as small, or have a datacenter a third of the size. The latter is a pragmatic consideration applicable at any time, but the former enables entirely new patterns of use and interaction.

July 29, 2009

The reusability fallacy and domain-driven design

How can you make software reusable? The prevailing design fashion is to anticipate changes in the way that software will be used, then try to provide mechanisms for accommodating these imaginary uses. This approach would work, if you could predict the future.

The root cause of the drive to build reusable software is that the circumstances under which software is used change, ergo software needs to be changed to accommodate those circumstances. Seen this way, the concept of "building for reusability" is nonsensical. The solution is to go to the source of the problem and make software easier to change. Stop wasting time trying to design for reusability, start investing time in continuous refactoring.

One way reusability is achieved is through abstraction. All successful software libraries (graphics, algorithms, etc.) set out to solve problems in a particular domain. This is not "designing for reusability," this is designing software to address a particular domain broad enough to be useful for a wide variety of applications.

Platonic software design would consist of composing these domain libraries together using engineering techniques of abstraction, the outside ones building on the inside ones, like the layers of an onion. Two problems preventing this from being reality are leaky abstractions, and domain mismatch, making techniques such as Open Implementation necessary.

The only code reusability technique that is somewhat successful is the strategy pattern, but that is because the strategy pattern is just first-class functions and polymorphic types, which have a simple formal model behind them.

June 8, 2009

Why your language needs macros

A couple of days ago someone posted yet another "why do I need macros?" thread on Hacker News. The usual arguments and unconvincing examples arguing for macros were posted. Noted absence were the arguments against macros (all of which seem to be of the variety "programmers are too dumb to understand someone else's macros" - if you were at the Great Macro Debate at ILC 09 you would have heard it stated more eloquently).

I've been thinking about macros in terms of domain-driven design lately, kicking around my idea of "domain onions" (I'll write more about this later), so I decided to post my current thoughts about why every programming language that aspires to be general-purpose needs macros.

May 4, 2009

On the value of metaprogramming

Several weeks ago I wrote about a way to implement Smalltalk-style predicate function-to-SQL translation in Common Lisp, so I was amused to come across Dejavu for Python (via Jonathan Ellis), which implements the same technique by inspecting CPython bytecode.

It's amazing what kind of dumb hoops people will jump through when they don't have a system that permits real metaprogramming.

April 15, 2009

Problem-solving is hard, let's go write XML configuration files

Previously I blogged about why the premise behind software frameworks turns out to be a logical fallacy. This blog post will continue my attack on the framework cult by examining the reasons why people continue to believe in the myth of increased productivity through frameworks.

There is one word that can summarize my argument: comfort.

Consider carpentry tools. How do you use them? What do you use them to accomplish? Now consider a toy construction set such as the Erector. The toy construction set offers you a path you can follow to arrive at some cool artifact, even if you don't know exactly what you want to do. The construction set can offer this security because it limits what you can accomplish, and how you can accomplish it.

According to Buddha, ignorance is the root of all evil. According to Christian tradition, people are inherently evil. It is then no surprise that most of the time most people do not know what they want to do. Finding out "what" is hard, requiring a lot of time and learning. In the realm of software development, this is practiced by methodologies such as domain-driven design. It is a lot easier to write XML configuration files instead.

There is a misguided comfort that comes from knowing that you did a day's worth of honest work. It doesn't matter if what you are doing is leading you down the wrong path, because with a framework you are at least accomplishing something, even if that something will not bring business value. As a project manager who decides to use a particular framework, you are in effect acting as a proxy sales agent for the party promoting that framework - selling your customer a solution that may not be in line with your customer's goals.

Many logical fallacies go into the typical software development decision-making process. Frameworks in particular are notoriously prone to the bandwagon effect (how many "enterprise" web-development frameworks for Java have come and gone and with what ridiculous frequency?). Any person held responsible for the consequences of a decision will be prone to post-purchase rationalization (remember that before a person tries to sell a methodology to his organization, he has to have been sold on it her/himself), so the bandwagon effect is frequently used as an argument for adopting a particular framework. In addition, nebulous terms such as "enterprise" (which, because of its strong association with frameworks, has almost universally acquired the definition as "verbose junk" in the software development world) somehow end up in place of well thought-out arguments and empirical evidence.

Obviously, there is some circumstantial evidence that frameworks do enhance productivity - people become experts at particular frameworks and can efficiently develop applications. This is not because they are using a particular framework, or because they are using a framework at all. This is because they have become experts at it.

March 12, 2009

Frameworks and the conjunction fallacy

Frameworks are great. After all, some helpful way to do X combined in some helpful way with some helpful way to do Y must be a whole lot more helpful than just a way to do X and just a way to do Y, right?

Wait a minute, anyone who has used a framework might say, what if someone wants to do Z instead of Y? Why, of course, say the framework "architects," we'll just provide a helpful way to help you choose helpful ways.

How helpful! Now not only do you have to know how to do X and how to do Y and how the framework helps you do X in a helpful way with doing Y, but you also need to know the helpful mechanisms behind letting you choose the helpful ways.

Clearly the original argument for helpfulness broke down somewhere. But where, and why?

The underlying fallacy behind the majority of software design today is the belief that computer systems can be "useful" and "helpful." Useful and helpful for doing what? For doing what they were designed to do. Stated in these terms it is immediately apparent that this mindset is a tautology. Completely useless as a basis for reasoning.

Is there a better way of thinking about software? Let's start by asking why. The entire motivation underlying our enterprise is the desire to accomplish X and Y. Each step we take can either bring us closer to that goal, or not. Given that time and other resources are finite, each step that does not bring us closer to the goal is "unhelpful" - it gets in the way of what we want to do.

I believe the right way to think about computer systems is as things that get in the way of what you want to accomplish. This way the goal of software design becomes not getting in the way of what you want to do.

Given this approach it immediately becomes obvious that the argument presented at the start of this post is simply a conjunction fallacy. Likewise many other "reasonable assumptions" about software that are not borne out by experience can be shown to be flawed a priori. Most importantly, this mindset helps prevent such "reasonable assumptions" from being taken up in the first place.

While this post debunked one of the arguments used to both justify the development of frameworks and their use, the decisions surrounding the latter are also driven by other logical fallacies, and, like the vast majority of human decision-making, by emotions. In a forthcoming post I will examine some of these factors.

[Major thanks to Ryan Holiday for providing the inspiration for this blog post.]

November 19, 2008

Hardware support for garbage collection.

A fascinating email exchange between David Moon and Cliff Click Jr. currently at Azul Systems about the Azul Java servers' architecture. Things that caught my attention:

One of the biggest impact changes we made was a hardware read-barrier for GC - a simple instruction that tests invariants of freshly loaded pointers and takes a fast-trap if the test fails.


GC read-barrier enables a fully parallel & concurrent GC; we can sustain 40G/sec allocation on a 400G heap indefinitely, with max-pause times on the order of 10-20msec. This uber-GC is partially made possible because of the read barrier (and partially possible because we 'own' the OS and can play major page-mapping tricks).


Yes, wide tag per pointer. No problem (yet) with running out of classes. Big Java Apps these days seem to have about 2^15 classes.


The new insight I took from this is that effective hardware support for garbage collection does not have to be complicated. The other two quotes provide further evidence for opinions I espouse: cons all you need (10% of the heap per second!!), and object orientation is an inadequate paradigm for writing software that is now being stretched to absurdity (30,000 classes!!).

May 21, 2007

The ontology of XP

I just finished reading Adrian Mackenzie's Cutting Code: Software And Sociality. The book attempts to explore the meaning of software in its many incarnations using the tools of contemporary literary analysis. Although I didn't like most of it (many assertions I disagreed with, others I could not make sense of, despite the conspicuous absence of poststructuralism in the book), one chapter that stood out was about eXtreme Programming. It's the best explanation of XP I have encountered, and well worth reading for everybody.

March 10, 2007

Complete computing system in 20,000 lines of code

I just finished watching Ian Piumarta's talk on the project at Viewpoints Research Institute to build a complete (metal up) personal computer system in 20,000 lines of code. While the easy way to do this would be to use APL, Ian, Alan Kay, Dan Ingalls, and the others working on the project have instead opted to go for building metacircular/self-describing systems instead. Of course, in modern parlance this is called "reflection," a very crappy version of which can be found in the Java language and runtime system. Among fascinating programming language and compiler topics, Ian discusses Schorre's Meta-II compiler compiler (developed in 1962), which had a self-describing grammar. Fascinating stuff, and in my opinion critically important, since the only proven way to reduce software complexity has been, to, well, reduce software complexity - less lines of source code written in a simpler way makes for better, more maintainable software, and this is exactly what the project aims to do.

Here is the link to the video:

http://stanford-online.stanford.edu/courses/ee380/070214-ee380-300.asx