Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Infix functions and user defined operators #64

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open

Conversation

fogfish
Copy link
Owner

@fogfish fogfish commented Jan 7, 2019

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].

@coveralls
Copy link

Coverage Status

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

@coveralls
Copy link

coveralls commented Jan 7, 2019

Coverage Status

Coverage decreased (-7.4%) to 39.627% when pulling 8444156 on infix into 19891d6 on master.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants