7 Hyper operators L<S03/"Hyper operators">
13 # L<S03/Hyper operators>
18 @r = (1, 2, 3) »+« (2, 4, 6);
20 is(~@r, ~@e, "hyper-sum two arrays");
22 @r = (1, 2, 3) »-« (2, 4, 6);
24 is(~@r, ~@e, "hyper-subtract two arrays");
26 @r = (1, 2, 3) »*« (2, 4, 6);
28 is(~@r, ~@e, "hyper-multiply two arrays");
30 @r = (1, 2, 3) »x« (3, 2, 1);
31 @e = ('111', '22', '3');
32 is(~@r, ~@e, "hyper-x two arrays");
34 @r = (1, 2, 3) »xx« (3, 2, 1);
35 @e = ((1,1,1), (2,2), (3));
36 is(~@r, ~@e, "hyper-xx two arrays");
38 @r = (20, 40, 60) »div« (2, 5, 10);
40 is(~@r, ~@e, "hyper-divide two arrays");
42 @r = (1, 2, 3) »+« (10, 20, 30) »*« (2, 3, 4);
44 is(~@r, ~@e, "precedence - »+« vs »*«");
48 @r = (1, 2, 3) >>+<< (2, 4, 6);
50 is(~@r, ~@e, "hyper-sum two arrays ASCII notation");
52 @r = (1, 2, 3) >>-<< (2, 4, 6);
54 is(~@r, ~@e, "hyper-subtract two arrays ASCII notation");
56 @r = (1, 2, 3) >>*<< (2, 4, 6);
58 is(~@r, ~@e, "hyper-multiply two arrays ASCII notation");
60 @r = (1, 2, 3) >>x<< (3, 2, 1);
61 @e = ('111', '22', '3');
62 is(~@r, ~@e, "hyper-x two arrays ASCII notation");
64 @r = (1, 2, 3) >>xx<< (3, 2, 1);
65 @e = ((1,1,1), (2,2), (3));
66 is(~@r, ~@e, "hyper-xx two arrays ASCII notation");
68 @r = (20, 40, 60) >>div<< (2, 5, 10);
70 is(~@r, ~@e, "hyper-divide two arrays ASCII notation");
72 @r = (1, 2, 3) >>+<< (10, 20, 30) >>*<< (2, 3, 4);
74 is(~@r, ~@e, "precedence - >>+<< vs >>*<< ASCII notation");
82 is(~@r, ~@e, "hyper auto increment an array");
88 is(~@r, ~@e, "hyper auto increment an array ASCII notation");
95 is(~@r, ~@e, "hyper op on assignment/pipeline");
99 is(~@r, ~@e, "hyper op on assignment/pipeline ASCII notation");
102 { # dimension upgrade - ASCII
104 @r = (1, 2, 3) >>+>> 1;
106 is(~@r, ~@e, "auto dimension upgrade on rhs ASCII notation");
108 @r = 2 <<*<< (10, 20, 30);
110 is(~@r, ~@e, "auto dimension upgrade on lhs ASCII notation");
113 #?rakudo todo 'list level extension'
114 { # list level extension
115 @r = (1,2,3,4) >>+>> (1,2);
117 is(~@r, ~@e, "list-level element extension on rhs ASCII notation");
119 @r = (1,2) <<+<< (1,2,3,4);
121 is(~@r, ~@e, "list-level element extension on lhs ASCII notation");
123 @r = (1,2,3,4) >>+>> (1,);
125 is(~@r, ~@e, "list-level element extension on rhs ASCII notation");
127 @r = (1,) <<+<< (1,2,3,4);
129 is(~@r, ~@e, "list-level element extension on lhs ASCII notation");
132 #?rakudo skip 'unicode hypers'
133 { # dimension upgrade - unicode
135 @r = (1, 2, 3) »+» 1;
137 is(~@r, ~@e, "auto dimension upgrade on rhs");
139 @r = 2 «*« (10, 20, 30);
141 is(~@r, ~@e, "auto dimension upgrade on lhs");
143 @r = (1,2,3,4) »+» (1,2);
145 is(~@r, ~@e, "list-level element extension on rhs");
147 @r = (1,2) «+« (1,2,3,4);
149 is(~@r, ~@e, "list-level element extension on lhs");
151 @r = (1,2,3,4) »+» (1,);
153 is(~@r, ~@e, "list-level element extension on rhs");
155 @r = (1,) «+« (1,2,3,4);
157 is(~@r, ~@e, "list-level element extension on lhs");
160 { # unary postfix with integers
162 @r = (1, 4, 9)».sqrt;
164 is(~@r, ~@e, "method call on integer list elements");
166 @r = (1, 4, 9)>>.sqrt;
168 is(~@r, ~@e, "method call on integer list elements (ASCII)");
171 #?rakudo skip '@array»++'
177 is(~@r, ~@e, "operator call on integer list elements");
179 (@r = (1, 4, 9)).»++;
180 is(~@r, ~@e, "operator call on integer list elements (Same thing, dot form)");
182 (@r = (1, 4, 9))».++;
184 is(~@r, ~@e, "operator call on integer list elements (Same thing, dot form)");
186 (@r = (1, 4, 9)).».++;
187 is(~@r, ~@e, "operator call on integer list elements (Same thing, dot form)");
189 (@r = (1, 4, 9))\ .»\ .++;
191 is(~@r, ~@e, "operator call on integer list elements (Same thing, upspace form)");
194 { # unary postfix again, but with a twist
196 eval '@r = ("f", "oo", "bar")».chars';
198 is(~@r, ~@e, "method call on list elements");
200 eval '@r = ("f", "oo", "bar").».chars';
202 is(~@r, ~@e, "method call on list elements (Same thing, dot form)");
205 eval '@r = ("f", "oo", "bar")>>.chars';
207 is(~@r, ~@e, "method call on list elements (ASCII)");
209 eval '@r = ("f", "oo", "bar").>>.chars';
211 is(~@r, ~@e, "method call on list elements (ASCII, Same thing, dot form)");
215 { # unary postfix on a user-defined object
217 class FooTest { method bar { 42 } }; $t = FooTest.new.bar;
218 is($t, 42, 'plain method call works OK');
221 class FooTest2 { method bar { 42 } }; @r = (FooTest2.new)>>.bar;
223 is(~@r, ~@e, "hyper-method-call on list of user-defined objects");
226 { # distribution for unary prefix
228 @r = -« ([1, 2], [3, [4, 5]]);
229 my @e = ([-1, -2], [-3, [-4, -5]]);
230 is(~@r, ~@e, "distribution for unary prefix");
231 is_deeply(@r, @e, "distribution for unary prefix, deep comparison");
233 @r = -<< ([1, 2], [3, [4, 5]]);
234 @e = ([-1, -2], [-3, [-4, -5]]);
235 is(~@r, ~@e, "distribution for unary prefix, ASCII");
236 is_deeply(@r, @e, "distribution for unary prefix, ASCII, deep comparison");
239 { # distribution for unary postfix autoincrement
241 @r = ([1, 2], [3, [4, 5]]);
243 my @e = ([2, 3], [4, [5, 6]]);
245 is(~@r, ~@e, "distribution for unary postfix autoincr");
246 is_deeply(@r, @e, "distribution for unary postfix autoincr, deep comparison");
248 @r = ([1, 2], [3, [4, 5]]);
250 @e = ([2, 3], [4, [5, 6]]);
252 is(~@r, ~@e, "distribution for unary postfix autoincr, ASCII");
253 is_deeply(@r, @e, "distribution for unary postfix autoincr, ASCII, deep comparison");
257 { # distribution for binary infix - ASCII
259 @r = (1, 2, [3, 4]) >>+<< (4, 5, [6, 7]);
260 my @e = (5, 7, [9, 11]);
261 is(~@r, ~@e, "distribution for binary infix, same shape, ASCII");
262 is_deeply(@r, @e, "distribution for binary infix, same shape, ASCII, deep comparision");
264 @r = (1, 2, [3, 4]) >>+>> (5, 6, 7);
265 @e = (6, 8, [10, 11]);
266 is(~@r, ~@e, "distribution for binary infix, dimension upgrade, ASCII");
267 is_deeply(@r, @e, "distribution for binary infix, dimension upgrade, ASCII, deep comparison");
269 @r = ([1, 2], 3) <<+>> (4, [5, 6]);
270 @e = ([5, 6], [8, 9]);
271 is(~@r, ~@e, "distribution for binary infix, S03 cross-upgrade, ASCII");
272 is_deeply(@r, @e, "distribution for binary infix, S03 cross-upgrade, ASCII, deep comparison");
276 { # distribution for binary infix - unicode
278 @r = (1, 2, [3, 4]) »+« (4, 5, [6, 7]);
279 my @e = (5, 7, [9, 11]);
280 is(~@r, ~@e, "distribution for binary infix, same shape");
281 is_deeply(@r, @e, "distribution for binary infix, same shape, deep comparison");
283 @r = (1, 2, [3, 4]) »+» (5, 6, 7);
284 @e = (6, 8, [10, 11]);
285 is(~@r, ~@e, "distribution for binary infix, dimension upgrade");
286 is_deeply(@r, @e, "distribution for binary infix, dimension upgrade, deep comparison");
288 @r = ([1, 2], 3) «+» (4, [5, 6]);
289 @e = ([5, 6], [8, 9]);
290 is(~@r, ~@e, "distribution for binary infix, S03 cross-upgrade");
291 is_deeply(@r, @e, "distribution for binary infix, S03 cross-upgrade, deep comparison");
294 { # regression test, ensure that hyper works on arrays
300 is(~@r1, ~@e1, "hyper op works on variables, too.");
306 is(~@r2, ~@e2, "hyper op and correctly promotes scalars");
310 # mixed hyper and reduce metaops -
311 # this unveils a spec bug as << recurses into arrays and [+] never gets applied,
312 # so we disable the entire chunk for now.
313 =begin todo unspecced
315 is ~([+]<< ([1,2,3], [4,5,6])), "6 15", "mixed hyper and reduce metaop ([+]<<) works";
316 ## XXX: Test for [+]<<<< - This is unspecced, commenting it out
317 #is ~([+]<<<< ([[1,2],[3,4]],[[5,6],[7,8]])), "3 7 11 15",
318 # "mixed double hyper and reduce metaop ([+]<<<<) works";
320 is ~([+]« [1,2,3], [4,5,6]), "6 15",
321 "mixed Unicode hyper and reduce metaop ([+]«) works";
325 #?pugs todo 'hyper ops'
326 { # hyper dereferencing
333 my $full = join '', eval '@array>>.<key>';
334 is($full, 'valvalval', 'hyper-dereference an array');
336 my $part = join '', eval '@array[0,1]>>.<key>';
337 is($part, 'valval', 'hyper-dereference an array slice');
340 #?pugs todo 'feature'
341 { # junction hyper -- regression?
344 ok ?(@a »|« @b), '»|« hyperjunction evals';
345 ok ?(@a >>|<< @b), '>>|<< hyperjunction evals, ASCII';
346 ok ?(@a »&« @b), '»&« hyperjunction evals';
347 ok ?(@a >>&<< @b), '>>&<< hyperjunction evals, ASCII';
350 # test hypers on hashes
352 my %a = a => 1, b => 2, c => 3;
353 my %b = a => 5, b => 6, c => 7;
354 my %c = a => 1, b => 2;
355 my %d = a => 5, b => 6;
359 is +%r, 3, 'hash - >>+<< result has right number of keys (same keys)';
360 is %r<a>, 6, 'hash - correct result form >>+<< (same keys)';
361 is %r<b>, 8, 'hash - correct result form >>+<< (same keys)';
362 is %r<c>, 10, 'hash - correct result form >>+<< (same keys)';
365 is +%r, 3, 'hash - »+« result has right number of keys (union test)';
366 is %r<a>, 6, 'hash - correct result form »+« (union test)';
367 is %r<b>, 8, 'hash - correct result form »+« (union test)';
368 is %r<c>, 3, 'hash - correct result form »+« (union test)';
371 is +%r, 3, 'hash - >>+<< result has right number of keys (union test)';
372 is %r<a>, 6, 'hash - correct result form >>+<< (union test)';
373 is %r<b>, 8, 'hash - correct result form >>+<< (union test)';
374 is %r<c>, 7, 'hash - correct result form >>+<< (union test)';
377 is +%r, 3, 'hash - <<+>> result has right number of keys (same keys)';
378 is %r<a>, 6, 'hash - correct result form <<+>> (same keys)';
379 is %r<b>, 8, 'hash - correct result form <<+>> (same keys)';
380 is %r<c>, 10, 'hash - correct result form <<+>> (same keys)';
383 is +%r, 2, 'hash - <<+>> result has right number of keys (intersection test)';
384 is %r<a>, 6, 'hash - correct result form <<+>> (intersection test)';
385 is %r<b>, 8, 'hash - correct result form <<+>> (intersection test)';
388 is +%r, 2, 'hash - <<+>> result has right number of keys (intersection test)';
389 is %r<a>, 6, 'hash - correct result form <<+>> (intersection test)';
390 is %r<b>, 8, 'hash - correct result form <<+>> (intersection test)';
393 is +%r, 3, 'hash - >>+>> result has right number of keys';
394 is %r<a>, 2, 'hash - correct result from >>+>>';
395 is %r<b>, 4, 'hash - correct result from >>+>>';
396 is %r<c>, 3, 'hash - correct result from >>+>>';
399 is +%r, 2, 'hash - >>+>> result has right number of keys';
400 is %r<a>, 6, 'hash - correct result from >>+>>';
401 is %r<b>, 8, 'hash - correct result from >>+>>';
404 is +%r, 3, 'hash - <<+<< result has right number of keys';
405 is %r<a>, 2, 'hash - correct result from <<+<<';
406 is %r<b>, 4, 'hash - correct result from <<+<<';
407 is %r<c>, 3, 'hash - correct result from <<+<<';
410 is +%r, 2, 'hash - <<+<< result has right number of keys';
411 is %r<a>, 6, 'hash - correct result from <<+<<';
412 is %r<b>, 8, 'hash - correct result from <<+<<';
416 my %a = a => 1, b => 2, c => 3;
418 is +%r, 3, 'hash - -<< result has right number of keys';
419 is %r<a>, -1, 'hash - correct result from -<<';
420 is %r<b>, -2, 'hash - correct result from -<<';
421 is %r<c>, -3, 'hash - correct result from -<<';
424 is +%r, 3, 'hash - --<< result has right number of keys';
425 is %r<a>, 0, 'hash - correct result from --<<';
426 is %r<b>, 1, 'hash - correct result from --<<';
427 is %r<c>, 2, 'hash - correct result from --<<';
428 is +%a, 3, 'hash - --<< result has right number of keys';
429 is %a<a>, 0, 'hash - correct result from --<<';
430 is %a<b>, 1, 'hash - correct result from --<<';
431 is %a<c>, 2, 'hash - correct result from --<<';
434 is +%r, 3, 'hash - >>++ result has right number of keys';
435 is %r<a>, 0, 'hash - correct result from >>++';
436 is %r<b>, 1, 'hash - correct result from >>++';
437 is %r<c>, 2, 'hash - correct result from >>++';
438 is +%a, 3, 'hash - >>++ result has right number of keys';
439 is %a<a>, 1, 'hash - correct result from >>++';
440 is %a<b>, 2, 'hash - correct result from >>++';
441 is %a<c>, 3, 'hash - correct result from >>++';
445 our sub postfix:<!>($a) {
449 my %a = a => 1, b => 2, c => 3;
451 is +%r, 3, 'hash - >>! result has right number of keys';
452 is %r<a>, 1, 'hash - correct result from >>!';
453 is %r<b>, 2, 'hash - correct result from >>!';
454 is %r<c>, 6, 'hash - correct result from >>!';
458 # test non-UTF-8 input
459 #?pugs skip 'eval(Buf)'
460 #?rakudo skip 'eval(Buf)'
463 my $t = '(1, 2, 3) »+« (4, 3, 2)';
464 ok !eval($t.encode('ISO-8859-1')),
465 'Latin-1 »+« without pre-declaration is an error';