Deprecate Foldable for Either

Edward Kmett ekmett at gmail.com
Fri Mar 24 14:22:41 UTC 2017


On Fri, Mar 24, 2017 at 5:17 AM, Anthony Clayden <
anthony_clayden at clear.net.nz> wrote:

> Thanks Edward for the comprehensive reply.
>
> Yes I know Foldable isn't powerful enough to construct.
> I wasn't seriously proposing that as the signature.
>
> I was pointing out that there were several value judgments
> in arriving at the FTP changes.


Sure. There are plenty of them to poke at. It was a big complicated messy
process. I have plenty of warts I would have liked to have shaved off, but
which we couldn't justify because of costs in other areas.


> > Neither Foldable f nor even Traversable f give you the
> > power to construct a new 'f' with different shape.
> >
>
> Exactly. So why even bother with
> concat (Right [...]); or concat (Just [...]) ?
>
> Because it was already there in Foldable along side a number of other
combinators that are already being generalized, and there was no good
reason to explicitly _exclude_ it.


> > concat is just a type restricted version of fold = foldMap
> > id provided basically for legacy compatibility.
> >
>
> OK. It's arbitrary but your justification is it was always
> arbitrary.
> FTP `concat` does the same as pre-FTP `concat`.
> "For legacy compatibility".
>

By that same argument:
> pre-FTP `length` wasn't even in Foldable.
> It was arbitrarily restricted to Lists.
> "For legacy compatibility" it should have stayed restricted
> to Lists.


length/null were generalized by a separate proposal to the FTP that
happened at the same time.

Nobody put forth such a proposal to generalize concat.

> The Foldable/Traversable proposal was to bring the
> > functions that already existed in base in Data.Foldable
> > into the Prelude and eliminate the monomorphic versions of
> > those combinators that made importing these more general
> > versions painful for users.
>
> `length` was never in Data.Foldable.
> There was never a more general version.
> You're blowing smoke.


No, I clarified that length/null generalization was a separate proposal,
just later in my reply.

I'm not assuming malice or dissimilation on your part. Please do not assume
it on mine

> A number of container types can use 'length' rather than
> > having to supply their own monomorphic size function.
> > Would 'length' have been better called 'size'?
>
> Yes! Or `cardinality`.


This runs afoul of the concern with taking new names from the Prelude which
was a *very* heavy concern at the time.

> That is another color the bikeshed could have been
> colored,
>
> That's an arrogant comment.
>

It wasn't dismissive. I was acknowledging that it was a different way
things could have gone. We decided against it because of other concerns.
There are lots of parts to this proposal that could have been concocted
differently. And lots of reasons to favor one variation on the theme over
another.


> > but it would have involved taking a fresh name, possibly
> in the
> > Prelude, and the name collisions of a common name with
> > existing code was considered to be the greater evil.
>
> Data.Set has `size`. It used to have `cardinality`, that was
> removed.
> OK not the Prelude, but close enough.
> `size` in Data.Set does exactly what `length` now does.




> > > `concat` and `length` should not be in Foldable.
> > > They should be in a separate class `Consable` (say),
> > > which would be a sub-class of Foldable.
> > >
> >
> > length being in such a class would mean that every author
> ..
>
> Would use a sensibly-named method (`size`) when they wanted
> the, er, size of a Foldable.
> And using `length` would document the code
> that they were applying to something that might be lengthy.
>



> > While working on the Foldable/Traversable Proposal what
> > happened was we found we needed to add a number of methods
> > to the Foldable class to avoid silent changes in the
> > semantics of existing Haskell programs. Some Foldable
> > combinators folded in different directions than their
> > monomorphic counterparts.
> >
>


> OK. How well communicated was that?
>
> It certainly couldn't have applied for `length`.
> The semantics of existing Haskell programs
> was that `length` worked for Lists.
> Only for Lists. Not Foldables in general.
>
>
I was conveying the process by which extra surprising members wound up in
Foldable at all, it doesn't directly apply to length and I was not trying
to say that it did. I was trying to say why we wound up with things like
sum, etc. in the class as a preamble to this next paragraph.


> > Along the way as we worked to fix these infelicities and
> > noticed that as a side-effect that this allowed Foldable
> > authors some power to execute these operations with better
> > asymptotics where possible for their containers. This nice
> > knock-on effect lets folks shed some names that they were
> > taking from the environment by using what Prelude offers.
> > During this process some folks noticed that length/null
> > fit into the scheme,
>
> Well those folks were wrong.
> What they should have noticed was that `size`/null fit.
>

size would have involved taking a fresh name.

> With the choices made all of the "mainstream" base modules
> > now have no name conflicts and can be imported
> > unqualified.
>
> Good. I am not criticising the FTP change in general,
> nor its objectives.
> But moving `length` from Prelude to Foldable
> isn't justified on those grounds.
> There wasn't previously a `size` (or equivalent) in
> Foldable.
> Why introduce it when there was no experience of
> "using for a decade" -- if that was the criterion?


"Using it for a decade" is a short hand for saying that the bulk of the
Foldable machinery had existed unchanged for a very long time. The proposal
wasn't initially intended to break all that much new ground.

Again length/null generalization was a separate proposal that happened at
the same time as FTP proper.

> Could we have named them flength (or size) and fnull so
> > that people had to ask for them explicitly and left
> > length/null alone? Yes. But it would have meant taking new
> > names from the Prelude or not re-exporting them from
> > Data.Foldable, and the AMP/FTP tried to very careful about
> > introducing any new names to the Prelude, and wanted users
> > to be able to supply instances without having to
> > explicitly import Data.Foldable.
> >
> > We were very dubious about the response we'd get
> > introducing new, untested, names to Prelude ...
>
> So you preferred to introduce new, unattested behaviour.
>
> `length` of an Either is unattested.
> `length` of a Maybe is unattested.
> That `length` of (1, 2) is 1 is unattested.
>
>
Yes, and sum in Prelude previously only worked on lists, etc.

Little existing code was broken by the change due to it being a strict
generalization. I can't say none, because length "foo" with
OverloadedStrings broke.

If I had it to do over again? I probably would have bitten the bullet and
had us take a fresh name. The outcry over fresh names turned out to be
smaller than intended and the outcry over length much larger. That isn't to
say I'm in a hurry to go through a second wave of breakage that churns the
waters twice to fix it at this point.


> So do you think it unsurprising asking for the length of a
> Maybe?
> Do you think it unsurprising that the length of (1, 2) is 1?
>

Yes. Once you understand what Foldable is and must mean. I even _use_ these
facts in concrete code that deliberately knows nothing about the
Foldable/Traversable container over which it is working, when that code is
put into a larger context.


> Note: "length", not "size".
>

The name could well have been size. It was a very near thing. We let the
hard rule about new unnecessary names shape the proposal very heavily. In
retrospect it may well have been better to accept some new names. This
prevented re-export of a lot of combinators in Data.Traversable as well.

However, by the time such discussion could have happened everything got
caught up in the drama of the massive up/down vote that was put up as a
last-ditch effort to stop the whole thing. No such nuanced discussion could
be heard through that noise.

I'm simply asking you to accept that there are some reasons on the other
side o the "length" vs. "cardinality" name choice and that there is a
reasonable scope for debate about which is the best to go with. The
alternative was very close to having been chosen, but wasn't for the
reasons I enumerated above and before.

I simply don't have a time machine, and the amount of pain involved in
thrashing this design _now_ would be rather disproportionate.

-Edward
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20170324/8422c0fd/attachment-0001.html>


More information about the Libraries mailing list