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

Reply via email to