"David A. Black" <dblack / wobblini.net> wrote
> > The proposal is for
> >    [x,y] = obj
> > to do exactly x=obj[0]; y=obj[1].
>
> What's gained by that, though?

In a method signature
    def  m  [start,end]
is more informative than
    def  m obj
or
    def m start_end

The first tells me I have to pass in something from which start can be
extracted with [0], and end with [1]. And if available in method signatures,
it should be available other places where variables get bound, like
assignment, for-loops, ... (A separate side-comment: for the same reasons I
think the rules of * and ',' should be changed to be the same for assignment
as method calls).

> It sounds like you want:
>
>    (join, x) = array

    (join() x) = array, but that's a minor nit. I agree it is hard to read.
#instance_eval kindof comes close, but
    array.instance_eval { x = join() }
would bind a quite inaccessible 'x'. Maybe pattern matching is too hard on
the syntax.

> checks/assertions/declarations, in my judgement it's been because
> they're unconvinced of the soundness of the conditions that Ruby
> imposes on programming.

I know that Ruby's just_in_time duck typing safety check is sound. But I
also believe access to duck-typing information can be used for many several
purposes besides just to check on every call.

If you wrote an app that hooked together other objects, doing some checking
on compatibility before doing so, might it be useful to have access to some
non-class-based signature information? Would you prefer this to be done
separately from the method definitions? And independently invent conventions
for each end?

And I believe duck-typing information should allow duck-type expressions of
the form (borrowing your 'can')
    can?(:a, :b) || (can?(:x) && can?([:k]))
A duck, d, that can either do:
    d.a, d.b, d.c
or
    d.x, d[:k]
Type inference (if feasible) might build such expressions as it traverses
calls, assignments, branches, etc. What do you think? Does this make be more
or less of a quack? ;-)

> > Perhaps. I think duck-typing is about focusing on respond_to and
steering
> > clear of class-based tests (unless they are truly part of what a method
> > requires, arguments of style aside). Duck-typing, like any strong
typing,
> > can be static (associated with variables and expressions) or dynamic
> > (associated only with objects), or in-between (dynamically select
between,
> > or even generate, multiple threads of type-specialized code).
>
> I think it's a somewhat simpler and less sweeping (though rather
> profound) concept; see http://www.rubygarden.org/ruby?DuckTyping

Hmm. I see the warning of class-based type info, but nothing against
respond_to?-style type info. Did I miss something?

case...when allows
    Class === x for case matching. Not very ducky.
But a hypothetical
    duck_expression === x
would be quite ducky, imo.

> > Alternatives welcome, but they should allow for selected use to be
> > unambiguously about type declaration.
>
> See my #can? method in the last post.
>
>    module Kernel
>      def can?(*methods)
>        methods.all? {|m| respond_to?(m) }
>      end
>    end
>
>    class C
>      def blah(x)
>        raise ArgumentError unless x.can?(:a,:b,:c)
>      end
>    end

Sure, but:
- What tells any runtime reflective access, or a compiler, to treat this as
part of the signature of #blah?
- I'd like to name and compose can?-based types in a way that is, again,
available to runtime reflective access or a compiler.

Cheers.