(This is a snapshot of my old weblog. New posts and selected republished essays can be found at raganwald.com.)

Thursday, September 27, 2007
  Java is the right answer to the wrong question, Ruby is the wrong answer to the right question

Large code bases are the problem, not the language they’re written in. Find a way to break/decompose big code bases into little ones.
Bill de hÓra, calming a heated debate

Can we please stop calling each other silly names over the languages we choose and move on to calling each other silly names over our choices for writing literate programs, eliminating redundancy, decoupling modules from each other, and so forth?

The very next time you find yourself being drawn into a debate about Java vs. Ruby, try saying something obscure, such as, Java is the right answer to the wrong question, Ruby is the wrong answer to the right question and see if you can redirect the energy towards exploring new ground instead of stagnating in the same old tired place.

Do not follow in the foot steps of the Sages. Seek what they sought.

When we argue Java vs. Ruby, or testing vs. type checking, we are arguing about foot steps. Take the debate to the next level. What is it we are trying to accomplish with those features? What are we seeking?

My favourite example of this is the subject of automatic refactoring. My current text editor doesn’t perform automatic refactoring (ducks). Are you about to blast a flaming comment or perhaps an entire blog post explaining what a dunderhead I am for not using an IDE that can move a method with a single dialog box?

Stop for a moment. Why do we move methods? What are we trying to accomplish? What is it about our code after we have refactored that makes the code better? Now you have a really juicy comment to make, a deep and insightful point of view to bring to a discussion. Let’s talk about that quality of good code first, and then we can talk about how to get there later, if ever.

So the next time you read that “Strong, static typing is superior because it enables the IDE to provide automatic refactoring support,” take a deep breath. Don’t nod and agree. Don’t shake your head and disagree. Ask a polite question: What are we trying to accomplish with automatic refactoring? And when told that “Unit tests are superior to compiler type checking for catching bugs,” don’t settle for “catching bugs” as axiomatic. Ask what quality really means for code.

Nothing is going to save us from talking ourselves to death. But at least we can debate at a higher level of abstraction.



Comments on “Java is the right answer to the wrong question, Ruby is the wrong answer to the right question:
Okay, I might be violating the spirit of your post here, but can you put a finger on why not having IntelliJ style rename and move methods while coding in Ruby/Python doesn't hurt?

The point of those refactorings is mostly to keep the code understandable by breaking the code into smaller chunks and adjusting method/class names as the intent of the method/class becomes more clear or changes.

How are you able to do that in Ruby coding without being backed up by automated refactoring?
keep the code understandable by breaking the code into smaller chunks

I think we can agree on the importance of smaller chunks. But is taking a large thing and breaking it into a collection of smaller things the only way to do that? How else could we arrive at a program that consists of small chunks?
But it is not the same level which is compared here. Java was pushed for a long time, and is faster than Ruby. However it is also overly verbose and leads to those huge chunks of code.

Ultimately, you cant use Ruby alone except for smaller projects (where it beats perl into the ground; python beast perl as well)

Sooner or later you HAVE to combine ruby with one of the faster languages, and among these there is a wide array of languages C/C++/Java/C#, maybe even D in the future.

Refactoring in a language like ruby is simply on another scale than doing so in one of those "bigger" languages mentioned above
Are the first two comments really comparing Java to Ruby?

Please tell me you are both close friends who are trying to play with my head.
What is your editor (for Java, Ruby etc.) of choice, Reginald?

I use TextMate for Ocaml, Javascript, Java, and Ruby. I drop into IntelliJ and Eclipse for Java from time to time when given projects already organized around them.
You shouldn't need an editor that refactors code for you. You should be doing it while you're working through the code.

Refactoring is excellent but the point at which you do it should be changed.

Mr Braithwaite is gently leading readers to the conclusion that there is a different way to code. The best way to summarize his post is, "Always ask why you are doing something."
"How else could we arrive at a program that consists of small chunks?"

By not writing big chunks in the first place. Did I get my brownie points?

Seriously even if we have a sufficiently expressive and compact notation (e.g. Ruby or Haskell) we still have the huge problem of finding (one of) the minimal correct API that would allow us to express our problem in the most readable way. A refactoring tool let us experiment with possible choices, otherwise we need to be prescient or incur in large doses of pain.
You shouldn't need an editor that refactors code for you. You should be doing it while you're working through the code.

You shouldn't need one, but you're probably going to need a refactoring IDE or wish you had one, because you're going to write bad code. I don't mean you personally, I mean everyone. You're going to make a poor choice about a method signature or something that you call more than once and you're going to want to change it.
enjoyed your post a lot!

It's not the first time i wonder why we tend to talk much more about the medium / instruments rather than about goals.

After all, it should be more about the context we should reflect about - for almost every pro, we could find a con when switching the context ...


I hate the every day language debates. Everybody always makes the same points, but as you said I think they tend to miss the point.

Fundamental features of languages support and influence design decisions, but in my opinion principles of good software design are orthogonal to those features.
principles of good software design are orthogonal to those features

Or to put it another way, Real Programmers can write FORTRAN in any language.
Let hope that the people fighting these pointless debates aren't too busy patting each other on the back to read and understand what you've said here.

Thanks for making my brief visit to programming.reddit.com enjoyable today.
Or to put it another way, Real Programmers can write FORTRAN in any language.
I'm probably dense and just missed your point, but it seems like you're suggesting that if you ignore language features and idioms that you'll end up writing code that doesn't make much sense in the context of that language (basically by definition, right?)

My point was that if you're going through Design Patterns in Ruby, you'll end up not implementing much of them because Ruby solves a lot of the same problems at the language level. However you ought to be able to take away the ideas and goals behind those patterns regardless of which language you're using.
Pat, I was being flippant. What I meant was, you can write Lisp or Haskell or Ruby or Smalltalk in any language, as well.
And like I said, I was being dense :)
Refactor to reduce the entropy of the code. I have to disagree w/ you Reginald: sometimes the path to minimum entropy has to traverse a region of higher entropy cf. simulated annealing. By continuously refactoring an locally reducing entropy you can miss an opportunity to capture some big, chunky abstraction that only appears after your code has gotten cruft with several instances of a pattern.

I don't recall saying that the global optimum is a consequence of local optimization for anything.
Erk... right, I must have confounded your post with some several of the comments on Cedric's blog. Or else I was setting up a straw man. Can't remember now.

That's ok, your comment shows we're thinking along the very same lines, although you expressed the thought in a different, and interesting way!
"What is it we are trying to accomplish with those features? What are we seeking?" This appeared to be the main point of your post.

There is an old adage that says if you have a hammer everything looks like a nail. While ADS is a Rails development firm (our hammer), we also work with Flex, JRuby, and other technologies. The right tool for the right job is our modus operandi. If Ruby and/or Rails doesn't present the best fit technology solution to a client's challenge, then we find the one that will. To solve client challenges, one must be flexible.
I didn't put the time in up front to identify all possible directions my earlier implementation would take. My customer was paying for only so much, today, not the future. I didn't have the foresight to measure which feature would be most desired by my customer. And, the predictions I dared to make, turned out incorrect. I just didn't have the time/money/foresight/divinity to engineer the early release with the right structure that would be resilient to change.

So, I refactor.

The legacy code I inherited to support was originally written 10 years ago. It has undergone some development, bug fixes and new features, but has not undergone a redesign. A redesign would position it for lower maintenance costs and prepare it for a large feature improvement that has finally been funded.

So, I refactor.

The person who I replaced on a project had a very low appreciation for good code, code that is efficient and easy to look at. He disregarded all stlye conventions. He provided his own implementation of features available in the language library. He used features of the language that have been deprecated and replaced by better performing alternatives. And the worst part, he didn't even know how to spell!

So, I refactor.

I find that the dynamic typing in Ruby leads to a few problems. In an environment without solid process, it can become a major impediment when you have more than a few developers that depend on each others' code. Compilers help you detect some things very quickly that Ruby does not.

I ran into quite a few problems with my code when someone changed one of the Rails base classes without telling anyone. It took quite a while to track that one down. With a compiler and strong typing, I'd have caught that one almost immediately, and saved myself quite a bit of debugging time.

Of course, not having much by way of debugging tools just exacerbated the problem.

<< Home
Reg Braithwaite

Recent Writing
Homoiconic Technical Writing / raganwald.posterous.com

What I‘ve Learned From Failure / Kestrels, Quirky Birds, and Hopeless Egocentricity

rewrite_rails / andand / unfold.rb / string_to_proc.rb / dsl_and_let.rb / comprehension.rb / lazy_lists.rb

IS-STRICTLY-EQUIVALENT-TO-A / Spaghetti-Western Coding / Golf is a good program spoiled / Programming conventions as signals / Not all functions should be object methods

The Not So Big Software Design / Writing programs for people to read / Why Why Functional Programming Matters Matters / But Y would I want to do a thing like this?

The single most important thing you must do to improve your programming career / The Naïve Approach to Hiring People / No Disrespect / Take control of your interview / Three tips for getting a job through a recruiter / My favourite interview question

Exception Handling in Software Development / What if powerful languages and idioms only work for small teams? / Bricks / Which theory fits the evidence? / Still failing, still learning / What I’ve learned from failure

The unary ampersand in Ruby / (1..100).inject(&:+) / The challenge of teaching yourself a programming language / The significance of the meta-circular interpreter / Block-Structured Javascript / Haskell, Ruby and Infinity / Closures and Higher-Order Functions

Why Apple is more expensive than Amazon / Why we are the biggest obstacles to our own growth / Is software the documentation of business process mistakes? / We have lost control of the apparatus / What I’ve Learned From Sales I, II, III

The Narcissism of Small Code Differences / Billy Martin’s Technique for Managing his Manager / Three stories about The Tao / Programming Language Stories / Why You Need a Degree to Work For BigCo

06/04 / 07/04 / 08/04 / 09/04 / 10/04 / 11/04 / 12/04 / 01/05 / 02/05 / 03/05 / 04/05 / 06/05 / 07/05 / 08/05 / 09/05 / 10/05 / 11/05 / 01/06 / 02/06 / 03/06 / 04/06 / 05/06 / 06/06 / 07/06 / 08/06 / 09/06 / 10/06 / 11/06 / 12/06 / 01/07 / 02/07 / 03/07 / 04/07 / 05/07 / 06/07 / 07/07 / 08/07 / 09/07 / 10/07 / 11/07 / 12/07 / 01/08 / 02/08 / 03/08 / 04/08 / 05/08 / 06/08 / 07/08 /