smalltalk

Refactoring misconceptions

September 5, 2005 9:58:58.687

Wilfred Springer clearly hasn't seen the refactoring tools in Smalltalk, or he wouldn't have let loose with this:

But I also remembered some conference sessions on dynamicly typed languages that I attended in the past. None of these sessions ever mentioned the fact that refactoring tools can be so much more powerful if the type is known before runtime. Renaming an operation in a large codebase would be practically impossible. Tracing the usage of a class would be equally hard.

Comments

Could you explain a little more?

[Brian L.] September 5, 2005 11:22:40.000

Since smalltalk is not near the mainstream, I don't think it's reasonable to assume that each person, in order to speak credibly on a topic relating to software engineering, must be familiar with every aspect of it. Though I've spent a little bit of time with the language, I'm still not aware of specifically how smalltalk deals with these refactoring issues. It seems that the biggest problem would be a method-rename. Lexical scoping should solve the variable/class rename problems just fine, and type/signature/return issues go away because of dynamic typing or because changing the "signature" of a keyword method actually makes a different method. Does smalltalk have some magical way I don't know about to tell the difference between two messages with the same selector on different objects? How can you find all the references to a particular method on your object for renaming purposes when the point of the language is that it's not to be resolved till runtime? Until you demonstrate otherwise, I think the java guy has a point. Of course, I've always found refactoring to be much easier/less neccesary in dynamically typed languages anyhow, but it's hard for me to see how automated refactoring tools could be as powerful as those for, say, java. Instead of belittling the author of the quote, why don't you provide a credible and instructive response?

all I know is...

[keith ray] September 5, 2005 13:55:37.000

All I know is that the first refactoring tools were invented in Smalltalk.... so I wouldn't say something is impossible unless I knew the history of that something (and no one is going around trying to conceal that history).

See here and here

In Java projects, where class-names and methods names may not just be specified in source code, but also in XML files, databases, etc., a change-class-name refactoring that only looks at source code could break things. Ditto for method names.

In Smalltalk, where everything is an object living in the image (normally), everything is accessible... all instances of "Class" and "Method" (or whatever the actual class-names are) can be found and queried programmatically without parsing source-code.

Ok...

[Brian L.] September 5, 2005 14:53:51.000

None of what you said or linked to speaks to the refactoring of *calls* to a particular method, which is what I was getting at. You can query the runtime for method objects all day long and change all sorts of things, but since you don't know the class of an object to runtime, you can't know by looking at the code (compiled or uncompiled) whether a certain message send should be renamed or not. I'm not defending java, so much as suggesting that the nature of smalltalk makes the method-rename refactoring non-deterministic. The other benefits of the environment may outweigh this, but I think you'd be hard pressed to feature-match java tools when it comes to refactoring because the type information isn't there and ultimately, some of java's refactorings depend on type information.

a specific example

[Isaac Gouy] September 5, 2005 15:37:10.445

Brian L. wrote: Does smalltalk have some magical way I don't know about to tell the difference between two messages with the same selector on different objects?
To be more specific, say we wish to follow the example provided by Keith Ray and rename Integer>>+ to Integer>>plus:

Using rename from the Method menu gives a dialog "This will modify all 10 implementors. Do you want to proceed?" but we didn't want to modify all 10 implementors just Integer>>+

It seems that Brian is quite reasonably asking: Is there a way for me to use the rewrite engine to rename just implementors and senders of Integer>>+ rather than all implementors and senders of +

And if there isn't a way to do that, then it seems Wilfred Springer's comment was accurate and James is blowing smoke.

Rewrite engine

[ James Robertson] September 5, 2005 17:16:33.954

Comment by James Robertson

I'm fairly certain that the rewrite engine can accomplish that, but I haven't had the need. In practice, in my code, I haven't run across that problem very often.

who has refactoring misconceptions?

[Isaac Gouy] September 5, 2005 17:43:41.061

James, would you agree that your posting strongly implied Wilfred Springer wrote incorrectly ("refactoring tools can be so much more powerful if the type is known before runtime") and in ignorance of the refactoring tools in Smalltalk?

Would you now agree that you don't know enough about the refactoring tools in Smalltalk to know if Wilfred Springer is correct or incorrect?

Isaac

[ James Robertson] September 5, 2005 17:47:13.679

Comment by James Robertson

I said - "I haven't had the need". I think the cost imposed by typing is higher than this benefit, based on my experience.

senders of a message

[keith ray] September 5, 2005 18:30:21.209

Finding all senders of a message has been around since the original release of ST-80... it brings up a list of every caller for a named method (including, I understand, wildcarded search strings). Since that functionality is so old, it didn't get mentioned in the context of the Refactoring Browser. (See docs for the "System Browser".) You're right that the class of the callee is not always explicitly listed in the code, (*) but in practice (from what I hear) that is not often a problem. There are naming conventions which tend to identify the type that was expected for a variable or parameter, and someone using TDD or extensive unit testing will be able to run the unit tests to identify code that calls the method in question. There have also been various extensions to Smalltalk environments that do various kinds of static or dynamic analysis to identify the classes of objects that various parameters and variables refer to. One of the more interesting extensions I've heard about lately is "Traits", which allows a form of multiple-inheritance (of behavior but not data). Footnote: (*) sometimes it is: " x := SomeClass new. x someMessage. ... " is pretty unambiguous as to what class of object that 'someMessage' is being sent to.

James

[Isaac Gouy] September 5, 2005 18:59:20.967

"Since the rules only look at the names, you can change code that shouldn't be changed. For example, if we have another class that defines the at:ifAbsent: message, but not the at:ifAbsentPut: variant, then our rewrite rule about would break all uses of this other class since it is only going by the message name at:ifAbsent: not the type of the object that receives the message."
Refactoring Browser - Rewrite Rule Editor
"refactoring tools can be so much more powerful if the type is known before runtime"
Have you the grace to admit that Wilfred Springer is correct?

I've been stung..

[Sean M] September 5, 2005 19:37:23.880

I got stung by the Smalltalk Refactoring issue described here. You make the mistake once and then you get more careful after that..

Refactoring a well known symbol is a bad bad idea. At a global scope anyway. Dolphin provides many scopes to provide the refactoring within. (Global, Package, Class, Method), so its not all bad, but the default option is Global, and it can cause issues when you don't realise you've been refactoring all of the built in methods :)

Edit refactorings before they are committed

[Tim] September 6, 2005 11:21:30.021

From the VisualLauncher -> Settings toobar button, select "Browser" in the left had selection list. Check the box "Show Refactoring Changes" This will allow you to see the changes that will be made. One can also remove some of the changes by the method or by class.

automatic - manual

[Isaac Gouy] September 6, 2005 12:30:45.534

Time wrote: "One can also remove some of the changes by the method or by class"
And here we reach the difference between what refactoring can do when type information is available and when no type information is available. With type information we can automate refactoring; without type information we must read the code for each method, figure out what we think the types are and decided if the method should be changed.

As Wilfred Springer wrote refactoring tools can be so much more powerful if the type is known before runtime.

Of course, saying "Renaming an operation in a large codebase would be practically impossible" is hyperbole - it is practically possible but quite tedious (the more polymorphism, the more tedious).

theory vs practice

[Tim] September 7, 2005 10:49:44.142

I've been using the Refactoring browser in Smalltalk for years and have not run into the problems you describe. The capability to review changes before committing them seems to me to be a plus. I already know what classes I want changed and not changed so its not a big deal. If there are a huge number of changes then I would be concerned even in a typed system as you describe. Automation of mass changes in a large application will leave the system in an unpredictible state. Anyway method names can be made very descriptive in Smalltalk including the methods that accept parameters (#someMethodNeedParm1: andParm2:). In the c-ish langs I can see the problem (someMethod(parm1, parm2). In Smalltalk most likely the method should clearly describe the action to be taken and each parm needed, so renaming a mehtod that may be used in multiple classes would not be a huge problem. If I used a method name that is common to the core smalltalk environment then renaming needs care and the use of the show changes is very helpful.

Really?

[] September 7, 2005 11:57:31.452

If there are a huge number of changes then I would be concerned even in a typed system as you describe. Automation of mass changes in a large application will leave the system in an unpredictible state.
Really? Could you elaborate? If a program compiles in a static language after a method renaming refactoring, doesn't that guarentee correctness?

follow up

[] September 8, 2005 13:05:08.654

Your probably right about the static compilation. I have no experience with the c-ish refactoring tools. I hope that you are productive with the c-ish refactoring tools as we are with the smalltalk tools. Whatever gets the job done.

Why Types Isaac?

[Peter William Lount] September 9, 2005 9:57:05.124

Since you pointed me to this discussion I'll ask again: Why Types Isaac?

 Share Tweet This
-->