[erlang-questions] A matter of style?

Richard O'Keefe ok@REDACTED
Mon Aug 16 01:46:46 CEST 2010


On Aug 14, 2010, at 3:11 AM, Iñaki Garay wrote:

> Hello everyone,
> while coding a spatial indexing tree, I often use a small helper
> function within/9, which given three sets of xyz coordinates
> describing three points, returns true when first point lies within the
> bounding box created by the other two points.
> 
> This is nothing more than:
> 
> within(X, Y, Z, Xmin, Ymin, Zmin, Xmax, Ymax, Zmax) ->
>    (Xmin =< X) and
>    (X =< Xmax) and
>    (Ymin =< Y) and
>    (Y =< Ymax) and
>    (Zmin =< Z) and
>    (Z =< Zmax).

(1) It is a shame the way Erlang gets the relative precedence
    of '=<' and 'and' wrong.  
(2) This evaluates *every* test, which may not be what you want.
> 
> I ask of you this, what difference, if any, is there between using an
> if clause and this function, and inserting the body of this function
> as a guard?

(3) There is the obvious difference that the guard really ought to
    be
	Xmin =< X, X =< Xmax,
	Ymin =< Y, Y =< Ymax,
	Zmin =< Z, Z =< Zmax
    with commas instead of ands.

> There is the obvious code reuse when using the function, instead of
> copy-pasting the body. But it makes me do this:
> 
>    Within = within(X, Y, Z, Xmin, Ymin, Zmin, Xmax, Ymax, Zmax),
>    if
>        Within ->
>            do_something()
>        true ->
>            {error,out_of_bounds}
>    end.
> 
> which I dislike for personal reasons.

No, it doesn't make you do that.  What it DOES make you do is

	case within(X, Y, Z, XMin, Ymin, Zmin, Xmax, Ymax, Zmax)
	  of true -> do_something()
	   ; _    -> {error, out_of_bounds}
	end

By the way, a function with 9 arguments, all of them of the same
type, in which the argument order is surprising (I would have
expected X, Xmin, Xmax, Y, Ymin, Ymax, Z, Zmin, Zmax) is just
begging for trouble that even type checking cannot help you with.

> Is using a guard more efficient than calling a function?

No single answer is possible.  It depends on which guard and what
function and what the data are like, _and_ the maturity of the
compiler, the total amount of code you need to keep in your L1/I
cache, and probably the phase of the moon.

> Is the impact negligible even when done many times?

No single answer is possible.  In specific cases, measure it.
This is a micro-optimisation question and system level issues
are likely to be more important.

> Do you see a better way?

Abstract patterns answer this particular problem perfectly.
(Why do I always seem to end up saying that?)

As for what you can do now, if you find yourself having to do
something awkward often, *redesign*.  Why do you have to test
containment in a box so often that it _matters_ how you do it?
Can't you restructure the program so that most of the time you
_know_?  If you are doing some sort of spatial subdivision,
most of the time you _do_ know 3 of the 6 sides and should not
be retesting them.  So what are you actually doing?

It was proposed many years ago to extend Erlang with a 'cond'
construct that would eliminate all the complaints about 'if'.
I'm actually glad that hasn't happened, because it seems as
if every time this kinds up there _is_ a better way,
once we know enough about the real problem.



More information about the erlang-questions mailing list