SHOVE came into existence because there was no feasible way to dispatch infix automatically from paths. LEFT SHOVE now gives you the same behavior you would get if an infix operation had dispatched:
>> add 1 2 * 3 == 7 >> add 1 2 <- lib/* 3 == 7
Not only can you now run enfixed functions out of objects, but you can invoke refinements on infix arguments. It’s even smart enough to pick up on the quoting convention of the right hand side:
>> x: null >> x: <- lib/default [1 + 2] == 3 >> x == 3
It doesn’t even matter if the thing on the right is enfixed or not, it will act like it was…just in case you felt like putting an argument to the left of something:
>> 1 + 2 <- lib/multiply 3 == 9
And since one of the many reasons for SHOVE existing is to avoid double-group evaluation in lookahead, note it has that covered:
>> 1 + 2 <- lib/(print "only prints once" first [*]) 3 only prints once == 9
That’s a lot of stuff to take in. But of course, who do you think you’re talking to… of course there’s more!
Now there’s a difference between <- and ->
Both are shove operators, but
-> doesn’t act like an infix operation happened when it runs the right.
>> if 10 = 5 + 5 [print "Classic error"] ** Script Error: + does not allow logic! for its value1 argument >> if 10 <- = 5 + 5 [print "Error parity when using shove left"] ** Script Error: + does not allow logic! for its value1 argument >> if 10 -> = 5 + 5 [print "But shove right has your back!"] But shove right has your back!
Even though the right doesn’t operate as infix, the left does. So if you have more than one thing to put on the left, you’ll have to put it in a group:
>> (1 + 2) -> = 2 + 1 == true
But hey, at least it works, this used to be impossible!
>> (1 + 2) = 2 + 1 ** Script Error: + does not allow logic! for its value1 argument
Even more fun: RIGHT BAR |> is a “postponing shove”
In case you wanted to run all the stuff on the left…
>> x: add 1 add 2 3 |> lib/* 4 == 24 >> x == 24
It still has to follow the rules of postponement, it has to be at a “full stop” position (e.g. anywhere an an expression barrier would be legal).
And for good measure: LEFT BAR is…some other thing
This may seem kind of random, but it’s actually the only thing in this list that’s meant the same thing since the symbol started being used. It’s a postponing invisible evaluator. It acts as a barrier and evaluates to what was on its left, forgetting the right.
>> 1 + 2 <| print "Hi" x: 10 y: 20 Hi == 3 >> x == 10 >> y == 20
People need to try these things out!
These aren’t frivolous…they’re very important. SHOVE was a solution to very real problems about needing to dispatch overloaded words from LIB, as well as some hypothetical-yet-interesting questions about being able to put refinements on infix.
But ponder this: being able to avoid parenthesization is very good when you want to save your GROUP!s for some other thing (like COMPOSE). So if you can clearly express yourself with just -> or <-, that’s the same number of characters and you aren’t sacrificing your groups.
I’d love to sit around imagining every possible test and edge case for these things, but I do not have time to do that and everything else. Try using them and tell me what happens!