develooper Front page | perl.perl5.porters | Postings from March 2001

Distributive -> and indirect slices

Thread Next
From:
David M. Lloyd
Date:
March 16, 2001 13:20
Subject:
Distributive -> and indirect slices
Message ID:
Pine.LNX.4.21.0103161518060.13798-100000@homebody.freemm.org
I have an idea that I'm going to try to put into my Perl, but I want some
'professional' opinions on it first.

The first thing I'd like to do, is make the -> operator 'distributive' for
all cases of it (that I can think of anyways).

Examples:

    # Call $x->foo(); and $y->foo(); instead of
    # current, less-useful $y->foo();
    ($x, $y)->foo();

    # Call foo() for all @bar instead of
    # current 'Can't call method ... without a package or object
    # reference'
    @bar->foo();

    # Call both functions with args
    ($coderef1, $coderef2)->('Param1', 2);

    # Return (1, 3) in list context as lvalues
    ([1, 2], [3, 4])->[0];

    # Return (1234, 5432) (hash derefs) in list context as lvalues
    ({'key' => 1234}, {'key' => 5432})->{'key'};

This would be different from the standard -> notation in that the left
side of the value is a list or array, instead of a scalar.  This
distinction makes it possible to allow the -> notation to create indirect
slices:

    @arrayrefs->[1..3];

because I can say (hopefully), "If the left side is a list, then the index
is also a list".  This logic would allow things like this:

    ($structure)->[1,3,7]->{'key1', 'key2'}; # Returns 6 things

Or this, to get really nuts:

    # foo() is called in list context...
    @structure->[2,0,3,1]->{'keyA', 'keyB', 'keyC'}->foo();

which calls 12 foo()s for each thing in @structure, in this order:

    $structure[0]->[2]->{'keyA'}->foo();
    $structure[0]->[2]->{'keyB'}->foo();
    $structure[0]->[2]->{'keyC'}->foo();
    $structure[0]->[0]->{'keyA'}->foo();
    $structure[0]->[0]->{'keyB'}->foo();
    $structure[0]->[0]->{'keyC'}->foo();
    $structure[0]->[3]->{'keyA'}->foo();
    $structure[0]->[3]->{'keyB'}->foo();
    $structure[0]->[3]->{'keyC'}->foo();
    $structure[0]->[1]->{'keyA'}->foo();
    $structure[0]->[1]->{'keyB'}->foo();
    $structure[0]->[1]->{'keyC'}->foo();

and returns the return values of foo() as one big long list.

Or this, to use a simple slice on a reference:

    ($arrayref)->[0..15]; # The () gives me list context

Without changing the behaviour of this:

    # Still returns boring old $arrayref->[0]
    $arrayref->[0..15];

or this:

    # Still returns boring old $arrayref->[15]
    $arrayref->[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];


I was looking at perly.y and I was kind of thinking that I would need to
change the various 'term ARROW ...' rules to do some sort of check on the
left-hand side.

Is this worth investigating?  Is there any chance that such behaviour
would ever be integrated into Perl 5?  What about Perl 6?

Thanks for any feedback!

- D

<david@freemm.org>


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About