Operator::Util
      Nick Patch

   Perl Seminar NY

   15 February 2011
released yesterday
released yesterday

   i ♥ feedback
Perl 6 is pretty cool
meta-operators
meta-operators

[ ☺] Z ☺ X ☺ » ☺«
reduction
[+] 1..4       # 10
[*] 1..4       # 24
[~] 'a'..'d'   # 'abcd'
zip
(1,2) Z+ (2,3)   # 3,5
(1,2) Z* (2,3)   # 2,6
(1,2) Z~ <a b>   # 1a,2b
cross (flat)
(1,2) X+ (2,3)   # 3,4,4,5
(1,2) X* (2,3)   # 2,3,4,6
(1,2) X~ <a b>   # 1a,1b,2a,2b
cross (lol)
(1,2) X+ (2,3)   # [3,4],[4,5]
(1,2) X* (2,3)   # [2,3],[4,6]
(1,2) X~ <a b>   # [1a,1b],[2a,2b]
hyper
1..4   »~«   'a'..'d'   #   1a,2b,3c,4d
1..4   »~»   'x'        #   1x,2x,3x,4x
1..4   «~»   <x y>      #   1x,2y,1x,2y
1..4   «~«   <x y>      #   1x,2y
more hyper!
-« (1,2,3)       #   -1,-2,-3
[1,[2,3]] »++    #   [2,[3,4]]
%foo «+» %bar    #   intersection
%foo »+« %bar    #   union
%foo »+=« %bar   #   %foo = union
but it's not Xmas yet
cpanm Operator::Util
use Operator::Util qw(
    reducewith
    zipwith
    crosswith
    hyperwith
);
reducewith a.k.a. reduce
 hyperwith a.k.a. hyper
reduction
reduce('+', [1..4])       # 10
reduce('*', [1..4])       # 24
reduce('.', ['a'..'d'])   # 'abcd'
zip
zipwith('+', [1,2], [2,3])       # 3,5
zipwith('*', [1,2], [2,3])       # 2,6
zipwith('.', [1,2], ['a','b'])   # 1a,2b
cross (flat)
crosswith('+', [1,2], [2,3])
crosswith('*', [1,2], [2,3])
crosswith('.', [1,2], ['a','b'])

         # 3,4,4,5
         # 2,3,4,6
         # 1a,1b,2a,2b
cross (lol)
crosswith('+', [1,2], [2,3],     flat=>0)
crosswith('*', [1,2], [2,3],     flat=>0)
crosswith('.', [1,2], ['a','b'], flat=>0)

            # [3,4],[4,5]
            # [2,3],[4,6]
            # [1a,1b],[2a,2b]
hyper
hyper('.',   [1..4],   ['a'..'d']              );
hyper('.',   [1..4],   'x',       dwim_right=>1);
hyper('.',   [1..4],   ['x','y'], dwim=>1      );
hyper('.',   [1..4],   ['x','y'], dwim_left=>1 );

                  #    1a,2b,3c,4d
                  #    1x,2x,3x,4x
                  #    1x,2y,1x,2y
                  #    1x,2y
more hyper!
hyper('prefix:-',   [1,2,3]);
hyper('postfix:++', [1,[2,3]]);
hyper('+', %foo, %bar, dwim=>1);
hyper('+', %foo, %bar);
hyper('+=', %foo, %bar);

          #   -1,-2,-3
          #   [2,[3,4]]
          #   intersection
          #   union
          #   %foo = union
default ops
  zipwith(',',   [1,2],   ['a','b'])
      zip(       [1,2],   ['a','b'])
crosswith(',',   [1,2],   ['a','b'])
    cross(       [1,2],   ['a','b'])

       #   1,a,2,b
       #   1,a,2,b
       #   1,a,1,b,2,a,2,b
       #   1,a,1,b,2,a,2,b
associativity
   reduce('-', [4, 3, 2])
   reduce('**', [4, 3, 2])

# 4-3-2 = (4-3)-2 = -1
# 4**3**2 = 4**(3**2) = 262144
chaining
reduce('eq', @a)   # all elements eq?
reduce('!=', @c)   # no repeating elements?
reduce('<', @b)    # ascending elements?
dwim for < 2 elems
    reduce('+',   [] )   #   0
    reduce('+',   [5])   #   5
    reduce('*',   [] )   #   1
    reduce('*',   [5])   #   5
even more hyper!
hyper('->', @objects, 'run', dwim=>1)
hyper('+', [[1, 2], 3], [4, [5, 6]], dwim=>1)
hyper('prefix:-', {a => 1, b => 2, c => 3})

         # call ->run() on each
         # [[5, 6], [8, 9]]
         # a => -1, b => -2, c => -3
resources
git:    github.com/patch
slides: patch.github.com

Extending Operators in Perl with Operator::Util