Is Automatic Refactoring Possible in Dynamic Languages?
Asked Answered
B

5

10

Perhaps I am limited by my experience with dynamic languages (Ruby on Netbeans and Groovy on Eclipse), but it seems to me that the nature of dynamic languages makes it impossible to refactor (renaming methods, classes, pushing-up, pulling-down, etc.) automatically.

Is it possible to refactor AUTOMATICALLY in any dynamic language (with any IDE/tool)? I am especially interested in Ruby, Python and Groovy, and how the refactoring compares to the 100% automatic refactoring available in all Java IDEs.

Barber answered 23/2, 2010 at 11:14 Comment(0)
T
16

Given that automatic refactoring was invented in a dynamic language (Smalltalk), I would have to say "Yes".

In particular, John Brant, Don Roberts and Ralph Johnson developed the Refactoring Browser which is one of the core tools in, for instance, Squeak.

My Google-fu is weak today, but you could try find this paper: Don Roberts, John Brant, and Ralph Johnson, A Refactoring Tool for Smalltalk, "The Theory and Practice of Object Systems", (3) 4, 1997.

Tubule answered 23/2, 2010 at 12:10 Comment(2)
while this historical note is groovy (excuse the pun), I'm not trying to figure out if it's possible whatsoever. Even in Ruby we have "automatic refactoring" but in practice it doesn't work. In Netbeans there's even a warning, but the reality is quite bleak. Also, I don't know if you declare all types in Smalltalk, which would help refactoring. In Ruby you don't, which is one of the things that makes it so difficult.Barber
Sorry, I didn't mean to only give a historical note. I meant to suggest that the Refactoring Browser's a standard tool in many Smalltalk IDEsTubule
J
13

Smalltalk does not declare any types. The Refactoring Browser has successfully performed correct refactorings in commercial code since 1995 and is incorporated in nearly all current Smalltalk IDE's. - Don Roberts

Jasso answered 23/2, 2010 at 13:21 Comment(1)
Thanks Don, now I'd just need to get a job working in Smalltalk. How can it do refactoring without declaring types (excuse my ignorance)?Barber
M
9

Automatic Refactoring was invented in Smalltalk, a highly dynamic language. And it works like a charm ever since.

You can try yourself in a free Smalltalk version (for instance http://pharo-project.org)

In a dynamic language you can also script refactorings yourself or query the system. Simple example to get the number of Test classes:

TestCase allSubclasses size

Moll answered 23/2, 2010 at 13:35 Comment(0)
P
2

I have wondered the same thing. I'm not a compiler/interpreter writer, but I think the answer will be that it is impossible to get it perfect. However, you can get it correct in most cases.

First, I'm going to change the name "dynamic" language to "interpreted" language which is what I think of with Ruby, Javascript, etc. Interpreted languages tend to take advantage of run-time capabilities.

For instance, most scripting languages allow the following

-- pseudo-code but you get the idea
eval("echo(a)");

I just "ran" a string! You would have to refactor that string also. And will a be a variable or does this language allow you to print the character a without quotes if there is no variable a?

I want to believe this kind of coding is probably the exception and that you will get good refactoring almost all of the time. Unfortunately it seems that when I look through libraries for scripting languages, they get into such exceptions normally and maybe even base their architecture on them.

Or to up the ante a bit:

def functionThatAssumesInputWillCreateX(input)
    eval(input)
    echo(x)


def functionWithUnknownParms( ... )
   eval(argv[1]);

At least when you refactor Java, and change a variable from int to string, you get errors in all the places that were expecting the int still:

String wasInt;
out = 3 + wasInt;

With interpreted languages you will probably not see this until run-time.

Philia answered 22/2, 2012 at 21:18 Comment(0)
T
1

Ditto the points about the Refactoring Browser...it is highly effective in Smalltalk. However, I imagine there are certain types of refactoring that would be impossible without type information (whether obtain by explicit type annotation in the language or through some form of type inferencing in a dynamic language is irrelevant). One example: when renaming a method in Smalltalk, it will rename all implementors and senders of that method, which most often is just fine, but is sometimes undesirable. If you had type information on variables, you could scope the rename to just the implementors in the current class hierarchy and all senders when the message is being sent to a variable declared to be of a type in that hierarchy (however, I could imagine scenarios where even with type declaration, that would break down and produce undesirable results).

Tend answered 24/2, 2010 at 21:2 Comment(9)
thanks for that. What does this mean "it will rename all implementors and senders of that method"? Are methods globally scoped (or something like that?)?Barber
Also, is it Smalltalk day or something? I'll never understand why this question went down the smalltalk route. Did you see a link somewhere? It's kind of more about Python, Ruby and Groovy, but ST is obviously valid as a case.Barber
@yar: Sure, methods are globally scoped. Must be the same in Python and Ruby, but if a method takes a parameter and sends a message to/calls a method on the parameter, it will work for all classes that implement that method, so renaming, say, one call site will mean renaming all call sites and implementations. Only you know which subset of renames will still work when you run the program.Stirps
@Stirps perhaps I don't know what we're talking about. In Ruby, methods on a class are on that class :)... but then they can be mixed-in from other places.Barber
@yar: Sure, methods on any class have a name, and anywhere that calls a method, in a dynamic language, doesn't know the class of the object its calling the method on. It just knows the name of the method. So it doesn't matter which classes have a method of a given name, nor the implementations of them, just the spelling of the name.Stirps
@Stirps so do you tend to use unique method names to help refactoring? In ruby this might help but be annoyingBarber
I don't necessarily use unique method names. Sometimes I just change the name of a method and run all the tests to see which call sites are affected.Stirps
@yar The Smalltalk Day thing's probably my fault. I moaned that I was turning into a Grouchy Old Man on squeak-dev because of your question, and next thing Ralph Johnson was mailing Don Roberts and John Brant, and I guess the Squeakers just jumped all over the question.Tubule
aha! I knew there was an explanation for this, coincidence made no sense.Barber

© 2022 - 2024 — McMap. All rights reserved.