"David A. Black" <dblack / wobblini.net> wrote > rather than simply > asking an object to do something at the moment you want it to do that > thing, you're introducing a wrapper/notation mechanism Not always true. Below I've dropped many of the ':' as I think they are not syntactically essential. [x,y] = obj is the same as x = obj[0] y = obj[1] So I ask obj to 'do' its [0], [1] right where I want it. Variables are bound to results. (m1(obj1) x, m2(obj2) y) = obj is the same as x = obj.m1(obj1) y = obj.m2(obj2) Again, I ask obj to do it's m1(), m2() right where I want it. Variables are bound to results. x = obj Object x = obj are identical. Now T x = obj would be x = obj assert x.is_of_type(T) # Object#is_of_type would handle named types, type patterns, classes, etc. So: (m1(), m2()) x = obj declares that m1() and m2() are needed, but does not invoke them since there are no variables to bind to obj.m1(), obj.m2(). This is like regexs cases where you want a match but don't care for a variable to be bound. Hence, besides binding x to full obj, it also includes an assertion x = obj assert( x.is_of_type(::(m1(), m2()) # i.e. assert( x.respond_to?(:m1) && x.respond_to?(:m2) ) And such assertions might not be needed if other type info was known (either simple type propagation, or more sophisticated type inference, to the extent possible in Ruby): def f (T obj) x = obj # so x.is_of_type T T y = x # no type assertion needed for T y = obj > ...[can] prevent you from getting to that point at all > under certain conditions. Yes, this pattern matching can fail, and depending on context might sometimes raise errors e.g. In places like a case-when or if- statement a match can fail without raising any error; its just a boolean check, with the added bonus of variable bindings from a successful match. In a regular assignment it can fail to match and will raise the same errors as the equivalent regular ruby code. - [x,y]=obj : can raise same errors as x=obj[0], y=obj[1] - (m1(), m2()) x = obj can raise errors from 'assert x.respond_to...' > That doesn't make it good or bad in itself -- it > would just be clearer, I think, not to label it duck typing. I see. Some usages of it are intentionally closer to explicit type declarations. Maybe 'duck type declarations'? > Maybe there's some way to develop the pattern-matching idea but not > necessarily put it all in the method signature. Yes. For example we could put this info right after the def f(x,y) so the def line is uncluttered. Something like this would be ok. def f ( x, y ) (m1(), m2()) x # or T x, if T was named type defined as m1(), m2() In this case Ruby should associate the type-declared x with the parameter x, rather than a new local variable. Would you agree? But this would not allow deconstructing (taking apart and pattern matching) anonymous args. def f [x,y] would instead become def f obj obj[0] x # new local var? appears in signature? obj[1] y # new local var? appears in signature? Do you think there should be some way to treat the "obj[0] x" as part of the signature? I am certain that def f [start, end] communicates much better signature info, with zero overhead, than def f start_end > Could incremental > things, like allowing #respond_to? to take an array or multiple > arguments, work in that direction? I see where you are going. Do you mean: def f(x) x.respond_to? :m1, :m2, :m3 I did want to somehow distinguish patterns used as type declarations from a regular (and overridable!) method call like respond_to. There may be other alternatives to "punctuation", but how would using 'normal' respond_to would for this purpose? Cheers.