Some (most?) of these don't strike me as ternary at all – but, after giving it a bit of thought, I think I see. To take a Raku example: in <10 20 30> «+» <4 5>, you're thinking of the « » operator as having three operands (<10 20 30>, +, and <4 5>). Is that right?
I ask because that's not how I conceptualize it. I'd say that « » is unary circumfix operator with the operand +. That operation returns a new binary infix operator, which takes <10 20 30> and <4 5> as its two operators.
And Raku actually does let you decompose this process by assigning the new operator to a function (just as you showed in J). Admittedly, the syntax for doing so is slightly obscure and more than slightly ugly. So it's definitely not something the language really leads you to. Here's how that'd look:
my &h = &[«+»]; <10 20 30> [&h] <4 5>
(This uses the [&…] syntax to call a function as if it were an infix operator; you could also explicitly create an infix h operator: my &infix:<h> = &[«+»]; <10 20 30> h <4 5>.)
Assigning works exactly the same with the assignment metaop: my &h = &[max=]. And the same "it a unary op that returns a binary op" logic applies.
More generally, I'm not 100% convinced that there's any inherent reason that any ternary operator can't be decomposed. Sticking to Raku (if False { 'one' } else { 'two' }) looks a lot like a ternary. But (if False { 'one'}) is perfectly valid and returns (). It seems that any ternary could allow decomposition, even if most of them – including Raku's $a ?? $b !! $c conditional ternary – don't. What am I missing?
Some (most?) of these don't strike me as ternary at all – but, after giving it a bit of thought, I think I see. To take a Raku example: in
<10 20 30> «+» <4 5>
, you're thinking of the« »
operator as having three operands (<10 20 30>
,+
, and<4 5>
). Is that right?I ask because that's not how I conceptualize it. I'd say that
« »
is unary circumfix operator with the operand+
. That operation returns a new binary infix operator, which takes<10 20 30>
and<4 5>
as its two operators.And Raku actually does let you decompose this process by assigning the new operator to a function (just as you showed in J). Admittedly, the syntax for doing so is slightly obscure and more than slightly ugly. So it's definitely not something the language really leads you to. Here's how that'd look:
my &h = &[«+»]; <10 20 30> [&h] <4 5>
(This uses the
[&…]
syntax to call a function as if it were an infix operator; you could also explicitly create an infixh
operator:my &infix:<h> = &[«+»]; <10 20 30> h <4 5>
.)Assigning works exactly the same with the assignment metaop:
my &h = &[max=]
. And the same "it a unary op that returns a binary op" logic applies.More generally, I'm not 100% convinced that there's any inherent reason that any ternary operator can't be decomposed. Sticking to Raku
(if False { 'one' } else { 'two' })
looks a lot like a ternary. But(if False { 'one'})
is perfectly valid and returns()
. It seems that any ternary could allow decomposition, even if most of them – including Raku's$a ?? $b !! $c
conditional ternary – don't. What am I missing?