This one is weird, and by my understanding of things, it is a bug. Label
and Goto
are on the list of compilable functions, and in fact, if you make your function completely compilable (i.e. compilable to code that does not call MainEvaluate
), there is no problem. For example, this works without a hitch:
toy = Compile[{{x, _Real}},
c = 0;
Label[t];
c++;
If[x*RandomReal[{-1., 1.}] < -0., Goto[t]];
c]
In your original function, however, the print statements prevented the Goto
to be compiled, and it stayed inside a call to MainEvaluate
. CompilePrint
says your function is compiled into:
2 V17 = MainEvaluate[ Function[{x}, y = RandomReal[{-1., 1.}]][ R0]]
3 R3 = MainEvaluate[ Function[{x}, y][ R0]]
4 R4 = R0 * R3
5 B0 = R4 < R5 (tol R6)
6 R4 = MainEvaluate[ Function[{x}, If[x y < 0., Print[y x]; Goto[t], Print[y x, , done]]][ R0]]
You see the Goto
is still there, inside the MainEvaluate
call, but the Label
has been compiled away: thus, the warning that the label cannot be found.
If you remove the print statement near the Goto
, the If
is compiled and MainEvaluate
is called only on its second branch:
toy3 = Compile[{{x, _Real}},
Label["t"];
y = RandomReal[{-1., 1.}];
If[x*y < -0., Goto["t"], Print[y*x, " ", "done"]]];
gives
2 V17 = MainEvaluate[ Function[{x}, y = RandomReal[{-1., 1.}]][ R0]]
3 R3 = MainEvaluate[ Function[{x}, y][ R0]]
4 R4 = R0 * R3
5 B0 = R4 < R5 (tol R6)
6 if[ !B0] goto 9
7 goto 2
8 goto 10
9 V17 = MainEvaluate[ Function[{x}, Print[y x, , done]][ R0]]
which works fine too, because now both the Label
and the Goto
have been compiled.
The reason I call it a bug is that I don't see this limitation specified anywhere in the documentation. I suggest reporting it to Wolfram support.