From: Dan Doel Date: 2004-04-04T18:37:43+09:00 Subject: Re: deciding between ruby and python As you say, this whole thread has been done many times before. > Alright, let's assume that we have a function f that should always > return a string. > > output = "".join([f(entry) for entry in [1,2,3,4,5,6] ]) > > If f suddenly returned something else, it's usually indicative of an > error of some kind. Too bad this error can easily go unnoticed if the > code is in production. OTOH, if the implicit conversion wasn't done, > the customer would just call you and said "the code crashed, and I got > this exception traceback..." which immediately points you to the right > line of code. A Ruby advocate would likely suggest putting some sort of unit test on f to make sure that it always returns a String. In fact, that'd likely be better in Python as well, as you'd get an error message that it failed the particular test case with specific information, rather than simply getting a random place in your code where a String was expected and failed to show up. Neither method is much better than another. > No need to make up words about dynamic typing, I'm a big advocate of > that (which maked this a bit of a strawman argument). This was merely > about debunking the claim that implicit conversion is somehow an > example of duck typing, whereas duck typing also has the flip side of > the coin - if it doesn't quack and walk like a duck, it's not a duck, > and an exception is in order. Actually, in a sense, the automatic conversion is duck typing in this case. Defining #to_s in a Ruby class means, "You should call this to automatically convert if a String is expected." If you just want to be able to cast to a String, you define #to_str. This is not called for implicit conversion, and is more analogous to the __str__ method in Python, I think. The only difference is that Object has a default #to_s, so if you want it to raise an exception, you need to redefine it to do so. At least, that's how I've seen it described (and a quick check reveals that join calls #to_s, never #to_str, and when I redefine #to_s, it can throw an exception, just like Python would). > Aren't you blowing this out of proportion? Would Python be on the > 'wild side' if it added the following function: > > def join_as_strings(seq, sep): > return sep.join([str(s) for s in seq]) > > See? Everyone can opt to choose the Ruby way in Python too, it's just > not the default because it's deemed dangerous and a violation of > "explicit is better than implicit". And the Ruby community doesn't always follow that principle, so our default is the opposite. Neither is inherently better. > I think this thread has been an interesting example of how similar the > two languages are - it started from "Python OO is a hack, Ruby is > better in FP also because it supports List Processing" (someone still > needs to tell me what List Processing is in Ruby) but it all really > boils down to are these small cultural differences. And they have been > hashed again and again in the past. I'm not the poster of that opinion, but I imagine he was referring to things like #each and #inject and the Enumerable module. I don't know Python, so I don't know what the analogues to these are, or if it has them at all. Perhaps whenever he looked at Python, it didn't. Ruby doesn't have list comprehensions like Python and Haskell do, though, if that's what you took it to mean. Not having list comprehensions doesn't mean your bad at list processing, though. Otherwise Lisp would be bad at it (by default, at least), and Lisp stands for List Processing. :) > I bet you could use either language, and get exactly the same > productivity. I don't know that one is inherently better than the other at anything, really. It's mostly a matter of taste. We should probably stop quibbling. :) Have a nice day. - Dan