I think I found a bug, but I still have MMA version 11.0.1 installed. Can somebody please check if this persists in the latest version?
When I compile this function:
cf = Compile[{{n, _Integer}},
Module[{good},
good = True;
If[DuplicateFreeQ[{}] && n == 15, good = False];
good
]
];
The result changes once the condition is met:
cf[14]
cf[15]
cf[14]
(* True *)
(* False *)
(* False *)
Here it is immaterial what list is given to DuplicateFreeQ.
Addendum 1
As @Jason B. and @Michael E2 pointed out, the important thing is that DuplicateFreeQ cannot be compiled. Thus, a more general example is
fun := True; (* use := so fun cannot be compiled *)
With[{cf = Compile[{{n, _Integer}},
Module[{xyz},
xyz = True;
If[fun && n == 15, xyz = False];
xyz
]
]},
{cf[14], cf[15], cf[14]}
]
(* {True, False, False} *)
Now, @Michael E2 wrote that it seems as if
there is a runtime environment in the WVM connected to cf, in which the assignment
good = Falseleaks out in some form and is stored across calls to cf.
Here is some evidence for that, I think:
- Quit the kernel.
?Global`xyz*gives a warning that there is noxyzdefined.- Evaluate
With[{cf = Compile[{{n, _Integer}}, Module[{xyz}, xyz = True; If[n == 15, xyz = False]; xyz]]}, {cf[14], cf[15], cf[14]}] (* {True, False, True} *)
as it should be.
?Global`xyz*shows that aGlobal`xyzhas been defined.Evaluate the code at the beginning of Addendum 1, giving the wrong result
{True, False, False}, and you find thatGlobal`xyzas well asGlobal`xyz$are defined, whereGlobal`xyz$has the attributeTemporary.
Comments
Post a Comment