That’d be Cédric Beust, who, writing both in my new comment system and his own space, declaims “The bottom line is that IDE’s for dynamic languages will *never* be able to perform certain refactorings, such as renaming” and asks “Who wants a refactoring IDE that ‘works most of the time’?” He closes with a major dynamic-language diss: “I'm convinced that they are not suited for large-scale software development”. Obviously a fun-loving fellow. Geek girls and boys, I think that man is getting in yo face.



Contributions

Comment feed for ongoing:Comments feed

From: Ian Bicking (Oct 02 2006, at 20:54)

I think Cédric is right about the limited potential of reliable refactoring in an IDE.

I personally don't think refactoring should be done on a large scale anyway. On a large scale you need public and stable APIs, which means you don't refactor or rename them, you create new interfaces and deprecate the old ones. Creating (or better identifying) internal boundaries turns big projects into smaller ones. And once you don't have a monolithic project, no IDE can know where your code might be used.

So I'd turn it around and say that IDEs enable large monolithic software projects, and so are enablers of bad software design.

[link]

From: Patrick Mueller (Oct 02 2006, at 22:11)

This is simply a religious issue. We went through similiar arguments ten years in the Smalltalk community when Java appeared.

I've come to feel the same as Ian over the last year. If it wasn't for the fantastic IDEs available for Java, no one would be able to code in it, at least with the hugemongous frameworks we have today. And the overly verbose patterns in use in Java - interfaces for everything, factories, etc etc. If you don't live in an overly verbose world, you don't need a super whiz-bang IDE.

[link]

From: assaf (Oct 03 2006, at 00:42)

Anyone knows an IDE that works all of the time? One that can substitute names scattered through sources, XML files, database schemas, remote APIs, HTML IDs, build files, reflections?

IDEs are easier than grep, but they both have the same scalability problem. The easiest solution I found is to have less mentions of each name.

[link]

From: Reinier Zwitserloot (Oct 03 2006, at 03:30)

No.

I know of at least one project which fragmented it's monolithic big bad self into a series of mostly independent projects (I think they're up to 7 now, with 3 of those completely stand-alone, 3 others dependent on only one, and only that 7th one ties them all together).

Without refactoring that would have been an utter nightmare, probably impossible, as they are on the clock; they have to release a new version every so often due to service contracts. Any change to the codebase structure can't take more than about a month tops.

I am again surprised with this view; in the real world it just doesn't hold water, in fact, the opposite is true. Just like 100% code coverage for your tests is a ridiculous proposal compared to just typing your identifiers, these statements are backwards.

As I've <a href="http://www.zwitserloot.com/2006/10/01/pythonruby-script-languages-nothing-more/">mentioned previously</a>, python and ruby do not scale for software development. Cedric said the same thing. He's absolutely right.

[link]

From: clint hill (Oct 03 2006, at 05:20)

Ian makes a strong point. Enterprise systems suffer from good Refactoring tools. It has happened to me.

However - it is clearly a huge time saver when you have this feature for a desktop based application. Java Swing app for example.

Ruby is such a wonderful language to read, and when good design practices are kept, I think refactoring features becomes a non-issue.

[link]

From: Pierre Phaneuf (Oct 03 2006, at 07:33)

Like some mentioned on Cédric's page, optional typing can be very useful, on my opinion. Proper type inference might also be a solution, but this is still a subject of research, and being somewhat conservative, I'd prefer to rely on static typing, being quite familiar with it.

As mentioned in his article and comments, Groovy has optional typing, as well as Objective-C(++), and the upcoming Perl 6. I'm partial to Objective-C's "duck typing when useful, static typing when more appropriate", myself. Note that it does have "doesNotUnderstand"...

[link]

From: Lennon (Oct 03 2006, at 09:43)

Obviously, without any type annotations you lose a great deal of "automatic" refactoring, but it's far more complicated than just base types in most OO languages, since methods may be part of a interface defined by a superclass, or utilitized by a subclass or mixin.

Even with type inference, you can't cover every potential case in a language like Ruby which provides the 'method_missing' catch-all for dynamic dispatch. Once an object implements 'method_missing', even the most clever refactoring tools are going to fall down, because there an infinite number of possible method calls available on that object.

How do we poor, miguided Ruby programmers ever build systems more complex than "Hello, world!" then? And how on earth could we ever have any real confidence in them? Simple: we follow the model set by the Ruby core libraries, and build our system as a large number of very loosely-coupled components, all interacting via a handful of simple idioms/interfaces (collection indexing and enumeration, function application with blocks, etc.).

However, even more than the lower linecount due to Ruby's concise syntax, this model of minimal coupling and small, easily-understood interfaces makes a lot of the refactoring needed in more statically typed languages like Java and C++ less necessary -- when you don't have 2,000 instances of 'someMethodThatTakesManyTypeArguments(OfVaried types, AndMuch verbosity)', it becomes rather painless to refactor via delgates, dynamic dispatch, etc., rather than term rewriting.

Is it a perfect environment? Certainly not; there are common idioms such as the single method which takes an 'options' hash with a large and poorly-defined domain of values which occur all to often (I'm looking at you, DHH!) and make even line-by-line analysis of methods' interfaces even more difficult to accomplish.

However, just as some of the criticisms of Java from Ruby/Python/etc. codes seem to stem from a lack of awareness of best practices in that realm, I think that really understanding the different model of system and interface design that Ruby facilitates might help to illustrate why we all seem so unconcerned about strict type checking and all its benefits (compiler warnings, refactoring, low-level JIT optimizaiton, etc.).

[link]

From: Daniel Haran (Oct 03 2006, at 09:50)

Tim, you apparently suffer from "fantastic delusions" (says a poster above in their linked blog). There's obviously lots of fun-loving folks reading your blog!

Fun-loving is synonymous with religious, right?

[link]

From: Cedric (Oct 03 2006, at 12:34)

Well, I would certainly love to be proved wrong with my prediction, because I cringe whenever I have to downgrade back to emacs (or the limited Ruby Eclipse plug-ins) when I want to write Ruby code. Actually, I even sometimes choose Java over Ruby for certain projects, not because it's easier (it pretty much never is), but because of Eclipse.

The sad thing is that I have time on my side: after all these years that Ruby/Python and co have been around (more than ten years) and especially with the (vastly overhyped in my opinion) amassed Smalltalk knowledge about refactoring, how come we still don't have a decent refactoring browser for Ruby? (or any other dynamic language, for that matter)

By all means, please prove me wrong and give me back my Eclipse for Ruby!

--

Cedric

[link]

From: Andrew (Oct 03 2006, at 13:22)

Watching people take part in editor wars is amusing. They are a great lesson in human psychology. That aside, it seems to me that you should use the editor that makes you the most productive, be that a standalone program or an IDE. The mistake I see people making over and over is that they do not bother to really learn their editor of choice.

“I'm convinced that they are not suited for large-scale software development”

Fundamentally a dynamically typed language is not going to be as efficient as something that is compiled down to assembler before runtime. There are simply more levels of indirection between the language and the semiconductor. Whether this matters totally depends on your application, regardless of 'scale'. If you know you can meet your performance constraints with a dynamically typed language then great, but if not you'll need to use something closer to the metal. Either way, choosing the wrong language will negatively impact developer productivity.

My only answer to "What's your favorite language?" is "What problem will I be solving?"

[link]

From: Cedric (Oct 03 2006, at 19:10)

Patrick,

I object to your characterization that it's a religious issue (and you probably imply that it should therefore not be discussed because we'll never reach a resolution).

It's not a religious issue because you can prove me wrong very easily: just show me a browser for a dynamically typed language that can do renaming as well as for Java (i.e. let's leave reflection aside). I would suggest starting by one that can refactor the snippet of code I posted on my blog.

I would go even further and claim that when people say it's a religious issue, it's a cop out to avoid facing the truth that it can't be done, but that would be going a bit too far and I don't like to be confrontational (okay, that's a lie ;-)).

[link]

From: Ian Bicking (Oct 03 2006, at 20:14)

Cedric -- I don't think anyone is saying that an IDE for a dynamic is easy. I think this post describes the divide well: http://osteele.com/archives/2004/11/ides

Optional static typing won't help either, or at least it won't give you *certainty* (though it may make some tools work *better*). Nothing optional can give you certainty. Type inferance can help much more given optional static typing, but it again is limited.

I think the answer is that there are a set of important practices that you have to practice to build large software with dynamic languages. Important practices exist for static languages too, but they are different practices. So it's not surprising that someone familiar with the static practices will see that they don't work in a dynamic language, and then feel the dynamic language is lacking.

This is why it seems religious to some people. But you are right, it's not a matter of religion, it's just a hard discussion.

[link]

From: Dan Davies Brackett (Oct 04 2006, at 07:06)

All religious discussions are "just a matter of hard discussion"; it's the fact that the discussion is hard that makes people nt want to have it, and fall back on unexamined proclamations.

On the language front, I am convinced that the language you write in doesn't actually matter all that much. At best, it's a linear factor in a software-quality equation with much higher-order terms than that, like team cohesion and decent management and good programmers and QA staff.

[link]

From: Isaac Gouy (Oct 04 2006, at 11:35)

Cedric wrote "...just show me a browser for a dynamically typed language that can do renaming as well as for Java (i.e. let's leave reflection aside)"

Cedric, this is an example of special pleading, you're asking that we ignore the problems with rename-method refactoring in Java IDEs while accepting the problems with rename-method refactoring in dynamic languages.

Let's be straightforward. The Smalltalk Refactoring Browser does not provide precise automatic rename-method refactoring - without programmer assistance the Refactoring Browser will rename all methods and call-sites. A Java IDE can provide precise automatic rename-method refactoring because we can use type information to identify call-sites. Unfortunately there are other things which break automatic rename-method refactoring in Java.

There are 29 refactorings listed here http://www.refactory.com/RefactoringBrowser/Refactorings.html can you only find problems with 1 out of 29? :-)

[link]

From: Isaac Gouy (Oct 04 2006, at 12:14)

1) Cedric wrote "... still don't have a decent refactoring browser for Ruby? (or any other dynamic language, for that matter) ..."

For some unknown definition of decent ;-)

Back in the day, I would occasionally go into the office, on the weekend, with my colleagues, and refactor the code base by brute force - finding implementors and senders, checking the inheritance hierarchy, manually editing methods ...

From that perspective, bothering about whether rename-method refactoring tool-support is automatic or semi-automatic is a lot of fuss over nothing.

2) The interesting use of the rewrite techniques underlying refactoring tools is changing behaviour not preserving behaviour - and for that we do need lots of unit tests.

"Transformation of an Application Data Layer" Will Loew-Blosser

http://oopsla.acm.org/extra/pracreports/TransformDataLayerReport.pdf#search=%22Loew-Blosser%20smalltalk%22

[link]

From: Assaf (Oct 04 2006, at 14:32)

It's a religious discussion when you claim one is better than another on very narrow technical merits which are insignificant to the end conclusion. (I'm using the royal You)

Will Ruby ever have a good renaming mechanism? If I knew now that Ruby will never find a good solution to this problem, I would choose Ruby, because it makes refactoring so much simpler. It more than makes up for the loss of one act out of a very complex process.

It's the sum of all its strengths against all its weaknesses, and that sum is very hard to reason about. The results are easy to measure: do I get more work done? am I solving more important problems? am I more confident in the software I deliver? But the path from features to results is very hard to dissect because it includes not just language features but also people features.

I'm sure there are exceptions to this rule, but as long as we're discussing needle feature in a haystack preference system, we're having a religious discussion.

[link]

From: Orion Edwards (Oct 04 2006, at 15:13)

Sure you can't implement automated refactorings in dynamic languages. Intellisense usually doesn't work either. These things are obvious.

Is it just me, but really, who cares? Automated refactorings are nice, but they absolutely fall into the same category as other things like intellisense. If they work, that's nice, and it might save you some time, but if they don't work (and a fair amount of the time they won't regardless of your language or project), you still need to carry on and get the job done.

Saying that you can't use a dynamic language for large scale projects because you can't do automated refactoring seems to imply that "large scale projects" require programmers incapable of working without automated refactoring tools, which is so obviously stupid that I'm just going to stop right there.

[link]

From: Aristotle Pagaltzis (Oct 06 2006, at 04:39)

I’ve been reading along and really the arguments don’t seem to make sense to me.

You need automated tools for Java because at least with frameworks that are in use nowadays, you have oceans of code to move. You’ll just drown if you try to do it manually.

But in any dynamic language I’ve used, individual units of functionality tend to be much smaller. The lack of static typing that impedes refactoring also permits code reuse far beyond what can be done in statically typed languages.

It is barely any use trying to draw comparisons. No doubt a dynamic language would falter under conditions as they exist in projects written in statically typed languages. What the static types people are missing, however, is that these conditions are just an artifact of static typing itself! They are not inherent to software development in general, so dynamically typed languages do not have to solve them. In fact, they are better off for not trying.

My experience has been that I can pick up any reasonably clean codebase for a dynamically typed language to find bugs and succeed at reading the code, understanding what’s going and tracing execution, to the point that I can sometimes write a moderately complex patch of acceptable quality even if I start out with no idea about the language at all. With statically typed languages, that would be a hopeless proposition.

Which gets at my main point. At the end of the day, I spend a lot more time reading code than writing any. That remains true regardless of the language. On that count, a significant reduction in meaningless verbiage is an incontrovertible advantage. I’ll gladly trade a little labour in writing code in exchange for lots of savings in reading it.

[link]

From: Isaac Gouy (Oct 06 2006, at 09:26)

Orion Edwards wrote "... seems to imply that "large scale projects" require programmers incapable of working without automated refactoring tools, which is so obviously stupid ..."

Perhaps the implication is that refactoring on "large scale projects" requires a very large number of code changes which just take too long to do manually.

Aristotle Pagaltzis wrote "You need automated tools for Java because at least with frameworks that are in use nowadays, you have oceans of code to move. You’ll just drown if you try to do it manually."

Tool support changes the cost/benefit ratio for change on large scale projects. On large scale projects "you have oceans of code to move. You'll just drown if you try to do it manually."

The difference between 4 years estimated work and 6 weeks actual work, is the difference between not making the change and making the change. (See "Transformation of an Application Data Layer".)

Cedric's criticism is bogus because of his insistence that tool support has no value unless it is complete and perfect. The (vastly overhyped in his opinion) amassed Smalltalk knowledge shows that incomplete and imperfect tool support is enough to radically change what's practical on large scale projects.

[link]

From: David Megginson (Oct 06 2006, at 10:13)

(Nice to see your comment system running, Tim, though Bloglines redisplays your postings as new every time there's a new comment.)

I think it's worth distinguishing between local refactoring and system-wide refactoring. For example, let's say that I have a module of code that exposes 20 interface points (variables, methods, etc.) to the rest of my system. Backing up those 20 interface points may be many thousands of lines of code.

Changing those interface points is always going to be a difficult problem, but most of the time, the refactoring is going to happen inside my module, with methods and variables that are never exposed to the rest of the system. All the code for these is local, and a typical IDE's refactoring support can be a huge help.

IDE refactoring support is never perfect even for a strongly-typed language like Java, but combined with unit tests, it can still allow you to experiment with changes much more quickly and confidently, and that will eventually mean better code.

[link]

author · Dad · software · colophon · rights
picture of the day
October 02, 2006
· Technology (85 fragments)
· · Coding (98 more)
· · Dynamic Languages (45 more)

By

I am an employee of Amazon.com, but the opinions expressed here are my own, and no other party necessarily agrees with them.

A full disclosure of my professional interests is on the author page.