If you evaluate the following code twice, results will be different. Can anyone explain what's going on?
findHull[points_] := Module[{},
Needs["ComputationalGeometry`"];
ConvexHull[points]
];
findHull[RandomReal[1, {10, 2}]];
Remove["Global`ConvexHull"];
findHull[RandomReal[1, {10, 2}]]
Not a direct answer to the question, but a bit too large for a comment. As another alternative, a general way to delay the symbol parsing until run-time is to use
Symbol["your-symbol-name"]
. In your case, you can replaceConvexHull
on the r.h.s. of your definition bySymbol["ConvexHull"]
:This solution is not very elegant though, since
Symbol["ConvexHull"]
will be executed every time afresh. This can also be somewhat error-prone, if you do non-trivial manipulations with$ContextPath
. Here is a modified version, combined with a generally useful trick with self-redefinition, that I use in similar cases:For example,
What happens is that the first time the function is called, the original definition with
Module
gets replaced by the inner one, and that happens already after the needed package is loaded and its context placed on the$ContextPath
. Here we exploit the fact that Mathematica replaces an old definition with a new one if it can determine that the patterns are the same - as it can in such cases.Other instances when self-redefinition trick is useful are cases when, for example, a function call results in some expensive computation, which we want to cache, but we are not sure whether or not the function will be called at all. Then, such construct allows to cache the computed (say, symbolically) result automatically upon the first call to the function.
The problem is that even though the module is not evaluated untill you call
findHull
, the symbols are resolved when you definefindHull
(i.e.: The new downvalue forfindHull
is stored in terms of symbols, not text). This means that during the first round,ConvexHull
resolves toGlobal`ConvexHull
because theNeeds
is not evaluated. During the second round,ComputationalGeometry
is on$ContextPath
and soConvexHull
resolves as you intended.If you really cannot bear to load
ComputationalGeometry
beforehand, just refer toConvexHull
by its full name:ComputationalGeometry`ConvexHull
. See also this related answer.HTH