From World.nqp, line 3602 :
nqp::if(
nqp::istype(nqp::atpos($task,3),$!Block),
QAST::Op.new( :op<call>,
QAST::WVal.new(:value(nqp::atpos($task,3))),
$self,
$getattr
),
nqp::if(
nqp::iseq_i($code,5),
QAST::IVal.new(:value(nqp::atpos($task,3))),
QAST::NVal.new(:value(nqp::atpos($task,3)))
)
),
whereas from World.nqp, line 3314 :
if $invocant_type =:= $!acc_sig_cache_type {
$sig := $!acc_sig_cache;
}
# First time, create new signature and mark it cached
else {
$sig := $!w.create_signature_and_params(
NQPMu, %sig_empty, $block, 'Any', :method, :$invocant_type);
$!acc_sig_cache := $sig;
$!acc_sig_cache_type := $invocant_type;
}
I thought the last form of if
(without nqp::
) in front was not allowed unless if
was a builtin? See NQP Built-in Subs List.
The first form, nqp::if
, is described in the NQP Opcode List,
however I could not find documentation for the second form, though
it seems to be the most common form in the Rakudo source tree.
Why are there two forms of if
statements in NQP?
The
if
statement in NQP is part of the language syntax rather than being any kind of built-in routine. It is parsed by the NQP compiler's grammar and compiled into an AST node. The AST node it produces is, so far as the conditional goes, the same one that annqp::if
would produce (thenqp::foo
syntax is just a means to createOp
AST nodes). Thecond() ?? foo() !! bar()
syntax also compiles into the same kind of node. This is also true for the full Perl 6.The notable differences are:
if
statement can only appear at statement level, whilenqp::if(...)
can appear anywhereif
statement form introduces a new lexical scope inside of the curly braces, while thenqp::if
form does not do thatIn the linked example, the expression form is desired, thus the use of the
nqp::if
construct. However,??
/!!
could also have been used, and would arguably be more readable. Mostly, it's just up to the author of the code to decide what they think communicates best or matches the surrounding context.