Polymorphism in the Prelude

Yitzchak Gale gale at sefer.org
Wed Jun 18 10:09:56 UTC 2014


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


More information about the Libraries mailing list