Re: [Haskell-cafe] Monad of no `return` Proposal (MRP): Moving `return` out of `Monad`

2015-10-05 11:59 GMT+02:00 Simon Thompson
[...] It’s really interesting to have this discussion, which pulls in all sorts of well-made points about orthogonality, teaching, the evolution of the language and so on, but it simply goes to show that the process of evolving Haskell is profoundly broken. [...]
I wouldn't necessarily call the process "broken", but it's a bit annoying: Because of the constant flux of minor changes in the language and the libraries, I've reached the stage where I'm totally unable to tell if my code will work for the whole GHC 7.x series. The only way I see is doing heavy testing on Travis CI and littering the code with #ifdefs after compilation failures. (BTW: Fun exercise: Try using (<>) and/or (<$>) in conjunction with -Wall. Bonus points for keeping the #ifdefs centralized. No clue how to do that...) This is less than satisfactory IMHO, and I would really prefer some other mode for introducing such changes: Perhaps these should be bundled and released e.g. every 2 years as Haskell2016, Haskell2018, etc. This way some stuff which belongs together (AMP, FTP, kicking out return, etc.) comes in slightly larger, but more sensible chunks. Don't get me wrong: Most of the proposed changes in itself are OK and should be done, it's only the way they are introduced should be improved...

Does anyone here use base-compat? It has worked quite well in my very
limited usage. I think that if the libraries committee officially
maintained it then most of the complaints about the difficulties of
maintaining backwards-compatible code and having to use conditional
compilation would go away. So we have a solution for a large subset of the
complaints here, why is nobody using it?
On Mon, Oct 5, 2015 at 6:27 AM, Sven Panne
2015-10-05 11:59 GMT+02:00 Simon Thompson
: [...] It’s really interesting to have this discussion, which pulls in all sorts of well-made points about orthogonality, teaching, the evolution of the language and so on, but it simply goes to show that the process of evolving Haskell is profoundly broken. [...]
I wouldn't necessarily call the process "broken", but it's a bit annoying: Because of the constant flux of minor changes in the language and the libraries, I've reached the stage where I'm totally unable to tell if my code will work for the whole GHC 7.x series. The only way I see is doing heavy testing on Travis CI and littering the code with #ifdefs after compilation failures. (BTW: Fun exercise: Try using (<>) and/or (<$>) in conjunction with -Wall. Bonus points for keeping the #ifdefs centralized. No clue how to do that...) This is less than satisfactory IMHO, and I would really prefer some other mode for introducing such changes: Perhaps these should be bundled and released e.g. every 2 years as Haskell2016, Haskell2018, etc. This way some stuff which belongs together (AMP, FTP, kicking out return, etc.) comes in slightly larger, but more sensible chunks.
Don't get me wrong: Most of the proposed changes in itself are OK and should be done, it's only the way they are introduced should be improved...
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

We use base-compat, and it works for addition of functions and
instances. It doesn't work for type class changes like this one.
On 5 October 2015 at 15:46, Greg Weber
Does anyone here use base-compat? It has worked quite well in my very limited usage. I think that if the libraries committee officially maintained it then most of the complaints about the difficulties of maintaining backwards-compatible code and having to use conditional compilation would go away. So we have a solution for a large subset of the complaints here, why is nobody using it?
On Mon, Oct 5, 2015 at 6:27 AM, Sven Panne
wrote: 2015-10-05 11:59 GMT+02:00 Simon Thompson
: [...] It’s really interesting to have this discussion, which pulls in all sorts of well-made points about orthogonality, teaching, the evolution of the language and so on, but it simply goes to show that the process of evolving Haskell is profoundly broken. [...]
I wouldn't necessarily call the process "broken", but it's a bit annoying: Because of the constant flux of minor changes in the language and the libraries, I've reached the stage where I'm totally unable to tell if my code will work for the whole GHC 7.x series. The only way I see is doing heavy testing on Travis CI and littering the code with #ifdefs after compilation failures. (BTW: Fun exercise: Try using (<>) and/or (<$>) in conjunction with -Wall. Bonus points for keeping the #ifdefs centralized. No clue how to do that...) This is less than satisfactory IMHO, and I would really prefer some other mode for introducing such changes: Perhaps these should be bundled and released e.g. every 2 years as Haskell2016, Haskell2018, etc. This way some stuff which belongs together (AMP, FTP, kicking out return, etc.) comes in slightly larger, but more sensible chunks.
Don't get me wrong: Most of the proposed changes in itself are OK and should be done, it's only the way they are introduced should be improved...
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On 2015-10-05 at 15:57:39 +0200, Erik Hesselink wrote:
Does anyone here use base-compat? It has worked quite well in my very limited usage. I think that if the libraries committee officially maintained it then most of the complaints about the difficulties of maintaining backwards-compatible code and having to use conditional compilation would go away. So we have a solution for a large subset of the complaints here, why is nobody using it?
We use base-compat, and it works for addition of functions and instances. It doesn't work for type class changes like this one.
Btw, this is exactly why GHC 7.10 droped support for the `haskell2010` library package. See also https://ghc.haskell.org/ticket/9590 for more details about that (and some ideas how to recover a `haskell2010` package in future GHC versions albeit with some tradeoffs). Cheers, hvr

On 2015-10-05 at 15:27:53 +0200, Sven Panne wrote:
2015-10-05 11:59 GMT+02:00 Simon Thompson
: [...] It’s really interesting to have this discussion, which pulls in all sorts of well-made points about orthogonality, teaching, the evolution of the language and so on, but it simply goes to show that the process of evolving Haskell is profoundly broken. [...]
I wouldn't necessarily call the process "broken", but it's a bit annoying: Because of the constant flux of minor changes in the language and the libraries, I've reached the stage where I'm totally unable to tell if my code will work for the whole GHC 7.x series. The only way I see is doing heavy testing on Travis CI and littering the code with #ifdefs after compilation failures. (BTW: Fun exercise: Try using (<>) and/or (<$>) in conjunction with -Wall. Bonus points for keeping the #ifdefs centralized. No clue how to do that...) This is less than satisfactory IMHO, and I would really prefer some other mode for introducing such changes: Perhaps these should be bundled and released e.g. every 2 years as Haskell2016, Haskell2018, etc. This way some stuff which belongs together (AMP, FTP, kicking out return, etc.) comes in slightly larger, but more sensible chunks.
Don't get me wrong: Most of the proposed changes in itself are OK and should be done, it's only the way they are introduced should be improved...
I think that part of the reason we have seen these changes occur in a "constant flux" rather than in bigger coordinated chunks is that faith in the Haskell Report process was (understandably) abandoned. And without the Haskell Report as some kind of "clock generator" with which to align/bundle related changes into logical units, changes occur whenever they're proposed and agreed upon (which may take several attempts as we've seen with the AMP and others). I hope that the current attempt to revive the Haskell Prime process will give us a chance to clean up the unfinished intermediate `base-4.8` situation we're left with now after AMP, FTP et al, as the next Haskell Report revision provides us with a milestone to work towards. That being said, there's also the desire to have changes field-tested by a wide audience on a wide range before integrating them into a Haskell Report. Also I'm not sure if there would be less complaints if AMP/FTP/MFP/MRP/etc as part of a new Haskell Report would be switched on all at once in e.g. `base-5.0`, breaking almost *every* single package out there at once. For language changes we have a great way to field-test new extensions before integrating them into the Report via `{-# LANGUAGE #-}` pragmas in a nicely modular and composable way (i.e. a package enabling a certain pragma doesn't require other packages to use it as well) which have proven to be quite popular. However, for the library side we lack a comparable mechanism at this point. The closest we have, for instance, to support an isolated Haskell2010 legacy environment is to use RebindableSyntax which IMO isn't good enough in its current form[1]. And then there's the question whether we want a Haskell2010 legacy environment that's isolated or rather shares the types & typeclasses w/ `base`. If we require sharing types and classes, then we may need some facility to implicitly instanciate new superclasses (e.g. implicitly define Functor and Applicative if only a Monad instance is defined). If we don't want to share types & classes, we run into the problem that we can't easily mix packages which depend on different revisions of the standard-library (e.g. one using `base-4.8` and others which depend on a legacy `haskell2010` base-API). One way to solve this could be to mutually exclude depending on both , `base-4.8` and `haskell2010`, in the same install-plan (assuming `haskell2010` doesn't depend itself on `base-4.8`) In any case, I think we will have to think hard how to address language/library change management in the future, especially if the Haskell code-base continues to grow. Even just migrating the code base between Haskell Report revisions is a problem. An extreme example is the Python 2->3 transition which the Python ecosystem is still suffering from today (afaik). Ideas welcome! [1]: IMO, we need something to be used at the definition site providing desugaring rules, rather than requiring the use-site to enable a generalised desugaring mechanism; I've been told that Agda has an interesting solution to this in its base libraries via {-# LANGUAGE BUILTIN ... #-} pragmas. Regards, H.V.Riedel

Thanks for splitting this off, as it really deserves its own conversation. % find cryptol -name '*.hs' | xargs egrep '#if.*(MIN_VERSION)|(GLASGOW_HASKELL)' | wc -l 49 % find saw-script -name '*.hs' | xargs egrep '#if.*(MIN_VERSION)|(GLASGOW_HASKELL)' | wc -l 242 I introduced most of these in order to accommodate AMP, and now I learn that there is another proposal that is considered to be part-and-parcel with AMP where I will have to make yet more changes to the same code and presumably introduce another layer of #ifdefs. As proposed, I will spend 2*n hours implementing, testing, and releasing these changes. Had both changes been bundled, it would have been 2*(n+ε). Also I'm not sure if there would be less complaints if AMP/FTP/MFP/MRP/etc
as part of a new Haskell Report would be switched on all at once in e.g. `base-5.0`, breaking almost *every* single package out there at once.
I doubt the number of complaints-per-change would be fewer, but I'm
strongly in favor of moving away from what feels like a treadmill that
doesn't value the time of developers and that doesn't account for the
more-than-sum-of-parts cost of the "constant flux".
Thanks,
Adam
On Mon, Oct 5, 2015 at 7:32 AM, Herbert Valerio Riedel
On 2015-10-05 at 15:27:53 +0200, Sven Panne wrote:
2015-10-05 11:59 GMT+02:00 Simon Thompson
: [...] It’s really interesting to have this discussion, which pulls in all sorts of well-made points about orthogonality, teaching, the evolution of the language and so on, but it simply goes to show that the process of evolving Haskell is profoundly broken. [...]
I wouldn't necessarily call the process "broken", but it's a bit annoying: Because of the constant flux of minor changes in the language and the libraries, I've reached the stage where I'm totally unable to tell if my code will work for the whole GHC 7.x series. The only way I see is doing heavy testing on Travis CI and littering the code with #ifdefs after compilation failures. (BTW: Fun exercise: Try using (<>) and/or (<$>) in conjunction with -Wall. Bonus points for keeping the #ifdefs centralized. No clue how to do that...) This is less than satisfactory IMHO, and I would really prefer some other mode for introducing such changes: Perhaps these should be bundled and released e.g. every 2 years as Haskell2016, Haskell2018, etc. This way some stuff which belongs together (AMP, FTP, kicking out return, etc.) comes in slightly larger, but more sensible chunks.
Don't get me wrong: Most of the proposed changes in itself are OK and should be done, it's only the way they are introduced should be improved...
I think that part of the reason we have seen these changes occur in a "constant flux" rather than in bigger coordinated chunks is that faith in the Haskell Report process was (understandably) abandoned. And without the Haskell Report as some kind of "clock generator" with which to align/bundle related changes into logical units, changes occur whenever they're proposed and agreed upon (which may take several attempts as we've seen with the AMP and others).
I hope that the current attempt to revive the Haskell Prime process will give us a chance to clean up the unfinished intermediate `base-4.8` situation we're left with now after AMP, FTP et al, as the next Haskell Report revision provides us with a milestone to work towards.
That being said, there's also the desire to have changes field-tested by a wide audience on a wide range before integrating them into a Haskell Report. Also I'm not sure if there would be less complaints if AMP/FTP/MFP/MRP/etc as part of a new Haskell Report would be switched on all at once in e.g. `base-5.0`, breaking almost *every* single package out there at once.
For language changes we have a great way to field-test new extensions before integrating them into the Report via `{-# LANGUAGE #-}` pragmas in a nicely modular and composable way (i.e. a package enabling a certain pragma doesn't require other packages to use it as well) which have proven to be quite popular.
However, for the library side we lack a comparable mechanism at this point. The closest we have, for instance, to support an isolated Haskell2010 legacy environment is to use RebindableSyntax which IMO isn't good enough in its current form[1]. And then there's the question whether we want a Haskell2010 legacy environment that's isolated or rather shares the types & typeclasses w/ `base`. If we require sharing types and classes, then we may need some facility to implicitly instanciate new superclasses (e.g. implicitly define Functor and Applicative if only a Monad instance is defined). If we don't want to share types & classes, we run into the problem that we can't easily mix packages which depend on different revisions of the standard-library (e.g. one using `base-4.8` and others which depend on a legacy `haskell2010` base-API). One way to solve this could be to mutually exclude depending on both , `base-4.8` and `haskell2010`, in the same install-plan (assuming `haskell2010` doesn't depend itself on `base-4.8`)
In any case, I think we will have to think hard how to address language/library change management in the future, especially if the Haskell code-base continues to grow. Even just migrating the code base between Haskell Report revisions is a problem. An extreme example is the Python 2->3 transition which the Python ecosystem is still suffering from today (afaik). Ideas welcome!
[1]: IMO, we need something to be used at the definition site providing desugaring rules, rather than requiring the use-site to enable a generalised desugaring mechanism; I've been told that Agda has an interesting solution to this in its base libraries via {-# LANGUAGE BUILTIN ... #-} pragmas.
Regards, H.V.Riedel _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Mon, Oct 5, 2015 at 5:23 PM, Adam Foltzer
Also I'm not sure if there would be less complaints if AMP/FTP/MFP/MRP/etc as part of a new Haskell Report would be switched on all at once in e.g. `base-5.0`, breaking almost *every* single package out there at once.
I doubt the number of complaints-per-change would be fewer, but I'm strongly in favor of moving away from what feels like a treadmill that doesn't value the time of developers and that doesn't account for the more-than-sum-of-parts cost of the "constant flux".
Broadly speaking, I'm a "fix it now rather than later" sort of person in Haskell because I've seen how long things can linger before finally getting fixed (even when everyone agrees on what the fix should be and agrees that it should be done). However, as I mentioned in the originating thread, I think that —at this point— when it comes to AMP/FTP/MFP/MRP/etc we should really aim for the haskell' committee to work out a comprehensive solution (as soon as possible), and then enact all the changes at once when switching to Haskell201X/base-5.0/whatevs. I understand the motivations for wanting things to be field-tested before making it into the report, but I don't think having a series of rapid incremental changes is the correct approach here. Because we're dealing with the Prelude and the core classes, the amount of breakage (and CPP used to paper over it) here is much higher than our usual treadmill of changes; so we should take that into account when planning how to roll the changes out. -- Live well, ~wren

Having so many #ifdefs isn't by itself a major problem. Yes, it does introduce a small increase in compilation time and the size of the codebase. The real cost is the developer time: every developer has to come up with these these #ifdef clauses from scratch for every change that gets made, tailored to their specific code. As more and more get added, it becomes more and more of a confusing mess. It makes me wonder if this can be automated somehow. It would be nice to have a mechanism to alleviate this cost so that most developers downstream (provided that the code was written in a reasonable manner) only need to make a minimal effort to keep up, while still being able to write code that works for a reasonably large range of GHC versions. The burden of breaking changes right now is on the downstream developers, but perhaps there could be a way to shift most of that upstream to avoid this large duplication of effort. Haskell should be allowed to evolve, but there also needs to be a counterweight mechanism that provides stability in the face of constant changes. It would be something similar in spirit to base-compat, but I don't think a library package alone is powerful enough to solve the problem: a missing 'return' for example is not something a library can just patch in. I don't have any preference for "lots of small changes" vs "one big change": in the former, there is a lot of overhead needed to keep track of and fix these small changes; in the latter, there is a risk of introducing a rift that fragments the community (cf Python 2 vs 3). Maybe something in-between would be the best.

Another problem with #ifdefs (especially machine-generated ones) is that it makes code much harder to read. One of the things I love about Haskell is the ability to read code and literally see an author describe how they're thinking about the domain. #ifdefs make life less fun :) Tom
El 5 oct 2015, a las 21:00, Phil Ruffwind
escribió: Having so many #ifdefs isn't by itself a major problem. Yes, it does introduce a small increase in compilation time and the size of the codebase. The real cost is the developer time: every developer has to come up with these these #ifdef clauses from scratch for every change that gets made, tailored to their specific code. As more and more get added, it becomes more and more of a confusing mess.
It makes me wonder if this can be automated somehow. It would be nice to have a mechanism to alleviate this cost so that most developers downstream (provided that the code was written in a reasonable manner) only need to make a minimal effort to keep up, while still being able to write code that works for a reasonably large range of GHC versions. The burden of breaking changes right now is on the downstream developers, but perhaps there could be a way to shift most of that upstream to avoid this large duplication of effort.
Haskell should be allowed to evolve, but there also needs to be a counterweight mechanism that provides stability in the face of constant changes. It would be something similar in spirit to base-compat, but I don't think a library package alone is powerful enough to solve the problem: a missing 'return' for example is not something a library can just patch in.
I don't have any preference for "lots of small changes" vs "one big change": in the former, there is a lot of overhead needed to keep track of and fix these small changes; in the latter, there is a risk of introducing a rift that fragments the community (cf Python 2 vs 3). Maybe something in-between would be the best. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
participants (9)
-
Adam Foltzer
-
amindfv@gmail.com
-
Erik Hesselink
-
Greg Weber
-
Herbert Valerio Riedel
-
Herbert Valerio Riedel
-
Phil Ruffwind
-
Sven Panne
-
wren romano