Kind of a weird use of “emergent” isn’t it? Scoping imports is a design choice that lets you do these exact things.
For a historical perspective, at the very least, the MLs have had powerful module systems for decades. If the author thinks Elixir’s module system is powerful then they might really like Ocaml’s or SML’s.
In trying to understand some of the code here, the semantics of |> strike me as really odd.
String.graphemes "Hello" |> Enum.reverse
Translates to:
String.graphemes("Hello" |> Enum.reverse)
I would totally expect that to be:
(String.graphemes "Hello") |> Enum.reverse
And to get what Elixir actually does, I would expect to have to do:
"Hello" |> Enum.reverse |> String.graphemes
Which would be equivalent to:
Enum.reverse "Hello" |> String.graphemes
The existing semantics kind of strike me as really confusing and not really making much sense in terms of what a pipe does.
Anyone know what the reasoning is behind this? THe |> operator has existed in multiple languages prior to Elixir with the semantics that make sense to me (F# and Ocaml).
I don’t know the reasoning behind the decisions but:
String.graphemes "Hello" |> Enum.reverse
This tries to run and fails, because it’s doing what you said it would - trying to reverse “Hello”, but a string/binary doesn’t support the Enumerable protocol (use String.reverse/1 instead).
To get the desired functionality, you need to use the call parentheses which are advised and not really optional inside a pipeline due to reasons I’m also unaware of.
FYI, I’m just reading the pre-release notes for v1.2 and it brings with it a compiler warning over the failure to use parentheses during a pipeline. So it’s gone from not enforced, to semi-enforced.
Kind of a weird use of “emergent” isn’t it? Scoping imports is a design choice that lets you do these exact things.
For a historical perspective, at the very least, the MLs have had powerful module systems for decades. If the author thinks Elixir’s module system is powerful then they might really like Ocaml’s or SML’s.
In trying to understand some of the code here, the semantics of
|>strike me as really odd.Translates to:
I would totally expect that to be:
And to get what Elixir actually does, I would expect to have to do:
Which would be equivalent to:
The existing semantics kind of strike me as really confusing and not really making much sense in terms of what a pipe does.
Anyone know what the reasoning is behind this? THe
|>operator has existed in multiple languages prior to Elixir with the semantics that make sense to me (F# and Ocaml).I don’t know the reasoning behind the decisions but:
This tries to run and fails, because it’s doing what you said it would - trying to reverse “Hello”, but a string/binary doesn’t support the Enumerable protocol (use String.reverse/1 instead).
To get the desired functionality, you need to use the call parentheses which are advised and not really optional inside a pipeline due to reasons I’m also unaware of.
Ah sorry, the
Enum.reversefailing is just an accident of me not knowing Elixir (I thought I copied it correctly from an example).But, ugh, I hate optional parens in these cases. Oh well.
Another, probably more canonical, way to do it would be:
Yeah, I would agree. They’re a double edged sword, I’m happy that at least I can enforce them in my own code.
Elixir definitely sides more on explicit is better than implicit though, this is an odd case which goes against that imo.
FYI, I’m just reading the pre-release notes for v1.2 and it brings with it a compiler warning over the failure to use parentheses during a pipeline. So it’s gone from not enforced, to semi-enforced.
OCaml has a nice thing