I agree that the pipe operator solves this already. I think what was meant by "difference between how code is executed inside clauses and outside" is the fact that guards have different rules than function bodies (i.e. you can only use a subset of "blessed" functions in guards). At least that's my understanding.
Paul On Wed, Aug 10, 2016 at 8:12 PM, Ben Wilson <[email protected]> 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/0d6666ed-106f-410a-9f1d- > d12dd76df102%40googlegroups.com > <https://groups.google.com/d/msgid/elixir-lang-core/0d6666ed-106f-410a-9f1d-d12dd76df102%40googlegroups.com?utm_medium=email&utm_source=footer> > . > > 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/CAK%3D%2B-Tttzgx07LbRXoNjpCWMYQhW3cOF-5Qp9QqvsYFwo-8eqA%40mail.gmail.com. For more options, visit https://groups.google.com/d/optout.
