Closed chshersh closed 2 years ago
You know full well that such proposal is never going to be accepted, because deprecation of $ and & would mean breaking pretty much every piece of Haskell code already written.
Yes, I'm completely aware of this. In fact, people in the community might know me as a vocal opponent of any (even tiny) breaking changes. To even consider that I'd want to break every single Haskell program, well, that's something 😅
That's why I see @int-index's suggestion to "add deprecation of $
and &
" into my proposal as a sure way to shut down this particular proposal immediately.
I generally try to avoid weighing in on bikeshedding proposals because the honest truth is that I, personally, very rarely care. In principle, the same is true of this proposal—I don’t think it will affect my own experience of writing or using Haskell to any significant degree.
But I do want to chime in simply to second some of the concerns around pedagogy made by @parsonsmatt and @endgame, as pedagogy is something I do personally care about. Haskell already has a reputation for having a wealth of infix operators that many find confusing. On the face of things, this proposal sounds like it might improve that situation slightly, but without any plan to actually replace $
and &
, it really does mostly make the situation (slightly) worse:
Imagine you are a new Haskell programmer, and you encounter some resources that use $
and &
and some resources that use <|
and |>
. Haskell already has a decent number of operators with fairly subtle distinctions—it can take some time for a novice to internalize the relationship between .
, $
, <$>
, >=>
, and >>=
for example—and it would be extremely logical to assume that there must be some subtle distinction between $
and <|
that they’re just not understanding. This is actively confusing!
Imagine you are an author of pedagogical resources for novice Haskellers.[^1] Do you choose to introduce $
and &
or <|
and |>
as the “preferred” operators? The latter may be more intuitive, but readers are most likely going to see the former for the foreseeable future, and I tend to be of the opinion that pedagogical resources that create expectations that are more or less immediately dashed by real code tend to be more harmful than helpful the large majority of the time.
Regardless, whichever one you pick, you do have to choose, and you probably also have to explain “there are also these other equivalent operators you see sometimes” when really you want to be focusing on the absolute basics. This is the part of the language that is most important to keep as simple and approachable as possible, and it is not a great look when the first chapter of your introduction has to talk about awkward historical caveats.
Imagine you are a senior Haskeller working on an established Haskell codebase that uses $
and &
. Do you switch to <|
and |>
everywhere, stick to $
and &
, or use a mixture of both? I think the latter is pretty unsatisfying, so you probably want to pick one and stick to it, but now this is just another arbitrary choice for people to argue over, like indentation width and line length.
Now, I want to be very clear: I basically buy the argument that <|
and |>
are the “better” choice of names for these operators purely because they have been widely adopted. I think migrating Haskell to them would make the language genuinely easier for newcomers to understand. It would, however, require rethinking more than just $
and &
: as others have alluded to, it would necessitate revisiting operators like <$>
and <&>
as well. And while I think I, personally, would be alright with that kind of sweeping overhaul, it seems to me that such a sweeping change would be a tough sell for much of the Haskell community.
I implore everyone with opinions about this change to think about this brutally pragmatically: what are we trying to accomplish here? Is this step one in a multi-year plan to rework Haskell’s operators to be more consistent with other ecosystems? Or are these operators going to remain duplicates of $
and &
forever? If people think the latter is really an improvement to Haskell’s accessibility (and I really think that’s all that’s at stake here other than mild aesthetic preferences; the choice is no significant obstacle to experienced Haskellers), I challenge you to think through the implications more fully. And if the former really is the goal, then great—I am in conditional support—but in that case, it really needs to be more explicit in the text of the proposal. Either way, I do not think it is fair to new users to make Haskell functionally more difficult to learn, with no concrete plan to fix that, simply because we as a community cannot agree between those two long-term visions and therefore have decided upon some awkward compromise that, in my opinion, serves nobody.
tl;dr: I oppose this proposal as currently written—not because I disagree with its motivation but because I don’t think it actually has any realistic hope of achieving its stated goals (and in fact makes the short-term situation worse). Give me a deprecation timeline for $
and &
and I’ll be on board.
[^1]: This one I don’t have to imagine, as I have done a decent amount of exactly this myself.
I am generally opposed to this proposal. In addition to everything others have said about name duplication, creep into <$>
, etc., I'm concerned about existing uses of <|
and |>
.
Data.Sequence
, which has been around approximately forever, uses <|
and |>
as cons and snoc operators. That notation has been taken up elsewhere, including (off the top of my head) in lens
and (less importantly) type-aligned
. Having to use those operators qualified to use the application operators the proponents of this proposal would like to be ubiquitous sounds pretty painful.
That notation has been taken up elsewhere, including (off the top of my head) in
lens
and (less importantly)type-aligned
.
And base
itself: Data.List.NonEmpty.<|
.
-1, don't want to program in F#/ML/Elm. Please don't remove $.
-1, don't want to read bottom-up code. I can tolerate a little & around lenses, but not much further.
-0, don't want more operators.
-1, sometimes I want the pointy things for myself.
while we are throwing ideas up...
Yes technically Unix streams are just character streams, so technically shell's |
is a function "application", but in practice most Unix programs buffer/delimit on newlines and treat each line as a new input (grep doesn't return the matches, it returns the line of the matches) so Unix streams are effectively streams of lists of characters, so |
from Unix is more like a reverse map
from Haskell. So |>
and <|
should be flip map
and map
. There's no reason to not take this further and make them be flip fmap
and fmap
, so |>
and <|
should be <&>
and <$>
. In this case >>>
and <<<
are then redundant as well since their only appeal over <&>
and <$>
is visual.
We often say fmap
"lifts" a function, its an upgrade. Thus |>
and <|
are upgraded versions of function application. It would be good if this was "visually apparent" too, so I propose >>
and <<
be &
and $
(see edit). This way |>
looks like a "piped" version of >>
.
These clash with Actually $>
and <$
in what visual reflection indicates. In this comment it just means flip
ing of arguments of a noncommutative operator, so f |> x
equals x <| f
. But $>
and <$
are not flip
ed versions of each other, they are different functions that share a sort of left/right duality.$>
is a flip
ed <$
. *>
and <*
, however, are not flip
s of each other, they have a left/right duality. It is a whole other discussion if we should attempt as a community to standardize visual reflection to mean only one of these. My vote is no, it would be too hard/disruptive to be worth it. (I've updated the language to be more careful. The reflection of *>
is <*
. The reversal of *>
is >*
.)
Theres a broader discussion on what to with "visually suggestive" operators and if its possible to produce a standard for what they should mean conceptually
|
typically indicates relation to Alternative
=
typically indicates relation to Monad
*
typically indicates relation to Applicative
$
typically indicates function application (so relation to r ->
) though I think its a poor choice since you can't make a visually flip
ed $
in ASCII$
roughly indicates Functor
, though its also used for function application, I think this is conflation?
ever used for Maybe
or booleans?!
in most of programming typically indicates boolean not, though in Haskell its used for strictnessI would propose >
and <
instead of >>
and <<
, but these are probably the only operators in all of programming that mean the same thing in all languages. So no.
Edit:
I just realized >>
is already taken by Monad
, but isn't it always true that *>
= >>
? So if you really wanted to redesign, one of those is up for grabs.
x <$ y
= const x <$> y
x $> y
= const y <$> x
f <*> x
= pure f <$> x
x <* y
= const <$> x <*> y
= liftA2 const
x *> y
= flip const <$> x <*> y
= `liftA2 (flip const)<&>
= flip <$>
<**>
= flip <*>
Are not <$
and $>
very obscure? 4 <$ "abc"
= [4,4,4]
, what is that used for?
but these are probably the only operators in all of programming that mean the same thing in all languages
Quite a few languages don’t use >
for greater-than, e.g. bash and brainfuck.
As others have said, |>
and <|
read like Alternative
combinators to me. And from their symbols I can assume reasonable implementations that mirror $>
etc:
(|>) :: Alternative f => f a -> b -> f b
a |> b = a <|> pure b
(<|) :: Alternative f => a -> f b -> f a
a <| b = pure a <|> b
Data.Sequence, which has been around approximately forever, uses <| and |> as cons and snoc operators.
Funnily enough (as pointed out by @tomjaguarpaw on Reddit) - the above operators are cons
and snoc
for Seq
(and all list-y Alternative
s)
And base itself: Data.List.NonEmpty.<|.
NonEmpty
can't be Alternative
, but it is Alt
. So a !>
and <!
would work nicely :wink:
To me, this adds up to these Alternative
getting first dibs on these operators in base
(we've "found" free little combinators all thanks to our operator "language"! :smile: )
@ramirez7 (->) t
doesn't have an Alternative
instance, so the mnemonic fails the most basic premise of the proposal.
@ramirez7
(->) t
doesn't have anAlternative
instance...
Oh I guess my comment wasn't clear - I wasn't suggesting that |>
had an alternative (heh) implementation for functions. Just adding another point that that operator may be better reserved for another purpose.
Haskell is a wonderful, high level, modern language. One wonderful thing in it is that is teaches us to love and use [monoidal] compositionality. We should be thinking in composable things and in their compositions. That is: in functions. We should be leaning toward point-free coding. We should not be thinking in points and how they flow through a chain of functions. In the situations when we do need function application: we should do it in one single canonical way, which is juxtaposition.
In short: instead of writing p |> x |> y |> z
we should write let f = x >>> y >>> z in f p
.
Composition oriented code is more probable to work well with future needs for changes in the code.
Hence we should not have any infix name for normal function application. Names like apply_function
and apply_argument
would have been sufficient and better.
But what about using the low precedence of the infix name for grouping?
That is a only a popular hack to reduce the number of round brackets. Infix function naming was not invented for this purpose. This is not normal usage of them.
There is nothing wrong with the good old round brackets. Everyone knows and understands them, even without Haskell knowledge. They are much more readable than infix name precedences. They not only eliminate the need to do precedence memorization and calculation in our brain unconsciously but also provide a nice, immediately obvious visual boxing.
But too many round brackets are difficult to read.
If an expression contains too many brackets then it is ripe for a restructuring with introducing let-expressions or whatever. Introduce some names.
If you do introduce |>
then please choose something different. |
to me feels like separation and function application feels to me rather like connection than separation. I would rather like something instead of |
that visualizes a point, as it is intuitive for me to think about an argument as a point in the domain of the function.
|
is impossible for operators in Haskell grammar anyways.
|
is impossible for operators in Haskell grammar anyways.
I meant that i do now like |
inside the <|
, |>
operators.
Ah, I see. Sorry.
I'd like to speak specifically to this point:
(and, in fact, it might even help! Lots of people find
$
and&
confusing for various reasons, having<|
and|>
can improve Haskell teaching and learning experience).
I very much disagree that having <|
and |>
could improve the Haskell teaching and learning experience today, even if they skipped Data.Function
and went straight to Prelude
.
Why? A couple of reasons spring to mind:
<|
in educational materials, that would cause a problem when they go off and read code written with $
. |>
in tutorials would also set up incorrect expectations about the relative frequency of "forward style" programming in Haskell. I suspect that the author(s) of this proposal are big fans of forward-style programming and want to lower the barrier to entry for writing code this way. Fair enough! But please recognise the burden that having competing styles within the language will place on new learners.$
is somehow harder to grok than <|
would be. In fact, I think that $
may be easier to leap-frog off pedagogically, since it appears much less syntactic than <|
and so doesn't carry as many connotations of being "special".In my course we only cover &
in passing, which reflects the relative infrequency of the style in the Haskell corpus. I think that forward-style programming would see more use if |>
made its way into Data.Function
. Regardless of whether such a thing would be good for Haskell, it would not prima facie be good for new learners.
Educational perspective aside (hence the separate comment):
I think that the introduction of <|
is essentially irrelevant and the real goal of this proposal is to introduce (and eventually make idiomatic) the use of |>
for data flow.
According to the Haskell2010 report, one of the Haskell goals is:
It should reduce unnecessary diversity in functional programming languages. I strongly believe that having
$
and&
while the rest of the world uses<|
and|>
is exactly that unnecessary diversity
Hopefully it's obvious, but the implication is a desire to (eventually) render $
and &
unidiomatic in Haskell and align Haskell with other functional languages in the use of <|
/|>
.
I don't think that following that path would be wise, but others can do a better job of explaining why than me 🙂
Edit: In fact, I think if we did want to promote forward style programming, the obvious step would be to move (&)
into Prelude
. That is something I could get behind much more readily, actually. But I'll leave it at that (please nobody respond to this exceptionally bikesheddy edit!)
These are quite popular languages that use or want to add
<|
and|>
(the list might not be exhaustive):* [F#](https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/symbol-and-operator-reference/#function-symbols-and-operators) * [Elm](https://elm-lang.org/docs/syntax#operators) * [Elixir](https://elixirschool.com/en/lessons/basics/pipe_operator) * [TC39: Pipe operator in JavaScript](https://tc39.es/proposal-pipeline-operator/)
The last link says "Stage 2 Draft". Could you please elaborate what does it mean in the context of JavaScript standartization process? Also I think that https://github.com/tc39/proposal-pipeline-operator#readme is a more relevant link.
The thing is that I don't find F# / Elm / Elixir prior art very convincing, these languages are at the best equal to Haskell in the community size. One can reasonably expect them to adopt $
and &
, not vice versa. However, if JavaScript is going to have |>
, this is a much stronger reason to adopt this convention in Haskell, because JavaScript community is magnitudes larger.
It seems that neither JavaScript nor Elixir have or will have <|
. Do you insist on including both operators? Including <|
into base conflicts with Data.List.NonEmpty.<|
, while |>
does not. I think the latter is less controversial and more widely used.
A library flow implements these operators in Haskell.
The proposal can benefit from demonstrating examples of adoption and community traction around flow
or testimonials of its users. Did the operators make way into any alternative prelude?
According to the Haskell2010 report, one of the Haskell goals is:
- It should reduce unnecessary diversity in functional programming languages.
To be precise, these are not Haskell goals, these are goals of the Haskell Report committee.
Stage 2 in the ECMAScript standardization process means that “The committee expects the feature to be developed and eventually included in the standard”. However, |>
in ES will be a “Hack pipe”, where the elements aren’t unary functions but expressions with a placeholder.
These are quite popular languages that use or want to add
<|
and|>
(the list might not be exhaustive):[..]
Ocaml also has |>
, but not <|
(yet).
A library flow implements these operators in Haskell.
Since we're bikeshedding I thought I'd take this chance to shamelessly plug my own library op. In my not-so-humble opinion it's way more consistent, usable, and fully-featured than flow.
@Bodigrim
The last link says "Stage 2 Draft". Could you please elaborate what does it mean in the context of JavaScript standartization process?
I believe, @schuelermine answered this question in a comment above.
Also I think that https://github.com/tc39/proposal-pipeline-operator#readme is a more relevant link.
I've updated the link in my proposal.
The thing is that I don't find F# / Elm / Elixir prior art very convincing, these languages are at the best equal to Haskell in the community size
The combined size of these language communities is much larger than the Haskell community alone 🙂
It seems that neither JavaScript nor Elixir have or will have <|. Do you insist on including both operators? Including <| into base conflicts with Data.List.NonEmpty.<|, while |> does not. I think the latter is less controversial and more widely used.
I believe that having both <|
and |>
would be better than one for symmetric reasons. I don't think conflicts with Data.List.NonEmpty.<|
is a big deal because base
already has many examples of functions sharing the same name but being implemented in different modules for different data structures. For example,
Both <|
for function and NonEmpty
are in different modules so there's no conflict of names.
The proposal can benefit from demonstrating examples of adoption and community traction around flow or testimonials of its users. Did the operators make way into any alternative prelude?
I'm not aware of any alternative prelude adopting this operator. I've checked all preludes here.
I've searched for some testimonials in favour of the flow
library on Twitter, so I've added them to my proposal. If @tfausak or anyone else can share more constructive feedback examples, I'd be happy to add them 🙂
To be precise, these are not Haskell goals, these are goals of the Haskell Report committee.
I don't understand this. I thought the report was for the Haskell programming language. The report explicitly says those are the Haskell goals:
The committee’s primary goal was to design a language that satisfied these constraints: ...
I believe that having both
<|
and|>
would be better than one for symmetric reasons. I don't think conflicts withData.List.NonEmpty.<|
is a big deal becausebase
already has many examples of functions sharing the same name but being implemented in different modules for different data structures. For example,
I don't think that's comparable. All those toList
versions roughly have the same signature (f a -> [a]
) and do the same thing (convert some container to a list), whereas Data.List.NonEmpty.<|
and the proposed <|
have wildly different types and do completely different things.
whereas Data.List.NonEmpty.<| and the proposed <| have wildly different types and do completely different things.
Maybe a little bit of creativity may help to not see these two versions as "wildly different" 😉
<|
for NonEmpty
is "pushing an element to NonEmpty"<|
for function (->)
is "pushing an argument to a function"Doesn't look too different to me anymore!
In any case, I don't like the vagueness in the "wildly different" description. There's no strict rule telling when it's okay to have things of the same name in base
and when it's not. Unless there's a formal rule, everything is subjective.
Maybe a little bit of creativity may help to not see these two versions as "wildly different"
Why can't a little bit of creativity be applied to justify $
and &
if it's on the table?
@chshersh I'm confused why you want to get this into base.
base is not even a good place for a beginner to start. It's overuse of lazy IO, String types everywhere and underdocumented unsafe functions make it a questionable choice.
I had expected that your courses start off with relude. And then you can just add these operators there and see how your next couple of courses go.
@chshersh I'm confused why you want to get this into base.
I have my reasons but they shouldn't matter because we evaluate this proposal based on objective measures and not personal motives.
base is not even a good place for a beginner to start. It's overuse of lazy IO, String types everywhere and underdocumented unsafe functions make it a questionable choice.
And yet, it's the place where all Haskell newcomers start. base
is available by default without any hassle on all systems. interactive REPLs, web playgrounds, problem-solving platforms, etc. What you've described sounded to me like even more reasons to improve base
through documentation and principled API adjustments.
I had expected that your courses start off with relude. And then you can just add these operators there and see how your next couple of courses go.
I'm not aware of any surveys regarding the usage of alternative preludes but I have the impression that base
is still used by at least 9 Haskell developers out of 10. In my course, I want to prepare people for the "default" and "common" Haskell. relude
is nice and it significantly increases my productivity! But using relude
for teaching Haskell beginners doesn't align with my teaching goals.
Adding <|
and |>
to relude
before base
would be a good step in making these operators more widespread. Unfortunately, I'm not maintaining relude
anymore so this work is out of scope for me.
I want to prepare people for the "default" and "common" Haskell.
Then the obvious choice is to stick with ($)
and, rarely, (&)
. Neither of the pipe operators are default or common. Using <|
/|>
is just as unhelpful for a newcomer as using relude
or flow
would be.
Neither of the pipe operators are default or common. Using <|/|> is just as unhelpful for a newcomer as using relude or flow would be.
Well, if <|
and |>
are in base
they become one of the defaults 😉
Neither of the pipe operators are default or common. Using <|/|> is just as unhelpful for a newcomer as using relude or flow would be.
Well, if
<|
and|>
are inbase
they become one of the defaults wink
But the vast majority of introductory literature, existing source, stackoverflow answers, everything will continue to use $
and sometimes &
. Just because something is in base
doesn't mean people will use it.
Just because something is in base doesn't mean people will use it.
Despite the common impression (and I don't know where people got it), I'm not trying to force everyone to use new operators instead of existing ones. Only time will show if these operators will be more widespread. Who knows, maybe in 10 years everyone will use these new operators, the Haskell community has enough funding to update all the documentation, update SO answers and someone can put a proposal to deprecate $
and &
eventually.
But for now, having <|
and |>
will reduce friction for a few people who find these pipe operators more convenient and natural. This will make Haskell friendlier for more people, increasing its adoption, without hurting any of the existing language users.
You do know that you can continue using $
and &
even if <|
and |>
will be added to base
? You know that, right?
In fact, I have a feeling that if <|
and |>
are just silently added to base
, people won't even notice it for years. So the cost of adding these two operators seems exaggerated to me.
But for now, having <| and |> will reduce friction for a few people who find these pipe operators more convenient and natural. This will make Haskell friendlier for more people, increasing its adoption, without hurting any of the existing language users.
I've followed this entire thread, but I've yet to find an example of someone who wants to use Haskell, but the lack of |>
and <|
puts them off. A handful of people who say "I like using them", but those people seem perfectly content to either define them themselves, or use libraries/alternative bases with them in.
In fact, I have a feeling that if <| and |> are just silently added to base, people won't even notice it for years. So the cost of adding these two operators seems exaggerated to me.
If you make a change and nobody notices for years, I don't think that was a very useful change.
If the operators are intended to go very rarely used, then it makes ~0 difference whether they are in base
or not.
If they are intended to become well-used, then we'll end up in a situation where both ($)
/(&)
and (<|)
/(|>)
are widely used, which (imo) would be a huge net negative for the ecosystem, even if the initial cost of introducing them is very small (which it probably is, I agree!)
From @lexi-lambda 's post upthread:
Imagine you are a new Haskell programmer, and you encounter some resources that use
$
and&
and some resources that use<|
and|>
[..] it would be extremely logical to assume that there must be some subtle distinction between$
and<|
that they’re just not understanding. This is actively confusing!
This is not hypothetical. In fact, the proposal specifically creates a subtle distinction between (&)
and (|>)
(a different fixity).
@chshersh could you please add OCaml to the list of languages having the pipe operators? It would also be helpful for the further discussion, if you mark which languages feature both |>
and <|
, and which offer |>
only.
@Bodigrim Added OCaml and specified which languages have which operators.
Here is my (non-binding) opinion. I'm -1 on adding (<|)
, but +1 on adding (|>)
.
Pretty much every Haskell package uses ($)
. Any Haskell learner must be taught about ($)
anyway, so introducing (<|)
for the same purpose does not really make anyone a favor.
One might argue that (<|)
operator might be known to a learner already, from another programming language. However, the prior art shows that only few languages introduce (<|)
, and probably primarily as a counterpart to the existing (|>)
, never vice versa.
Having Data.Function.(<|)
in the same package with Data.List.NonEmpty.(<|)
seems very unfortunate to me. Yes, there are name clashes in base
already, but I don't feel like increasing their number is a good strategy.
Unix pipes never flow backwards. So if you think about function application in pipe terms, (|>)
is very intuitive (as long as |
itself is already taken), but (<|)
is not.
($)
is deeply ingrained into other operators: $!
, <$>
, <$!>
, <$
, >$
, >$<
, >$$<
, $<
. There is much less operators with &
in base
, only <&>
.
While (&)
is popular in the lens
ecosystem, I personally never used it or encountered in the projects I maintain. Given overwhelming evidence for (|>)
in other programming languages from JavaScript to OCaml and that it resembles a Unix pipe, I think it would have been better to offer it instead of (&)
from base
. We cannot rewrite past decisions, but providing Data.Function.(|>)
at least as an option seems quite helpful to me.
Dear CLC members, before we proceed to a vote, may I ask for your (non-binding) opinions? @tomjaguarpaw @chessai @emilypi @mixphix @cgibbard
Dear CLC members, before we proceed to a vote, may I ask for your (non-binding) opinions?
I think i'd be fine with the addition of |>
to base
, but i'm not entirely convinced it needs to be in base
when it exists in flow
and in op
. I'm leaning towards just telling people to use those libraries. That said, if it comes down to a tiebreaker, having it in base
wouldn't irk me - I'd just never use it because the current idioms really aren't that difficult to learn.
I've reviewed this thread and have changed my position: I don't think adding (<|)
is a good idea, even to "match" with (|>)
. Its defence as a mnemonic for use in educational material holds no water when faced with the fact that the vast majority of Haskell code uses ($)
for this operator, to the point that it's a meme: code that uses it is instantly recognizable as Haskell code, even to some folks coming from other languages.
As for adding (|>)
: I personally like that (&)
is also one character's width for my own formatting idiosyncrasies, but I can't possibly use that as a defence to prevent its addition to a non-Prelude module. Are we allowed to donate our votes to a community poll?
@chessai @cgibbard @tomjaguarpaw I'd love to hear your preliminary, non-binding opinions.
@Bodigrim only adding |>
seems to not be in line with this proposal and probably should be a separate one? I believe the author made clear arguments why both variants should be included, so only adding one seems to be out of scope.
@hasufell It is desirable to explore the design space, even if it goes beyond the current form of proposal.
My preliminary opinion is that I am -1 on adding either or both of these operators, at the moment.
If $
were not already widely used and we were considering adding it then I would be in favour of adding <|
instead, and for consistency and completeness, |>
too. However, we cannot overlook path dependence when it comes to iterating on a standard library. Despite my belief that |>
and <|
are mnemonically better, and more consistent with other programming languages, $
and &
are already entrenched (the former very deeply). I don't like the inconsistency of Haskell having different operators to other languages, but I like even less the potential future inconsistency between Haskell code using $
and other Haskell using <|
.
There's one way I would support getting these operators into base, and that is as part of a wider effort to reconsider decisions taken decades ago, and come up with a coherent plan for where we want our standard library to end up and how to get it there. That will necessarily take a lot of hard work and double-digit months of consensus-building work throughout the community. In the absence of such a plan I am extremely wary of admitting incremental changes, even if they locally look like improvements. I think base is past the point where incremental improvements can lead to global benefit.
@chshersh Judging from the opinions above it seems that (<|)
is unlikely to gather required 4 votes in favor. How would you like to proceed? One opportunity is to scale the proposal down to (|>)
, however as a proposer you absolutely have a right to trigger a CLC vote as is.
I'm also -1 on either or both. We already have operators for these concepts, and these symbols are already used by other libraries for unrelated purposes, so it doesn't seem particularly convenient to put definitions in Data.Function that would trample the namespace and make people fix their imports, especially for something that is already a one-liner / conveniently expressed otherwise.
Also, you're repeating the mistake of ($) and making it right-associate, when function application should clearly associate to the left, as does whitespace. ;) I could almost have some sympathy for a left-associating but low-precedence function application symbol, as that would actually open up some new forms of expression here and there, but without a clear signal from the Haskell community (many libraries defining it for their own purposes, say), probably not really enough to say it'd be a good idea to steal <| for it.
@Bodigrim I'm okay with scaling the proposal down to (|>)
only. I've changed my proposal to recommend only |>
for addition.
Dear CLC members, let's vote on the proposal to add (|>)
only, with infixl 0 |>
, as detailed in https://github.com/haskell/core-libraries-committee/issues/78#issue-1303767312. If you vote against, please comment whether some minor amendments (e. g., change of fixity) can sway your opinion. CC @tomjaguarpaw @chessai @emilypi @mixphix @cgibbard.
+1 from me.
In the absence of such a plan I am extremely wary of admitting incremental changes, even if they locally look like improvements. I think base is past the point where incremental improvements can lead to global benefit.
-1. I agree with Tom here. I'd be eager to reconsider this proposal as part of base-5.0
or another similar major overhaul; but I'd rather avoid adding to the pile of things to sort through until we get there.
-1. The way forward for something like this is to convince many people to start using operators like this in their own projects, so that it would be a convenience rather than an inconvenience to put the definition in base. However, I expect that's an uphill battle by this point, as it'll be hard to convince people to type |> in place of $ when everyone already knows what the latter means.
+1 from me, provided @chshersh makes the MR to base
. The single (|>)
proposal is relatively harmless, and the implementation is already here. I don't see it as a huge burden.
as it'll be hard to convince people to type |> in place of $ when everyone already knows what the latter means.
@cgibbard to avoid confusion: the proposal suggests (|>)
only, which is a synonym of (&)
, not ($)
.
@chessai just a gentle reminder to vote.
Proposal
Add the
|>
pipe operator to theData.Function
module, similar to the already existing&
:Motivation
Haskell is one of the oldest Functional Programming languages that are still actively used nowadays. It inspired multiple features in many other programming languages. And I believe it's time for Haskell to take expiration from more modern FP langs.
Specifically, the pipe application operator
|>
(and sometimes<|
) is popular in other FP languages while Haskell remains almost the only language that uses$
and&
.These are quite popular languages that use or want to add
<|
or|>
(the list might not be exhaustive):|>
<|
and|>
|>
<|
and|>
|>
|>
In fact, Haskell itself has several libraries that reimplement these operators:
And some libraries reimplement
|>
in their internals:Here are some people on Twitter who like using the
flow
library or forward style of application:According to the Haskell2010 report, one of the Haskell goals is:
I strongly believe that having
$
and&
while the rest of the world uses<|
and|>
is exactly that unnecessary diversity, so adding these two operators tobase
will help to reduce this while not conflicting with other goals (and, in fact, it might even help! Lots of people find$
and&
confusing for various reasons, having<|
and|>
can improve Haskell teaching and learning experience).