# [erlang-questions] "Symmetrical" function

Tue Feb 17 09:01:58 CET 2009

```Richard O'Keefe writes:
> > 	oi([X|Xs], [Y|Ys]) ->
> > 	    if X < Y -> oi(Xs, [Y|Ys])
> > 	     ; X > Y -> oi([X|Xs], Ys)
> > 	     ; true  -> oi(Xs, Ys)
> > 	    end;
> > 	oi(_, _) ->
> > 	    [].
> >
> > Here #A is infinite, the number of clauses is 2, and I don't see
> > any good way to write half of f.

Joking aside, your example got me thinking -- and there is another way
to look at the function I think you meant:

oi([],     [])                 -> [];
oi([],     [_|_])              -> [];
oi([_|_],  [])                 -> [];			% *
oi([X|Xs], [Y|Ys]) when X < Y  -> oi(Xs, [Y|Ys]);
oi([X|Xs], [Y|Ys]) when X == Y -> [X | oi(Xs, Ys)];
oi([X|Xs], [Y|Ys]) when X > Y  -> oi([X|Xs], Ys).	% *

(I think this is the simplest way to write the function without relying
on the evaluation order of clauses.)

Seen this way, you have already managed to write fewer than half of the
mutually exclusive clauses.

Also, note that either the "parse transform" or "exception" methods
would allow half of the off-diagonal clauses to be omitted (*), if only
Erlang had a syntax for guards that could live inside the parameter list:

oi([X (when X < Y) | Xs], [Y|Ys])-> oi(Xs, [Y|Ys]);

Mike

P.S. Wouldn't it be nice if regular matches had the same syntax, e.g.,
X (when X < 3) = f(X)
I think "(when" is never currently legal, so it's even unambiguous.

```