|« November 2014|
I’ve had some success teaching the concept of cohesion using an unusual approach that exploits the word’s etymology. I know that sounds unlikely, but bear with me. In my experience, it seems to register well with people.
Cohesion comes from the same root word that "adhesion" comes from. It’s a word about sticking. When something adheres to something else (when it’s adhesive, in other words) it’s a one-sided, external thing: something (like glue) is sticking one thing to another. Things that are cohesive, on the other hand, naturally stick to each other because they are of like kind, or because they fit so well together. Duct tape adheres to things because it’s sticky, not because it necessarily has anything in common with them. But two lumps of clay will cohere when you put them together, and matched, well-machined parts sometimes seem to cohere because the fit is so precise. Adhesion is one thing sticking to another; cohesion is a mutual relationship, with two things sticking together.
This is also why we refer to a sound line of reasoning, for example, as coherent. The thoughts fit, they go together, they relate to each other. This is exactly the characteristic of a class that makes it coherent: the pieces all seem to be related, they seem to belong together, and it would feel somewhat unnatural (it would result in tight coupling!) to pull them apart. Such a class exhibits cohesion. No glue is required, you don’t have to build extra code to make the pieces fit together; the pieces hang together naturally because they’re closely related. In contrast, sometimes a class will seem to have its fingers in way too many parts of your system. Such a class is adhesive, and that’s not what we’re looking for.
And whereas coherent means things fit well together, we use the word "adherent" to refer to a follower, and there’s a connotation that the follower isn’t necessarily wanted: a hanger-on.
There’s another common word that stems from the same root: "inherent". Something that adheres sticks to something else, and two things that are coherent mutually stick to each other, but something that is inherent isn’t stuck to something so much as it’s embedded: it is an integral part of the other thing, tightly and inextricably bound. Although you don’t hear them very often, the two sister words "inhere" and "inhesion" are real words, as well.
So cohesion/cohesive/coherent occupy the middle territory between the sort of arbitrary, forced relationship of adhesion/adhesive/adherent and the integral, unbreakable relationship of inhesion/inhesive/inherent. That mental picture often helps me make wise decisions when I’m designing and refactoring. I want to build classes that are cohesive, not adhesive.
Michael writes, "For years, in the software industry, we’ve made the assumption that some language features are just too powerful for the typical developer—too prone to misuse." I’ve heard that argument many, many times, from people I strongly respect. And for a long time I believed it. For several years after I became enthusiastic about Ruby, I worked in places where most of the developers were typical, average programmers, and I refrained from really pushing Ruby in those environments because I thought Ruby was too powerful for them.
Then, a few years ago, I spent some time in a role where I was doing architectural reviews of IT projects (mostly Java projects). And one day I came to a shocking realization: there’s no way those projects could have been screwed up any worse if they had been written in Ruby.
What was alarming and depressing about those Java projects I was reviewing was not that they were poorly designed. I expected that; design is, after all, difficult. No, the surprising thing was that somehow, against all odds, the developers had managed to wrestle these monstrous designs over the finish line. The sheer dogged determination it took to do so was impressive and horrifying. I would have given up in despair long before.
The experience taught me a valuable lesson:
Weak developers will move heaven and earth to do the wrong thing. You can’t limit the damage they do by locking up the sharp tools. They’ll just swing the blunt tools harder.
I’ve been working full-time in Ruby now for almost four years. Everything I’ve seen while working on Ruby projects confirms what I realized back then, and it matches what Michael wrote about the ethic of responsibility that a powerful language like Ruby fosters. Ruby isn’t a panacea. The weak developers will wreak havoc in Ruby projects as well. But I think Ruby also makes it more difficult to hide from those mistakes without learning something from them. Yes, many Ruby projects have design weaknesses, but the usual standard is better than what I’ve seen in other languages, not worse.
If you want your team to produce great work and take responsibility for their decisions, give them powerful tools.
Like Chad, I think MagLev’s initial performance numbers will hold up. It’s possible that as it matures it will get slower, but it could get a lot slower than it is now and still easily be the fastest Ruby VM around.
And I agree with Chad that it might even get faster. I’ve also spent some time investigating how to make Ruby run on a Smalltalk VM, and it’s a really close fit. During the presentation at RailsConf, either Avi or the Gemstone guys revealed that they had modified their Smalltalk VM by adding two new bytecodes aimed at Ruby. I’ll go so far as to speculate: it’s likely that those two bytecodes deal with variadic methods and creation/lookup of dynamic instance variables. It sounds as though the core Ruby language is nearly complete on top of that base, so it’s easy to imagine that the early, hurried implementation of those two new bytecodes could be optimized further. And some of the Ruby features that have hurt JRuby’s performance will be no problem on a Smalltalk VM—ObjectSpace, for example, can work using the same facilities that Smalltalk’s development tools use today.
The persistence story is amazing. Avi and the team at Gemstone plan to implement an interface that is similar to ActiveRecord, but cleaner, since the object/relational impedance mismatch no longer applies.
Finally, there’s the question of licensing. I’ll be shocked if MagLev is open-source, but I think there’s room for a proprietary Ruby implementation. The team has committed to complying with RubySpec, which means I’m not very worried about compatibility. Most Ruby projects won’t need MagLev, but the ones that do will gladly pay for a top-notch, supercharged implementation with great scalability and persistence stories.
I’m definitely looking forward to hearing more about MagLev over the next few months.
The story so far (for the probably 99% of my readers who don’t read a lot of Smalltalk blogs): Avi and I had a discussion last year at OSCON about Ruby and Smalltalk, and Rails and Seaside. Avi was once a Ruby guy, but switched to Smalltalk (but he’s still friendly to the Ruby crowd). I’m currently a Ruby and Rails guy, but I’ve evangelized Seaside rather extensively.
During our discussion, we talked about the different tradeoffs that the two communities make.
I related that story to Neal Ford, which helped him to understand some things he’d been wondering about, which led to these blogs. In a vastly oversimplified nutshell: Ruby has some strengths that Smalltalk is missing, because it gives you a place to put all your stuff. (Please note that this does not imply that Smalltalk is fundamentally inferior to Ruby. I believe Smalltalk, in turn, has other strengths that Ruby is missing.)
James Robertson took issue with Neal’s blog, but gave no real evidence to back up his point. I was getting a bit frustrated with the "all heat and no light" nature of the discussion, until Avi saved the day by explaining the Smalltalk way of doing things.
I have to say that I think to some degree Avi confirms Neal’s and my point: Ruby provides a ready-made place for stuff like "has_many", whereas in Smalltalk, to provide similar functionality while preserving the "statement of intent" (as we’ve been calling it) the tool has to build a place for that statement. Which is fine, but it seems to me that "to make the generated code round-trippable," as Avi says, adds extra complexity to building such tools.
Again, this is not to say that the Ruby way is necessarily superior. These different approaches reflect different tradeoffs. That’s the conclusion Avi and I reached during our chat last year, and we were both happy to agree to disagree. Smalltalkers tend to prefer generating the methods directly, because that way they can get the most value out of their terrific toolset. And Alan Knight (in his comment on James’ blog) definitely prefers generating the methods in-place, so that the full API will be visible to developers. We Rubyists, on the other hand, having generally crappy tools, are free to do things in a way that even rdoc doesn’t understand, and I for one like the fact that all those boilerplate methods aren’t physically cluttering up my source code. You pays your money and you takes your choice.
My interest in discussions like this is not to have a language war, and especially not between Smalltalk and Ruby. (There’s brother against brother for you.) The point is to learn from each other and, through learning about the other, to understand more clearly the strengths of both approaches.
It’s absolutely certain that the biggest factor in their early maturity as programmers is that they’re just very smart guys. I’m also sure they started programming at a younger age than I did.
But Alan and I think there’s a third factor: Ruby itself. Ruby helps to teach those good programming skills, and makes them easier to learn. I got the chance later to talk to Koz about it, and he enthusiastically agreed.
The first thing I said in my talk on Saturday was that Rails is like an instructional laboratory for how to build good software. I think that’s the thing I like most about Rails. A big part of that is Ruby itself. Ruby, its libraries, and its documentation are filled with examples of clean, well designed code, and Ruby makes it easier than most other languages to create clean code yourself. The community values and encourages it. Ruby teaches good programming by setting the goal, lowering the barrier, and providing a lot of assistance and encouragement.
I was thrilled last year when Chris Pine’s Learn to Program was published, and now _why has taken up the flag with his brilliant Hackety Hack. We should support efforts that are focused on using Ruby to teach children to program. I think it’s the best way available right now to grow a generation of great programmers.
Hot on the heels of that, Chad strumming on his ukelele while Rich Kilmer gamely tried to deadpan through his introduction of David Heinemeier Hansson.
From David’s RailsConf keynote: "What we want to manipulate … is people." (With a little careful editing, you can turn a harmless quote into just about anything!)
Seeing Uncle Bob speak. He’s a master, and I haven’t seen him speak for about three years. The talk was about clean code, and I already understood about 48 out of the 50 minutes of material he presented—but as a speaker, watching the way he presents and works the audience is always fantastic and educational. (James' photo captures the magic perfectly.)
Another quotable moment from David (this time with no editing required) during Alan’s talk: "People don’t stop doing stupid things because you make fun of them once."
Being blocked out of Adam Keys' standing-room-only talk. (Not a highlight for me, but I was thrilled for Adam, and it was great to see so many people interested in such an important but underemphasized topic.)
Ze Frank. ‘Nuff said.
My audience cheering wildly. I always thought you had to deserve something like that, but apparently you can just ask! I’ll try that again sometime. (But even though I got the cheers by cheating, it was nice to know everyone was on my side. :-)
James Adam is a great speaker, and his talk on "The Dark Art of Developing Plugins" was loads of fun.
Jeff Barczewski and Deb Lewis demonstrating MasterView at the lightning talks session. Deb told me about MasterView last year at OSCON when she and Jeff had just begun working on it. MasterView is an alternative templating system for Rails that’s HTML-centric, designed to allow page designers to use HTML editors like Dreamweaver within a Rails project. I was a bit skeptical of MasterView, because I’m most comfortable when the programmers are in control of HTML generation. But Deb and Jeff get it; MasterView works just like a Rails templating engine should. Reopen the page in Dreamweaver, edit things, save, and when you click refresh in the browser the changes are there. Great stuff.
The personal page editor demonstrated by the guys from Revolution Health. Impressive!
Rich and Marcel finally believing I wasn’t a werewolf.
Charles Nutter and Tom Enebo giving some really boring demos of JRuby. Boring is great for JRuby. It’s supposed to be just Ruby, on a different platform, and with Java integration that just seems natural. And it is! That was the challenge for them, to make JRuby boring, and they’ve done a great job.
Erik Hatcher’s fantastic talk about Solr on Rails, with demos of very cool things he’s doing with full-text search at the University of Virginia.
All of James' photos. He keeps getting better.
Beginning with many attendees at the Pragmatic Studio’s introductory Guidebook tutorial (but continuing throughout the week), the Ruby community raised (at last count) $26,000 for some excellent causes. (Update: over $33,000!)
Finally, Dave Thomas’ closing keynote was the perfect finish. Thanks so much, Dave.
But of course, at all of the really good conferences the best things happen in the halls and over lunch and dinner. I had the pleasant privilege of chatting with loads of great people—some old friends, and some new. I’m already looking forward to next year.
Tim Bray, as he so often does, nails it.
Being intentionally provocative to knock people out of old assumptions is all well and good … but even though I love Ruby, and am so glad to be working in it now after 11 years of Java, my perspective is more pragmatic.
There is no perfect world. You gain a lot by giving up static typing for dynamic typing, but you also give up some things. It’s six of one, a half-dozen of the other. Or maybe 9 and 3. Whatever. Whether the tradeoff works in your favor depends on a lot of things — the kinds of systems you’re building, the process and practices you use, how well you understand your domain, and other things. And folks like Tom Ball make great points when they point out some of those tradeoffs.
(Furthermore, "static typing" doesn’t necessarily mean "Java-style static typing." It’s just that the industry right now is all wrapped up in static typing done the wrong way, while ignoring static typing done the right way.)
In spite of all that, though, I do agree (mostly) with Neal and Stu. I, too, would rather write Ruby in vi (er … that is, emacs) than Java in IDEA.
If you’re still on the fence about this, or even downright skeptical, here’s my advice. Having been a static typing bigot for a very long time, I know all of the arguments from that side. I used them myself. And what I’ve learned is that you can’t figure this out by thinking about it. There are things about dynamic programming languages — and about how programmers work in those languages, and how systems are designed in those languages — that you don’t really understand until you’ve gained some real experience. It’s the Blub paradox at work. Knowing about the flaws in the language isn’t enough either. What’s important is knowing when they bite you, and how badly, and what you have to do to stay clear of them. Primitive types in Java represent one of that language’s worst flaws, but in my many years of Java programming I was impressed by how rarely they really got in my way. (They did get in my way, but not as much as I expected them to when I first learned Java.)
So just give Ruby (or Groovy, or Python) a try. Find a way to build a system of some reasonable size (a few thousand lines or so) in it. Give yourself time to get over the learning curve of syntax and names, and learn to think in the language. Decide based on experience, not fear or doubt.
Our field is at its worst when we act (when we teach, design, manage, plan, argue) as if we’ve got it all figured out, as if we’ve got it down to a science. Nothing could be further from the truth. Our field is one of creativity, experimentation, guesswork, hunches, and feedback. Above all, feedback.
Nothing blinds us and deafens us to feedback like being convinced we’ve found the one true way.