datum icon indicating copy to clipboard operation
datum copied to clipboard

Support Infix functions and user defined operators

Open fogfish opened this issue 7 years ago • 2 comments

In Erlang, we apply functions using prefix notation - name is followed by its arguments in brackets plus(1, 2). Humans are more used to infix operators than prefix or postfix. If a function takes two arguments, we have the option of using it in infix form, where we place it between its first and second arguments 1 /plus/ 2.

Operators

The parse_transform feature implements a syntax sugar for infix, which is compiled into valid Erlang code using corresponding function at compile-time. To apply a function using infix notation, we enclose its name in slash characters (/). This allows us to use any arity 2 functions as infix operators.

-compile({parse_transform, infix}).

1 /plus/ 1.

F /lists:map/ [1, 2, 3].

Infix notation does not change a function's behavior, it is purely a syntactic convenience that help readability in a specific situation.

Example of math operator for tuples

example() ->
   {1,2,3} /add/ {4,5,6}, %% {5,7,9}
   1 /add/ {4,5,6},       %% {5,6,7}
   {1,2,3} /add/ 1.       %% {2,3,4}

add(X, Y)
 when is_tuple(X), is_tuple(Y) -> 
   list_to_tuple([
      A + B || {A, B} <- lists:zip(tuple_to_list(X), tuple_to_list(Y))
   ]);

add(X, Y)
 when is_integer(X), is_tuple(Y) ->
   list_to_tuple([
      A + X || A <- tuple_to_list(Y)
   ]);

add(X, Y)
 when is_tuple(X), is_integer(Y) ->
   list_to_tuple([
      A + Y || A <- tuple_to_list(X)
   ]).

User defined operators do not/cloud not/will not introduce any kind of polymorphism or overloading that Erlang does not already implement.

Partial application

The infix notation supports a partial application, just replace left/right operand with unbound variable _

%% partial application
_ /plus/ 1
1 /plus/ _

%% transformed to
fun(X) -> plus(X, 1) end.
fun(X) -> plus(1, X) end.

%% e.g. infix notation to increment elements in array
1 /erlang:'+'/ _ /lists:map/ [1,2,3,4].

fogfish avatar Jan 07 '19 15:01 fogfish

Coverage Status

Coverage decreased (-7.3%) to 39.222% when pulling 5009ad0b69c1d47982a06a972719d3f0e452257d on infix into f78c8f71ed88ad8ab327eadd7efbd5cc5061757a on master.

coveralls avatar Jan 07 '19 15:01 coveralls

Coverage Status

Coverage decreased (-7.4%) to 39.627% when pulling 844415612e4e8753239b5084b9660fad072e203d on infix into 19891d6515fa9720e151b51aeda93107ab046a59 on master.

coveralls avatar Jan 07 '19 15:01 coveralls