
I think it's a pretty clear tradeoff: if you write 'map f xs' you know
that 'xs' must be a list. If you write 'fmap f xs', you know only that
'xs' is a Functor. So you gain flexibility in when you can use 'fmap',
but you lose the local information you get from the more constrained
type of 'map'. The same argument applies when generalizing 'mapM' and
friends. I'm still in favor of generalizing the Prelude functions to
their Foldable/Traversable variants, but the downside is also clear to
me.
This seems like a perfect problem for an IDE to solve, by the way.
Erik
On Wed, Jun 18, 2014 at 2:49 PM, Jake McArthur
I find this argument against polymorphism baffling. Do I really have to state the benefits of parametricity here? Probably not. Most likely, there is some specific style of polymorphism in mind going unsaid here, such as ListLike type classes that have tons of methods and don't really have any meaningful laws. Is this the case, or do you *really* mean to argue that polymorphism makes code confusing? If the latter, would you mind explaining why?
Please forgive me for any weird autocorrections, typos, or bad grammar. This was written on my phone, which is hard to write and proofread on.
Richard Eisenberg wrote:
Having lots of polymorphism in the Prelude is great, but for two problems: 1) It's very confusing to novices. 2) In the case of using Control.Category definitions: kind-polymorphism is not portable
I wish to ignore (2) for now, as it's a smaller concern given that it affects only a portion of the proposed changes.
In my opinion, Richard missed the most important reason:
3) Gratuitous polymorphism makes code much less readable and much costlier to maintain, usually for almost no gain.
One of the biggest strengths of Haskell is semantic clarity. You can often look at a Haskell expression, recognize its type, and then immediately understand exactly what the expression is doing. That is immensely valuable, not only for writing code, but for maintaining and refactoring it over the lifetime of an application, often by people other than the original author.
Adding polymorphism to code is semantically lossy. One of the biggest disasters I have ever suffered in software engineering was when someone went through an entire fairly large code base and changed it to use a more polymorphic Prelude, then left the company. Adding the polymorphism was mostly mechanical, but undoing it required hours upon hours of puzzling out the meaning of the code, line by line.
And do not relegate Richard's point #1 to CS 101 at university. Most software maintenance is done by the developers with the least Haskell experience. And that is the largest cost of software over time.
Polymorphism can be very powerful, of course, and there are a lot of great tools and techniques that use it in various ways. But why force some particular polymorphic generalization down everyone's throat when the cost of enabling it if you want it is essentially zero?
If you use a different Prelude in a large project, or in many small projects, take a few minutes to set up your dev environment accordingly.
As a case in point: Yesod uses many GHC extensions universally, among them NoImplicitPrelude. These are all listed in the automatically-generated default cabal file; they never need to be typed, and never appear in any source files. There is a single extra line in each file which sets up the whole environment:
import Import
You can bind that to an editor key if you'd like. You can write scripts. There are packages on Haskell which automate a lot of things. Need I go on with these trivialities?
A lot of thought went into making it easy to use GHC extensions. Advanced and experienced developers who need them should have no trouble at all using them, including alternative Preludes.
That is not to say that no changes should be made to the Prelude. Now that people are using a number of different alternative Preludes more regularly, I would hope we can use that experience to make much-needed improvements to the default Prelude. But the principal design considerations should be simplicity, ease of use even for beginners, and semantic clarity of code using it.
Thanks, Yitz _______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries