tag:blogger.com,1999:blog-6579772240267288367.post8268271589780902463..comments2023-06-05T08:45:12.716-04:00Comments on kwblog: POODR's Duck TypesKevin Berridgehttp://www.blogger.com/profile/13759114853595462455noreply@blogger.comBlogger6125tag:blogger.com,1999:blog-6579772240267288367.post-41270326944717111542013-02-25T16:20:08.439-05:002013-02-25T16:20:08.439-05:00Sounds to me like what you want is some IDE goodne...Sounds to me like what you want is some IDE goodness. RubyMine is pretty solid in this regard from what I've heard.Matthew Casehttp://ascendantlogic.comnoreply@blogger.comtag:blogger.com,1999:blog-6579772240267288367.post-74535083127433468892013-02-16T11:48:02.048-05:002013-02-16T11:48:02.048-05:00Do you spend much time in IRB when you use Ruby? R...Do you spend much time in IRB when you use Ruby? Ruby objects have a very rich set of introspection methods. In IRB you can interrogate a module/class/object for its methods, accessors, data members, ancestors, etc. I can learn more about an object in a few seconds in IRB than all the menus in Visual Studio combined. Part of "embracing the language" is learning the tools. Tools like Visual Studio are great in some circumstances (last week I built a Metro app for the Surface Pro and VS 2012 was amazing) but you'll never be truly productive in Ruby if you don't fully embrace REPL-based programming. <br /><br />-JerryJerry in Akronhttps://www.blogger.com/profile/15934433871354942006noreply@blogger.comtag:blogger.com,1999:blog-6579772240267288367.post-28337017871282250652013-02-15T22:13:54.155-05:002013-02-15T22:13:54.155-05:00Thanks Jerry. "I don't miss the compiler...Thanks Jerry. "I don't miss the compiler at all" I admit this surprises me some, but at the same time, I can see how that would be true. When I play with Ruby, I love not needing to wait for the compiler. Until I typo something... Or want to rename a method or something. Or want to know what methods are available to call on some object. :)Kevin Berridgehttps://www.blogger.com/profile/13759114853595462455noreply@blogger.comtag:blogger.com,1999:blog-6579772240267288367.post-77806400174188299752013-02-15T08:42:18.409-05:002013-02-15T08:42:18.409-05:00Great post. Definitely made me think and clarify m...Great post. Definitely made me think and clarify my thoughts on this topic. I have a lengthy response in my head but I haven't had time to write it, so I'll give you the abbreviated version for now...<br /><br />This is not too dissimilar to the Ruby metaprogramming talk I gave at Burning River. My main points were to 1) recognize that the power comes with inherent risks and 2) embrace the language as it exists (don't try to make Ruby into C# or vice versa).<br /><br />I'm currently working on an open-source statistics gem (https://github.com/jdantonio/ratistics). I intentionally designed the library so that calculations can be performed against virtually any collection object that can be iterated with an #each method. Some functions also require that the collection be accessible by index. You are absolutely correct that the code itself is less expressive than it would be were it written in C# with interfaces. On the other hand, all the functions currently work (and are tested against) Array, ActiveRecord result sets, and most Hamster collection classes, and probably a zillion other collection classes I've never heard of. And I did that with no metaprogramming, monkey-patching or other shenanigans. The flexibility that duck-typing gives me here is unequaled in languages like C# and Java.<br /><br />I spent the first decade of my career working in static languages (C++, Java, and C#). When I first started heavily using dynamic languages (Python) I was (literally) afraid of dynamic typing. After years of using Ruby as my primary development language I have no interest in returning to statically-typed languages. I don't miss the compiler at all, FWIW.<br /><br />I think a lot of this comes down to programmer preference. If one approach were undeniably better than the other I don't think we'd have as many language choices.<br /><br />-JerryJerry in Akronhttps://www.blogger.com/profile/15934433871354942006noreply@blogger.comtag:blogger.com,1999:blog-6579772240267288367.post-35534050581958571352013-02-14T13:44:23.814-05:002013-02-14T13:44:23.814-05:00I like that last quote, that's a nice balanced...I like that last quote, that's a nice balanced way of thinking about it.<br /><br />I think part of what I occasionally struggle with in dynamic languages (or think that I might struggle with if I were to work with them more) is that as someone reading existing code I have fewer hints as to what the author intended or was thinking.<br /><br />In a static language, the method definition gives me:<br /> - parameter type, which immediately leads me to everything that object is capable of<br /> - parameter name, which tells me more about the context the author is writing in<br /><br />In a dynamic language, I just get the parameter name. And then I have to hunt (a bit) to find what capabilities of that object they are depending on. And if I should want to use a new capability of that object, I may not be able to. And finding that out requires finding every usage of the method to ensure that all the objects being passed in are of the same "duck type."<br /><br />For example, I may write a method expecting it to receive a String. And if I use only a small subset of it's methods, that method may also work with Array. But if I later update it to use .ToUpperCase, how do I know I haven't broken anyone?<br /><br />Static typing makes those issues disappear. And good use of interfaces returns some of the benefits of a "duck type." But I'll admit much of this is hypothetical. It's likely these constraints of a dynamic language would simply force you to write code differently. And in many ways, maybe better.<br /><br />Anyway, thanks for the comment!Kevin Berridgehttps://www.blogger.com/profile/13759114853595462455noreply@blogger.comtag:blogger.com,1999:blog-6579772240267288367.post-76085272260849820022013-02-14T13:33:18.016-05:002013-02-14T13:33:18.016-05:00This is very interesting. I had to go back and re...This is very interesting. I had to go back and read that section in the book I learned C# from to understand what you were saying. I've never actually used an interface, though I knew they existed, but they seem to be slightly more practical than what I was picturing them to be (which is probably something akin to the "header interfaces" you mention above). I think I definitely see how static interfaces would be a much safer way to solve this problem: it would seem to avoid problems where an object implements 'to_i()' or '+', but in an unexpected way which subtly breaks something but throws no errors (whereas associating with an interface ensures that those methods must be explicitly defined and thus likely defined as intended). The other thing that seems huge to me, is that it allows someone after the fact to get a sense of what a method does purely by its declaration: "public static Numeric operator +(Numeric a, Numeric b)" probably adds; "public static Text operator +(Text a, Numeric b)" probably concatenates; but what does "def +(a)" do?—and moreso, how does one know what methods it expects 'a' to implement without reading the whole definition as you said?<br /><br />I also went back and read the "Duck Typing" chapter in the book I learned ruby from too (Pickaxe). They explicitly state that their opinion is that, despite there being more potential pitfalls with duck typing, one just doesn't run into these issues often enough in real-world usage to justify the extra overhead of static typing. So that's at least three people's answer to your question. I'll end with their quote at the end of that chapter, because it sounds good:<br />"Duck typing can generate controversy. Every now and then a thread flares on the mailing lists, or someone blogs for or against the concept. Many of the contributors to these discussions have some fairly extreme position.<br />Ultimately, though, duck typing isn't a set of rules; it's just a style of programming. Design your programs to balance paranoia and flexibility. If you feel the need to constrain the types of objects that the users of a method pass in, ask yourself why. Try to determine what could go wrong if you were expecting a String and instead get an Array. Sometimes, the difference is crucially important. Often, though, it isn't. Try erring on the more permissive side for a while, and see if bad things happen. If not, perhaps duck typing isn't just for the birds."Noahhttps://www.blogger.com/profile/04517299250607213500noreply@blogger.com