-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Restrict the type of Data.List.NonEmpty.unzip
#86
Comments
I would want to change the implementation as well, so as not to be gratuitously lazy (and memory leaky). unzip ((a, b) :| abs) = (a :| as, b :| bs)
where
(as, bs) = Data.List.unzip abs |
Many of the other functions in that module are defined using lazy pattern matching |
Many things in that module may be lazier than they should be. I haven't looked at it recently. The current |
> Data.List.NonEmpty.map id undefined `seq` ()
() |
I'm hesitant to remove this function completely, though. It's already here and useful. I wonder if it would be better to export this function from |
I opened #88 today (completely independently of this - weird timing!). That proposal discusses having |
Haha, well in any case, they seem to be in tandem with each other :) |
I don't understand why this is a bad thing. With the exception of functions whose sole purpose is to restrict types ( |
As @treeowl mentioned, strictness is one factor. Another is performance, though here it may not apply: for specific types one might be able to write it more efficiently than the general abstraction could perform, since the latter mustn't assume anything about the representation. |
Since I was being a bit vague above.... For traverseBia :: Biapplicative f => (a -> f b c) -> [a] -> f [b] [c]
traverseBia _ [] = bipure [] []
traverseBia f (x : xs) = biliftA2 (:) (:) (f x) (traverseBia f xs) In particular, traverseBia :: (a -> (b, c)) -> [a] -> ([b], [c]) The bipure = (,)
biliftA2 f g ~(a, b) ~(c, d) = (f a c, g b d) Inlining, traverseBia :: (a -> (b, c)) -> [a] -> ([b], [c])
traverseBia _ [] = ([], [])
traverseBia f (x : xs) = (fx1 : r1, fx2 : r2)
where
(fx1, fx2) = f x
(r1, r2) = traverseBia f xs Walking one of the result lists will cause the other one to be realized, with selector thunks for elements (assuming the optimizer doesn't do anything horrible). Memory leak averted, despite remaining very lazy. It'll still be quite a bit lazier than the hand-written |
To sum up my position, I think |
FWIW, I would be fine to have all three. Also,
More specific types can lead to more specific type errors. |
While I see the merits of each of these versions of |
I described the conditions under which I'm prepared to vote in favour of this breaking change on a related discussion |
Since this is a breaking change, an impact assessment is due. It's quite possible that someone exported |
Here is a real world example in non-public code: #88 (comment) |
@mixphix are you still interested in this? Could we make some progress towards impact assessment? |
I'd like to take this proposal over, if you're stuck/need help @mixphix. Is the next step still the impact assessment? |
Yes, impact assessment. |
If you wouldn't mind, @ocharles, I'd be grateful to hand this proposal over to you. |
You got it! I'll try and put together an impact assessment in the next few days |
If I did everything correctly, I believe I've completed the impact assessment. I used https://gitlab.haskell.org/ghc/ghc/-/merge_requests/9757 to build a new version of GHC, then built So, to reiterate: the proposed change doesn't seem to break anything in
|
Thanks, @ocharles. I'll trigger the vote once a new cast of CLC is selected in February. |
@Bodigrim Good to go with a vote now? |
Dear CLC members, the proposal is to restrict Strategically the proposed change is in line with the monomorphisation of CLC has approved addition of polymorphic Before we trigger a vote, I would like to hear (non-binding) opinions from new members of CLC. |
It's a gratuitous breaking change, so -1 from me, as outlined in a previous comment. [EDIT: oh sorry, my opinion wasn't actually requested at this time, but FWIW that's my opinion, and my vote] |
What worries me in the current plan is that if anywhere out there exists a consumer of polymorphic #88 (comment) describes a possible approach to gradual replacement, but I think inroducing If there is an appetite for a smoother transition, I'd suggest the following:
This is slightly antithetical to the purpose of the proposal, because until GHC 9.10 users would not have access to a monomorphic |
@ocharles since you took over the proposal, what would you like to do? We can vote on the original proposal, but judging from the discussion above this is likely to fail. I think that changing the proposal to a warning now and monomorphisation later (say, in GHC 9.14) has much better chances to succeed. |
I would like to vote with the original proposal. Personally with my stackage evaluation I don't see any significant breakage, but the CLC are of course free to see things differently. I don't think I have the resources to do much more than that though, and took this from @mixphix to try and keep things moving forward |
I'm obviously in favour of the proposal as written; preferably with @parsonsmatt's fast-tracked warning/restriction two-release plan, but I'll gladly accept any schedule for the sake of a more sensible type. |
@Bodigrim could you remove "awaits-impact-assessment", as that has been done (#86 (comment)) |
I'm going to use your permission and put for a vote a plan from #86 (comment) as it's likely to gain more support. Dear CLC members, let's vote on the following plan:
@tomjaguarpaw @chshersh @hasufell @mixphix @angerman @parsonsmatt +1 from me. This is a very conservative migration plan for a virtually unused function, eventually bringing in more consistency. |
+1 - would also +1 a more aggressive schedule |
I don't quite understand point 1. If a user of I'm ok with this proposal, but it doesn't sit great because legitimate uses will have to turn the warning off, but that's (at least) module wide, and while you get a warning about the deprecation, you get no such warning to stop ignoring deprecations when you reach 9.14. |
As there is no suggestion for an implementation change, I find the motivation insufficient and vote -1. |
+1 The deprecation schedule indeed may look too conservative. But I think it would be huge success if we could enforce and follow the same schedule for every breaking change. I also wouldn't block this improvement on the grounds of "not doing enough". If someone in the future wants to create a proposal to change the implementation of |
+1 However, I really think we should also add I'm sympathetic to @hasufell's point of view, but I still think that it's better to bring it to the attention of users that |
The proposal to strengthen to |
@hasufell making @mixphix could you please cast your vote on #86 (comment)? |
+1 |
Thanks all, we have enough votes for the proposal to pass. @mixphix would you like to execute on Step 1 of #86 (comment) and raise an MR? |
Hi from the cabal team! Do y'all know if there is a |
I'm no expert but something along the lines of - warn: {name: "Avoid NonEmpty.unzip", lhs: "Data.List.NonEmpty.unzip", rhs: "(fmap fst &&& fmap snd)"} (or |
@mixphix - that works. Given the user already made the choice to use a function for this, and that |
…NonEmpty b) Implementing the final phase of CLC proposal haskell/core-libraries-committee#86
…NonEmpty b) Implementing the final phase of CLC proposal haskell/core-libraries-committee#86
…NonEmpty b) Implementing the final phase of CLC proposal haskell/core-libraries-committee#86
…NonEmpty b) Implementing the final phase of CLC proposal haskell/core-libraries-committee#86
…NonEmpty b) Implementing the final phase of CLC proposal haskell/core-libraries-committee#86
Currently we have
unzip :: Functor f => f (a, b) -> (f a, f b)
exported fromData.List.NonEmpty
. The implementation can remain the same, but I propose that the type should be restricted tounzip :: NonEmpty (a, b) -> (NonEmpty a, NonEmpty b)
for analogy withData.List
as well as to avoid exporting overgeneralized functions from specific modules. Really, why should we be exporting something that works with anyFunctor
fromData.List.NonEmpty
?The text was updated successfully, but these errors were encountered: