One of the more longstanding problems in Elixir is the fact that there is a 
difference between how code is executed inside clauses and outside.

The choice was made to only define infix operators for the kinds of 
operations that are guard-safe, so it is not confusing as to when you are 
and when you are not allowed to use these infix operators.

There is another problem that operators have: They are very cryptic. The 
only way to know what an operator does, is if you've read its definition, 
and still remember it. (Could you guess what `<|>`, `|^|` and `~?=` do in 
Haskell?)

Names of functions, on the other hand, are self-describing (as long as they 
are named well, of course), so you instantly see what a piece of code does.


However, there are many operations that take two equally-important 
arguments, which are much more natural to write in an infix-style than in a 
prefix-style, as this is also the direction in which we 'think' them in.

Some common examples include:
- Arithmetic operations like `+`, `-`, `*`, `/`, `div`, `mod`, `pow`.
- Comparison operations like `>`, `<=`, `!=`, `match?`, `MapSet.subset?`, 
`lt?`, `gte?`, `neq?`.
- Access-based operations like the Access Protocol's `arr[x]`, `elem`, 
`put_in`, `List.delete`.
- Operations that combine two structures, like `|`, `Map.merge`, 
`MapSet.intersection`.


Because it is discouraged to override the infix operators for operations 
that are not (and often cannot be) guard-safe, it feels a little 'clunky' 
to use custom data structures, as we're forced to do things like:
Decimal.add(decimal_a, Decimal.div(decimal_b, Decimal.new(2))

Timex.before?(Timex.shift(Timex.today, days: 1), Timex.today)



As Guy Steele said in his marvelous talk 'Growing a Language 
<https://www.youtube.com/watch?v=_ahvzDzKdB0>': "When faced with this, 
programmers that are used to performing addition using a plus sign, 
quetch". (It is one of the most amazing talks I've ever seen, by the way. I 
totally recommend tha you watch it right now.)

If there were a way to use an infix notation for non-operators, users could 
instead improve on the language in a "smooth and clean" way.


Taking inspiration from Haskell's syntax, I realized that there is a way to 
circumvent this problem:

*My proposal: Introduce backtick-syntax to use arity-2 functions inline.*

- Functions (and macros) with arity 2, can be written as
a `div` b
This is rewritten during compilation into
div(a, b)


Some more examples:
users[1][:name] `put_in` "José"
{x, _} `match?` foo
{1, 2, 3} `elem` 2


- Both local and remote functions can be called this way. The following is 
thus also valid:
%{a: 1, b: 2} `Map.merge` %{c: 3, d: 4}
["foo", "bar", "baz"] `List.delete` "bar"


- This rewriting happens from left-to-right,(left-associative) so:
import Map
a `merge` b `merge` c
is rewritten into:
merge(merge(a, b), c)


As far as I know, this is completely backwards-compatible: Backticks are 
not allowed inside Elixir syntax right now.
The only place where they are 'used' is inside documentation strings, to 
delimit in-line markdown code snippets. 
This is not a problem, however; To create an in-line code snippet that 
allows backticks to be used internally, one can simply delimit it with two 
backticks. This is already used inside the documentation of Elixir itself, 
such as on the page about writing documentation. 

-------


Adding infix backtick-syntax is better than the current situation, because:
- It allows a more natural syntax for binary operations, making the 
language more readable.
- It makes custom data structures feel more integrated into the language.

This solution is better than 'just adding more possible operators' because:
- It keeps it very clear what is allowed inside guard-clauses and what 
isn't.
- It is explicit what an operation does, as names are self-describing while 
operator symbols are not.


--------


Please, tell me what you think. :-)


~Wiebe-Marten/Qqwy

-- 
You received this message because you are subscribed to the Google Groups 
"elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/2d7507ef-9ea3-4d0e-809b-8c1c674eb951%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to