From: Martin Pilkington Date: 2010-09-29T08:07:47+09:00 Subject: [ruby-core:32616] Re: Proposal for Optional Static Typing for Ruby Hi Loren, Joshua I think it might be worth pointing out that the availability of type information, be it through static typing in the language or adding it via a DSL to be accessed on live objects or some other suggestion, should be considered a separate issue to how that information may be used. The issue at the moment is that to get this information requires a lot of work and isn't always reliable. If that information was available an an easy and reliable format then there are all sorts of interesting things that could happen. Personally, I've had no experience with multiple dispatch beyond the theory of it. It sounds like an interesting idea, but I'm never too keen on overloading a method purely based on argument types or number. But that isn't to say that someone else wouldn't find it interesting or useful. Ultimately it isn't really a case of being "fully duck typed" or not or "fully statically typed" or not. Neither one in their pure form are perfect. Myself, I'd always tend towards duck typed for the extra freedom it gives me. However, there are benefits to both and the trick is to find a middle ground where you get as much of these benefits with as few of the disadvantages. Hopefully, even if people disagree about how this information should be used, there can be some agreement that actually having the information there is worth considering. Thanks Martin On 28 Sep 2010, at 10:47PM, Loren Segal wrote: > > On 2010-09-28, at 4:04 PM, Joshua Ballanco wrote: > >> On Sep 28, 2010, at 12:35 PM, Loren Segal wrote: >> >>> We've all seen and written these methods before. They're annoying to write, they're even harder to document. Why couldn't we just do (forgive me, I'm using a different syntax to that which was proposed in this thread): >>> >>> def run(opts: Hash) >>> Server.new(opts).start >>> end >>> >>> def run(server: Server) >>> server.start >>> end >>> >>> Before all the duck-typists go nuts, there's no reason why you couldn't specify a duck-type here. >> >> The problem is that this proposal fundamentally misunderstand the concept of Duck typing. What if I create a class which behaves exactly as a Hash, has all the same methods with the same signatures as a Hash, but I call my class FunTimeCrazyDuckyHash? Which of these methods should be called? > > If you read my next example (which you conveniently left out of your quote) you can see how duck types can be expressed. You also seemed to miss my statement (which you did quote) that ducktypes *could* indeed be used. This situation, however, is not a duck-typing situation. The Server class is not meant to "act like a hash". In the example above, the run() command takes a convenience hash and constructs a server object for you (a common idiom for Ruby factory methods). >> >> If you're testing your arguments against a specific class, you're "Doing it wrong". > > That's a little extreme. There are plenty of uses cases that require specific classes, or use inheritance instead of duck-typing to specify an interface. Ruby is still an object-oriented programming language, last time I checked. There's no reason not to merge the strengths of each paradigm. > >> And all of us have done this at some point, but that still makes it wrong. The "duck type" way to write the above is: >> >> def run(thing) >> if thing.respond_to? :start >> thing.start >> else >> Server.new(thing).start >> end >> end > > This is just as messy. You're putting dispatching logic that could easily be handled by your interpreter into your business logic. Again, the solution here could still be expressed with type annotations: > > def run(thing: #start) > thing.start > end > > def run(thing) > Server.new(thing).start > end > > This is similar to the next example I showed. Of course this skews the discussion of typed annotations into something it's not. We're not talking about the "best" way to implement something in Ruby. There is no "one" way in Ruby, and the idea that you should never need to type by classes is as naive as the idea that you should never need to duck-type. Ruby is a useful language because it's multi-paradigm and can be used to express more than one problem-space. > >> >> Mostly, if you find yourself doing this sort of checking too often, it's probably symptomatic of a larger issue with the structure of your code. > > Again, I would disagree. There are plenty of fairly proper codebases that use the above examples a lot. Particularly for convenience methods, which Ruby libraries have plenty of-- far more than other languages I've seen. > > - Loren