On Sun, May 23, 2021 at 9:12 PM Joseph Brenner <doom...@gmail.com> wrote: > > my impression was that junctions, by design aren't supposed to be > treated as compound data structures, they're a *single* thing but > with multiple values that co-exist with each other in "superposition".
That's correct. Until they're expanded, they're a single thing. By default, when you call a function (or use an operator, because operators are functions) that isn't special cased to accept an unexpanded junction for a parameter, any argument that's a junction is expanded before calling the function, and the function is applied once per combination of each junction argument's elements. > For example, you can't get a count of the number of elements in a junction: > > my $junction = any( 'a', 'b', 'c' ); > say $junction.elems; # any(1, 1, 1) Right. Like about 99.99% of all functions, `elems` isn't special cased. > But then, this actually works: > > $junction>>.say; > # a > # b > # c Right. Hypers also aren't special cased. So that works as expected (if you expect the very simple rules that drive how it works by default). (It's one hyper call on `a`, one on `b`, one on `c`. The hyper operator does *not* see a junction. It gets call three times, each time with a different invocant.) > So going the other way, using a hyper operator to create a > junction isn't such a silly thing to look at... To *create* one? Sure. But that's unrelated to what's going on in the above. > Though really then this idiom creates an array of multiple any > junctions with single values, which would behave just like the > individual values themselves: > > my $values = < A B C >; > my $junction2 = $values>>.any; > say $junction2; > # (any(A) any(B) any(C)) The `>>` is called three times, once with `A` as its invocant, and so on. The result is a `List` of three `any` junctions, each containing a single element. The variable `$junction2` contains that `List`, not a junction. Now we *do* arrive at the first and only special case among your examples, the `say`, which uses `gist`. The `gist` of a junction is special cased to be a single string providing a human friendly gist of a junction, rather than multiple strings, once for each element of the junction. Thus you get the result you see. This is where some of the *costs* of DWIMs starts to creep in. There are behaviors that don't follow the norm, and thus WATs that need to be explained. Provided the explanations sit well enough with those who experience them for them to get over the shock, all is good, and perhaps even great (one can learn *better* due to a shock than merely things working as expected). The key things are for PL designers and construct/object/function creators to be very judicious about choosing which DWIMS they are willing to be responsible for, valuing WATs as potential teachable moments, and for users to realize that WATs can be a really good thing. -- love, raiph