82 (v2): Apply operators component-wise in a list context

[email protected] ("Casey R. Tweten")
Newsgroups perl.perl6.language.data
Message-ID <[email protected]>
=head1 TITLE

Apply operators component-wise in a list context

=head1 VERSION

  Maintainer: Jeremy Howard <[email protected]>
  Created: 10 August 2000
  Last modified: 16 August 2000
  Version: 2
  Mailing List: [email protected]
  Number: 82

=head1 ABSTRACT

It is proposed that in a list context, operators are applied
component-wise to their arguments. Furthermore, it is proposed that
this behaviour be extended to functions that do not provide a specific
list context.

=head1 CHANGES

=head2 Since v1

=over 4

=item *

Added the ability to apply an operator to a scalar and a list.

=item *

Added more examples, including text processing examples.

=back

=head1 DESCRIPTION

Currently, operators applied to lists in a list context behave
counter-intuitively:

  @b = (1,2,3);
  @c = (2,4,6);
  @d = @b * @c;   # Returns (9) == scalar @b * scalar @c

This RFC proposes that operators in a list context should be applied
component-wise to the elements of their arguments:

  @d = @b * @c;   # Returns (2,8,18)

If the lists are not of equal length, the shorter lists should be treated
as if they were padded with undefs at the right-hand end. However, this
implicit padding should not cause these elements in the shorter lists to
auto-vivify.

If an operator is used in a list context with one list, and one or more
scalars, the scalars are treated as if they were a list of that scalar:

  @b = (1,2,3);
  @e = @b * 2;      # Returns (2,4,6)
  @f = @b * (2,2,2) # Same thing

Functions that do not return a list should be treated in the same way:

  @e = (-1,1,-3);
  @f = abs(@e);   # Returns (1,1,3)

=head1 EXAMPLES

=head2 Text processing

If @first_names contains a list of peoples first names, and @surnames
contains their surnames, this creates a new list that concatenates the
elements of the two lists:

  @full_names = @first_names . @surnames;

To quote a number of lines of a message by prefixing them all with '> ':

  @quoted_lines = '> ' . @raw_lines;

To create a histogram for a list of scores:

  @people = ('adam', 'eve ', 'bob ');
  @scores = (7,9,5);          # Score for each person
  @histogram = '#' x @scores; # Returns ('xxxxxxx','xxxxxxxxx','xxxxx')
  print join("\n", @people . ' ' . @histogram);

  adam xxxxxxx
  eve  xxxxxxxxx
  bob  xxxxx

=head2 Number crunching

This snippet multiplies the absolute values of three arrays together and
sums the results, in a very efficient way:

  @b = (1,2,3);
  @c = (2,4,6);
  @d = (-2,-4,-6);
  $sum = reduce ^_+^_, abs(@b * @c + @d);

Lists can be reordered or sliced with list generation functions (RFC 81)
allowing flexible data manipulation:

  @a = (3,6,9);
  @reverse = (3..1);
  @b = @a * @a[@rev];   # (3*9, 6*6, 9*3) = (27,36,27)

Slicing plus array operations makes matrix algebra easy:

  @a = (1,2,3,
        2,4,6,
        3,6,9);
  @column1of3 = (1:3:7);   # (1,4,7) - every 3rd elem from 1 to 7
  @row1of3 = (1..3);       # (1,2,3)
  $sum_col1_by_row1 =
    sum ( @a[@column1of3] * @a[@row1of3] );  # (1*1+2*2+3*3)=14

=head1 IMPLEMENTATION

These operators and functions should be evaluated lazily. For instance:

  @b = (1,2,3);
  @c = (2,4,6);
  @d = (-2,-4,-6);
  $sum = reduce ^_+^_, @b * @c + @d;

should be evaluated as if it read:

  $sum = 0;
  $sum += $b[$_] * $c[$_] + $d[_] for (0..$#a-1));

That is, no temporary list is created, and only one loop is required.

The proposal to handle functions is tricky, since there is currently no
obvious way to see whether a function is going to return a list. For
instance, in the case:

  @b = abs(@a);

we either need some kind of more advanced prototyping (or other way of
creating a signature) so that Perl knows to apply abs() to the elements of
@a, or we need to manually change abs to check for list context and Do The
Right Thing.

=head1 REFERENCES

The Mathematica Navigator, Heikki Ruskeep,
Academic Press, ISBN 0-12-603640-3, p383.

Expression Templates (C++ Implementation):

http://extreme.indiana.edu/~tveldhui/papers/techniques/techniques01.html#l32

Implementation in Perl Data Language:
http://pdl.perl.org

RFC 76: reduce

RFC 23: Higher-order functions

RFC 81: Lazily evaluated list generation functions
-- 
print(join(' ', qw(Casey R. Tweten)));my $sig={mail=>'[email protected]',site=>
'http://home.kiski.net/~crt'};print "\n",'.'x(length($sig->{site})+6),"\n";
print map{$_.': '.$sig->{$_}."\n"}sort{$sig->{$a}cmp$sig->{$b}}keys%{$sig};
my $VERSION = '0.01'; #'patched' by Jerrad Pierce <belg4mit at MIT dot EDU>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.