🔬22. The infix nature of the ternary operator in Perl 6

🔬22. The infix nature of the ternary operator in Raku

N. B. Perl 6 has been renamed to Raku. Click to read more.


The ternary operator ?? !! takes three operands, obviously. Although, it is said in the documentation that the operator is an infix. Let us figure out why.

Here is the fragment from the Grammar that handles the ternary operator:

token infix:sym<?? !!> {
    :my $*GOAL := '!!';
    $<sym>='??'
    <.ws>
    <EXPR('i=')>
    [ '!!'
    || <?before '::' <.-[=]>> { self.typed_panic: "X::Syntax::ConditionalOperator::SecondPartInvalid", second-part => "::" }
    || <?before ':' <.-[=\w]>> { self.typed_panic: "X::Syntax::ConditionalOperator::SecondPartInvalid", second-part => ":" }
    || <infixish> { self.typed_panic: "X::Syntax::ConditionalOperator::PrecedenceTooLoose", operator => ~$<infixish> }
    || <?{ ~$<EXPR> ~~ / '!!' / }> { self.typed_panic: "X::Syntax::ConditionalOperator::SecondPartGobbled" }
    || <?before \N*? [\n\N*?]? '!!'> { self.typed_panic: "X::Syntax::Confused", reason => "Confused: Bogus code found before the !! of conditional operator" }
    || { self.typed_panic: "X::Syntax::Confused", reason => "Confused: Found ?? but no !!" }
    ]
    <O(|%conditional, :reducecheck<ternary>, :pasttype<if>)>
}

The most of the body is filled with different error reporting additions that pop up when something is wrong with the second part of the operator. Let us reduce the noise and implement the simplest form of our own artificial operator ¿¿ ¡¡ that does no such error checking:

token infix:sym<¿¿ ¡¡> {
    '¿¿'
    <.ws>
    <EXPR('i=')>
    '¡¡'
    <O(|%conditional, :reducecheck<ternary>, :pasttype<if>)>
}

Now you can clearly see the structure of the token. It matches the following components: a literal string '¿¿', an expression, and another string '¡¡'. We’ve already seen the use of the O token when we were talking about precedence.

If you consider ¿¿ ¡¡ as an infix operator  ($left ¿¿ $mid ¡¡ $right), then the first and the third operands of the ternary operator are, respectively, the left and the right operands of the combined operator. The code between ¿¿ and ¡¡ is caught by the <EXPR> rule.

Before wrapping up for today, let us print what the Grammar finds at that position:

token infix:sym<¿¿ ¡¡> {
    '¿¿'
    <.ws>
    <EXPR('i=')> {
        nqp::say('Inside we see: ' ~ $<EXPR>)
    }
    '¡¡'
    <O(|%conditional, :reducecheck<ternary>, :pasttype<if>)>
}

Compile and run:

$ ./perl6 -e'say 3 ¿¿ 4 ¡¡ 5'
Inside we see: 4 
4

It is quite difficult, though, to find the place where the actual logic of the ternary operator is defined. I would not even recommend doing that as homework 🙂 Nevertheless, come back tomorrow to see more details of the internals of the ternary operators.

One thought on “🔬22. The infix nature of the ternary operator in Perl 6”

Leave a Reply