Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
243 messages Options
12345 ... 13
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Greg Weber
yes, an automated upgrade would need to do a backwards compatible upgrade (inserrt macros, etc)

On Fri, Sep 25, 2015 at 8:46 AM, David Feuer <[hidden email]> wrote:

It *should* be possible to recognize

return = pure
return x = pure x
pure = return
pure x = return x
and also cases where pure and return are defined the same up to alpha equivalence. It should also be possible to fix this up automatically, but there are several different fixes that programmers may want. Many package maintainers strive to support old GHC versions--some as far back as 7.0--and a few even try to keep their code running in Hugs, although that seems a bit silly. Those maintainers will probably want to use MIN_VERSION_base to maintain backwards compatibility. Some of those packages (e.g., containers) approximate fake versions of that macro for non-cabal compilation, but such conditional definitions may occur in each file separately or in a global include file.

On Sep 25, 2015 11:35 AM, "Greg Weber" <[hidden email]> wrote:
Is the upgrade automatable with tooling that analyzes Haskell source code?
If so can we provide an executable that will automatically upgrade packages?
Pull requests could even be sent automatically.

On Fri, Sep 25, 2015 at 5:02 AM, Alexander Berntsen <[hidden email]> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

Enthusiastic +1 from me too, of course.

- --
Alexander
[hidden email]
https://secure.plaimi.net/~alexander
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2

iQIcBAEBCgAGBQJWBTfiAAoJENQqWdRUGk8BU00QAMQfZo07CKomsjqcwNCDNqdm
ifIhiz2kldR+A/gp6t/8IRf0RG3ZgZfwxhR5s/BWt7yV28napZfTMHPTfV8gE+bm
V8AzvsXe/XLa9gTDyxqnY+ovYBDnEqmbX3SU03rRdtcN3jHiNuFkfIEIkRx6+HVx
BKfoebxD7r1tgs/4nxjD8HljJEh6W8ux2Q8+sMWiCJEbVN5ixzTzGSk28vT2Ldyl
GkoZJoXYM4K3WVCn23UmH9eokbdbnaCu2WRqzGgM7eQf+qqpouSjE3KRL5d9O/pE
NMJIrNkC1L613GpfNeHLikOCKd78vbT0xnXyKHwAxv4Cr/7IZI3dyu+5MYwFntrY
cdX7PgNQw7RN/tvZ63OOaRQEqvQfiOSdhPdFxAF5MabPNYMZMjIHqJuQseBaiUJf
SWOU9oYNWW7XQVaQRVS5bP0KvRUhsA2+QXEd6pnhBEZ6u7qRQhaJowjca/A1TbB/
LHVG9nXE04fvc+CRkMK/xZEbuNWiMF0p4CZUiyeuAzhcZ9dge367ExfrTpTSLz8O
Gfh04LgWs3rnvc3w8yhJJjcfsHhYZKQJMv40Rn8dgE/hyGFRpwQvBvFolZtFBZiS
h6A/MyLDaSJCw3jwj+cU5PGLULGzdfNnTRlJ/jb4/CD2xUEOaQcAd+NvIJOlREcK
RZBk4o5MU1aCsujOzjRd
=VfnC
-----END PGP SIGNATURE-----
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Herbert Valerio Riedel
In reply to this post by Edward Kmett-2
On 2015-09-25 at 04:40:25 +0200, Edward Kmett wrote:

> I'm a rather enthusiastic +1 on this, given a sufficiently long time table
> for the switch!
>
> We ARE asking a lot of people to break code here.
>
> It does drastically reduce the amount of "magic" involved in the
> ApplicativeDo story and avoids enshrining the current historical artifact
> in a future Haskell report that includes the AMP.
>
> I'd also like to consider employing the exact same migration plan for (>>)
> at the same time. It is redundant with (*>), and the choice of which gets
> implemented in terms of the other introduces precisely the same set of
> issues. If we can do that then this would fix the remaining performance
> issues for mapM, letting us eventually remove that from Traversable as
> well, moving it to a top level alias in the same way -- maybe not until 8.8
> or something, but it'd at least give us a roadmap to get there
> eventually.

+1

It makes totally sense to apply the same treatment for `Monad((>>))`
also because the same warning machinery in GHC can be reused for that.

A simple grep heuristic shows about 114 packages affected:

 https://gist.github.com/hvr/0dd477935266c00c58e0


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Michael Walker
In reply to this post by Bardur Arantsson-2
> I propse to remove the "Legacy" designation (see below for reasoning).
> There should probably also be some reference to the Applicative type
> class, so I'd propose a wording more like:
>
>     Alias for 'pure' in the 'Applicative' type class.
>
> Reasoning: I happen to rather like "return" for purely pedagogical
> purposes since it lets you pretend (as a sufficient-for-beginners
> approximation) that code in the do-notation in IO is imperative code and
> "return" is the usual name for what it does in that context. I think
> that has a certain value, but "Legacy" is quite off-putting.

+1

"Legacy" suggests that there is a plan to remove `return` at some point.

--
Michael Walker (http://www.barrucadu.co.uk)
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

wren romano-2
In reply to this post by Bardur Arantsson-2
On Fri, Sep 25, 2015 at 1:23 AM, Bardur Arantsson <[hidden email]> wrote:
> Reasoning: I happen to rather like "return" for purely pedagogical
> purposes since it lets you pretend (as a sufficient-for-beginners
> approximation) that code in the do-notation in IO is imperative code and
> "return" is the usual name for what it does in that context. I think
> that has a certain value, but "Legacy" is quite off-putting.

+1.

I like the proposal to merge pure/return into a single thing, but I
rather prefer the name "return" for all the same pedagogical reasons
it was originally chosen.

--
Live well,
~wren
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Christopher Allen
Agreed.

The name pure is pretty awful. It's not _that_ big of a deal, but pure is annoyingly senseless and my coauthor noticed this of her own accord as well.

+1 for the proposal, just wish it wasn't named pure ;)

On Fri, Sep 25, 2015 at 6:47 PM, wren romano <[hidden email]> wrote:
On Fri, Sep 25, 2015 at 1:23 AM, Bardur Arantsson <[hidden email]> wrote:
> Reasoning: I happen to rather like "return" for purely pedagogical
> purposes since it lets you pretend (as a sufficient-for-beginners
> approximation) that code in the do-notation in IO is imperative code and
> "return" is the usual name for what it does in that context. I think
> that has a certain value, but "Legacy" is quite off-putting.

+1.

I like the proposal to merge pure/return into a single thing, but I
rather prefer the name "return" for all the same pedagogical reasons
it was originally chosen.

--
Live well,
~wren
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



--
Chris Allen
Currently working on http://haskellbook.com

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

David Feuer

I think they're both wretched. return makes beginners think it's a control structure; pure just seems meaningless (I guess that's a slight improvement, arguably). I'd have gone for something like inject myself, but there's no way that's happening.

On Sep 25, 2015 8:00 PM, "Christopher Allen" <[hidden email]> wrote:
Agreed.

The name pure is pretty awful. It's not _that_ big of a deal, but pure is annoyingly senseless and my coauthor noticed this of her own accord as well.

+1 for the proposal, just wish it wasn't named pure ;)

On Fri, Sep 25, 2015 at 6:47 PM, wren romano <[hidden email]> wrote:
On Fri, Sep 25, 2015 at 1:23 AM, Bardur Arantsson <[hidden email]> wrote:
> Reasoning: I happen to rather like "return" for purely pedagogical
> purposes since it lets you pretend (as a sufficient-for-beginners
> approximation) that code in the do-notation in IO is imperative code and
> "return" is the usual name for what it does in that context. I think
> that has a certain value, but "Legacy" is quite off-putting.

+1.

I like the proposal to merge pure/return into a single thing, but I
rather prefer the name "return" for all the same pedagogical reasons
it was originally chosen.

--
Live well,
~wren
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



--
Chris Allen
Currently working on http://haskellbook.com

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Imants Cekusins
In reply to this post by Christopher Allen

 > wish it wasn't named pure

How about "wrap" or "box" (as in box-unbox)?


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Christopher Allen
Box is good but overlaps with unboxed/boxed types. Wrap is good.

On Fri, Sep 25, 2015 at 7:27 PM, Imants Cekusins <[hidden email]> wrote:

 > wish it wasn't named pure

How about "wrap" or "box" (as in box-unbox)?




--
Chris Allen
Currently working on http://haskellbook.com

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

M Farkas-Dyck
In reply to this post by Christopher Allen
On 25/09/2015, Christopher Allen <[hidden email]> wrote:
> wish it wasn't named pure

While we're proposing names: point?
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Reid Barton-2
On Fri, Sep 25, 2015 at 9:40 PM, M Farkas-Dyck <[hidden email]> wrote:
On 25/09/2015, Christopher Allen <[hidden email]> wrote:
> wish it wasn't named pure

While we're proposing names...

Hi,

We're not actually proposing names. Thanks.

Regards,
Reid Barton

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Manuel Gómez
In reply to this post by David Feuer
On Fri, Sep 25, 2015 at 7:56 PM, David Feuer <[hidden email]> wrote:
> I think they're both wretched. return makes beginners think it's a control
> structure; pure just seems meaningless (I guess that's a slight improvement,
> arguably). I'd have gone for something like inject myself, but there's no
> way that's happening.

Just my $0.02:

I wouldn't say `pure` is meaningless.  It takes a value and turns it
into a computation in the relevant computational context that performs
no effects apart from yielding the given value.  Computations whose
only effect is yielding a single value are typically said to be pure
computations in the Haskell community.  It's a really nice name.

`return`, on the other hand, is tremendously misleading for imperative
programmers who won't understand why in the world anything after it
isn't dead code.  It'd be a reasonable name for a continuation monad
action that actually did something akin to what it does in the
contexts whence the name was borrowed, but even that would be
inaccurate since not even in the context of a continuation monad is
there a notion of "the current procedure".  In any case, `return`
evokes the imperative intuition in learners that should be trying
desperately to avoid the imperative intuition in order to understand
Haskell's use of the word "function", especially since the Haskell
community does also use the word "return" to talk about the value
produced by a function when applied to an argument.

I see no pedagogical value in `return`, and I've had better results
teaching Haskell when I avoid mentioning it at all.  Not a single
Haskell monad can be described clearly and accurately using the
traditional vocabulary of imperative programming; not even IO.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Bardur Arantsson-2
In reply to this post by Reid Barton-2
On 09/26/2015 03:46 AM, Reid Barton wrote:

> On Fri, Sep 25, 2015 at 9:40 PM, M Farkas-Dyck <[hidden email]> wrote:
>
>> On 25/09/2015, Christopher Allen <[hidden email]> wrote:
>>> wish it wasn't named pure
>>
>> While we're proposing names...
>>
>
> Hi,
>
> We're not actually proposing names. Thanks.
>

+1


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

M Farkas-Dyck
In reply to this post by Reid Barton-2
On 25/09/2015, Reid Barton <[hidden email]> wrote:
> We're not actually proposing names. Thanks.

I'm not arguing to rename it now, but some were proposing names, for
examples: inject, box, wrap.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Bart Massey
unmonadify

On Fri, Sep 25, 2015 at 10:25 PM M Farkas-Dyck <[hidden email]> wrote:
On 25/09/2015, Reid Barton <[hidden email]> wrote:
> We're not actually proposing names. Thanks.

I'm not arguing to rename it now, but some were proposing names, for
examples: inject, box, wrap.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

David Luposchainsky
In reply to this post by wren romano-2
A rename of neither pure nor return is going to happen.

- There is no known better name
- Renaming a popular class function eclipses any breaking change in its headache
potential (since the changes implied are highly non-local)
- Adding the name as a top-level synonym aliasing return aliasing return would
just grow the zoo of synonyms that we're trying to get rid of

Can we end the bikeshedding, or move this to a different discussion on the list?

Greetings,
David/quchen
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

Richard Eisenberg-2
In reply to this post by Herbert Valerio Riedel
Thanks for making this proposal.

I'm leery of the breakage that this would cause. But, there has been no chorus of voices complaining about breaking changes in the recent past (AMP and changes to Typeable are top on my mind), so perhaps our community is more tolerant of breakage than I would guess.

Given that, I'm +1 on this.

The one point of this proposal that's gotten some debate is preferring `pure` or preferring `return`. (I'm considering any contemplation of other names to be more noise than signal. Besides, I interpret most [all?] of those emails to be in varying degrees of jest.)

I vote for `pure` over `return`. Although some have pointed out that `return` feels more natural to those coming from other languages, it is a false friend [1]. `return` is emphatically not a language construct in Haskell, and it has no effect on flow control. On the other hand `pure` embeds a pure bit in an effectful computation. When I say do { x ; pure $ y }, `y` is indeed pure, as the function suggests. I think this is a much simpler approach than trying to convince skeptical Java programmers that `return` is nothing special.

Richard

[1]: https://en.wikipedia.org/wiki/False_friend

On Sep 24, 2015, at 5:43 PM, Herbert Valerio Riedel <[hidden email]> wrote:

> Hello *,
>
> Concluding AMP and MFP, We (David and I) proudly present you the final
> installment of the Monad trilogy:
>
>
> Monad of no `return` Proposal
> =============================
>
> TLDR: To complete the AMP, turn `Monad(return)` method into a
>      top-level binding aliasing `Applicative(pure)`.
>
>
> Current Situation
> -----------------
>
> With the implementation of Functor-Applicative-Monad Proposal (AMP)[1] and
> (at some point) the MonadFail proposal (MFP)[2] the AMP class hierarchy
> becomes
>
>
>    class  Functor f  where
>        fmap    :: (a -> b) -> f a -> f b
>
>
>    class  Functor f => Applicative f  where
>        pure    :: a -> f a
>        (<*>)   :: f (a -> b) -> f a -> f b
>
>        (*>)    :: f a -> f b -> f b
>        u *> v  = …
>
>        (<*)    :: f a -> f b -> f a
>        u <* v  = …
>
>
>    class  Applicative m => Monad m  where
>        (>>=)   :: m a -> (a -> m b) -> m b
>
>        return  :: a -> m a
>        return  = pure
>
>        (>>)    :: m a -> m b -> m b
>        m >> k  = …
>
>
>    class  Monad m => MonadFail m  where
>        fail    :: String -> m a
>
>
> Consequently, the `Monad` class is left with a now redundant `return`
> method as a historic artifact, as there's no compelling reason to
> have `pure` and `return` implemented differently.
>
> Traditionally, `return` is often used where `pure` would suffice
> today, forcing a `Monad` constraint even if a weaker `Applicative`
> would have sufficed.
>
> As a result, language extensions like `ApplicativeDo`[3] have to
> rewrite `return` to weaken its `Monad m =>` constraint to
> `Applicative m =>` in order to benefit existing code at the cost
> of introducing magic behavior at the type level.
>
> Finally, this redundancy becomes even more significant when viewed in
> light of the renewed Haskell standardisation process[7]: The next
> Haskell Report will almost certainly incorporate the AMP (and MFP)
> changes, and there's no justification for the Report to retain
> `return` as a method of `Monad`. A good reason would have been to
> retain backward compatibility with Haskell 2010. However, as the AMP
> superclass hierarchy requires `Monad` instances to be accompanied by
> `Applicative` instances (which aren't part of Haskell 2010, c.f. [6]),
> backward compatibility with Haskell 2010 goes out the window when it
> comes to defining `Monad` instances (unless via use of `-XCPP` or
> similar).  Consequently, meeting the high bar for a formal document
> such as the Haskell Report demands that `Monad` shall not carry a
> redundant `return` method that serves no purpose anymore. Moreover,
> getting `return` out of the way is desirable to facilitate
> standardising potential candidates such as the earlier mentioned
> `ApplicativeDo` in the future and avoids the technical debt incurred
> by keeping around this language wart.
>
>
> Proposed Change
> ---------------
>
> Remove `return` as a method from the `Monad` class and in its place
> define a top-level binding with the weaker `Applicative` typeclass
> constraint:
>
>
>    -- | Legacy alias for 'pure'
>    return :: Applicative f => a -> f a
>    return = pure
>
>
> This allows existing code using `return` to benefit from a weaker
> typeclass constraint as well as cleaning the `Monad` class from a
> redundant method in the post-AMP world.
>
> A possible migration strategy is described further below.
>
>
> Compatibility Considerations
> ----------------------------
>
> Generalizing the type signature of a function from a `Monad`
> constraint to its superclass `Applicative` doesn't cause new
> type-errors in existing code.
>
> However, moving a method to a top-level binding obviously breaks code
> that assumes `return` to be a class method. Foremost, code that
> defines `Monad` instances it at risk:
>
> ### Instance Definitions
>
> Code defining `return` as part of an instance definition
> breaks. However, we had the foresight to provide a default
> implementation in `base-4.8` for `return` so that the following
> represents a proper minimal instance definition post-AMP:
>
>
>    instance Functor Foo where
>        fmap g foo  = …
>
>    instance Applicative Foo where
>        pure x      = …
>        a1 <*> a2   = …
>
>    instance Monad Foo where
>        m >>= f     = …
>
>        -- NB: No mention of `return`
>
>
> Consequently, it is possible to write forward-compatible instances
> that are valid under this proposal starting with GHC 7.10/`base-4.8`.
>
> Heuristically `grep`ing through Hackage source-code reveals a
> non-negligible number of packages defining `Monad` instances with
> explicit `return` definitions[4]. This has a comparable impact to the
> AMP, and similarly will require a transition scheme aided by compiler
> warnings.
>
> ### Module Import/Export Specifications
>
> A second source of incompatibility may be due to
> `import`s. Specifically module import that assert `return` to be a
> method of `Monad`, e.g.:
>
>    import Control.Monad  (Monad ((>>=), return))
>
> or
>
>    import Prelude hiding (Monad(..))
>    import Control.Monad  (Monad(..)) as Monad
>
>    f = Monad.return ()
>
> The dual situation can occur when re-exporting `return` via module
> export specifications.
>
> However, given that `return` is exported by `Prelude` and the examples
> above are rather artificial, we don't expect this to be a major source
> of breakage in the case of `return`. In fact, a heuristic grep[5] over
> Hackage source-code revealed only 21 packages affected.
>
> ### Example for writing compatible code
>
>
>    instance Functor Foo where
>        fmap g foo  = …
>
>    instance Applicative Foo where
>        pure x      = …
>        a1 <*> a2   = …
>
>    instance Monad Foo where
>        m >>= f     = …
>
>    #if !(MIN_VERSION_base(4,8,0))
>        return = pure
>    #endif
>
>
> Migration Strategy
> ------------------
>
> The migration strategy is straightforward:
>
> **Phase 1** *(GHC 8.0)*: Implement new warning in GHC which gets
>   triggered when `Monad` instances explicitly override the
>   default `return` method implementation.
>
> **Phase 2** *(GHC 8.2 or later)*: When we're confident that the
>   majority of Hackage has reacted to the warning (with the help of
>   Stackage actively pursuing maintainers to update their packages) we
>   turn the `return` method into a top-level binding and remove the
>   warning implemented in Phase 1 from GHC again.
>
>
> Discussion period
> -----------------
>
> A discussion period of three weeks (until 2015-10-15) should be enough
> to allow everyone to chime in as well as leave enough time to make the
> required preparations for GHC 8.0 should this proposal pass as we hope.
>
> ----
>
> [1]: https://wiki.haskell.org/Functor-Applicative-Monad_Proposal
> [2]: https://wiki.haskell.org/MonadFail_Proposal
> [3]: https://ghc.haskell.org/trac/ghc/wiki/ApplicativeDo
> [4]: https://gist.github.com/hvr/b0e34463d85b58f169d9
> [5]: https://gist.github.com/hvr/afcd040783d980594883
> [6]: https://ghc.haskell.org/trac/ghc/ticket/9590
> [7]: https://mail.haskell.org/pipermail/haskell-prime/2015-September/003936.html
>
> --
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

amindfv
+0.5 on the overall proposal, -1 on breaking anything more in order to favor "pure" or "return". Both are iffy names.

My issues with Richard's arguments against "pure":

 - Purity/effectful-ness and applicative/monadic are sorta orthogonal, e.g.:

pure (print 0) :: [IO ()]

 - In the sense that "pure 7 :: IO Int" does actually take a pure thing and make it impure, it still has the opposite of function naming convention, namely describing what the function does to the value. It's a little like defining

oneLess = (+1)

and then saying "no, see, in 'oneLess 7'", 7 is one less than the result"

Tom



> El 26 sept 2015, a las 18:04, Richard Eisenberg <[hidden email]> escribió:
>
> Thanks for making this proposal.
>
> I'm leery of the breakage that this would cause. But, there has been no chorus of voices complaining about breaking changes in the recent past (AMP and changes to Typeable are top on my mind), so perhaps our community is more tolerant of breakage than I would guess.
>
> Given that, I'm +1 on this.
>
> The one point of this proposal that's gotten some debate is preferring `pure` or preferring `return`. (I'm considering any contemplation of other names to be more noise than signal. Besides, I interpret most [all?] of those emails to be in varying degrees of jest.)
>
> I vote for `pure` over `return`. Although some have pointed out that `return` feels more natural to those coming from other languages, it is a false friend [1]. `return` is emphatically not a language construct in Haskell, and it has no effect on flow control. On the other hand `pure` embeds a pure bit in an effectful computation. When I say do { x ; pure $ y }, `y` is indeed pure, as the function suggests. I think this is a much simpler approach than trying to convince skeptical Java programmers that `return` is nothing special.
>
> Richard
>
> [1]: https://en.wikipedia.org/wiki/False_friend
>
>> On Sep 24, 2015, at 5:43 PM, Herbert Valerio Riedel <[hidden email]> wrote:
>>
>> Hello *,
>>
>> Concluding AMP and MFP, We (David and I) proudly present you the final
>> installment of the Monad trilogy:
>>
>>
>> Monad of no `return` Proposal
>> =============================
>>
>> TLDR: To complete the AMP, turn `Monad(return)` method into a
>>     top-level binding aliasing `Applicative(pure)`.
>>
>>
>> Current Situation
>> -----------------
>>
>> With the implementation of Functor-Applicative-Monad Proposal (AMP)[1] and
>> (at some point) the MonadFail proposal (MFP)[2] the AMP class hierarchy
>> becomes
>>
>>
>>   class  Functor f  where
>>       fmap    :: (a -> b) -> f a -> f b
>>
>>
>>   class  Functor f => Applicative f  where
>>       pure    :: a -> f a
>>       (<*>)   :: f (a -> b) -> f a -> f b
>>
>>       (*>)    :: f a -> f b -> f b
>>       u *> v  = …
>>
>>       (<*)    :: f a -> f b -> f a
>>       u <* v  = …
>>
>>
>>   class  Applicative m => Monad m  where
>>       (>>=)   :: m a -> (a -> m b) -> m b
>>
>>       return  :: a -> m a
>>       return  = pure
>>
>>       (>>)    :: m a -> m b -> m b
>>       m >> k  = …
>>
>>
>>   class  Monad m => MonadFail m  where
>>       fail    :: String -> m a
>>
>>
>> Consequently, the `Monad` class is left with a now redundant `return`
>> method as a historic artifact, as there's no compelling reason to
>> have `pure` and `return` implemented differently.
>>
>> Traditionally, `return` is often used where `pure` would suffice
>> today, forcing a `Monad` constraint even if a weaker `Applicative`
>> would have sufficed.
>>
>> As a result, language extensions like `ApplicativeDo`[3] have to
>> rewrite `return` to weaken its `Monad m =>` constraint to
>> `Applicative m =>` in order to benefit existing code at the cost
>> of introducing magic behavior at the type level.
>>
>> Finally, this redundancy becomes even more significant when viewed in
>> light of the renewed Haskell standardisation process[7]: The next
>> Haskell Report will almost certainly incorporate the AMP (and MFP)
>> changes, and there's no justification for the Report to retain
>> `return` as a method of `Monad`. A good reason would have been to
>> retain backward compatibility with Haskell 2010. However, as the AMP
>> superclass hierarchy requires `Monad` instances to be accompanied by
>> `Applicative` instances (which aren't part of Haskell 2010, c.f. [6]),
>> backward compatibility with Haskell 2010 goes out the window when it
>> comes to defining `Monad` instances (unless via use of `-XCPP` or
>> similar).  Consequently, meeting the high bar for a formal document
>> such as the Haskell Report demands that `Monad` shall not carry a
>> redundant `return` method that serves no purpose anymore. Moreover,
>> getting `return` out of the way is desirable to facilitate
>> standardising potential candidates such as the earlier mentioned
>> `ApplicativeDo` in the future and avoids the technical debt incurred
>> by keeping around this language wart.
>>
>>
>> Proposed Change
>> ---------------
>>
>> Remove `return` as a method from the `Monad` class and in its place
>> define a top-level binding with the weaker `Applicative` typeclass
>> constraint:
>>
>>
>>   -- | Legacy alias for 'pure'
>>   return :: Applicative f => a -> f a
>>   return = pure
>>
>>
>> This allows existing code using `return` to benefit from a weaker
>> typeclass constraint as well as cleaning the `Monad` class from a
>> redundant method in the post-AMP world.
>>
>> A possible migration strategy is described further below.
>>
>>
>> Compatibility Considerations
>> ----------------------------
>>
>> Generalizing the type signature of a function from a `Monad`
>> constraint to its superclass `Applicative` doesn't cause new
>> type-errors in existing code.
>>
>> However, moving a method to a top-level binding obviously breaks code
>> that assumes `return` to be a class method. Foremost, code that
>> defines `Monad` instances it at risk:
>>
>> ### Instance Definitions
>>
>> Code defining `return` as part of an instance definition
>> breaks. However, we had the foresight to provide a default
>> implementation in `base-4.8` for `return` so that the following
>> represents a proper minimal instance definition post-AMP:
>>
>>
>>   instance Functor Foo where
>>       fmap g foo  = …
>>
>>   instance Applicative Foo where
>>       pure x      = …
>>       a1 <*> a2   = …
>>
>>   instance Monad Foo where
>>       m >>= f     = …
>>
>>       -- NB: No mention of `return`
>>
>>
>> Consequently, it is possible to write forward-compatible instances
>> that are valid under this proposal starting with GHC 7.10/`base-4.8`.
>>
>> Heuristically `grep`ing through Hackage source-code reveals a
>> non-negligible number of packages defining `Monad` instances with
>> explicit `return` definitions[4]. This has a comparable impact to the
>> AMP, and similarly will require a transition scheme aided by compiler
>> warnings.
>>
>> ### Module Import/Export Specifications
>>
>> A second source of incompatibility may be due to
>> `import`s. Specifically module import that assert `return` to be a
>> method of `Monad`, e.g.:
>>
>>   import Control.Monad  (Monad ((>>=), return))
>>
>> or
>>
>>   import Prelude hiding (Monad(..))
>>   import Control.Monad  (Monad(..)) as Monad
>>
>>   f = Monad.return ()
>>
>> The dual situation can occur when re-exporting `return` via module
>> export specifications.
>>
>> However, given that `return` is exported by `Prelude` and the examples
>> above are rather artificial, we don't expect this to be a major source
>> of breakage in the case of `return`. In fact, a heuristic grep[5] over
>> Hackage source-code revealed only 21 packages affected.
>>
>> ### Example for writing compatible code
>>
>>
>>   instance Functor Foo where
>>       fmap g foo  = …
>>
>>   instance Applicative Foo where
>>       pure x      = …
>>       a1 <*> a2   = …
>>
>>   instance Monad Foo where
>>       m >>= f     = …
>>
>>   #if !(MIN_VERSION_base(4,8,0))
>>       return = pure
>>   #endif
>>
>>
>> Migration Strategy
>> ------------------
>>
>> The migration strategy is straightforward:
>>
>> **Phase 1** *(GHC 8.0)*: Implement new warning in GHC which gets
>>  triggered when `Monad` instances explicitly override the
>>  default `return` method implementation.
>>
>> **Phase 2** *(GHC 8.2 or later)*: When we're confident that the
>>  majority of Hackage has reacted to the warning (with the help of
>>  Stackage actively pursuing maintainers to update their packages) we
>>  turn the `return` method into a top-level binding and remove the
>>  warning implemented in Phase 1 from GHC again.
>>
>>
>> Discussion period
>> -----------------
>>
>> A discussion period of three weeks (until 2015-10-15) should be enough
>> to allow everyone to chime in as well as leave enough time to make the
>> required preparations for GHC 8.0 should this proposal pass as we hope.
>>
>> ----
>>
>> [1]: https://wiki.haskell.org/Functor-Applicative-Monad_Proposal
>> [2]: https://wiki.haskell.org/MonadFail_Proposal
>> [3]: https://ghc.haskell.org/trac/ghc/wiki/ApplicativeDo
>> [4]: https://gist.github.com/hvr/b0e34463d85b58f169d9
>> [5]: https://gist.github.com/hvr/afcd040783d980594883
>> [6]: https://ghc.haskell.org/trac/ghc/ticket/9590
>> [7]: https://mail.haskell.org/pipermail/haskell-prime/2015-September/003936.html
>>
>> --
>> _______________________________________________
>> Libraries mailing list
>> [hidden email]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

John Wiegley-2
In reply to this post by Richard Eisenberg-2
>>>>> Richard Eisenberg <[hidden email]> writes:

> I'm leery of the breakage that this would cause. But, there has been no
> chorus of voices complaining about breaking changes in the recent past (AMP
> and changes to Typeable are top on my mind), so perhaps our community is
> more tolerant of breakage than I would guess.

Also, the breakage argument never resolves itself with time, so if it's always
heeded, we simply cannot progress toward the solution most of us would have
chosen from the beginning, had we foreknowledge of things to come. I think
it's a great thing we're enduring the pain now to correct past decisions, and
move toward a cleaner theoretic foundation.

As for pure vs. return: What I like about 'pure' is that it declaratively says
something about the value, rather than the action constructed from that value.
It says "this action has no other semantics than what can be determined from
the value itself".

John
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

David Feuer
In reply to this post by Herbert Valerio Riedel

For the benefit of people trying out code from papers, tutorials, etc., would it be possible to craft a permanent custom error message for explicit return definitions? I don't remember AMP having such for the new constraint; if it doesn't, maybe it should.

On Sep 24, 2015 5:43 PM, "Herbert Valerio Riedel" <[hidden email]> wrote:
Hello *,

Concluding AMP and MFP, We (David and I) proudly present you the final
installment of the Monad trilogy:


Monad of no `return` Proposal
=============================

TLDR: To complete the AMP, turn `Monad(return)` method into a
      top-level binding aliasing `Applicative(pure)`.


Current Situation
-----------------

With the implementation of Functor-Applicative-Monad Proposal (AMP)[1] and
(at some point) the MonadFail proposal (MFP)[2] the AMP class hierarchy
becomes


    class  Functor f  where
        fmap    :: (a -> b) -> f a -> f b


    class  Functor f => Applicative f  where
        pure    :: a -> f a
        (<*>)   :: f (a -> b) -> f a -> f b

        (*>)    :: f a -> f b -> f b
        u *> v  = …

        (<*)    :: f a -> f b -> f a
        u <* v  = …


    class  Applicative m => Monad m  where
        (>>=)   :: m a -> (a -> m b) -> m b

        return  :: a -> m a
        return  = pure

        (>>)    :: m a -> m b -> m b
        m >> k  = …


    class  Monad m => MonadFail m  where
        fail    :: String -> m a


Consequently, the `Monad` class is left with a now redundant `return`
method as a historic artifact, as there's no compelling reason to
have `pure` and `return` implemented differently.

Traditionally, `return` is often used where `pure` would suffice
today, forcing a `Monad` constraint even if a weaker `Applicative`
would have sufficed.

As a result, language extensions like `ApplicativeDo`[3] have to
rewrite `return` to weaken its `Monad m =>` constraint to
`Applicative m =>` in order to benefit existing code at the cost
of introducing magic behavior at the type level.

Finally, this redundancy becomes even more significant when viewed in
light of the renewed Haskell standardisation process[7]: The next
Haskell Report will almost certainly incorporate the AMP (and MFP)
changes, and there's no justification for the Report to retain
`return` as a method of `Monad`. A good reason would have been to
retain backward compatibility with Haskell 2010. However, as the AMP
superclass hierarchy requires `Monad` instances to be accompanied by
`Applicative` instances (which aren't part of Haskell 2010, c.f. [6]),
backward compatibility with Haskell 2010 goes out the window when it
comes to defining `Monad` instances (unless via use of `-XCPP` or
similar).  Consequently, meeting the high bar for a formal document
such as the Haskell Report demands that `Monad` shall not carry a
redundant `return` method that serves no purpose anymore. Moreover,
getting `return` out of the way is desirable to facilitate
standardising potential candidates such as the earlier mentioned
`ApplicativeDo` in the future and avoids the technical debt incurred
by keeping around this language wart.


Proposed Change
---------------

Remove `return` as a method from the `Monad` class and in its place
define a top-level binding with the weaker `Applicative` typeclass
constraint:


    -- | Legacy alias for 'pure'
    return :: Applicative f => a -> f a
    return = pure


This allows existing code using `return` to benefit from a weaker
typeclass constraint as well as cleaning the `Monad` class from a
redundant method in the post-AMP world.

A possible migration strategy is described further below.


Compatibility Considerations
----------------------------

Generalizing the type signature of a function from a `Monad`
constraint to its superclass `Applicative` doesn't cause new
type-errors in existing code.

However, moving a method to a top-level binding obviously breaks code
that assumes `return` to be a class method. Foremost, code that
defines `Monad` instances it at risk:

### Instance Definitions

Code defining `return` as part of an instance definition
breaks. However, we had the foresight to provide a default
implementation in `base-4.8` for `return` so that the following
represents a proper minimal instance definition post-AMP:


    instance Functor Foo where
        fmap g foo  = …

    instance Applicative Foo where
        pure x      = …
        a1 <*> a2   = …

    instance Monad Foo where
        m >>= f     = …

        -- NB: No mention of `return`


Consequently, it is possible to write forward-compatible instances
that are valid under this proposal starting with GHC 7.10/`base-4.8`.

Heuristically `grep`ing through Hackage source-code reveals a
non-negligible number of packages defining `Monad` instances with
explicit `return` definitions[4]. This has a comparable impact to the
AMP, and similarly will require a transition scheme aided by compiler
warnings.

### Module Import/Export Specifications

A second source of incompatibility may be due to
`import`s. Specifically module import that assert `return` to be a
method of `Monad`, e.g.:

    import Control.Monad  (Monad ((>>=), return))

or

    import Prelude hiding (Monad(..))
    import Control.Monad  (Monad(..)) as Monad

    f = Monad.return ()

The dual situation can occur when re-exporting `return` via module
export specifications.

However, given that `return` is exported by `Prelude` and the examples
above are rather artificial, we don't expect this to be a major source
of breakage in the case of `return`. In fact, a heuristic grep[5] over
Hackage source-code revealed only 21 packages affected.

### Example for writing compatible code


    instance Functor Foo where
        fmap g foo  = …

    instance Applicative Foo where
        pure x      = …
        a1 <*> a2   = …

    instance Monad Foo where
        m >>= f     = …

    #if !(MIN_VERSION_base(4,8,0))
        return = pure
    #endif


Migration Strategy
------------------

The migration strategy is straightforward:

**Phase 1** *(GHC 8.0)*: Implement new warning in GHC which gets
   triggered when `Monad` instances explicitly override the
   default `return` method implementation.

**Phase 2** *(GHC 8.2 or later)*: When we're confident that the
   majority of Hackage has reacted to the warning (with the help of
   Stackage actively pursuing maintainers to update their packages) we
   turn the `return` method into a top-level binding and remove the
   warning implemented in Phase 1 from GHC again.


Discussion period
-----------------

A discussion period of three weeks (until 2015-10-15) should be enough
to allow everyone to chime in as well as leave enough time to make the
required preparations for GHC 8.0 should this proposal pass as we hope.

----

 [1]: https://wiki.haskell.org/Functor-Applicative-Monad_Proposal
 [2]: https://wiki.haskell.org/MonadFail_Proposal
 [3]: https://ghc.haskell.org/trac/ghc/wiki/ApplicativeDo
 [4]: https://gist.github.com/hvr/b0e34463d85b58f169d9
 [5]: https://gist.github.com/hvr/afcd040783d980594883
 [6]: https://ghc.haskell.org/trac/ghc/ticket/9590
 [7]: https://mail.haskell.org/pipermail/haskell-prime/2015-September/003936.html

--

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

David Luposchainsky
On 28.09.2015 00:16, David Feuer wrote:
> For the benefit of people trying out code from papers, tutorials, etc., would it
> be possible to craft a permanent custom error message for explicit return
> definitions? I don't remember AMP having such for the new constraint; if it
> doesn't, maybe it should.

Sure, that's something we can probably do. I've done some (futile) digging in
GHC, but the plan is to implement this as a "if a Monad definition contains a
binding referring to 'return' emit a warning", which is or can be made orthogonal
of there actually being a "return" in the actual class.

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
12345 ... 13