When You are Programming in an OO Language, You are Always Creating Domain Specific Languages
As is often said and written, the history of programming, and programming language design, is about programs becoming more expressive, fluent, lingual. All of the Object Oriented programmers I know and trust most would say that when they program, they are creating what are, in effect, languages. So, as a community of software craftsmen, how intentional and explicit are we about programming — and teaching programming — in a “lingual way,” and what does that mean?
I care a lot about helping novice OO programmers learn OOD, because when I set out to learn it years ago, my education was flawed. And because most programmers in OO languages are very bad at OOD. And because when I try to teach OOD to others, these concepts are still not as easy to teach as I want them to be. And finally, because there is no better or more natural metaphor for expressiveness than the notion of a spoken language itself. Perhaps by definition.
I want to encourage novice OO programmers to think in an expressive, lingual, semantic way. And the terms of art in OOD are not helpful enough there.
Turns out there is an emerging popular notion, the Domain Specific Language (DSL), that is all about how expressive we are in software development. Cool! Let’s hijack that term to critique the expressiveness of the code we write.
(The definition of Domain Specific Language offered by Martin Fowler does not strictly permit us from designating something as non-fluent as a Java API as a DSL — I think this is a mistake. I use the term DSL to mean “anything that we program, for a given domain, that can and should be as fluent and lingual as possible.”)
I Dislike a Lot of OOD Terms. DSL is Not One of Them.
Don’t get me wrong. There is a rich vocabulary about being clear, clean, and expressive in programming, but none of the terms helps me the way the noun DSL helps me.
Here are some terms that are helpful, but not in the right way: programming by intention, meaningful names, expressive names, abstraction level, object modeling, domain-driven design, etc, etc. Each of these terms is either just plain hard to learn (“abstraction level”), or it is focused on too small a lingual granule (a meaningfully-named method), or it is not especially lingual in focus at all (“object modeling”).
An object model can be healthy in the sense that the classes and their methods are about the right size, and focus on about the right scope of responsibility. And it can have OK, not great names, that are not semantically coherent. And the whole thing can feel like a non-German speaker driving through Germany: “What a beautiful little town! Where the hell are we?”
An abstraction level can be decoupled nicely, and still not be expressive in a lingual way. “Wow, nice clean scoping! But, uh, what’s going on in here?”
A group of classes, methods, and variables can be pretty well named, in their own narrow, individual contexts, and still not form a semantically consistent little vernacular. This is not common, surely. My point is that if we focus on programming in a lingual way, constantly focusing on how well our code reads as a language, we can get all of the stuff we want: SRP-compliance, decoupling, expressiveness, clarity, DRY, etc.
In Charges this Shiny New DSL Term
There is a sudden sexiness emerging around Domain Specific Languages (DSLs), and Martin Fowler’s book will increase the buzz. To Fowler’s mind, based on his research into the prior art around DSLs, the term should be reserved for a level of fluency that is “sentence like” in its grammatical richness. The chief application is to make problem domains, more than solution domains, very fluent and expressive, especially to non-technical stakeholders, rather in a Ubiqituous Language, Domain-Driven Design fashion. Fair enough. It’s a great idea, and frequently worth the effort. I am 110% in favor of it.
But FitNesse/Slim Given/When/Then DSLs (for example) don’t solve my problem, which is this: encouraging OO programmers to program in a lingually expressive way, within the limits of whatever programming language they are using. You can create real DSLs in Java using techniques like method chaining, and tools like Hamcrest matchers, but that ain’t exactly novice-level craft.
Fowler’s book draft defines DSL to explicitly exclude traditional command-query class APIs in languages like Java and C#. I want a term that encourages, describes, and defines what it means to make those command-query APIs as lingual as possible. I want novices to have guidelines for creating command-query APIs that form consistent, lingual semantics as collections of verbs, nouns, and other parts of speech.
That thing. That thing I just said. That’s what I want a term for. Why can’t I use DSL as a term to mean that? Well, I’m gonna. It’s too useful a term for programmers everywhere.
DSLs and Lingual Design
One typical scope for a DSL, in Java programming, is a package that adheres to all of the package coherence principles of common reuse and common closure. Those classes that tend to be released, reused, and changed together and therefore tend to cohere in their own package together, really ought to be crafted as a little language. That’s an example of what we mean by a Lingo.
And, a class can be a DSL, and should be when it can: the semantics of the method names within the class should be grammatically consistent.
Now, Lingual Design is simply an orientation toward ensuring that our command-query APIs have clear, SRP-compliant boundaries (e.g., package boundaries or class boundaries), and tend to hang together as coherent, consistent DSLs.
No, Java and C# and many strongly typed languages do not make this easy to do, and make you jump through fancy hoops to get all the way to Fowler’s definition of DSL fluency. So what!
Even without the fancy hoops, you can make classes small and expressive, and methods small and expressive. You can have can have separate classes for Operators/Operations and their Operands.
You Are Always Creating a Language
Whatever general purpose programming language, or Domain Indifferent Language (as Mike Hill puts it) you are using, no matter what sort of API and object model you are crafting, you are always creating another language. More or less crude, more or less fluent, more or less semantically consistent, whatever you end up making will be read by other programmers in the high hopes that it reads like a consistent little bit of spoken language.
Try thinking, for a bit of your programming, in terms of Lingual Design. Try to see the boundaries between, and the hierarchical tiers, of your DSLs.
How does it feel, and how does it work, to be intentional about OOD in this particular way? Can this be a useful way to teach and learn OOD?