Although the result of the two lines is the same, the parse trees look different, which is quite explainable. Instead of examining the parse trees, let us try locating the place where Perl 6 prints the string.

The say sub

This function is a multi-sub, which is defined in the src/core/io_operators.pm file in four different variants:

I did that mistake and faced an infinite loop that wanted all CPU and memory resources because our additional instruction used the same variant say(Str:D) for a defined string. Even more, the real printing never happened as the $out.print method is called a bit later and is never reached.

Using the nqp:: namespace easily bypasses the problem.

$ ./perl6 -e'say "Hello, World"'
say(Str:D \x)
Hello, World

The say method

Now, let’s try guessing where the say method can be located. I am talking about our second one-liner, 'Hello, World'.say. The first idea is to look for it in src/core/Str.pm, although you will not see it there.

The method is located in the grandgrandparent class Mu (Str←Cool←Any←Mu). You may be surprised to see how it looks like:

proto method say(|) {*}
multi method say() { say(self) }

The fact that it has a prototype and that it is a multi-sub, although there is only one implementation, is not that important now. What is interesting, is that the method barely calls the say sub, which we examined in the previous section.

Add another nqp::say to the method of Mu:

multi method say() { nqp::say('Mu.say()'); say(self) }

Now, run the second program:

$ ./perl6 -e'"Hello, World".say'
Mu.say()
say(Str:D \x)
Hello, World

As you see, we ended up in the same function. Although the difference between the two parse trees was quite big, the actual work was done by the same function in the end.

That’s all for today. Tomorrow, let’s examine other variants of the say sub.