doc
doc copied to clipboard
what does the » vs. « direction in hyperoperation mean?
Problem or new feature
Here's what the docs say about hyperoperator angle direction:
Hyper operators include « and », with their ASCII variants << and >>. They apply a given operator enclosed (or preceded or followed, in the case of unary operators) by « and/or » to one or two lists, returning the resulting list, with the pointy part of « or » aimed at the shorter list. Single elements are turned to a list, so they can be used too. If one of the lists is shorter than the other, the operator will cycle over the shorter list until all elements of the longer list are processed.
This is from syntax/<<
but also found on language/operators
This doesn't really make sense to me. If one is shorter, and if the operator will cycle over the short one, then why does the direction matter? But it does, because if both point inward and list sizes don't match, an error is raised.
I couldn't figure out from the documentation what it means, and a (very small) amount of testing by hand didn't make me say "a-ha!". This feels like something that might actually be easy to explain, but the existing docs didn't make it clear.
Suggestions
🤷🏽
The text of the docs is insufficiently detailed about exactly your point of confusion, and is also not worded well.
"operator will cycle over the shorter list until all elements of the longer list are processed" is only true when the hyper is "aimed at" the shorter list. Omitted is the opposite case; when the hyper is "aimed at" the longer list, that list is truncated to match the size of the shorter list. Running the attached code, I see that when the hyper points outward toward both lists, the shorter list is cycled, which may be more useful than truncation, but is also not documented.
Since it is past midnight here, I am only describing current behavior above, and including code and annotated output to further the discussion, instead of proposing specific new wording to fill the gaps. raku_doc_4077_code.txt raku_doc_4077_output.txt
@Util Thanks for your reply!
I think -- knowing very very little about how the meta-operators involved work -- there are at least a few questions I'd like to see addressed:
- How do the "angles on both sides" forms differ from "angles on one side"? I believe that unary operators get angles on one side, and binary on both. The documentation points at this, but could probably be more specific.
- What is the relationship between the direction of the arrow and the behavior of the newly formed operator?
- Are the behaviors of
<<x>>
and>>x<<
the obvious outcome of how<<
and>>
are defined, or are they special? - Given unequal length lists using
>>+<<
the error says "non-dwimmy hyperop". What is "dwimmy" here? (I know what DWIM is, as a generic term.)
My Theory Formed via Experimentation
I think maybe the way it works is this:
- Theorem 1: unary operators must be hypered with the arrow pointing from the list toward the operator
!<<(1,2,3)
(1,2,3)>>.say
-
Theorem 2: The
>>x>>
and<<x<<
forms for binary operators should be viewed as a single four-angle arrow pointing in one direction. They point at the shorter list, which will be cycled through. If the list is not actually shorter, an error is raised. They are not "dwimmy" because you must tell them what to do and you must be correct. -
Theorem 3: The
>>+<<
form is also not "dwimmy". It will not cycle either list, so they must be the same size. -
Theorem 4: The
<<+>>
form is the only "dwimmy" one. It will cycle whichever list list is shorter. The programmer doesn't need to think about it.
On IRC, Nemokosch points out that Theorem 2 is incorrect:
> (1,2,3) <<+<< (1,2)
(2 4)
…but I formed that after trying
> (1,2,3) <<+<< 2
Lists on either side of non-dwimmy hyperop of infix:<+> are not of the same length while recursing
left: 3 elements, right: 1 elements
in block <unit> at <unknown file> line 9
Nemokosch further informed me that that (1,2,3) <<+<< (2,)
would work, because (2,)
is a list and (2)
is not.
The repl is your friend ;-)
Single Item & List:
Wrong way gives an error:
> (1,2,3) <<+<< 2
Lists on either side of non-dwimmy hyperop of infix:<+> are not of the same length while recursing
left: 3 elements, right: 1 elements
in block <unit> at <unknown file> line 1
Right way does not:
> (1,2,3) >>+>> 2
(3 4 5)
Both are Lists
Wrong way does not cycle (ie. exits when exhausted):
> (1,2,3) <<+<< (1,2)
(2 4)
Right way cycles:
> (1,2,3) >>+>> (1,2)
(2 4 4)
I guess another way (postulate) to look at this is that the blunt end of the angles determines the length of the result.
I opened a mega-issue about hyper meta-operators a while ago: https://github.com/Raku/problem-solving/issues/346
It includes loads of behavior (as of the latest version at that time) but also undocumented, possibly buggy corner cases.