<div dir="ltr"><div>There are 4 different issues being brought up and conflated in this thread:</div><div><br></div><div>* Some people are complaining about the FTP entirely.<br></div><div>* Some people are complaining about adding instances they don't use.</div><div>* Some people are complaining about length.</div><div><div></div></div><div><br></div><div>Re: FTP as a whole</div><div><br></div><div>The FTP on the whole was and remains overwhelmingly popular. Frankly, the vast majority, not all, but most of the users complaining in this thread are the same people who were complaining about the FTP in the first place, rehashing precisely the same arguments. The FTP itself passed with an overwhelming 82% majority. If we can't act in the presence of that large of a public majority, when _can_ we act?</div><div><br></div><div>Re: length</div><div><br></div>We DID see these so called "wats" when we decided the FTP. It made a small, but noticeable, dip in the acceptance rate. Before the public reaction to `length (1,2) = 1` , FTP was running at about 84% acceptance. Afterward a series of posts pushed that issue, support dipped to 82% acceptance in aggregate, and about half of the votes came in afterwards. So that is still in 80% territory, even with the weird Data.List member story, and extra members of Foldable, and every thing that was thrown against the wall looking for something that would stick. Yes, these numbers aren't factored out on all axes, and yes information diffusal wasn't perfect, but it does show the relative scale of the issue against the FTP as a whole and measurably deflate the "we didn't know about this" argument.<div><div><br></div><div>There is, however, a good reason to consider length a member of the Foldable class. It avoids hoisting users on the dilemma of choosing between what is portable and what is fast.</div><div><br></div><div>length in the class can give you O(1) answers for most containers foldl' (+) 0 always pays O(n), getSum . foldMap Sum can be at best O(log n) but will typically be O(n). The latter two always work, the former can always be selected to be the optimal version for the container in question. If no memoization is provided and no sharing is possible it can turn into the foldl' form. If sharing is possible, then it can be the foldMap form. If a size is carried for things like Data.Set or Data.Map it can be the O(1) form.<br><br>That way if you want to, say, build a toVector function that takes any Foldable container, you can use the length to size the array and get it as quickly as possible, without having to balance the choice of 3 different implementations and always having to worry that you are calling the wrong one.<br></div><div><br></div><div>Given it to do over, I might have argued harder against the camp that generalized length and null, and instead pushed to add new names, however, that has to be balanced against the fact that we'd have another raft of complaints about new symbols being taken by the Prelude, and that there really, and the fact that there wasn't an objectively 'nice' set of names available and that sniping between folks who wanted 'length' vs. something like 'flength' would likely be just as vicious today.</div><div><br><div>APIs written after the addition of length/null to Foldable can elide exporting their own length/null definitions and just use the one from the Prelude, this reduces namespace pressure and the need for qualified imports. As 7.8 falls out of the support window of more and more packages it starts to become an option to drop existing null/size/length members for many data types, similar to how some container types simply use empty from Alternative as their empty value.</div><div><br></div></div><div>Re: instances you don't use</div><div><br></div><div>It has already been covered in this thread that the instances in question are the only possible instance for the types involved.</div><div><br></div><div>The alternative is splintering the ecosystem with different sets of orphans that provide precisely the same code. I, for one, would simply put an orphan instance package at or near the bottom of the set of packages I maintain and incur a dependency from day 1 were these somehow removed. I use them throughout the code and libraries I write, and do not want to deal with the ecosystem fragmentation. That would pretty much drag them back in for a large percentage of Haskell users. This is simply a practical effect of what I'd have to do to keep the packages I ship today working together.</div><div><div><br></div></div><div>We've already seen folks wrestling with where to get access to newer instances we've added to base on older GHCs, and had to consolidate many efforts on a base-orphans package. The direct reverse dependency list of this fairly new package is quite small,</div><div><br></div><div><a href="http://packdeps.haskellers.com/reverse/base-orphans">http://packdeps.haskellers.com/reverse/base-orphans</a><br></div><div><br></div><div>but the transitive dependency set is rather large. Getting it integrated has required a huge number of retrofitted version bounds on hackage and Herbert and Ryan have done yeoman's work fixing subtle build issue after build issue caused by conflicting orphan sets.</div><div><br></div><div>We'd wind up in a similar situation for these instances.</div><div><br>Removing these instances would accomplish little other than ecosystem fragmentation.</div></div><div><br></div><div>-Edward</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Feb 24, 2016 at 4:21 PM, Andreas Abel <span dir="ltr"><<a href="mailto:abela@chalmers.se" target="_blank">abela@chalmers.se</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Your example gives enough incentive to row back "the ship that has sailed" (to quote the favorite idiom on this list).<br>
<br>
It is very unfortunate that we did not see these Wats when we decided about FTP.<br>
<br>
The strong type checker of GHC is a major productivity tool for large code bases, and it would be a shame if we lost trust in it.<br>
<br>
My opinion as a GHC user is that deprecation of the features leading to these Wats should seriously be considered. (Of course, as I am not a developer, and I will not do the work involved, I cannot make a strong case.)<br>
<br>
--Andreas<div><div class="h5"><br>
<br>
On <a href="tel:24.02.2016%2020" value="+12402201620" target="_blank">24.02.2016 20</a>:15, Andrew Farmer wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Even this is problematic. Simplifying a bit, I managed to do this recently:<br>
<br>
module A (foo) where<br>
foo :: Bar -> [Int]<br>
foo = ... some hacky explicit recursion ...<br>
<br>
module B where<br>
import A<br>
bar :: Bar -> Int<br>
bar = ... expression containing 'sum . foo' ...<br>
<br>
Then I noticed I had some calls to 'maximum' on the result of 'foo',<br>
and wanted to just modify 'foo' to return the maximum value directly,<br>
along with the list:<br>
<br>
foo :: Bar -> ([Int], Int)<br>
foo = ...<br>
<br>
I went through and replaced the calls to 'maximum' with 'snd', but<br>
forgot about 'sum'. GHC happily compiled my code, but was now<br>
returning the maximum value instead of the sum of the values. This, of<br>
course, caused some other bit to behave strangely, and took some calls<br>
to 'trace' to figure out what was going on.<br>
<br>
There are lots of ways to avoid this... richer return type, use<br>
Data.OldList, write some tests, more conscientious search and replace<br>
refactoring... but the ease of refactoring code is one of the things I<br>
love about Haskell. Normally, I can just change a type signature and<br>
hit :r in ghci and start fixing type errors, confident that I've<br>
covered my bases when it eventually compiles. Now I feel like I can't<br>
rely on the typechecker as much.<br>
<br>
And yes, explaining the difference between maximum (2,1) and maximum<br>
[2,1] to a beginner is a pain, and really weakens your claim that the<br>
type system will prevent a lot of bugs in your code (at least in the<br>
beginner's eyes).<br>
<br>
I don't know what the solution is... the instances are already there<br>
and a lot of code relies on them, but I do feel like they fall on the<br>
wrong side of the expressivity/safety line.<br>
<br>
On Wed, Feb 24, 2016 at 1:04 AM, Simon Peyton Jones<br>
<<a href="mailto:simonpj@microsoft.com" target="_blank">simonpj@microsoft.com</a>> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
| So, my advice is to use tuples only for very short-lived data, like<br>
| returning multiple results from a function.<br>
<br>
I strongly agree, for all the reasons Andreas mentions. GHC's source code has *lots* of data types that are isomorphic to tuples. Crucial!<br>
<br>
Simon<br>
<br>
| -----Original Message-----<br>
| From: Libraries [mailto:<a href="mailto:libraries-bounces@haskell.org" target="_blank">libraries-bounces@haskell.org</a>] On Behalf Of<br>
| Andreas Abel<br>
| Sent: 24 February 2016 08:58<br>
| To: Nathan Bouscal <<a href="mailto:nbouscal@gmail.com" target="_blank">nbouscal@gmail.com</a>>; <a href="mailto:libraries@haskell.org" target="_blank">libraries@haskell.org</a><br>
| Subject: Re: Haskell Foldable Wats<br>
|<br>
| In my n+1 years of participating in a 100kloc Haskell project, I<br>
| learned that programming with the "categorical" data type building<br>
| blocks "Either" and tuples leads to code that is hard to read and<br>
| maintain. It is tempting to use a pair<br>
|<br>
| type QNamed a = (QName, a)<br>
|<br>
| instead of a hand-rolled data type<br>
|<br>
| data QNamed a = QNamed { qname :: QName, qnamedThing :: a }<br>
|<br>
| since with pairs, I get lots of operations for free, and even more if I<br>
| use Functor and Traversable, it seems. However, in the long run, if I<br>
| come back after months to my original code, or even worse, to someone<br>
| else's code, I dearly pay for this:<br>
|<br>
| 1. Harder to read the code, as I may only see the non-telling "fst"<br>
| and "snd" instead of the semantics-loaden "qname" and "qnamedThing".<br>
|<br>
| 2. Lack of code exploration facilities like grep and tags. I can<br>
| grep for "QName" and "qname", but grepping for "," and "fst" returns<br>
| lots of irrelevant locations.<br>
|<br>
| 3. Non-telling error messages.<br>
|<br>
| And all the arguments of using newtypes over type synonyms apply here<br>
| as well.<br>
|<br>
| So, my advice is to use tuples only for very short-lived data, like<br>
| returning multiple results from a function. I am speaking here of<br>
| Haskell as a language for software development, not of Haskell as a<br>
| realization of category theory.<br>
|<br>
| For getting a broader acceptance of Haskell as a language for software<br>
| development, Foldable on tuples is not helpful.<br>
|<br>
| And yes, if I was new to Haskell and learned the GHCI thinks that<br>
|<br>
| minimum (1,2) == 1<br>
|<br>
| then I would advice GHCI to visit some mental institution to get its<br>
| delusions fixed.<br>
|<br>
| --Andreas<br>
|<br>
|<br>
| On 23.02.2016 18:29, Nathan Bouscal wrote:<br>
| > Sorry, poor quoting on my part. I was attempting to reply to<br>
| Andreas's<br>
| > earlier points:<br>
| ><br>
| > >> Use of tuples is highly discourageable…<br>
| >>>I see no point in Functor or Foldable for tuples.<br>
| ><br>
| > On Tue, Feb 23, 2016 at 5:18 PM, Mario Blažević <<a href="mailto:mblazevic@stilo.com" target="_blank">mblazevic@stilo.com</a><br>
| > <mailto:<a href="mailto:mblazevic@stilo.com" target="_blank">mblazevic@stilo.com</a>>> wrote:<br>
| ><br>
| > On 16-02-23 11:23 AM, Nathan Bouscal wrote:<br>
| ><br>
| > It's a bit bold to simultaneously say "Nobody should use this<br>
| > type," and<br>
| > also "If you use this type, you should do it this way." If<br>
| you think<br>
| > that it's bad practice to use tuples, that's a fine and<br>
| respectable<br>
| > opinion, but at that point you should start being a bit more<br>
| > wary about<br>
| > telling those who think otherwise /how/ they should use them.<br>
| ><br>
| ><br>
| > I believe he was referring to lists, not to tuples.<br>
| There<br>
| > were few Prelude functions limited to tuples before FTP, and<br>
| those<br>
| > haven't changed.<br>
| ><br>
| ><br>
| ><br>
| > On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek<br>
| > <<a href="mailto:marcin.jan.mrotek@gmail.com" target="_blank">marcin.jan.mrotek@gmail.com</a><br>
| > <mailto:<a href="mailto:marcin.jan.mrotek@gmail.com" target="_blank">marcin.jan.mrotek@gmail.com</a>><br>
| > <mailto:<a href="mailto:marcin.jan.mrotek@gmail.com" target="_blank">marcin.jan.mrotek@gmail.com</a><br>
| > <mailto:<a href="mailto:marcin.jan.mrotek@gmail.com" target="_blank">marcin.jan.mrotek@gmail.com</a>>>> wrote:<br>
| ><br>
| > > I can assure you that Andreas is not delusional<br>
| ><br>
| > I didn't say that. I was referring to his response to my<br>
| > post, that<br>
| > "Some delusions have very sophisticated explanations."<br>
| ><br>
| > > You have to show good taste or you'll end up with a<br>
| mess<br>
| > that might be logically consistent, but unpleasant to use.<br>
| ><br>
| > This is entirely subjective, and frankly I don't think<br>
| that<br>
| > post-FTP<br>
| > Haskell is a "mess" or is "unpleasant to use". If<br>
| anything,<br>
| > it became<br>
| > more useful to me, because now Prelude functions aren't<br>
| > limited to the<br>
| > one data structure I almost never use.<br>
| ><br>
| > Best regards,<br>
| > Marcin Mrotek<br>
| ><br>
| ><br>
| > _______________________________________________<br>
| > Libraries mailing list<br>
| > <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a> <mailto:<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a>><br>
| ><br>
| ><br>
| <a href="https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h" rel="noreferrer" target="_blank">https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h</a><br>
| > <a href="http://askell.org" rel="noreferrer" target="_blank">askell.org</a>%2fcgi-<br>
| bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs<br>
| ><br>
| imonpj%<a href="http://40064d.mgd.microsoft.com" rel="noreferrer" target="_blank">40064d.mgd.microsoft.com</a>%7ce4033ee9a03a42eaa97108d33cf89187%7c7<br>
| ><br>
| 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf<br>
| > xosR3yBA09CQaZs%3d<br>
| ><br>
| ><br>
| ><br>
| ><br>
| > _______________________________________________<br>
| > Libraries mailing list<br>
| > <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
| ><br>
| <a href="https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h" rel="noreferrer" target="_blank">https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h</a><br>
| > <a href="http://askell.org" rel="noreferrer" target="_blank">askell.org</a>%2fcgi-<br>
| bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs<br>
| ><br>
| imonpj%<a href="http://40064d.mgd.microsoft.com" rel="noreferrer" target="_blank">40064d.mgd.microsoft.com</a>%7ce4033ee9a03a42eaa97108d33cf89187%7c7<br>
| ><br>
| 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf<br>
| > xosR3yBA09CQaZs%3d<br>
| ><br>
|<br>
|<br>
| --<br>
| Andreas Abel <>< Du bist der geliebte Mensch.<br>
|<br>
| Department of Computer Science and Engineering Chalmers and Gothenburg<br>
| University, Sweden<br>
|<br>
| <a href="mailto:andreas.abel@gu.se" target="_blank">andreas.abel@gu.se</a><br>
| <a href="https://na01.safelinks.protection.outlook.com/?url=http:%2f%2fwww2.tcs" rel="noreferrer" target="_blank">https://na01.safelinks.protection.outlook.com/?url=http:%2f%2fwww2.tcs</a>.<br>
| <a href="http://ifi.lmu.de" rel="noreferrer" target="_blank">ifi.lmu.de</a>%2f~abel%2f&data=01%7C01%7Csimonpj%<a href="http://40064d.mgd.microsoft.com" rel="noreferrer" target="_blank">40064d.mgd.microsoft.com</a>%7<br>
| Ce4033ee9a03a42eaa97108d33cf89187%7C72f988bf86f141af91ab2d7cd011db47%7C<br>
| 1&sdata=kvwlaXofxhQV2ZCD9K%2bemtG4S9oCujNYhn1IXTnSZtc%3d<br>
| _______________________________________________<br>
| Libraries mailing list<br>
| <a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
| <a href="https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.ha" rel="noreferrer" target="_blank">https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.ha</a><br>
| <a href="http://skell.org" rel="noreferrer" target="_blank">skell.org</a>%2fcgi-<br>
| bin%2fmailman%2flistinfo%2flibraries%0a&data=01%7c01%7csimonpj%40064d.m<br>
| <a href="http://gd.microsoft.com" rel="noreferrer" target="_blank">gd.microsoft.com</a>%7ce4033ee9a03a42eaa97108d33cf89187%7c72f988bf86f141af9<br>
| 1ab2d7cd011db47%7c1&sdata=gMTA2SOTm1seAHbvHPWnsDjAa7y1gAS681kW6YUx1mQ%3<br>
| d<br>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</blockquote></blockquote>
<br>
-- <br>
Andreas Abel <>< Du bist der geliebte Mensch.<br>
<br>
Department of Computer Science and Engineering<br>
Chalmers and Gothenburg University, Sweden<br>
<br>
<a href="mailto:andreas.abel@gu.se" target="_blank">andreas.abel@gu.se</a><br>
</div></div><a href="http://www2.tcs.ifi.lmu.de/~abel/" rel="noreferrer" target="_blank">http://www2.tcs.ifi.lmu.de/~abel/</a><div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
Libraries mailing list<br>
<a href="mailto:Libraries@haskell.org" target="_blank">Libraries@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries</a><br>
</div></div></blockquote></div><br></div>