Talk:Blogs:JaroslavTulach:Theory:LanguagesForEvolution
From APIDesign
(New page: This is where Java's strong typing steps in your way. What about languages which do not have such strong typing? For example Ruby's duck-typing seems to sidestep this problem in a simple w...) |
|||
Line 1: | Line 1: | ||
This is where Java's strong typing steps in your way. What about languages which do not have such strong typing? For example Ruby's duck-typing seems to sidestep this problem in a simple way - because there is no need for "abstract" in Ruby, this issue obviously does not exist there. The price you pay for this flexibility in Ruby in this case is that you should use introspection (xx.respond_to? :getHTMLTitle) to find out whether the object xx actually provides the method getHTMLTitle or not. However, if you have not used Ruby before, beware - Java programmers usually do hate it, just because it is not strong typed - they refuse the duck-typing just because it seems perverse to them. However, it is not so perverse once you get used to it. ;-) | This is where Java's strong typing steps in your way. What about languages which do not have such strong typing? For example Ruby's duck-typing seems to sidestep this problem in a simple way - because there is no need for "abstract" in Ruby, this issue obviously does not exist there. The price you pay for this flexibility in Ruby in this case is that you should use introspection (xx.respond_to? :getHTMLTitle) to find out whether the object xx actually provides the method getHTMLTitle or not. However, if you have not used Ruby before, beware - Java programmers usually do hate it, just because it is not strong typed - they refuse the duck-typing just because it seems perverse to them. However, it is not so perverse once you get used to it. ;-) | ||
+ | |||
+ | -- an Anonymous Coward on 20:11, 21 September 2008 | ||
+ | |||
+ | OK, let's accept the view that duck-typing really helps to solve the problem of enhancing an existing interface with String getHTMLTitle() method. What can users of such method do? Well, they need to check whether an object implements the method or not and either send the message or do something else: | ||
+ | |||
+ | <source lang="ruby"> | ||
+ | // written in a pseudo language with "respond_to" operator: | ||
+ | title = null; | ||
+ | if (xx.respond_to? :getHTMLTitle) { | ||
+ | title = xx.getHTMLTitle(); | ||
+ | } else { | ||
+ | title = "<b>" + xx.getDisplayName() + "</b>"; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | this is possible. However it does not contribute to the simplicity of API usage. The '''if''' statements are only likely to grow, and after few releases the maintenance becomes nightmare. Btw. in [[Code_Against_Interfaces,_Not_Implementations|Chapter 6]], Code Against Interfaces, Not Implementations, I show that similar nightmare can happen in Java: | ||
+ | |||
+ | <source lang="java"> | ||
+ | public abstract class View { | ||
+ | public abstract String getDisplayName(); | ||
+ | } | ||
+ | public abstract class ViewVersion2 extends View { | ||
+ | public abstract String getHTMLTitle(); | ||
+ | } | ||
+ | |||
+ | title = null; | ||
+ | if (xx instanceof ViewVersion2) { | ||
+ | title = ((ViewVersion2)xx).getHTMLTitle(); | ||
+ | } else { | ||
+ | title = "<b>" + xx.getDisplayName() + "</b>"; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | As can be seen, this style produced almost as bad code as the Ruby example above. The truth is that when evolving an interface, you most likely want to provide default implementation of '''getHTMLTitle''' to all existing and already written classes. The simplest trick to achieve that in Java is: | ||
+ | |||
+ | <source lang="java"> | ||
+ | public abstract View/*version 2.0*/ { | ||
+ | public abstract String getDisplayName(); | ||
+ | public String getHTMLTitle() { | ||
+ | return "<b>" + getDisplayName() + "</b>"; | ||
+ | } | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | Only then you simplify life of your API clients. I'd bet that similar code can be rewritten to Ruby, without use of duck-typing. As such, I'd like to conclude that duck-typing does not simplify API evolution, at least not in this particular case. | ||
+ | |||
+ | --[[User:JaroslavTulach|JaroslavTulach]] 15:48, 22 September 2008 (UTC) |
Revision as of 15:48, 22 September 2008
This is where Java's strong typing steps in your way. What about languages which do not have such strong typing? For example Ruby's duck-typing seems to sidestep this problem in a simple way - because there is no need for "abstract" in Ruby, this issue obviously does not exist there. The price you pay for this flexibility in Ruby in this case is that you should use introspection (xx.respond_to? :getHTMLTitle) to find out whether the object xx actually provides the method getHTMLTitle or not. However, if you have not used Ruby before, beware - Java programmers usually do hate it, just because it is not strong typed - they refuse the duck-typing just because it seems perverse to them. However, it is not so perverse once you get used to it. ;-)
-- an Anonymous Coward on 20:11, 21 September 2008
OK, let's accept the view that duck-typing really helps to solve the problem of enhancing an existing interface with String getHTMLTitle() method. What can users of such method do? Well, they need to check whether an object implements the method or not and either send the message or do something else:
// written in a pseudo language with "respond_to" operator: title = null; if (xx.respond_to? :getHTMLTitle) { title = xx.getHTMLTitle(); } else { title = "<b>" + xx.getDisplayName() + "</b>"; }
this is possible. However it does not contribute to the simplicity of API usage. The if statements are only likely to grow, and after few releases the maintenance becomes nightmare. Btw. in Chapter 6, Code Against Interfaces, Not Implementations, I show that similar nightmare can happen in Java:
public abstract class View { public abstract String getDisplayName(); } public abstract class ViewVersion2 extends View { public abstract String getHTMLTitle(); } title = null; if (xx instanceof ViewVersion2) { title = ((ViewVersion2)xx).getHTMLTitle(); } else { title = "<b>" + xx.getDisplayName() + "</b>"; }
As can be seen, this style produced almost as bad code as the Ruby example above. The truth is that when evolving an interface, you most likely want to provide default implementation of getHTMLTitle to all existing and already written classes. The simplest trick to achieve that in Java is:
public abstract View/*version 2.0*/ { public abstract String getDisplayName(); public String getHTMLTitle() { return "<b>" + getDisplayName() + "</b>"; } }
Only then you simplify life of your API clients. I'd bet that similar code can be rewritten to Ruby, without use of duck-typing. As such, I'd like to conclude that duck-typing does not simplify API evolution, at least not in this particular case.
--JaroslavTulach 15:48, 22 September 2008 (UTC)