<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Is static typing and refactoring really connected?</title>
	<atom:link href="http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/feed/" rel="self" type="application/rss+xml" />
	<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/</link>
	<description>no buzzwords allowed</description>
	<lastBuildDate>Wed, 01 Feb 2012 18:42:00 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/comment-page-1/#comment-1071</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Tue, 12 Aug 2008 16:15:54 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=14#comment-1071</guid>
		<description>@James

I think you are right, type propagation is much easier than value propagation. You can reconstruct the scope from the program and refactor in it. It may not do exactly what you&#039;d expect it to do, but it would definitely compile and work.

Can you do a runtime instanceOf/cast to a structural type? And wouldn&#039;t that make analysis more complicated?</description>
		<content:encoded><![CDATA[<p>@James</p>
<p>I think you are right, type propagation is much easier than value propagation. You can reconstruct the scope from the program and refactor in it. It may not do exactly what you&#8217;d expect it to do, but it would definitely compile and work.</p>
<p>Can you do a runtime instanceOf/cast to a structural type? And wouldn&#8217;t that make analysis more complicated?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Iry</title>
		<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/comment-page-1/#comment-1070</link>
		<dc:creator>James Iry</dc:creator>
		<pubDate>Tue, 12 Aug 2008 14:15:07 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=14#comment-1070</guid>
		<description>@Jevgeni

The type alias was just a convenient way to explain what I was talking about.  Even if we drop it or make it two different type aliases the argument still stands.  It just may require tracing &quot;backwards&quot; and &quot;forwards&quot; in the relationships between classes/traits and structural types.

The same goes for the case you mention.  If I rename foo to bar in MyClass then it&#039;s possible to statically find all the places that MyClass (or subtypes) is being assigned to a variable, parameter, or return with a structural type and start doing fixups.  There&#039;s no reason we should end up moving from compilable code to uncompilable code in the process (as long as all the affected source is available - but again, that&#039;s a limitation of all rename refactorings).

Look at it this way: a compiler statically analyzes code for type incompatibilities, missing methods/functions/classes/traits, etc.  There&#039;s no reason that a rename refactoring tool can&#039;t use the same or similar analysis and incrementally play &quot;what if&quot; with changes until it gets code to pass that analysis.

Still, you and I are on the same page about the central points.  First, structural type refactoring can create incompatibilities in code we can&#039;t see (e.g. if we&#039;re writing a library).  But then again, renaming a method in a normal nominative class/interface can cause problems in code we can&#039;t see if users of our library have subclassed our code. 

Second, there are some excellent refactoring tools for e.g. Smalltalk.  Refactoring in such a dynamic environment is usually more of an incremental affair than in a statically analyzed environment, but it still works very well - especially if you remember the cardinal rule of always having good test coverage to back you up.</description>
		<content:encoded><![CDATA[<p>@Jevgeni</p>
<p>The type alias was just a convenient way to explain what I was talking about.  Even if we drop it or make it two different type aliases the argument still stands.  It just may require tracing &#8220;backwards&#8221; and &#8220;forwards&#8221; in the relationships between classes/traits and structural types.</p>
<p>The same goes for the case you mention.  If I rename foo to bar in MyClass then it&#8217;s possible to statically find all the places that MyClass (or subtypes) is being assigned to a variable, parameter, or return with a structural type and start doing fixups.  There&#8217;s no reason we should end up moving from compilable code to uncompilable code in the process (as long as all the affected source is available &#8211; but again, that&#8217;s a limitation of all rename refactorings).</p>
<p>Look at it this way: a compiler statically analyzes code for type incompatibilities, missing methods/functions/classes/traits, etc.  There&#8217;s no reason that a rename refactoring tool can&#8217;t use the same or similar analysis and incrementally play &#8220;what if&#8221; with changes until it gets code to pass that analysis.</p>
<p>Still, you and I are on the same page about the central points.  First, structural type refactoring can create incompatibilities in code we can&#8217;t see (e.g. if we&#8217;re writing a library).  But then again, renaming a method in a normal nominative class/interface can cause problems in code we can&#8217;t see if users of our library have subclassed our code. </p>
<p>Second, there are some excellent refactoring tools for e.g. Smalltalk.  Refactoring in such a dynamic environment is usually more of an incremental affair than in a statically analyzed environment, but it still works very well &#8211; especially if you remember the cardinal rule of always having good test coverage to back you up.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/comment-page-1/#comment-1068</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Tue, 12 Aug 2008 01:39:44 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=14#comment-1068</guid>
		<description>@James 

I&#039;m glad we mostly agree.

Even with type synonyms you&#039;re still hitting the case when you rename a method in a usual class/object/trait, but it matches also a method in a structural type. Should you rename the structural type? Both decisions may cause uncompilable code, unless you rename everything in the application, which is overkill.

I&#039;m not sure if practically it will be such a big problem, but it does somewhat hinder refactoring. Mainly I posted this to challenge the &quot;static types make refactoring easy&quot; crowd.</description>
		<content:encoded><![CDATA[<p>@James </p>
<p>I&#8217;m glad we mostly agree.</p>
<p>Even with type synonyms you&#8217;re still hitting the case when you rename a method in a usual class/object/trait, but it matches also a method in a structural type. Should you rename the structural type? Both decisions may cause uncompilable code, unless you rename everything in the application, which is overkill.</p>
<p>I&#8217;m not sure if practically it will be such a big problem, but it does somewhat hinder refactoring. Mainly I posted this to challenge the &#8220;static types make refactoring easy&#8221; crowd.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/comment-page-1/#comment-1067</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Tue, 12 Aug 2008 01:36:58 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=14#comment-1067</guid>
		<description>@Daniel

Actually the problem isn&#039;t &quot;external&quot; code at all. That the example used it was just a coincidence. Consider what a common name &quot;getName&quot; is. You can have such methods all over your application. Only a fraction of them will be ever called with the example method. Choosing which ones to rename with the structural type is a non-trivial task.</description>
		<content:encoded><![CDATA[<p>@Daniel</p>
<p>Actually the problem isn&#8217;t &#8220;external&#8221; code at all. That the example used it was just a coincidence. Consider what a common name &#8220;getName&#8221; is. You can have such methods all over your application. Only a fraction of them will be ever called with the example method. Choosing which ones to rename with the structural type is a non-trivial task.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: James Iry</title>
		<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/comment-page-1/#comment-1066</link>
		<dc:creator>James Iry</dc:creator>
		<pubDate>Tue, 12 Aug 2008 00:38:03 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=14#comment-1066</guid>
		<description>@Jevgeni,

You&#039;re mostly right about refactoring structural typing.  

Still, there&#039;s one area where structural typing can support static analysis and refactoring.  If you have a structural &quot;type hasFoo = {def foo()}&quot; and a method somewhere else &quot;def doSomething(x:hasFoo)&quot; and a another method somewhere else still &quot;def doSomethingElse(x:hasFoo), then renaming the method required by the hasFoo type from foo to bar can cause a refactoring that statically finds all classes/traits that are ever used as parameters for the doSomething and doSomethingElse methods(assuming whole program availability, which is something most rename refactorings assume), plus of course rename the calls to foo inside those methods.  At that point you&#039;ve got a normal rename refactoring.

What it misses, of course, is all the classes/traits that potentially could be used as parameters types for the doSomething and doSomethingElse methods but didn&#039;t happen to be used in the program being analyzed.  There&#039;s no reason you couldn&#039;t have a refactoring utility find all such potential uses, but as you say now we&#039;re into the land of slightly sophisticated search and replace - sophisticated because it&#039;s not just regex searching, Scala&#039;s refinement types can be pretty rich and give a lot more context than my simple hasFoo type.</description>
		<content:encoded><![CDATA[<p>@Jevgeni,</p>
<p>You&#8217;re mostly right about refactoring structural typing.  </p>
<p>Still, there&#8217;s one area where structural typing can support static analysis and refactoring.  If you have a structural &#8220;type hasFoo = {def foo()}&#8221; and a method somewhere else &#8220;def doSomething(x:hasFoo)&#8221; and a another method somewhere else still &#8220;def doSomethingElse(x:hasFoo), then renaming the method required by the hasFoo type from foo to bar can cause a refactoring that statically finds all classes/traits that are ever used as parameters for the doSomething and doSomethingElse methods(assuming whole program availability, which is something most rename refactorings assume), plus of course rename the calls to foo inside those methods.  At that point you&#8217;ve got a normal rename refactoring.</p>
<p>What it misses, of course, is all the classes/traits that potentially could be used as parameters types for the doSomething and doSomethingElse methods but didn&#8217;t happen to be used in the program being analyzed.  There&#8217;s no reason you couldn&#8217;t have a refactoring utility find all such potential uses, but as you say now we&#8217;re into the land of slightly sophisticated search and replace &#8211; sophisticated because it&#8217;s not just regex searching, Scala&#8217;s refinement types can be pretty rich and give a lot more context than my simple hasFoo type.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Daniel Spiewak</title>
		<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/comment-page-1/#comment-1065</link>
		<dc:creator>Daniel Spiewak</dc:creator>
		<pubDate>Tue, 12 Aug 2008 00:35:08 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=14#comment-1065</guid>
		<description>As I think Ricky was hinting at, this isn&#039;t so much a problem with structural types as it is a matter of defining the desired behavior.  The bit where things get tricky is the fact that structural types can impose an interface on an *external* type (in this case, java.io.File).  In cases where code affects external types, refactoring can never be &quot;from safe code to safe code&quot;.  This can occur in Java as well if an API is refactored without changing the external &quot;consumer code&quot;.

In terms of behavior, I should think that the correct thing to do would be to change all internal calls to the structural type (obviously).  Additionally, all defined instantiations of the structural type should be located (in this case by finding method calls) and all definitions which can be changed, should be.  In this case, this means that the File#getName() method should be refactored, while java.io.File should remain untouched.  Thus, the refactoring will lead to an error on line 12.  This is the expected behavior I think because a mismatch in the structural type indicates that the *usage* is wrong, obviously not the external definition.</description>
		<content:encoded><![CDATA[<p>As I think Ricky was hinting at, this isn&#8217;t so much a problem with structural types as it is a matter of defining the desired behavior.  The bit where things get tricky is the fact that structural types can impose an interface on an *external* type (in this case, java.io.File).  In cases where code affects external types, refactoring can never be &#8220;from safe code to safe code&#8221;.  This can occur in Java as well if an API is refactored without changing the external &#8220;consumer code&#8221;.</p>
<p>In terms of behavior, I should think that the correct thing to do would be to change all internal calls to the structural type (obviously).  Additionally, all defined instantiations of the structural type should be located (in this case by finding method calls) and all definitions which can be changed, should be.  In this case, this means that the File#getName() method should be refactored, while java.io.File should remain untouched.  Thus, the refactoring will lead to an error on line 12.  This is the expected behavior I think because a mismatch in the structural type indicates that the *usage* is wrong, obviously not the external definition.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/comment-page-1/#comment-1064</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Mon, 11 Aug 2008 14:33:54 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=14#comment-1064</guid>
		<description>@Ricky 

I really feel that we miss each other&#039;s point. Of course rename is &lt;b&gt;not&lt;/b&gt; always a refactor, but what I say is that it cannot always be &lt;b&gt;made&lt;/b&gt; into a safe refactor in a statically typed language with structural types.</description>
		<content:encoded><![CDATA[<p>@Ricky </p>
<p>I really feel that we miss each other&#8217;s point. Of course rename is <b>not</b> always a refactor, but what I say is that it cannot always be <b>made</b> into a safe refactor in a statically typed language with structural types.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jevgeni Kabanov</title>
		<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/comment-page-1/#comment-1063</link>
		<dc:creator>Jevgeni Kabanov</dc:creator>
		<pubDate>Mon, 11 Aug 2008 14:32:11 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=14#comment-1063</guid>
		<description>@Scot

You are right that refactoring structural types won&#039;t be too often, but what if you rename a method name in a type that just &quot;happened&quot; to coincide with one in a structural type? This is a very annoying side effect...</description>
		<content:encoded><![CDATA[<p>@Scot</p>
<p>You are right that refactoring structural types won&#8217;t be too often, but what if you rename a method name in a type that just &#8220;happened&#8221; to coincide with one in a structural type? This is a very annoying side effect&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Scot</title>
		<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/comment-page-1/#comment-1062</link>
		<dc:creator>Scot</dc:creator>
		<pubDate>Mon, 11 Aug 2008 13:49:38 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=14#comment-1062</guid>
		<description>I thought the point of structural typing was to add a certain amount of &quot;dynamism&quot; to Scala. It gives you most of the benefits (and drawbacks) of dynamic typing in the small amount of your code that would actually benefit from dynamic typing while leaving the rest of your code properly statically typed. So I&#039;m not that surprised that structurally typed code is about as difficult to refactor as dynamically typed code as it effectively is dynamically typed code.

Seeing as it&#039;s meant to be used sparingly (unsurprisingly, it has a large performance hit) I doubt refactoring would be that much of an issue, simply because there shouldn&#039;t be that many instances of it in your code.</description>
		<content:encoded><![CDATA[<p>I thought the point of structural typing was to add a certain amount of &#8220;dynamism&#8221; to Scala. It gives you most of the benefits (and drawbacks) of dynamic typing in the small amount of your code that would actually benefit from dynamic typing while leaving the rest of your code properly statically typed. So I&#8217;m not that surprised that structurally typed code is about as difficult to refactor as dynamically typed code as it effectively is dynamically typed code.</p>
<p>Seeing as it&#8217;s meant to be used sparingly (unsurprisingly, it has a large performance hit) I doubt refactoring would be that much of an issue, simply because there shouldn&#8217;t be that many instances of it in your code.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ricky Clarkson</title>
		<link>http://dow.ngra.de/2008/08/11/is-static-typing-and-refactoring-really-connected/comment-page-1/#comment-1061</link>
		<dc:creator>Ricky Clarkson</dc:creator>
		<pubDate>Mon, 11 Aug 2008 13:39:05 +0000</pubDate>
		<guid isPermaLink="false">http://dow.ngra.de/?p=14#comment-1061</guid>
		<description>Your point about rename is unrelated to structural types.

Rename x() to toString() in Java, and if the IDE doesn&#039;t complain at you, you&#039;ll probably have broken code somewhere.  Not all renames are refactors *even without structural typing*.</description>
		<content:encoded><![CDATA[<p>Your point about rename is unrelated to structural types.</p>
<p>Rename x() to toString() in Java, and if the IDE doesn&#8217;t complain at you, you&#8217;ll probably have broken code somewhere.  Not all renames are refactors *even without structural typing*.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

