-
Notifications
You must be signed in to change notification settings - Fork 29
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
Deprecate MonadZero #62
Comments
Sounds reasonable. |
I think I might post about this on Discourse, since this feels like a big enough change that we ought to solicit feedback on it. |
Based on the discussion in the Discourse post, what changes need to be made here to close this issue? Seems like
|
That, plus changing the definition of |
On reflection, I think whatever we do on #63, it's unlikely to have direct consequences for this issue. In particular, nobody seems to be defending MonadZero or proposing an alternative hierarchy which does include it. So I think we can go ahead and do this (and mark this library as 0.14-ready in the checklist on that compiler issue). |
As mentioned in #177, should other libraries in core which use |
One way to get around the CI issue is to censor the UserDefinedWarnings because we're using a custom compiler warning.
We'll want to censor it in some situations (e.g. updating repos) but not others (updating the package set). |
I think deprecating the class but removing the existing instances doesn’t make a whole lot of sense, because I’d guess most usages of the class probably rely on at least one of the instances in core; if we were going to remove the instances we might as well just remove the whole class. So for me it’s between skipping a deprecation cycle and just removing the whole class now, or removing the warning so that existing instances can compile without warnings. I’m leaning towards the latter. I think the policy of “all libraries should always compile without warnings” is often incompatible with backwards compatibility and deprecation cycles - if you look at the warnings produced by Haskell dependencies I think the majority are to do with ongoing deprecation cycles - so perhaps in the longer term we might want to try to find a better compromise, perhaps allowing certain warnings but not others. |
I think censoring UserDefinedWarning is probably not appropriate in general because of e.g
|
The right thing to do is probably to have a deprecation cycle. Yet due to how (I suspect) rarely MonadZero is used and how straightforward the fix is I am tempted to just remove it. In the long run, though, we’ll have some other deprecation warning in a library crop up and we’ll have to figure out what to do about warnings in CI. We could temporarily at least use @JordanMartinez’s solution or a similar flag — it’s better than disabling the warnings check altogether in CI. |
If we are talking about temporary approaches, I think keeping the MonadZero class and the instances but removing the Warn constraint on it is preferable to adding a flag to CI scripts to ignore custom warnings; I think it is very likely that we’d forget to remove the flag again, especially if we had to make that change across a few libraries. |
There are open issues on We could also add support for a spago build -u "--strict --censor-user-defined-warnings=\"'MonadZero' is deprecated\"" I’m not sure people will notice the deprecation of the class without a warning so given how little it is probably used I think we may as well remove the class and its instances now if we’re not going to warn before removing it later. |
People will notice if they've seen the notice on Discourse, or if they see the docs for MonadZero on Pursuit. I think it's plausible that people will see the docs on Pursuit even if they have missed the Discourse announcement - if you spot that |
I agree with @kl0tl that the visibility is much better if we can keep the warning in place. I rarely look at pursuit for functions and classes I already use regularly and could easily miss something like this change. I’m on board with a hybrid approach where we try to filter out warnings as narrowly as possible and leave issues to remove those filters later. I think that would be preferable to removing the warnings altogether from the source. |
I opened natefaubion/purescript-psa-utils#10 and natefaubion/purescript-psa#45 to add support for a |
I think we should consider adding this filtering in a bespoke script, or using a fork of psa temporarily, rather than adding it directly to psa. It's hacky and not something I would want to support if I was maintaining the tool. |
Alternatively, I guess we could justify censoring all UserDefinedWarning warnings if it's a temporary thing and we have an issue to track removing them further down the line. I think we're unlikely to encounter a UserDefinedWarning which isn't a deprecation warning within the core libraries; we shouldn't be using an |
I disagree on filtering user defined warnings in yet another tool and I think it would be useful in general to be able to temporarily ignore deprecations until one is ready to address them. Better compiler support for deprecations would of course be great but I’d rather think this through when integrating Regardless, I’m less confident than you in our ability to catch Warn constraints during reviews (I bet nobody will check newly imported bindings for Warn constraints) but I would happily settle for censoring all user defined warnings in some core libraries as long as we keep the deprecation warning. |
Of course in general the less tools you need to achieve something, the better, but I am specifically concerned about encouraging people other than us to depend on this behaviour in a widely used tool such as To clarify I think we're likely to catch any attempts to introduce |
I'm on board with either |
I've implemented that in purescript/purescript-lists#177 |
I proposed MonadZero originally, so it feels somehow appropriate that I’m going to be the one to argue for its demise.
Anyway, as noted in #51, the MonadZero annihilation law
empty >>= f = empty
is automatically satisfied for any law-abiding monad, due to parametricity: while evaluatingempty >>= f
, the functionf
can’t ever be called, since that would requireempty
to produce a value, which means thatempty >>= f
must be the same asempty >>= pure
, which by the monad laws is justempty
.As far as I’m aware, the only place we’re using MonadZero is in the definition of
guard
. However, I’d argue that the Alternative annihilation lawempty <*> f = empty
already gives us enough to ensure thatguard
behaves sensibly. Haskell seems to agree, with itsguard
only requiring Alternative.(Note: The Alternative annihilation law isn’t redundant: for a type which isn’t a monad, the effects of the second argument of
<*>
could be performed before the first).Therefore, I propose we do the following:
guard
to only require AlternativeThe text was updated successfully, but these errors were encountered: