Andy Hunt and Dave Thomas are the Pragmatic Programmers, recognized internationally as experts in the development of high-quality software. Their best-selling book of software best practices, The Pragmatic Programmer: From Journeyman to Master (Addison-Wesley, 1999), is filled with practical advice on a wide range of software development issues. They also authored Programming Ruby: A Pragmatic Programmer's Guide (Addison-Wesley, 2000), and helped to write the now famous Agile Manifesto.
In this interview, which is being published in ten weekly installments, Andy Hunt and Dave Thomas discuss many aspects of software development:
Bill Venners: In your book, The Pragmatic Programmer, you say, "Program close to the domain." What are the tradeoffs of creating a new domain language? I tend to like to do that myself, to build tools that make me more productive. When I suggested a particular tool to a particular manager, he discouraged me with, "but then we'll need to support and maintain the tool." Terence Parr, who wrote ANTLR, said, "Why spend 5 days coding something by hand that you could spend five years automating?" When is it worth it to build a tool?
Dave Thomas: Many people read our advice about domain languages and think we're talking about writing a parser or interpreter, manipulating an abstract syntax tree—as if we're recommending rewriting Java from scratch. We're not. For me, a domain language could be as simple as a half dozen C macros that let me create initial values and data structures. If I'm using a language with decent reflection, a domain language could be something that allows me to configure the system by constructing classes on the fly at runtime. Creating a domain language does not have to involve serious amounts of parsing. In fact, I prefer domain languages that have almost no parser, ideally none at all. So we're not talking about big up-front investment. I think you only do a domain language if the pay back is greater than the investment. It's really that simple.
Andy Hunt: One reason programming is hard in general is that you have to zoom in and out to different levels of detail. You might be groveling around in low-level bits and pointer arithmetic, then zoom out to an abstraction that's close to the business domain. You're always bopping back and forth. That's hard. It's much easier if the user gives you business rules in their domain language. It's easier if you don't have to map the business rules down to very low levels, like a compiler would do. Dave and I are big on using automation. That's why the computer is there. I am very against any technology that requires me to act like a compiler. If I can do a task with a couple of macros that match what the user is saying, as Dave suggested, hey that's a win. Let the compiler take it to the next step. Don't make me do that. Allowing me to stay at a high level is to me the real big advantage of domain languages.
Dave Thomas: But there is a danger of going too far. With some technologies, in particular C++ templates, people sometimes go too far the other way. They try and think of clever ways of using templates to generate compile-time behaviors. Yes, you can do it. Yes, you get real good geek points for doing it. But you end up with totally unmaintainable applications. You've got to be very careful to keep that balance in mind.
Andy Hunt: If you're doing obscure tricks and hacks with templates, that's one thing. If you've got a very nice, clean, 10-line YACC or ANTLR grammar, you're using more tools, but it's also very easy to follow. And it is very easy to maintain, because you've done it cleanly, instead of doing some set of obscure hacks. I think it's OK to introduce complexity, so long as it is actually clean and easy to follow. But going for geek points will kill you.
Dave Thomas: Since we wrote the book I came across a good example of programming close to the domain. A company makes software to test telephone switches. The software is hundreds of thousands of lines of C++. You configure the software for the switch being tested. It inputs signals and checks for the correct output. Previously, whenever a new switch came along, they had to alter the main program and recompile 800,000 lines of C++ to support the new switch. Now they use the Ruby scripting language. Ruby has a very simple interface to C++ that makes C++ objects look like Ruby objects. They wrapped their entire test suite in Ruby, so they can access it by writing a Ruby program. They now have a library and wrapper code. When a new switch comes along, they write a 50 line Ruby program to drive it. The Ruby program is a domain-specific language that happens to use this boatload of C++ code in the back end. To support a new switch, they now write code at the domain level. And they find that's made them infinitely more productive.
Andy Hunt: A domain language is just another level of leverage. Just as C is a layer of leverage above assembly language, Java is above C++, a domain language is above Java. A domain language is just one more layer in a stack that gets more and more abstract from assembly up to the domain level.
Bill Venners: Ruby is a general language in which I can program anything. To me, a domain language is specific to a particular kind of programming task, such as testing switches. How was Ruby their domain language?
Dave Thomas: Because in Ruby, I can write code that would say things like, "For each line in the input set, set the status to high." I can actually write code in Ruby that looks very domain specific.
Andy Hunt: So they might say: "For each phone line, snap relay on." The phrase we actually use is, "Program in a language close to the domain." You can do that with macros in C. You want code you can read. You want code you could show to a business person and maybe they'd understand roughly what you're talking about. You want to talk in their language, not the computer language.
Dave Thomas: That's a very good test. If you show the code to the customer and they understand it, at least in principle, then you're programming at the right level.
Andy Hunt: There might be some control flow that the business people don't necessarily understand, but in general, you want them to know what you're talking about. You want to be closer to their language than the computer's language.
Bill Venners: Differentiate between declarative and imperative languages. What are the advantages and disadvantages of both?
Dave Thomas: I prefer to code declaratively, because at the business level we're not executing a series of instructions. We're dealing with data. The longer I can keep my code at the data level, the closer I'm coding to the application domain. If I can find a way to express the program in terms of data and the relationships between data, I find that keeps me at a higher level longer. Alternatively, if I need to control, or if I need to be very specific about the order in which I do things, then I want to get down to the imperative level. What I don't want to do is jump back and forth between the two models in the same chunk of code. Because then you get the whiplash effect that Andy was talking about. You go back and forth and back and forth and you aren't sure what you're doing. Everything gets muddled up. If I can instead keep things nice and separate, I find I can focus very strongly on whether I am doing application level code or low level geeky code.
Andy Hunt: Declarative programming is really another example of programming closer to the user's domain. Look at SQL. SQL is a great example, because it is primarily a declarative language. With a typical select statement, you say, "Get me these fields from this table." You don't say how. Your don't say in SQL, "Chase down this pointer. Get this file off disk. Chase through this btree index. Optimize it." You don't say any of that. You say, "This is what I need. You go figure it out. Go get this for me." That's getting closer to programming the intent of the user: "I want this. I don't care how you do it. Just make it happen."
Come back Monday, April 14 for Part VII of this conversation with Pragmatic Programmers Andy Hunt and Dave Thomas. If you'd like to receive a brief weekly email announcing new articles at Artima.com, please subscribe to the Artima Newsletter.
Andy Hunt and Dave Thomas are authors of The Pragmatic Programmer, which is available on Amazon.com at:
The Pragmatic Programmer's home page is here:
Dave Thomas was not the first person I've interviewed who mentioned the arcade game Whack-a-Mole. James Gosling also called upon the versatile Whack-a-Mole metaphor while pointing out that it is sometimes hard in engineering to know if you've solved a problem or moved it:
The Agile Manifesto is here:
Ward's Wiki, the first WikiWikiWeb, created by Ward Cunningham, is here:
Extreme Programming: A Gentle Introduction:
XProgramming.com: An Extreme Programming Resource:
Bill Venners is president of Artima Software, Inc. and editor-in-chief of Artima.com. He is author of the book, Inside the Java Virtual Machine, a programmer-oriented survey of the Java platform's architecture and internals. His popular columns in JavaWorld magazine covered Java internals, object-oriented design, and Jini. Bill has been active in the Jini Community since its inception. He led the Jini Community's ServiceUI project that produced the ServiceUI API. The ServiceUI became the de facto standard way to associate user interfaces to Jini services, and was the first Jini community standard approved via the Jini Decision Process. Bill also serves as an elected member of the Jini Community's initial Technical Oversight Committee (TOC), and in this role helped to define the governance process for the community. He currently devotes most of his energy to building Artima.com into an ever more useful resource for developers.