“Lingos” and “Lingual Design”
Hypothesis: Good OOD Programming is “Lingual” Design
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.
I Dislike a Lot of OOD Terms
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 in the way that I want. 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! 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.
In Charges the DSL
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.
Lingos and Lingual Design
So, unscared by the prospect of inventing a dumb pair of terms, I am inventing these two, with the help of my pals Dave LeBlanc and Mike Hill, who helped me think this through. Truthfully, there is not much to it:
A Lingo, in our definition, is a coherent, object-model subset, a command-query API, that is semantically consistent in its limited grammar, and as fluent as the programming language permits (without fancy stuff).
One typical scope for a Lingo 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 Lingo, 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 Lingos.
[TODO: Insert code examples here!]
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!
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 Lingos.
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?
Are these terms useful or just more pedagogical noise?
Am I, once again, smoking crack?
Time, and my friend Ron, will tell. ;>
5 Comments so far
Leave a reply
I can’t speak for whether you are smoking crack. I think that’s independent of this post
This post reminds me of one of my *favorite* classes in school — Programming Language Pragmatics. In that class, I heard one of the most enlightening things I got out of college.
This professor taught us that every programming language is, exactly that — a language. It is an alphabet (our own english alphabet) and a syntax (a definion of rules about how those alphabet characters and a few more are allowed to be combined). Any programming language, he argued, was just defining a language, in exactly the same way a spoken language is defined.
I’m a tad leery of adding yet another term (I’m feeling a little overloaded by terms, many of which seem to mostly overlap with just slight differences), but these terms are a bit closer to a “Layman’s description” of OOD.
I’ll be interested in seeing where this goes ….
Interesting, but what do you want us to do with this information?
Also, I don’t understand why you include meaningful names in your list of terms that don’t help the way you want. You appear to equate “meaningful names” with “meaningful method names”, and we do name more than just methods.
I try to name things precisely, then meaningfully, and in the process, remove duplication. If you name a group of things precisely, meaningfully, and avoid duplication, is it possible to avoid a Lingual Design? If it’s possible, is it likely or reasonable? My gut says “no”.
Hi J.B.:
What I hope is that “Lingual” conveys a sense of a grammar for a multi-class API, as opposed to the word “meaningful,” which I think does not.
This idea is not fully fledged (and as yet has no code samples yet, mea culpa), but my notion is to eventually distinguish between names that are meaningful “in the isolation” of a method or class, as compared to a “Lingual,” meaningful semantics for a group of classes and methods. I am trying to encourage an orientation, via a metaphor: I want novices to think, for, say, a package worth of closely related and cohesive classes (for reuse, for modification), that they are creating a cohesive semantics.
Yes, I know you already think this way.
Many novices do not, and to my mind, can use the metaphor, or some such metaphor, if this one does not suffice.
What I want us to tell novices, up front, is this: think lingually, design lingually, be conscious about creating a consistent semantics, however hobbled it is by strong typing. And yes, this includes meaningful names a la Ottinger, and revealing intention a la Jeffries and Astels and others, etc, etc. The difference is its granule of focus.
Cheers,
–Patrick
I like “lingo”. I’m thinking of saying things like, “I’m having trouble picking up the ‘lingo’ of this class/package/project.” That usage, to my way of thinking, adds a helpful concept to the conversation about code (which, IMHO, has been preoccupied with terms like “patterns” for a long time).
I have done some thinking (and writing) about the term “lucid” and I like that word as well:
1. Easily understood; intelligible.
2. Mentally sound; sane or rational.
3. Translucent or transparent.
But my thinking has been more in terms of a language’s facility for encouraging lucid code, rather than on the programmer’s goal and skill for writing lucid code. See http://www.clickherder.com/monkey-see-monkey-do and http://www.clickherder.com/more-monkey-business for my code examples
That said, I like “lingo” because it takes “lucid” and goes even further. “Lucid” implies clear, proper, easily understood in a general sense. Lingo suggests a reliance on a shared context, which, let’s face it, we must always have when writing real code together.
I agree completely. When you boil it all down, code is always conformant to a language and dialect(s). You are also always communicating with your code: to both the machine/compiler, and to other programmers. When you create a framework, you’re just creating a dialect, which is then interpreted by other programmers.
As a somewhat related aside, one of the more interesting things I’ve come across recently was the history of the meta-language BNF and it’s history. Specifically how it related to P??ini’s theory of grammar.