... | @@ -11,25 +11,25 @@ However, there are many good reasons to do both the AMP and FTP generalizations |
... | @@ -11,25 +11,25 @@ However, there are many good reasons to do both the AMP and FTP generalizations |
|
|
|
|
|
- **By generalizing the `Prelude`, the `Prelude` will no longer cause name collisions anywhere within `base`**. This is a very simple rule to state; it is a very simple rule to understand. This is no panacea, other packages can and do still export combinators that collide with `Prelude`, but it means that simple things like explaining how `traverse` relates to `mapM` in `ghci` will no longer invite a comedy of errors and name conflicts.
|
|
- **By generalizing the `Prelude`, the `Prelude` will no longer cause name collisions anywhere within `base`**. This is a very simple rule to state; it is a very simple rule to understand. This is no panacea, other packages can and do still export combinators that collide with `Prelude`, but it means that simple things like explaining how `traverse` relates to `mapM` in `ghci` will no longer invite a comedy of errors and name conflicts.
|
|
|
|
|
|
- `Foldable` and `Traversable` are abstractions that have seen long use in the Haskell community, predating even the existence of `Applicative`, dating back into the early 2000s. We know and have tested these abstractions, and they have deep explanatory power.
|
|
- `Foldable` and `Traversable` are abstractions that have seen **long use in the Haskell community**, predating even the existence of `Applicative`, dating back into the early 2000s. **We know and have tested these abstractions**, and they have deep explanatory power.
|
|
|
|
|
|
- `Traversable` in particular has given us insight into the nature of finitary traversals and have been the subject of many papers since Jeremy Gibbons wrote [ The Essence of the Iterator Pattern](http://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf) each of which has managed to narrow the set of laws until we're left with only the obvious generalization of the `Functor` laws that allows for `Applicative` effects. [ An Investigation of the Laws of Traversals](http://arxiv.org/pdf/1202.2919v1.pdf) is one such paper, providing the common sense reading of the `Traversable` laws.
|
|
- `Traversable` in particular has given us insight into the nature of finitary traversals and have been the subject of many papers since Jeremy Gibbons wrote [ The Essence of the Iterator Pattern](http://www.cs.ox.ac.uk/jeremy.gibbons/publications/iterator.pdf) each of which has managed to narrow the set of laws until we're left with only the **obvious generalization of the `Functor` laws** that allows for `Applicative` effects. [ An Investigation of the Laws of Traversals](http://arxiv.org/pdf/1202.2919v1.pdf) is one such paper, providing the common sense reading of the `Traversable` laws.
|
|
|
|
|
|
- However, `Traversable` is too strong a requirement for many of the operations it enables. `foldMap` is what you get when you limit the power of `traverse` to just consumption, so `Foldable` has a role in this hierarchy. It is particularly telling that almost all the interesting combinators enabled by `Traversable` are actually enabled by merely `Foldable` constraints, including some at-first-surprising results such as `traverse_`. `Foldable` shows us a fairly deep connection between 33+ seemingly unrelated operations from the `Prelude`. `Traversable` adds connections between several more to that mix.
|
|
- However, `Traversable` is too strong a requirement for many of the operations it enables. `foldMap` is what you get when you limit the power of `traverse` to just consumption, so `Foldable` has a role in this hierarchy. It is particularly telling that almost all the interesting combinators enabled by `Traversable` are actually enabled by merely `Foldable` constraints, including some at-first-surprising results such as `traverse_`. **`Foldable` shows us a fairly deep connection between 33+ seemingly unrelated operations** from the `Prelude`. `Traversable` adds connections between several more to that mix.
|
|
|
|
|
|
- Despite this broad explanatory power and the ability to derive connections between a large chunk of the combinators that came before these abstractions were even named, they remain relegated to modules off to the side that contain combinators that are harder to use for the simple reason that using them requires qualified imports or massive amounts of manual hiding.
|
|
- Despite this broad explanatory power and the ability to derive connections between a large chunk of the combinators that came before these abstractions were even named, they remain relegated to modules off to the side that contain combinators that are **harder to use for the simple reason that using them requires qualified imports or massive amounts of manual hiding**.
|
|
|
|
|
|
- Nothing in `Foldable` or `Traversable` ever changes the "shape" of the container it is given. This is actually more information for the user than seeing a combinator accepts any list and returns any list. While we give up the knowledge that the thing we're walking over is a list, we gain information as well. **The more general signatures can often tell the user more** about what a combinator can do behind the scenes. e.g. we can know that `forM` will not change the number of elements in the container by leaning on the `Traversable` laws alone and the lack of any other way to construct the result value. We're not just able to rely the fact that it gives back a list, but we can rely on the specific shape of the structure we get back.
|
|
- Nothing in `Foldable` or `Traversable` ever changes the "shape" of the container it is given. This is actually more information for the user than seeing a combinator accepts any list and returns any list. While we give up the knowledge that the thing we're walking over is a list, we gain information as well. **The more general signatures can often tell the user more** about what a combinator can do behind the scenes. e.g. we can know that `forM` will not change the number of elements in the container by leaning on the `Traversable` laws alone and the lack of any other way to construct the result value. We're not just able to rely the fact that it gives back a list, but we can rely on the specific shape of the structure we get back.
|
|
|
|
|
|
- At the time of the "Burning Bridges Proposal" thread on the libraries mailing list back in 2013, this question was widely polled, and there was an **overwhelmingly strong call from the community for generalization**. Admittedly, this was from the self-selecting subset of the community that is active on the [ libraries@ mailing list](https://www.haskell.org/mailman/listinfo/libraries).
|
|
- At the time of the "Burning Bridges Proposal" thread on the libraries mailing list back in 2013, this question was widely polled, and there was an **overwhelmingly strong call from the community for generalization**. Admittedly, this was from the self-selecting subset of the community that is active on the [ libraries@ mailing list](https://www.haskell.org/mailman/listinfo/libraries).
|
|
|
|
|
|
- One thing that we were very careful to avoid during this entire wave of generalization is an impact to performance on either asymptotic or constant factor grounds. The continuous performance testing that is done on GHC has done a lot to keep us honest in this regard, but has definitely complicated development.
|
|
- One thing that we were very careful to avoid during this entire wave of generalization is an impact to performance on either asymptotic or constant factor grounds. The **continuous performance testing ** that is done on GHC has done a lot to keep us honest in this regard, but has definitely complicated development.
|
|
|
|
|
|
- For better or worse, several hundred packages have already been adapted be compatible with GHC 7.10RC2 expecting that it would be a reasonable approximation of the final, shipping version of GHC 7.10. Package authors who have been actively working and who have attempted to build completely without warnings will have changes to partially undo. Keep in mind that they need to keep the AMP changes, and just roll back the FTP related ones, if the [Prelude710/List](prelude710/list) plan was followed. Rolling these changes back would mean that we're going to ask our most proactive users to re-release the majority of these packages, and to use the ability to change .cabal files for historic versions to make their old versions uninstallable or risk them being selected by cabal in the build plan. That is a messy solution at best. We're better as a community at "getting ahead" and making changes early in a GHC release cycle. Far more code is "GHC 7.10 ready" at this point in the release cycle than was at a comparable point in the GHC 7.8 cycle, which exacerbates this problem.
|
|
- For better or worse, **several hundred packages have already been adapted** be compatible with GHC 7.10RC2 expecting that it would be a reasonable approximation of the final, shipping version of GHC 7.10. Package authors who have been actively working and who have attempted to build completely without warnings will have changes to partially undo. Keep in mind that they need to keep the AMP changes, and just roll back the FTP related ones, if the [Prelude710/List](prelude710/list) plan was followed. Rolling these changes back would mean that we're going to ask our most proactive users to re-release the majority of these packages, and to use the ability to change .cabal files for historic versions to make their old versions uninstallable or risk them being selected by cabal in the build plan. That is a messy solution at best. We're better as a community at "getting ahead" and making changes early in a GHC release cycle. Far more code is "GHC 7.10 ready" at this point in the release cycle than was at a comparable point in the GHC 7.8 cycle, which exacerbates this problem.
|
|
|
|
|
|
- Stretching out these sorts of changes over many releases increases the complexity of CPP and other tricks that authors have to use to maintain their packages over long support windows, so there is a case to be made for a fairly "sharp shock" to get this out of the way at the same time as the `Applicative`-`Monad` Proposal. Results so far have shown that the AMP changes break far more code than generalizing these signatures.
|
|
- **Stretching out these sorts of changes over many releases increases the complexity** of CPP and other tricks that authors have to use to maintain their packages **over long support windows**, so there is a case to be made for a fairly "sharp shock" to get this out of the way at the same time as the `Applicative`-`Monad` Proposal. Results so far have shown that the AMP changes break far more code than generalizing these signatures.
|
|
|
|
|
|
- Finally, once we make `Applicative` a superclass of `Monad`, `mapM` is basically **never** the right combinator for, well, anything. In particular requires far too tight a constraint (`Monad` rather than `Applicative`). Generalizing `mapM` to `Applicative`, runs afoul of several other issues stated below in the FAQ. On the other hand, going the 'wrong' direction and adding a monomorphized `traverse` breaks far more code, and makes the scoping problems even worse. Once you bring in a generalized `traverse`, it seems a very arbitrary choice to avoid bringing in the context necessary to define instances of the abstraction it uses.
|
|
- Finally, once we make `Applicative` a superclass of `Monad`, **`mapM` is basically **never** the right combinator** for, well, anything. In particular requires far too tight a constraint (`Monad` rather than `Applicative`). Generalizing `mapM` to `Applicative`, runs afoul of several other issues stated below in the FAQ. On the other hand, going the 'wrong' direction and adding a monomorphized `traverse` breaks far more code, and makes the scoping problems even worse. Once you bring in a generalized `traverse`, it seems a very arbitrary choice to avoid bringing in the context necessary to define instances of the abstraction it uses.
|
|
|
|
|
|
## Details
|
|
## Details
|
|
|
|
|
... | | ... | |