Elektrine lite

← Feed

@wim_v12e@merveilles.town

Post #2158812

2026-05-06 09:08 UTC

Until about 2022, I loved to program in Raku, the language formerly know as Perl 6. (Sadly, since then, genAI has ruined that for me.) Raku has neat feature called Junctions. A junction is a lazy expression of values of any type combined with Boolean-like operators `|`, `&` and `^`. When an operation is applied to a Junction, it is carried out for each junction element, and the result is the junction of the return values of the operations. You can optionally evaluate a Junction in a Boolean context using `so`. So you can do things like my \jj = 1&2; say so jj; # True say so (->\x {x-1})( jj ); # False Back in 2020 I pointed out an issue with Junctions, [The strange case of the greedy junction](https://limited.systems/articles/greedy-junctions/). Junctions are *greedy*, they turn anything they are combined with also into a Junction. This is not always desirable. I proposed an additional operation ("collapse") to undo this behaviour. In a second post [Reconstructing Raku's Junctions](https://limited.systems/articles/reconstructing-raku-junctions/) I provided a proof for both the observed behaviour and the need for a "collapse" operation, by formalising Junction semantics in terms of polymorphic algebraic data types. I just re-read it and I still think it is very cool. The `collapse` method never made it into the language (https://github.com/rakudo/rakudo/pull/3944) but my implementation still works. What I think is neat is that my formalisation lets you implement Junctions in any language. #programming #programmingLanguages #rakulang

Replies (1)

  • @timotimo@peoplemaking.games 2026-05-08 18:42

    @wim_v12e@merveilles.town I missed these articles the first time, but perhaps I can shed some light? Junction is derived directly from Mu, and Any is derived directly from Mu as well, and this is actually how auto-threading is triggered: whenever parameter binding for a function call fails because a Junction was passed to a parameter that was typed Any or a sub-type of Any, the call is re-attempted with the values inside the Junction one at a time, and the result of the call is re-assembled into a new Junction of the same type. If you just want your original code to work without the need for a collapse operation, then you can just change pair to take Mu arguments instead of the default that you get when you don't put a type constraint on parameters which is Any. Then instead of pair (42^43),R doing pair(42, R)^pair(43, R) because the call gets autothreaded, you end up with actually a function that calls its argument with (4243) and R instead of a junction with two functions, and fst and snd "accidentally" work

    Open ##2457470