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 = False
leaks 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 noxyz
defined.- 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`xyz
has been defined.Evaluate the code at the beginning of Addendum 1, giving the wrong result
{True, False, False}
, and you find thatGlobal`xyz
as well asGlobal`xyz$
are defined, whereGlobal`xyz$
has the attributeTemporary
.
Comments
Post a Comment