Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make compile-time code non-cached in Perl 6?

Tags:

raku

Let's say I want to create a number of types at compile-time, but before that let's test compile-time code with a simpler example:

# in file root.pm6
sub foo($a) { $a.say }

sub EXPORT {
    # Things here may be a lot more complex
    foo 1;
    foo 2;
    foo 1;
    %( one => 1 )
}

and a module between direct original library and end-user file:

# in file middle.pm6
use root;
class A {} # Do something with stuff from root.pm6

End-user file:

# in file user.pm6
use middle;

Then in command line:

➜  tester perl6 -I. user.pm6
1
2

It seems that third call to foo was cached and wasn't executed for the third time.

Such behavior makes any relatively complex computations(that are based on code re-use) in sub EXPORT(as well as in other compile-time areas) impossible.

According to my understanding, compile-time code is meant to be executed normally with its results(e.g. some declarations, tweaks and so on) being accessible from the compiled unit by other modules. However, there is some sort of caching involved too.

The question is, ultimately, "How to achieve what I want" with possible milestones:

1)Is such sort of caching intended?

2)If yes, can it be disabled while having advantages of compile-time code execution? If no, what another workarounds are possible?

UPDATE 1: explaining thing I want more specifically: at compile-time I am parsing a config file and creating types to export. I want those to be pre-compiled, that is the point. Types can be nested and various cases are possible, so I am handing in with a transitional state machine imitation implemented as a simple subroutine with a long given-where statement, some branches are recursive(bottom is always present). The issue I stuck at is that some branches won't be executed after being fired once, which I was able to golf into simple double foo 1 call I have presented in main question.

UPDATE 2: as raiph mentioned, it works correctly when ran from a command line when level of indirectness between original lib and user-one is 0, but when structure is root lib file that creates types -> middleware lib file that patches those -> end-user(be it a test file or another module, not all code is executed.

like image 300
Takao Avatar asked Jan 06 '19 21:01

Takao


2 Answers

This appears to be a Rakudo bug or something close enough to it.

At least, as advised by Jonathan Worthington, using note instead of say makes the example code work as necessary, which clears all implications being made about possible caching being involved.

like image 93
Takao Avatar answered Nov 20 '22 18:11

Takao


Maybe you are looking at the INIT phaser:

INIT {
    # Things here may be a lot more complex
    foo 1;
    foo 2;
    foo 1;
    %( one => 1 ) 
}

Which might be a bit too verbose for you:

> use user;
1
2
1
2
1

INIT is run at runtime. If you want to assign values to variables, it will get the job done.

like image 45
jjmerelo Avatar answered Nov 20 '22 17:11

jjmerelo