Thank you for your reply, Ben :-)

It is true that when compiled, `a foo b` and ` a |> foo(b)`, both become 
`foo(a, b)`. The argument that you gave against adding `` could just as 
well be applied against the pipeline operator itself:

> "At the end of the day, |> is exactly identical to normal function 
> application, it just looks a bit different. I don't see the value in extra 
> syntax to do something we can already do."

Aesthetics *do* matter. And in contrast to |>, `` will not raise a warning 
when the right hand side is not enclosed in brackets.

___

With my statement about 'writing binary functions in the same location as 
the guard-safe operators' I meant that you could use infix notation on 
them, rather than prefix. I totally agree that my statement was confusing, 
sorry. 

Maybe this fake infomercial, geared towards new Elixir users explains it 
better:

Hey, new Elixir user! Want your homebuilt data structure behave just like 
> the built-in Elixir types? Do not fret!
> While it is true that you cannot define new operators, and should not 
> redefine operators like >, + and * because they would stop working in guard 
> clauses, you can do the next best thing:
> create implementations for functions like *gt?*, *plus* and *pow* 
> instead, and use them just like you would normally use the operators:

import YourModule 
a `gt?` b
a `plus` b
if (ten `pow` (five `plus` three)) `div` two `gt?` fourty_two, do: "So 
long, and thanks for all the fish!"

>
> Look at this stuff!

Isn't it neat?

Wouldn't you think your struct now feels complete?


Thank you for your replies, everyone!

~Wiebe-Marten

On Thursday, August 11, 2016 at 4:43:17 PM UTC+2, Ben Wilson wrote:
>
> I'm confused what you mean by "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." Your proposal still won't let `lt` be used 
> in guard clauses, so I don't see how the guard clause discussion is 
> relevant here.
>
> At the end of the day the `` is exactly identical to |>, it just looks a 
> bit different. I don't see the value in extra syntax to do something we can 
> already do. That isn't to say that aesthetics never matters, but the 
> difference here is merely that it doesn't emphasize the left hand side, 
> whereas the |> operator does a little bit. That seems like entirely too 
> little of a distinction to warrant extra syntax.
>
> On Thursday, August 11, 2016 at 4:23:16 AM UTC-4, Aleksei Magusev wrote:
>>
>> 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/835fbb57-c657-4329-a971-81f91342b44f%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to