I think backticks syntax makes sense for the Haskell since it has function 
application via space, but for Elixir it hurts readability with no (visible 
to me) benefits.
Calling non-guard-safe function as the guard-safe operators doesn't feel 
like a good thing: we remove valuable hint about function property in our 
code.

– Aleksei

On Thursday, August 11, 2016 at 8:51:47 AM UTC+2, Wiebe-Marten Wijnja wrote:
>
> Thank you for your replies!
>
> Indeed, the word 'guard' is missing from that sentence: The fact that 
> Erlang only allows certain BIFs inside guard clauses, and therefore Elixir 
> discouraging the overriding of operators that will not work in them. 
>
> This suggestion is not at all meant as a replacement for the pipeline 
> operator |>.
> The pipeline operator is built to accomodate the need to pass a single, 
> most important, subject through a sequence of functions.
> These functions that work on a single, most important subject, can be 
> described as 'Take the left-hand side, and perform the action outlined by 
> the rest of the parameters'.
>
>
> However, the functions in the cases outlined above (arithmetic, 
> comparisons, access, combinatorial, and there are probably more), it feels 
> very weird, very unnatural to use the pipeline operator. 
> These functions do not work on a single most important subject. Both the 
> left-hand side and the right-hand side are equally important.
> These can be described as 'Take the left-hand side and the right-hand 
> side, and perform the action ontlined by the name of the operation.'
>
> Using these binary (arity-2) functions with the pipeline operator feels 
> strange and distracts from what is going on: 
> a |> div(b)
> x |> lt?(y)
> {1,2,3,4} |> elem(2)
> %{foo: 1} |> Map.merge(%{bar: 2}) |> Map.merge(%{baz:3})
>
> The pipeline operator also stops to be useful in the case that we want to 
> expand on the second argument of something:
>
> Observe that
> Decimal.add(decimal_a, Decimal.div(decimal_b, Decimal.new(2)))
> which the new syntax would let you write as
> decimal_a `Decimal.add` (decimal_b `Decimal.div` Decimal.new(2))
> was rewritten by Allen Madsen with the pipeline operator to
> decimal_b |> Decimal.div(Decimal.new(2)) |> Decimal.add(decimal_a) 
> which swaps the order of parameters passed into `Decimal.add`. For 
> addition this is not a problem, but take a non-reflexive operation like 
> subtraction:
>
> Decimal.sub(decimal_a,Decimal.div(decimal_b, Decimal.new(2)))
> When using the pipeline operator, this would mean creating a call 
> structure in this way:
> Decimal.sub(decimal_a, decimal_b |> Decimal.div(Decimal.new(2)))
> which would definitely be less readable than:
> decimal_a `Decimal.sub` (decimal_b `Decimal.div` Decimal.new(2))
>
>
> What I am trying to get at, is that the new syntax lets you write binary 
> functions in the same location as the guard-safe operators, which will make 
> user-defined structs feel more integrated with the language.
> If you can do 
> a > b
> when a and b are built-in types, but are forced to use 
> lg?(a, b)
>  or 
> a |> lg?(b)
>  when having custom data types, I am not very happy.
> But if I can use 
> a `lg?` b
> , I am. The semantics of the comparison are kept intact.
>
>
> ~Wiebe-Marten/Qqwy
>
>
>
>
> On Thursday, August 11, 2016 at 2:12:07 AM UTC+2, Ben Wilson wrote:
>>
>> I agree, this suggestion reads like the |> does not exist.
>>
>> I'm also not clear on what is meant by "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." What is a clause?
>>
>> On Wednesday, August 10, 2016 at 7:48:39 PM UTC-4, Allen Madsen wrote:
>>>
>>> In my opinion, the pipeline operator already solves this problem. I 
>>> would rewrite some of your examples as follows: 
>>>
>>> decimal_b |> Decimal.div(Decimal.new(2)) |> Decimal.add(decimal_a) 
>>> Timex.today |> Timex.shift(days: 1) |> Timex.before?(Timex.today) 
>>> a |> div(b) 
>>> Allen Madsen 
>>> http://www.allenmadsen.com 
>>>
>>>
>>> On Wed, Aug 10, 2016 at 6:17 PM, Wiebe-Marten Wijnja 
>>> <[email protected]> wrote: 
>>> > 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': "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. 
>>>
>>

-- 
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/e84c7377-4bef-458d-9a39-0ef2580533ef%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to