Kurt's answer catches the bugs that they wanted to receive. This additional answer is my initial research on Chi, which follows on :
Why does Curt Rakudo wait for runtime when compiling / running code to report two out of three errors?
At the end of this initial research, I came to the end of Kurt's code in the BEGIN block. This code reports all errors during compilation (one after the other, of course, after commenting on each previous error). ( Click to start the fragment .)
This is a straw response configured for 6-core Perl developers to shoot down.
Initial start of the Curt code results in:
=== SORRY! === ... Calling myprint (Distance) will never work ...
The host ===SORRY!=== means the error "compile-time" 1 .
But if we comment on the failed line and try again, we get:
Type check error when assigning $ d2 ...
This error message is a "run-time" 1 message - it does not start with ===SORRY!=== .
Why did the compiler wait for a "run time" to complain?
The answer seems to be a combination of Perl 6, mostly dynamic by default, and code that doesn't execute:
my Distance $d2 = $o;
Part of this part of my Distance $d2 fully processed (introducing the new lexically restricted character $d2 ) when the compiler first encounters this declaration at compile time. But the = part of this line is a "run-time" operator; the initialization assignment and the corresponding type check occur at runtime.
But the developer may want to force type checking, and therefore a type checking error, to happen at compile time. Now what?
BEGIN time
Perl 6 supports space / runtime of the program through phasers . The first phaser is the BEGIN phaser, which "starts at compile time as soon as possible" and can be used as follows:
BEGIN my Distance $d2 = $o;
If you recompile with this change, an error now appears during compilation 1 :
===SORRY!=== Error while compiling... An exception occurred while evaluating a BEGIN... Type check failed in assignment to $d2...
If we now comment on the last unsuccessful line and try again, we get:
Cannot Allow Caller Numeric (Distance:) ...
No lead ===SORRY!=== , so again this is a run-time error.
Reusing code with a modified line:
BEGIN say $d + $o;
gives:
0 12
on stdout, and on stderr we get:
Use of uninitialized value of type Distance in numeric context... Use of uninitialized value of type Offset in numeric context...
Uhh. There is not only a compile-time error, there is no runtime error! (Runtime warnings can give the game about 0 Since the lines my... declaring $d and $o were not prefixed with BEGIN , these characters have not yet been initialized at compile time, which is the time that BEGIN say $d + $o; line being launched But all this is debatable .. we are clearly a step back)
What happens if we pack all the Curt code in one BEGIN block?
BEGIN { ... Curt code goes here ... }
BEGIN { class Distance... class Offset... my Distance $d = Distance.new(12)... sub myprint(Int $i) { say $i } say $d + $o;... }
Bingo! Now all errors are detected because they were with the source code of Curt, but reporting seems to happen at compile time (one after the other, after commenting on each previous error).
1 I scare the citation of many references to “compile time” and “run time” because they are ambiguous in Perl 6. Perl 6 allows the user code to do anything, including starting the compiler at runtime, and allows the user code to do at compile time anything, including at runtime. Therefore, on the one hand, there can be one or more run-time phases during the compilation phase and vice versa. But from the second point of view, there is a compilation time phase, i.e. When you sit there during a development session, and you just started the compiler. There is also a run-time phase, that is, when your code, for example, works "in production". Where I do not frighten runtime / compilation quotes, I mean a link to this second perspective.