|« April 2012|
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.
I started a new Rails project last week. The customer had done an unusually good job of working out the site look-and-feel ahead of time, so my first day on the project I grabbed the HTML mockup of the first page we were going to implement and turned it into a Rails app. It was still static HTML -- there was no code at all in the application, and no database yet -- but the page was being rendered by the new Rails application. I carved the page up into a layout, main template, and appropriate partials, and got ready to start implementing features the next day.
But before I called it a day, I had an idea that seemed promising. I spent about 10 minutes (certainly not more than 15) going through that HTML looking for anything representing a feature that needed to be implemented. That meant links and buttons, plus anything that needed to be generated dynamically. Whenever I found something like that, I added a CSS class to the markup: "unimpl".
Then, using Chris Pederick's Web Developer Toolbar extension in Firefox, it became a simple matter to quickly highlight all of the not-yet-implemented features in the application:
Just use CSS selector syntax in the dialog to select all elements with class "unimpl":
Here's what the result looks like (demonstrated with the Streamlined sample application rather than my current project):
(By the way, those features are really implemented in Streamlined; I just marked that application up as an example.)
This provides a great, easy way of keeping track of things that remain to be done. As I implement those features, I replace static HTML with generated HTML, and I just delete the "unimpl" class as I go. Sometimes I partially implement a large part of the page; in that case, I move "unimpl" from the surrounding element to the individual pieces inside that I haven't completed yet.
This is no substitute for requirements, or an issue tracking system, or anything like that. But it's already proven very convenient as I implement features, trying to decide what's next. It's particularly nice when I have just a few minutes available … maybe not enough time to tackle a big feature, but I can quickly scan to see if there are any small things I could fix.
It takes just a little bit of discipline and consistency on the part of the development team, but it was really easy to annotate that first mockup, and now that the layout and commonly used partials are done, doing subsequent mockups will be even easier.
This morning I became annoyed by the three-click process to highlight those elements using the toolbar (how lazy is that?) so I hacked TextMate Footnotes to add a quick toggle link in the footnotes div at the bottom of the page:
If you're interested in that, let me know. If it's useful to people, I'll polish it up and submit it for inclusion in footnotes.
For a while now I've been using Duane Johnson's TextMate Footnotes plugin with my Rails development. It's been the biggest boost to my productivity since I started using Rails. I kind of assumed that most Rails developers were using it, but apparently it's not as widely known as it should be.
I first learned about footnotes from Geoff Grosenbach, when he interviewed me last year for the Ruby on Rails Podcast. Geoff mentioned that it links lines from a Rails stack trace (displayed in the browser in development mode) so that clicking will open the appropriate file in TextMate, positioned to the correct line. Nice!
But it does more than that. When there is no error and your page renders correctly, the plugin adds "footnotes" to it: a little div at the bottom of the page with useful features for development and diagnosis:
You can show the contents of the current session, current cookies, the parameters passed to the controller, and the last 200 lines of the Rails log. But the most useful things are the links that ask TextMate to open the controller, view, layout, and other important files that Rails used to build that page. (It only does all this when the app is running in development mode, of course.)
If you're doing Rails development on OS X, install it this way:
$ script/plugin install -x http://macromates.com/svn/Bundles/trunk/Bundles/Rails.tmbundle/Support/plugins/footnotes
If you aren't on OS X, I know there are ways to define URL schemes like the "txmt" scheme TextMate defines on OS X. What are you waiting for? Arrange for "txmt:" URLs to open your favorite editor appropriately, install footnotes, modify it (to remove the "only on OS X" code), and have fun!
I’m always interested in the things that other fields can teach us about my own field of programming. My blog on bridge building from a few weeks ago is one example; I also recall when Dave Thomas pointed out some relevant phrases from the U.S. Marine Corps’ document on Warfighting, and of course Dave and Andy learned about the Dreyfus Model of Skill Acquisition from reading about the nursing profession.
Now Greg’s found a delightful example from the world of woodworking. Read Greg's blog, and the short article it links to.
"So in your leisure or in your active moments, if you wish to advance, you must be alert."
Every now and then I hear someone compare software development to bridge building. (Bridge building, of course, is just a placeholder here for "real engineering," which in the speaker’s mind is much cleaner and more manageable than the current messy state of software development.) Sometimes it’s "software development isn’t like building bridges," while on other occasions it’s "software development should be more like building bridges." In either case, though, the implication is clear: bridge building is predictable, rote, unexciting, very manageable work, and software development is not. The only difference is whether the speaker likes software development the way it is, or wishes it could be different.
I think both positions are misinformed. And no, I’m not about to pull out my magic prescription for how to solve all the software industry’s problems by making it more like bridge building. In my experience, software developers tend to have an idealized, unrealistic view of what "real engineering" is like. Sure, some kinds of bridges are so well understood by now that there’s very little risk involved; freeway overpasses and the like are churned out regularly and routinely (in much the same way that simple CRUD applications, whether web- or desktop-based, are usually safe bets for even inexperienced development teams). But from what I’ve learned, bridge building in general is a lot more like modern software development than most people realize. And I think the software industry can learn some lessons from the history of bridge building.
Maillart was seeking new designs that would take advantage of the properties of a new material: reinforced concrete. It had been in use for some time, and builders had figured out how to work with it, but Maillart realized that reinforced concrete had unique properties that would permit the use of new forms, resulting in significant savings (due to reduced material costs).
The formal methods used by civil engineers at the time weren’t up to the challenge of analyzing these structures (known today as "hollow box arches" and "deck-stiffened arches"). Maillart verified the designs empirically, by building models, rolling barrels full of concrete over them, etc. etc. The civil engineering establishment of the day vilified him as a charlatan who was endangering lives and cheating his customers by building bridges that would fall down. But he got customers anyway, because his designs were much, much cheaper to build. (The fact that they were strikingly beautiful didn’t hurt.)
Another engineer of the time was Leon Moisseiff, a strong proponent of formal methods and the developer of "deflection theory," at the time the state of the art in mathematical analysis of suspension bridges. Moisseiff designed a bridge intended to be a showpiece for the power of deflection theory. It was the Tacoma Narrows bridge. After its famous collapse, other bridges that had been designed with Moisseiff’s assistance (such as the Golden Gate) were retrofitted with stiffening trusses. It turned out that deflection theory was deeply flawed in a way that nobody had yet realized.
One of Maillart’s bridges did fall down … after being buried under an avalanche. One was demolished because more capacity was required. The rest are still in use, and the forms he pioneered are now standard design taught to civil engineers. The math eventually caught up with Maillart’s methods. As the story I linked to above notes, Maillart is an inspiration to the current superstar of bridge design, Santiago Calatrava.
I think there are some important lessons here for the software profession. The lesson is definitely not that "real engineering" is a mechanistic, purely construction-oriented process, which is the lesson that is usually assumed when software is compared to bridges.
Note: I have at best an interested layman’s knowledge of the history of bridge engineering. Sources include Henry Petroski’s wonderful Engineers of Dreams: Great Bridge Builders and the Spanning of America for information about Moisseiff, and David P. Billington’s article "The Revolutionary Bridges of Robert Maillart" (from the July 2000 edition of Scientific American). For what I believe to be the best description of the true relationship between software development and other engineering disciplines, I encourage you to read "What is Software Design?", Jack Reeves’ brilliant essay.
Ben and Dion are planning to use a similar format for upcoming episodes, and I’m thrilled—I think it works really well, providing a continuity and depth of analysis that you just don’t get from a single interview. Bravo, guys!
I’m not the least surprised by this, and I don’t know many serious programmers who will be. Programmers and computer scientists have been raising a stink about electronic voting machines for several years, but it’s been difficult to explain to non-programmers the full extent of the danger. It’s nice to have a video that shows the complete cycle: how the machine can be subverted, how it can steal votes, and how the rogue software can cover its tracks. (The one thing about the video that did surprise me, by the way, was how quickly and easily the physical act of subverting the machine can be accomplished.)
Beyond this one example, though, are more dangers. I don’t believe that any such machine — any machine without a voter-verifiable paper trail — could be sufficiently secure for the purpose, even in principle. And that’s not just a hunch. I have good reasons for believing that it’s not possible to make such a machine secure enough to be entrusted with our votes.
The paper that’s available on the page with the video describes in detail the research that was performed, and the findings. It unavoidably contains some technical jargon, from the fields of software and security. Overall, though, it’s quite accessible, and I don’t think you need to be either a computer or a security expert to understand the issues. There’s also an executive summary that hits all the highlights.
Two years ago, when I went to vote, I was not amused to find myself having to vote on one of these very machines. In light of that, though, I most definitely was amused by the "My Vote Counted" sticker I was given as I left, and I felt compelled to augment the sticker's message. I’ll probably have to vote on the same machines again in a couple months. But I hope we’ll turn toward more secure, reliable equipment for future elections.
Avi has blogged before about the idea of implementing Ruby on an existing, fast Smalltalk VM (the object models of the two languages are very, very close; the biggest hurdle would be Ruby’s richer method argument handling).
But, as Avi points out, the open-source availability of Strongtalk, including the VM implementation, is a big development. Although it’s now ten-year-old technology, Strongtalk nevertheless represents the state of the art in dynamic language implementation. Strongtalks basic principles of operation have been widely known for years (although apparently not by Joel), but actual implementations of those ideas have all been in proprietary products. (The Hotspot source is available, but not as widely as a true open-source products.) For OSS developers who want to learn, the closest they could get to a cutting-edge dynamic language implementation has been Self. But although the techniques in Strongtalk originated in Self, the Strongtalk team took them a lot farther.
Sun’s HotSpot VM for Java already incorporates these techniques, so JRuby is already on track to take advantage of them. I don’t know that much about the CLR, but it wouldn’t surprise me to learn that it uses similar ideas, which bodes well for IronPython and an eventual Ruby implementation for the CLR. But there’s still a performance limitation imposed by the mismatch between object models, and the unavoidable mapping layer that implements one atop the other.
Mr. Malsky, I predict that in three years, Ruby will have performance rivaling Strongtalk’s — whether by someone adapting Strongtalk itself to run Ruby, or by mining it for techniques that can be rolled into YARV or some other VM project.
(Well, maybe three years is a bit optimistic. But I can hope.)