I Want Subtext
April 16, 2008
I haven't been this excited about a programming language since I tried to invent my own.
Subtext is a programming language invented by Jonathan Edwards. It's based on schematic tables (see figure) which display logic and computation in two dimensions. In contrast, textual languages show just one dimension (a stream of characters), and it's usually computation. Introducing conditionals requires you to puzzle out control flow.
Subtext makes logic and computation obvious by placing them on two axes in a table. To understand how this works, I recommend watching Jonathan's video demonstrating Subtext. (If you saw the video for the original version of Subtext, watch the new one--it's come a long way. I didn't even recognize it.)
Subtext nails a bunch of things that I want. To explain, I'll need to digress for a moment.
My background is in commercial software development in a wide variety of industries. I'm passionate about seeing software lead to real-world successes, which involves organizational success (return on investment, to oversimplify), technical success (maintainable code), and personal success for the systems' community. I've dedicated my career to improving my understanding of those three components of software development. I still have a long way to go.
Along this journey, I discovered Agile methods and I've became fairly proficient with them. Two Agile techniques that I've found to be particularly powerful are Test-Driven-Development (using a tool like JUnit) and Example-Driven Requirements (using a tool like Fit).
JUnit and its brethren are great. TDD works well. Example-driven requirements also works well, but I've become increasingly dissatisfied with Fit. Fit, in case you haven't heard of it, is a tool created by Ward Cunningham and maintained, in a
The great thing about Fit is that it enables example-driven requirements. This is incredibly powerful and useful, and Fit is the only tool I know of that focuses on this. (Most clones of Fit get it wrong, focusing on test automation rather than customer collaboration.)
The problem with Fit is that it's a maintenance burden. You have to write your examples in HTML and none of the existing tools (not even MS Word) make editing and revising HTML tables easy. You have to create fixtures. When done well, fixtures are small and simple, but they're easy to get wrong. You have to deal with Fit's primitive and difficult-to-use tool support. (Okay, I could fix this one, and should.) And, to top it off, almost everybody misunderstands and misuses Fit.
Okay, back to Subtext and Jonathan Edwards. TDD and example-driven requirements (EDR) can both be considered cases of example-driven development. In other words, your development efforts are focused around creating examples and making them work. The examples form sort of an incomplete specification of your work that are fleshed out along with your program. TDD operates at the level of programmer intent and EDR operates at the level of customer intent.
Well, Jonathan shares a passion for examples in programming. So it's no surprise that Subtext looks like it will support the Agile conception of example-driven development quite well. The best thing about it is that it looks like it will support TDD, example-driven requirements, and software development within a single paradigm. Brilliant.
In addition to its support for example-driven development, I like Subtext's focus on making programmers' intent more obvious. The schematic tables are a great way to show what happens computation is mixed with complex conditionals. I particularly liked Subtext's ability to automatically discover gaps and overlaps in conditions. A minor nit: I think Jonathan could decrease the verbosity of his language by allowing more complex statements on each line, perhaps allowing a click to change the view between the simple, linked form shown in the video and more complex compound statements. For example, the Fibonacci example could show the entire >= 2 case in one statement:
fib(in - 1) + fib(in - 2). I think I'd actually find that more readable than the current display.
Given that Subtext is a work in progress, I liked almost everything I saw in Jonathan's video. The one thing I disliked was towards the end, as he was talking about polymorphism. I got a sense of disdain towards object-oriented programming. That's not uncommon in the academic world--OOP is anything but well-defined from a formal perspective.
But although OOP is messy, it has an important characteristic that Jonathan also values: it makes programming languages more usable. Objects are an important way of organizing large programs so that the programmer can ignore irrelevant details. Although polymorphism makes control flow more complex, as Jonathan observes, it also enables design techniques that make programs easier to understand.
In a small program, an experienced programmer relies on well-named functions/methods with carefully-constructed semantics. When that's the case, she may use the context of the program to infer the behavior of those functions. For example, if you saw that a mathematical calculation called an "exponent" function, you could guess that it calculated the exponent of a number and move on, not bothering to look at the body of the function unless it was directly related to your work.
Classes and methods perform a similar service in OOP. In a large program, an experienced programmer also relies on well-named classes with carefully-constructed responsibilities. The noun-verb combination of classes and methods allows her to infer the behavior of those classes. For example, if you saw a call to
monster.attack(character), you could guess that it calculated attack and damage probability and adjusted
character's hit points accordingly.
Subtext could face challenges dealing with larger, more complicated systems. You can see in the figure how even minor complications in the damage calculation start to make the table unwieldy. Subtext provides a focusing mechanism to hide unnecessary details, but I'm skeptical of how useful the current incarnation is for this purpose. I think it will work well for simple algorithms, but not for the enormously complex, interrelated computations that large systems deal with.
Those enormously complex, interrelated computations are exactly what object-oriented programming languages are good at managing. (With good design, at least, which is by no means a given.)
I'd like to see Subtext give objects a more prominent role in the language. It's hard to tell from the video exactly what's going on, but it looks like the programmers' use of objects is largely limited to defining types and subtypes. I'd like to see more. Specifically, I'd like to see support for named methods attached to objects. They could be expanded and edited in-place, or they could be edited in the context of the object.
For example, a lot of the complexity of the damage calculation comes from the polymorphic 'power' constants. Magic attacks have a power of 5, melee attacks have a power of 4, and ranged attacks have a power of 3 (not shown in the figure). If Subtext showed that polymorphism as a reference to a method, then the diagram would be simpler. The effect of defense could be similarly collapsed into a 'damage' method.
To continue the example, if the programmer wished, he could open up the 'Attack' class and see 'power' and 'damage' defined there. Perhaps subclasses and/or methods could be shown as columns. That would allow him to contemplate the relationships between the classes and their methods--a common need--and make changes to them together.
This is actually a fairly minor tweak to an impressive system, and it's quite possible that Jonathan has already thought of or even included these improvements. If he hasn't, I hope he'll consider them. Either way, Subtext is impressive. I want it.
(Thanks to Keith Braithwaite for the link.)