Hi --

On Mon, 10 Jan 2005, itsme213 wrote:

> I am not a type-system expert, but I started thinking about Ruby-based duck
> typing some time ago and came up with something that seems promising to me.
> I wondered what other Ruby-ists think of the general idea.
>
> Duck typing should specify the minimal behavior required from an object that
> gets bound to a variable. Pattern matching (functional languages, Lisp loop
> macros, etc.) binds a set of variables (all at once) by stating the minimum
> necessary to extract values for the pattern variable from the target
> objects, ignoring other irrelevant bits of that object. Both are about
> matching criteria and binding of variables.
>
> Pattern matching is more concise than the corresponding code to bind each
> variable separately (think regexes, or multiple value assignment), and it
> happens to also convey type information (defines a criteria to match
> objects).
>
> Ruby already uses some special-case patterns: multi-value assignment,
> *splat, &block.
>
> So the basic idea is: duck typing = pattern matching
>    Types are patterns.
>    An object is a member of a type if the type pattern matches that object.
>
> Preliminary examples below, please don't get hung up on the (very tentative)
> syntax:
>
>    ::[x, y] = obj
>        # x = obj[0], y = obj[1]; # illustration only, defer *splat for now
>    ::[x, {k1: y}] = obj
>        # x = obj[0], y = obj[1][:k1]
>
>    def f ( [x, y] ) : []
>        # def f ( xy ); x = xy[0]; y = xy[1]..
>        # assert returns.respond_to? :[]
>        # Notice how revealing the signature has become
>
>    def f ( m(): x )
>        # you may prefer var : type style instead... later ..
>        # def f (x)
>        #    assert x.respond_to?(:m)
>
>    def f ( [ *m() ] : x )
>        # def f (x)
>        #    assert x.all?{|y| y.respond_to?(:m)}, or #each equivalent
>
>    M1 = ::(m1()) # things that have #m1()
>    M1M2 = M1 && ::(m2())  # things with m1(), m2()
>    def f ( M1M2: x )
>        # def f (x)
>        #     assert: x responds to :m1 and :m2
>
>    def f ( (m1(), m2()): x,  (m3(): y, m4(): z) )
>        # you may prefer var : type style instead... later ..
>        # def f ( x, yz )
>        #    assert x.respond_to?(:m1) && x.respond_to(:m2)
>        #    y = yz.m3()
>        #    z = yz.m4()
>        # Notice how revealing the signature has become.
>
> I am interested in any initial reactions.

My main first reaction was that I find the reference to duck typing
misleading.  I think what you're sketching out here is, in some
respects, the opposite of duck typing; that is, 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 which, as I
understand it, will prevent you from getting to that point at all
under certain conditions.  Thus your mechanism actually causes you to
*avoid* duck typing.  That doesn't make it good or bad in itself -- it
would just be clearer, I think, not to label it duck typing.

I know we're supposed to ignore all that punctuation for now... :-)
but one way or another, *something* would have to encapsulate all that
information, so it would be likely to look at least somewhat like what
you've got, which for me would be a fairly major drawback.  I love the
clean, not very punctuation-heavy look of Ruby so much that I'm
willing to give it lots of weigh against possible language features
and innovations.  I'd rather have some explicit calls to #respond_to?
than a system for abbreviating those calls into punctuation -- even
though it's more words, even though it takes longer to type.  Ruby is
already very concise; even doing a couple of explicit assignments (as
in the expansion of your last example) is a lot shorter than it would
be if, say, memory had to be allocated, or variable type declared.

Maybe there's some way to develop the pattern-matching idea but not
necessarily put it all in the method signature.  Could incremental
things, like allowing #respond_to? to take an array or multiple
arguments, work in that direction?


David

-- 
David A. Black
dblack / wobblini.net