# [erlang-questions] Trying to learn the Erlang Way

kraythe . kraythe@REDACTED
Fri Feb 7 18:26:57 CET 2014

```Good question Anthony! The reason is that this math in my simulation will
be run thousands of times per second on the cluster and it is very possible
that the culling of the vectors will need to be factored out into a port or
NIF for speed reasons. So I would prefer, if possible, to implement the
culling in one spot that could be, later, refactored.

Also it makes a good academic discussion for me to discover the erlang
mindset. :)

*Robert Simmons Jr. MSc.*
*Author of: Hardcore Java (2003) and Maintainable Java (2012)*

On Fri, Feb 7, 2014 at 10:59 AM, Anthony Ramine <n.oxyde@REDACTED> wrote:

> Hello,
>
> Good luck with your learning.
>
> Replied inline.
>
> Regards,
>
> --
> Anthony Ramine
>
> Le 7 févr. 2014 à 17:45, kraythe . <kraythe@REDACTED> a écrit :
>
> > So now the fixed code is:
> >
> > %% Subtract the second vector from the first
> > subtract({X1, Y1, Z1}, {X2, Y2, Z2}) -> {(X1 - X2), (Y1 - Y2), (Z1 -
> Z2)}.
>
> The parentheses are not required here but you seem to like to use them
> with arithmetic, won't argue against that.
>
> > %% Compute the magnitude of the vector
> > magnitude({X, Y, Z}) -> math:sqrt((X * X) + (Y * Y) + (Z * Z)).
> >
> > %% Compute whether the vector with components X, Y and Z has greater
> magnitude then the passed scalar M.
> > %% Note that this method avoids the expensive sqrt operation.
> > is_magnitude_greater(M, {X, Y, Z}) when is_number(M), is_number(X),
> is_number(Y), is_number(Z) ->
> >   Msq = M * M,
> >   Magsq = (X * X) + (Y * Y) + (Z * Z),
> >   Msq > Magsq.
>
> All the guards here are useless as M * M will crash with badarith if M
> isn't a number.
>
> > %% Determines if any coordinate in the given vector is bigger than the
> passed in value M
> > has_coordinate_greater_than(V, {X, Y, Z}) when X > V; Y > V; Z > V ->
> true;
> > has_coordinate_greater_than(V, Coordinate) when is_number(V),
> is_tuple(Coordinate) -> false.
>
> You can make that function in one clause:
>
> has_coordinate_greater_than(V, {X, Y, Z}) ->
>     X > V orelse Y > V orelse Z > V.
>
> As an aside, your second clause would traditionally be written as:
>
> has_coordinate_greater_than(_, {_, _, _}) -> false
>
> or, to document better the code sometimes:
>
> has_coordinate_greater_than(_V, {_X, _Y, _Z}) -> false
>
> > %% Culls the list of vectors X to only those that are in the sphere
> devined by vector C as a center and R as a radius.
> > cull(C, R, Vectors) when is_number(R), is_tuple(C), is_list(Vectors) ->
> cull(C, R, Vectors, []).
> > cull(C, R, [], Culled) -> Culled;
> > cull(C, R, [Head|Tail], Culled) ->
> >   D = subtract(C, Head),
> >   case has_coordinate_greater_than(R, Head) of
> >     true -> cull(C, R, Tail, Culled);
> >     false -> cull(C, R, D, Head, Tail, Culled)
> >   end.
> > cull(C, R, D, Head, Tail, Culled) when is_tuple(D), is_number(R) ->
> >   case is_magnitude_greater(R, D) of
> >      true -> cull(C, R, Tail, [Head | Culled]);
> >      false -> cull(C, R, Tail, Culled)
> >   end.
>
> Newlines are usually inserted between different functions.
>
> In cull/6, I would pass Head last, generally new arguments are always
> inserted last in recursive functions to make the code more efficient and
> avoid moving around register values in the VM.
>
> > Now the question is the resolution of the followup question of how to
> integrate this in a solution. Do we return a list of trues and falses and
> zip that with the objects to form a candidate list? How would you do it?
>
> Given that your function returns a boolean per value in the given list,
> why does it work on a list to begin with? Why doesn't it take just one
> vector?
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140207/de610ee9/attachment.htm>
```