Here is an example function which returns True if a point p is on an (open) line segment (A, B) assuming that Orientation[A, p, B] returns 0 if the three points are collinear:
PointIsOnSegment[p_, A_, B_] :=
If[Orientation[A, p, B] != 0 || SquaredEuclideanDistance[A, p] > SquaredEuclideanDistance[A, B] || SquaredEuclideanDistance[B, p] > SquaredEuclideanDistance[A, B], False, True];
So, if the point is on the line segment, this function evaluates SquaredEuclideanDistance[A, B] twice. So if we wanted to compute it only once, we could either use a Module or Block, like:
PointIsOnSegment[p_, A_, B_] := Block[{sqDistAB = SquaredEuclideanDistance[A, B]},
If[Orientation[A, p, B] != 0 || SquaredEuclideanDistance[A, p] > sqDistAB || SquaredEuclideanDistance[B, p] > sqDistAB, False, True]];
Or we could use an anonymous function:
PointIsOnSegment[p_, A_, B_] :=
If[Orientation[A, p, B] != 0 || SquaredEuclideanDistance[A, p] > # || SquaredEuclideanDistance[B, p] > #, False, True] &[SquaredEuclideanDistance[A, B]];
What I want to know is which method should be preferred in terms of efficiency? Keep in mind that this is a very simple example, but I have in mind slightly more complex functions where several intermediate values (like distSqAB above) need to be computed once and then used in the final return value.
Part of this stems from my coming from an imperative background and trying to learn to program mathematica in a functional style (so I am tending more towards the third option above), but I wanted to know if I'm create unnecessary work for myself (since excessive use of anonymous functions quickly becomes unreadable).
Withis more idiomatic thanBlock. However, I don't think you'd see a performance difference here (or in general) that should require your attention... more often than not, the bottleneck in your code will be elsewhere. – rm -rf May 24 '13 at 14:05With, notBlockorModule.Block/Modulecreate mutable local variables,With/Functiononly allow using constants.Functionis also a closer analog ofWithbecause both can inject expressions into a held expression. Personally I findWithmore readable thanFunctionbut I know that some people would useFunction... Regarding performance, why don't you just measure? My hunch is thatWithwill be marginally faster thanModule/Blockbecause it spares some evaluation steps, but I might be wrong. – Szabolcs May 24 '13 at 14:31