Deprecate Foldable for Either

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
76 messages Options
1234
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Ivan Lazar Miljenovic
On 3 March 2017 at 06:28, David Feuer <[hidden email]> wrote:
> Yes. That is an excellent plan. I'd love to call it Data.List, but others
> will disagree.

Same here.

I wasn't that happy with the FTP proposal when it first came up due to
potential confusions (primarily due to naming conventions like
"length"), but now that it's done we shouldn't go back.

So -1 on the proposal.

>
> On Mar 2, 2017 2:17 PM, "Andreas Abel" <[hidden email]> wrote:
>>
>> We could have a module
>>
>>   Data.List.ReallyJustListsAndNotSomeThingMoreGeneric
>>
>> which implements concat and friends just for lists and could be imported
>> if one wants to have the list operations.  Currently,
>>
>>   import qualified Data.List as List
>>
>> does not give on the list operations as e.g.
>>
>>   List.concat
>>
>> but the generic ones.
>>
>> See also http://ghc.haskell.org/trac/ghc/ticket/13345
>>
>> On 02.03.2017 20:02, Edward Kmett wrote:
>>>
>>>
>>> On Thu, Mar 2, 2017 at 11:59 AM, Andreas Abel <[hidden email]
>>> <mailto:[hidden email]>> wrote:
>>>
>>>     Ok, Foldable is a formal condition for Traversable, but not actually
>>>     used in the implementation of Traversable Either.  This still leaves
>>>     room to implement Foldable for Either by
>>>
>>>       instance Foldable (Either a) where
>>>         foldMap _ _ = error "Folding Either?  Naah, I don't think this
>>>     is a good idea."
>>>
>>>
>>> This would change the semantic of every
>>>
>>> forM_ myeither $ \i -> ....
>>>
>>> in existing code to silent errors.
>>>
>>> Hell no.
>>>
>>> -Edward
>>>
>>>
>>>     On 02.03.2017 17:48, David Feuer wrote:
>>>
>>>         The problem is that we'd then lose the perfectly good Traversable
>>>         instance, which would be sad.
>>>
>>>         On Mar 2, 2017 11:23 AM, "Andreas Abel" <[hidden email]
>>>         <mailto:[hidden email]>
>>>         <mailto:[hidden email]
>>>         <mailto:[hidden email]>>> wrote:
>>>
>>>             Today a student came to me wondering why a certain function
>>>         produced
>>>             a regular result, where he had expected an error.  Turned
>>>         out he had
>>>             used `concat`, but not on a lists of lists as he had
>>>         thought, but on
>>>             a lists of `Either a [b]`.
>>>
>>>             With the Foldable instance for Either, which considers
>>>         Either a b to
>>>             be a container of 0-1 elements of b, errors are happily
>>>         swallowed.
>>>
>>>             I think this instance is harmful and should be deprecated
>>>         (and later
>>>             removed) from base.
>>>
>>>             There are similarly pointless Foldable instances as well.
>>>
>>>             See a discussion one year ago, which was heated, but had no
>>>             consequences.
>>>
>>>
>>>
>>> https://mail.haskell.org/pipermail/libraries/2016-February/026678.html
>>>
>>> <https://mail.haskell.org/pipermail/libraries/2016-February/026678.html>
>>>
>>>
>>> <https://mail.haskell.org/pipermail/libraries/2016-February/026678.html
>>>
>>> <https://mail.haskell.org/pipermail/libraries/2016-February/026678.html>>
>>>
>>>
>>>             --
>>>             Andreas Abel  <><      Du bist der geliebte Mensch.
>>>
>>>             Department of Computer Science and Engineering
>>>             Chalmers and Gothenburg University, Sweden
>>>
>>>             [hidden email] <mailto:[hidden email]>
>>>         <mailto:[hidden email] <mailto:[hidden email]>>
>>>             http://www.cse.chalmers.se/~abela/
>>>         <http://www.cse.chalmers.se/~abela/>
>>>         <http://www.cse.chalmers.se/~abela/
>>>         <http://www.cse.chalmers.se/~abela/>>
>>>             _______________________________________________
>>>             Libraries mailing list
>>>             [hidden email] <mailto:[hidden email]>
>>>         <mailto:[hidden email] <mailto:[hidden email]>>
>>>             http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>         <http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries>
>>>             <http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>         <http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries>>
>>>
>>>
>>>
>>>     --
>>>     Andreas Abel  <><      Du bist der geliebte Mensch.
>>>
>>>     Department of Computer Science and Engineering
>>>     Chalmers and Gothenburg University, Sweden
>>>
>>>     [hidden email] <mailto:[hidden email]>
>>>     http://www.cse.chalmers.se/~abela/
>>> <http://www.cse.chalmers.se/~abela/>
>>>     _______________________________________________
>>>     Libraries mailing list
>>>     [hidden email] <mailto:[hidden email]>
>>>     http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>     <http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries>
>>>
>>>
>>
>>
>> --
>> Andreas Abel  <><      Du bist der geliebte Mensch.
>>
>> Department of Computer Science and Engineering
>> Chalmers and Gothenburg University, Sweden
>>
>> [hidden email]
>> http://www.cse.chalmers.se/~abela/
>
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>



--
Ivan Lazar Miljenovic
[hidden email]
http://IvanMiljenovic.wordpress.com
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Oleg Grenrus
In reply to this post by Francesco Ariis
Anecdotally, today I wrote `foldMap toList`, to use as `Maybe (NonEmpty
a) -> [a]`.
Also I rely heavily in lens-based code on the `folded :: Fold (Maybe a) a`.

So :-1: for me.

OTOH :+1: for using non-default preludes for teaching.

- Oleg

On 02.03.2017 19:35, Francesco Ariis wrote:

> On Thu, Mar 02, 2017 at 05:19:26PM +0000, Oliver Charles wrote:
>> Personally, I think it would be a shame to lose foldMap on EIther. I
>> frequently foldMap over Maybe values (where mempty is suitable in case of
>> "failure"), and I can certainly see myself doing the same thing with Either.
> I am not trying to be polemic, just to see where the community
> stands: regarding Either/Maybe: do you have use cases for length
> (sum) too?
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

amindfv
We had a very similar discussion this time last year (https://mail.haskell.org/pipermail/libraries/2016-February/026678.html), with many people on both sides of the issue. There wasn't enough agreement reached to change the status quo.

I'll just repeat two things from that discussion:
  - This is *not* just an issue of "beginners may be confused": Andrew Farmer describes encountering what I think is the most disconcerting part of having these instances: you can no longer have confidence in the process of change-the-type-then-just-fix-the-type-errors: https://mail.haskell.org/pipermail/libraries/2016-February/026782.html

  - The tl;dr of my argument last time: "Part of the power of a type system is which program it rejects, and I'm arguing we're cluttering the space of valid programs."

The last time this was discussed, we planned to implement a flag to forbid certain instances. Has anyone taken that up?

Tom


On Thu, Mar 2, 2017 at 5:35 PM, Oleg Grenrus <[hidden email]> wrote:
Anecdotally, today I wrote `foldMap toList`, to use as `Maybe (NonEmpty
a) -> [a]`.
Also I rely heavily in lens-based code on the `folded :: Fold (Maybe a) a`.

So :-1: for me.

OTOH :+1: for using non-default preludes for teaching.

- Oleg

On 02.03.2017 19:35, Francesco Ariis wrote:
> On Thu, Mar 02, 2017 at 05:19:26PM +0000, Oliver Charles wrote:
>> Personally, I think it would be a shame to lose foldMap on EIther. I
>> frequently foldMap over Maybe values (where mempty is suitable in case of
>> "failure"), and I can certainly see myself doing the same thing with Either.
> I am not trying to be polemic, just to see where the community
> stands: regarding Either/Maybe: do you have use cases for length
> (sum) too?
>
> ______________________________
_________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



______________________________
_________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

lennart spitzner
In reply to this post by Andreas Abel
(This is a reply to this topic in general, not specific to Andreas' suggestion. Also, this argument should generalize well to other Foldable methods/instances.)


I don't like the behaviour you observe either. Still the analysis/proposal ignores half of the cause - this has been (at least indirectly) pointed out repeatedly in this and past threads already, but I'd like to state it clearly because people also repeatedly seem to ignore the fact.

In order for the expression `concat (xs :: [Either a [b]])` to be accepted, two things need to be the case: Firstly the concat in scope needs to be one that is expressed in terms of Foldable. Secondly there needs to be a Foldable instance for Either. (Technically it needs to be in scope too, but the difference matters only if the instance was an orphan, but I'll assume for now that "orphanization" is not the solution.) The first reason is of course connected to the design of the default Prelude - which I suppose was responsible for getting the specific `concat` into scope here.

We could change either of these causes: Change what is exported from Prelude or Remove the instance (and both are breaking compatibility). As a consequence, I find going from "uses of concat(/length/maximum/..) may be confusing/cause bugs" to "we need to remove the instance" to be a weak conclusion.

Further, if don't overlook something, removing an instance (or removing a particular method from an instance) always would create at least as much trouble as changing what is exported from the Prelude would, as the types of concat/length/maximum/.. would necessarily change as a consequence of the former. So to all those arguing in favour of removing methods/instances: What does removing/prohibiting instances give in addition to a change to the type of concat(/length/..) as included unqualified in the default Prelude? In this direction, I have not seen any convincing arguments. (And sorry, I have not read all messages in the previous discussions - it was a bit too much to read for too little general enlightenment.)


(My solution is to use custom Preludes for personal projects with exclusively qualified imports, e.g. List.length :: [a] -> Int and Foldable.length :: Foldable t => t a -> Int. Works well, but I see the issues that a custom Prelude is yet another hurdle for beginners.)

-- lennart



On 02/03/17 17:22, Andreas Abel wrote:

> Today a student came to me wondering why a certain function produced a regular result, where he had expected an error.  Turned out he had used `concat`, but not on a lists of lists as he had thought, but on a lists of `Either a [b]`.
>
> With the Foldable instance for Either, which considers Either a b to be a container of 0-1 elements of b, errors are happily swallowed.
>
> I think this instance is harmful and should be deprecated (and later removed) from base.
>
> There are similarly pointless Foldable instances as well.
>
> See a discussion one year ago, which was heated, but had no consequences.
>
> https://mail.haskell.org/pipermail/libraries/2016-February/026678.html
>
>

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

David Feuer
Yes. I completely agree that the goal of being able to import
Data.Foldable unqualified was the wrong goal from the start. That goal
is sensible for Data.Traversable, I think, since Traversable has very
few methods and since instances are sufficiently constrained to
prevent *most* of these problems. But it falls apart for
Data.Foldable, which is too "wild". I for one would be quite happy to
banish the lion's share of Foldable operations back to Data.Foldable,
so the Prelude would re-export only  Data.Foldable (Foldable
(foldMap)), and Data.List would export only list-specific functions.

On Fri, Mar 3, 2017 at 10:32 AM, lennart spitzner
<[hidden email]> wrote:

> (This is a reply to this topic in general, not specific to Andreas' suggestion. Also, this argument should generalize well to other Foldable methods/instances.)
>
>
> I don't like the behaviour you observe either. Still the analysis/proposal ignores half of the cause - this has been (at least indirectly) pointed out repeatedly in this and past threads already, but I'd like to state it clearly because people also repeatedly seem to ignore the fact.
>
> In order for the expression `concat (xs :: [Either a [b]])` to be accepted, two things need to be the case: Firstly the concat in scope needs to be one that is expressed in terms of Foldable. Secondly there needs to be a Foldable instance for Either. (Technically it needs to be in scope too, but the difference matters only if the instance was an orphan, but I'll assume for now that "orphanization" is not the solution.) The first reason is of course connected to the design of the default Prelude - which I suppose was responsible for getting the specific `concat` into scope here.
>
> We could change either of these causes: Change what is exported from Prelude or Remove the instance (and both are breaking compatibility). As a consequence, I find going from "uses of concat(/length/maximum/..) may be confusing/cause bugs" to "we need to remove the instance" to be a weak conclusion.
>
> Further, if don't overlook something, removing an instance (or removing a particular method from an instance) always would create at least as much trouble as changing what is exported from the Prelude would, as the types of concat/length/maximum/.. would necessarily change as a consequence of the former. So to all those arguing in favour of removing methods/instances: What does removing/prohibiting instances give in addition to a change to the type of concat(/length/..) as included unqualified in the default Prelude? In this direction, I have not seen any convincing arguments. (And sorry, I have not read all messages in the previous discussions - it was a bit too much to read for too little general enlightenment.)
>
>
> (My solution is to use custom Preludes for personal projects with exclusively qualified imports, e.g. List.length :: [a] -> Int and Foldable.length :: Foldable t => t a -> Int. Works well, but I see the issues that a custom Prelude is yet another hurdle for beginners.)
>
> -- lennart
>
>
>
> On 02/03/17 17:22, Andreas Abel wrote:
>> Today a student came to me wondering why a certain function produced a regular result, where he had expected an error.  Turned out he had used `concat`, but not on a lists of lists as he had thought, but on a lists of `Either a [b]`.
>>
>> With the Foldable instance for Either, which considers Either a b to be a container of 0-1 elements of b, errors are happily swallowed.
>>
>> I think this instance is harmful and should be deprecated (and later removed) from base.
>>
>> There are similarly pointless Foldable instances as well.
>>
>> See a discussion one year ago, which was heated, but had no consequences.
>>
>> https://mail.haskell.org/pipermail/libraries/2016-February/026678.html
>>
>>
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Kris Nuttycombe
In reply to this post by lennart spitzner

On Fri, Mar 3, 2017 at 8:32 AM, lennart spitzner <[hidden email]> wrote:
(This is a reply to this topic in general, not specific to Andreas' suggestion. Also, this argument should generalize well to other Foldable methods/instances.)

I don't like the behaviour you observe either. Still the analysis/proposal ignores half of the cause - this has been (at least indirectly) pointed out repeatedly in this and past threads already, but I'd like to state it clearly because people also repeatedly seem to ignore the fact.

In order for the expression `concat (xs :: [Either a [b]])` to be accepted, two things need to be the case: Firstly the concat in scope needs to be one that is expressed in terms of Foldable. Secondly there needs to be a Foldable instance for Either. (Technically it needs to be in scope too, but the difference matters only if the instance was an orphan, but I'll assume for now that "orphanization" is not the solution.) The first reason is of course connected to the design of the default Prelude - which I suppose was responsible for getting the specific `concat` into scope here.

I think there's an even more fundamental cause that has been stated implicitly, but not explicitly, in this discussion. Some of us have been continuing the discussion on Twitter, and I want to recapitulate the essential points from that exchange here.

In Haskell, Either is the right-biased polymorphic 2-ary sum type; similarly, '(,)' is the snd-biased polymorphic 2-ary product type. These biases are, from my perspective at least, a historical artifact that we're kind of stuck with. @EyalL on Twitter correctly points out that in retrospect, having Either be unbiased, and having a second, biased type with 'Terminate' and 'Continue' constructors might have been the better choice. However, we depend uncritically upon the bias of Either all the time when we >>= it, so objecting to this bias propagating to its being Foldable is inconsistent. I personally depend upon the bias of (,) much less frequently, but I don't assume that gives me any claim to influence others' use of this bias. If, in days of yore, the semantics of Either and (,) had been defined to be unbiased, and separate biased versions been defined, these arguments might have been avoided, and we'd probably see relatively little use of the unbiased Either and predominant use of the unbiased (,). Maybe a new language will some day make this choice with the benefit of hindsight upon the Haskell community's struggles.

Kris

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Richard Eisenberg-4
In reply to this post by lennart spitzner
I think one of the reasons this debate continues to crop up is that there is a fundamental tension in the design of Haskell:

Haskell strives to be
  a) richly typed, leading to "if it compiles, it works!"
  b) as general as possible, leading to wide applicability of polymorphic functions

These two laudable goals work against each other. In many instances, we will have to choose between them, and different people will have different judgment calls.

Perhaps it would bring some of these issues into starker relief if we consider the following instance:

> instance Num Bool where
>   (+) = (||)
>   a - b = not (a == b)
>   (*) = (&&)
>
>   abs = id
>   signum = id
>
>   negate = not
>
>   fromInteger 0 = False
>   fromInteger _ = True

This instance is not wholly specious: it's based on well-studied Boolean algebra (at least, the definitions for (+) and (*) are), and it obeys the one documented law for Num instances. It's not fully canonical in the way that, say, the `Foldable ((,) a)` instance is, but not all instances in base are fully canonical, anyway. I venture to say it would find use in practice. But, at the same time, I imagine most Haskellers would find this instance distasteful, as it is too much in service of goal (b) and strays too far from goal (a).

About the current debate: my own tendency is to lean toward (a), but the community (now that we have FTP) appears to be drifting more toward (b). Though I see its merits -- and I take advantage of it in my own code -- I've never liked FTP and probably never will. That said, changing Either's Foldable instance to use `error` seems like unnecessary code breakage and goes against the apparent design principles at work in `base`.

But, to me, the most important aspect of a debate such as this one is that there is no one right answer, just differing viewpoints, scattered along a spectrum from (a) to (b) (surely among many other axes). We all must live with one `base`, so we all have skin in the game and the debate may be worth continuing. I just hesitate to call any comment I've seen here "wrong".

Richard

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Kris Nuttycombe


On Fri, Mar 3, 2017 at 10:37 AM, Richard Eisenberg <[hidden email]> wrote:
I think one of the reasons this debate continues to crop up is that there is a fundamental tension in the design of Haskell:

Haskell strives to be
  a) richly typed, leading to "if it compiles, it works!"
  b) as general as possible, leading to wide applicability of polymorphic functions

These two laudable goals work against each other. In many instances, we will have to choose between them, and different people will have different judgment calls.

This is an interesting assertion; I don't believe that these goals work against one another at all. In fact, I find that (b) leads to "if it compiles, it works" much more often than not. John De Goes goes into depth on this principle here: http://degoes.net/articles/insufficiently-polymorphic where he points out "Monomorphic code is much more likely to be incorrect than polymorphic code, because for every type signature, there are many more possible implementations.".

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Richard Eisenberg-4

On Mar 3, 2017, at 12:45 PM, Kris Nuttycombe <[hidden email]> wrote:

This is an interesting assertion; I don't believe that these goals work against one another at all. In fact, I find that (b) leads to "if it compiles, it works" much more often than not. John De Goes goes into depth on this principle here: http://degoes.net/articles/insufficiently-polymorphic where he points out "Monomorphic code is much more likely to be incorrect than polymorphic code, because for every type signature, there are many more possible implementations.".

Ah -- very good point. This is true for the *implementation* of a polymorphic function, where a polymorphic type signature beautifully restricts what the function can do. But it is not true for monomorphic *uses* of a polymorphic function, where the generality can lead to an unexpected instance selection and thus runtime behavior.

Richard

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Kris Nuttycombe
On Fri, Mar 3, 2017 at 10:48 AM, Richard Eisenberg <[hidden email]> wrote:

On Mar 3, 2017, at 12:45 PM, Kris Nuttycombe <[hidden email]> wrote:

This is an interesting assertion; I don't believe that these goals work against one another at all. In fact, I find that (b) leads to "if it compiles, it works" much more often than not. John De Goes goes into depth on this principle here: http://degoes.net/articles/insufficiently-polymorphic where he points out "Monomorphic code is much more likely to be incorrect than polymorphic code, because for every type signature, there are many more possible implementations.".

Ah -- very good point. This is true for the *implementation* of a polymorphic function, where a polymorphic type signature beautifully restricts what the function can do. But it is not true for monomorphic *uses* of a polymorphic function, where the generality can lead to an unexpected instance selection and thus runtime behavior.

I guess that, in the limit, this is why my code has been progressively mutating to a style in which I only define data structures for the purpose of being able to easily generate classy lenses/prisms into their components/inhabitants. I now generally find concrete types more restrictive and error-prone than I care for.

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Andreas Abel-2
In reply to this post by Richard Eisenberg-4
 > But it is not true for ...
 > *uses* of a polymorphic function

Which is confirmed by the present casus.  The new highly polymorphic
concat is a versatile weapon to shoot yourself in the foot.
(However, the weapon designer can sleep even more soundly now in the
confidence that his product does not malfunction.)

Anyway, for what it's worth, I retreat my proposal (or "proposal").
Sh*t has happened.

A monomorphic List library would make sense, though.

On 03.03.2017 18:48, Richard Eisenberg wrote:

>
>> On Mar 3, 2017, at 12:45 PM, Kris Nuttycombe
>> <[hidden email] <mailto:[hidden email]>> wrote:
>>
>> This is an interesting assertion; I don't believe that these goals
>> work against one another at all. In fact, I find that (b) leads to "if
>> it compiles, it works" much more often than not. John De Goes goes
>> into depth on this principle
>> here: http://degoes.net/articles/insufficiently-polymorphic where he
>> points out "Monomorphic code is much more likely to be incorrect than
>> polymorphic code, because for every type signature, there are many
>> more possible implementations.".
>
> Ah -- very good point. This is true for the *implementation* of a
> polymorphic function, where a polymorphic type signature beautifully
> restricts what the function can do. But it is not true for monomorphic
> *uses* of a polymorphic function, where the generality can lead to an
> unexpected instance selection and thus runtime behavior.
>
> Richard
>
>
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>


--
Andreas Abel  <><      Du bist der geliebte Mensch.

Department of Computer Science and Engineering
Chalmers and Gothenburg University, Sweden

[hidden email]
http://www.cse.chalmers.se/~abela/
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

David Menendez-2
In reply to this post by Kris Nuttycombe
On Thu, Mar 2, 2017 at 1:12 PM, Kris Nuttycombe <[hidden email]> wrote:
As with all of these discussions, the point of having Either be Foldable is not that you're going to call foldMap on an Either value directly. Instead, it is that you be able to pass whatever sort of foldable thing you choose (which Either certainly is) to a function that only requires foldability of its input. By removing or damaging the Foldable instance for Either, you don't simply prevent people from encountering problems that will be resolved the first time they test their software - you make a whole universe of nicely polymorphic functions unavailable for them to use without additional effort.

Not just polymorphic functions. Many higher-order type constructors have Foldable instances based on their parameters. For example,

data Cofree f a = a :< f (Cofree f a)

instance Foldable f => Foldable (Cofree f a) where
foldMap f (a :< as) = f a <> foldMap (foldMap f) as

Without the instance for Either b, we lose the instances for Cofree (Either b) and Cofree (Compose [] (Either b)), both of which seem reasonable and useful.

In particular, the idea that one should make all such functions partial by throwing an error is repugnant.

Yes, that seems like the worst possible solution. Better would be some way to give a warning when calling an overloaded function at a particular type.

--

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

amindfv
In reply to this post by David Feuer
I'd also support this.

> El 3 mar 2017, a las 11:23, David Feuer <[hidden email]> escribió:
>
> Yes. I completely agree that the goal of being able to import
> Data.Foldable unqualified was the wrong goal from the start. That goal
> is sensible for Data.Traversable, I think, since Traversable has very
> few methods and since instances are sufficiently constrained to
> prevent *most* of these problems. But it falls apart for
> Data.Foldable, which is too "wild". I for one would be quite happy to
> banish the lion's share of Foldable operations back to Data.Foldable,
> so the Prelude would re-export only  Data.Foldable (Foldable
> (foldMap)), and Data.List would export only list-specific functions.
>
> On Fri, Mar 3, 2017 at 10:32 AM, lennart spitzner
> <[hidden email]> wrote:
>> (This is a reply to this topic in general, not specific to Andreas' suggestion. Also, this argument should generalize well to other Foldable methods/instances.)
>>
>>
>> I don't like the behaviour you observe either. Still the analysis/proposal ignores half of the cause - this has been (at least indirectly) pointed out repeatedly in this and past threads already, but I'd like to state it clearly because people also repeatedly seem to ignore the fact.
>>
>> In order for the expression `concat (xs :: [Either a [b]])` to be accepted, two things need to be the case: Firstly the concat in scope needs to be one that is expressed in terms of Foldable. Secondly there needs to be a Foldable instance for Either. (Technically it needs to be in scope too, but the difference matters only if the instance was an orphan, but I'll assume for now that "orphanization" is not the solution.) The first reason is of course connected to the design of the default Prelude - which I suppose was responsible for getting the specific `concat` into scope here.
>>
>> We could change either of these causes: Change what is exported from Prelude or Remove the instance (and both are breaking compatibility). As a consequence, I find going from "uses of concat(/length/maximum/..) may be confusing/cause bugs" to "we need to remove the instance" to be a weak conclusion.
>>
>> Further, if don't overlook something, removing an instance (or removing a particular method from an instance) always would create at least as much trouble as changing what is exported from the Prelude would, as the types of concat/length/maximum/.. would necessarily change as a consequence of the former. So to all those arguing in favour of removing methods/instances: What does removing/prohibiting instances give in addition to a change to the type of concat(/length/..) as included unqualified in the default Prelude? In this direction, I have not seen any convincing arguments. (And sorry, I have not read all messages in the previous discussions - it was a bit too much to read for too little general enlightenment.)
>>
>>
>> (My solution is to use custom Preludes for personal projects with exclusively qualified imports, e.g. List.length :: [a] -> Int and Foldable.length :: Foldable t => t a -> Int. Works well, but I see the issues that a custom Prelude is yet another hurdle for beginners.)
>>
>> -- lennart
>>
>>
>>
>>> On 02/03/17 17:22, Andreas Abel wrote:
>>> Today a student came to me wondering why a certain function produced a regular result, where he had expected an error.  Turned out he had used `concat`, but not on a lists of lists as he had thought, but on a lists of `Either a [b]`.
>>>
>>> With the Foldable instance for Either, which considers Either a b to be a container of 0-1 elements of b, errors are happily swallowed.
>>>
>>> I think this instance is harmful and should be deprecated (and later removed) from base.
>>>
>>> There are similarly pointless Foldable instances as well.
>>>
>>> See a discussion one year ago, which was heated, but had no consequences.
>>>
>>> https://mail.haskell.org/pipermail/libraries/2016-February/026678.html
>>
>> _______________________________________________
>> Libraries mailing list
>> [hidden email]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
> _______________________________________________
> Libraries mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Edward Kmett-2
In reply to this post by David Menendez-2
100% this. Cofree Maybe is a a nicely general encoding of a non-empty list that shows how closely related it is to a rose tree Cofree []. It'd lose its ability to be folded if Maybe ceased to be Foldable. 

When I'm showing how the cofree comonad works, I often take time to work up those examples along with Cofree ((->) e) as an (infinite) Moore machine. About 3-4 examples in, it usually clicks.

instances on Either e, and Maybe, Identity, (,) e, etc. are all building blocks that are commonly used for larger things like this.

As you enumerate all the simple functors we have lying around in Haskell, looking at what they do when you compute `Cofree f` or `Free f` tends to be quite informative.

This teaching approach breaks down completely once you start cutting arbitrary holes in instance coverage and making everyone remember where those holes are.

-Edward

On Fri, Mar 3, 2017 at 5:04 PM, David Menendez <[hidden email]> wrote:
On Thu, Mar 2, 2017 at 1:12 PM, Kris Nuttycombe <[hidden email]> wrote:
As with all of these discussions, the point of having Either be Foldable is not that you're going to call foldMap on an Either value directly. Instead, it is that you be able to pass whatever sort of foldable thing you choose (which Either certainly is) to a function that only requires foldability of its input. By removing or damaging the Foldable instance for Either, you don't simply prevent people from encountering problems that will be resolved the first time they test their software - you make a whole universe of nicely polymorphic functions unavailable for them to use without additional effort.

Not just polymorphic functions. Many higher-order type constructors have Foldable instances based on their parameters. For example,

data Cofree f a = a :< f (Cofree f a)

instance Foldable f => Foldable (Cofree f a) where
foldMap f (a :< as) = f a <> foldMap (foldMap f) as

Without the instance for Either b, we lose the instances for Cofree (Either b) and Cofree (Compose [] (Either b)), both of which seem reasonable and useful.

In particular, the idea that one should make all such functions partial by throwing an error is repugnant.

Yes, that seems like the worst possible solution. Better would be some way to give a warning when calling an overloaded function at a particular type.

--

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

amindfv
To Richard's point, though, the ability right now to have e.g. Cofree (Compose [] (Either b)) is in direct conflict with not allowing much simpler terms that no one would ever want to call, e.g.:

sum ([1,2,3], 1) == 1

At the moment, we're picking points on the expressiveness-correctness spectrum.

Would David's proposal of making Foldable a qualified import not allow us to have our cake and eat it too?

Tom


El 3 mar 2017, a las 23:10, Edward Kmett <[hidden email]> escribió:

100% this. Cofree Maybe is a a nicely general encoding of a non-empty list that shows how closely related it is to a rose tree Cofree []. It'd lose its ability to be folded if Maybe ceased to be Foldable. 

When I'm showing how the cofree comonad works, I often take time to work up those examples along with Cofree ((->) e) as an (infinite) Moore machine. About 3-4 examples in, it usually clicks.

instances on Either e, and Maybe, Identity, (,) e, etc. are all building blocks that are commonly used for larger things like this.

As you enumerate all the simple functors we have lying around in Haskell, looking at what they do when you compute `Cofree f` or `Free f` tends to be quite informative.

This teaching approach breaks down completely once you start cutting arbitrary holes in instance coverage and making everyone remember where those holes are.

-Edward

On Fri, Mar 3, 2017 at 5:04 PM, David Menendez <[hidden email]> wrote:
On Thu, Mar 2, 2017 at 1:12 PM, Kris Nuttycombe <[hidden email]> wrote:
As with all of these discussions, the point of having Either be Foldable is not that you're going to call foldMap on an Either value directly. Instead, it is that you be able to pass whatever sort of foldable thing you choose (which Either certainly is) to a function that only requires foldability of its input. By removing or damaging the Foldable instance for Either, you don't simply prevent people from encountering problems that will be resolved the first time they test their software - you make a whole universe of nicely polymorphic functions unavailable for them to use without additional effort.

Not just polymorphic functions. Many higher-order type constructors have Foldable instances based on their parameters. For example,

data Cofree f a = a :< f (Cofree f a)

instance Foldable f => Foldable (Cofree f a) where
foldMap f (a :< as) = f a <> foldMap (foldMap f) as

Without the instance for Either b, we lose the instances for Cofree (Either b) and Cofree (Compose [] (Either b)), both of which seem reasonable and useful.

In particular, the idea that one should make all such functions partial by throwing an error is repugnant.

Yes, that seems like the worst possible solution. Better would be some way to give a warning when calling an overloaded function at a particular type.

--

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Edward Kmett-2
It would thrash the entire community back more than half-way to where things stood before the Foldable/Traversable proposal and force us back into a world of qualified imports. Everyone who has adapted their code to the status quo over the last 2-3 years and have enjoyed the benefit of a base that doesn't have any internal conflicts would have to go through all the work of reverting their code, or add yet more CPP to hack around the mess. 

That strikes me, on balance, as a bad option.

-Edward

On Sat, Mar 4, 2017 at 9:16 PM, <[hidden email]> wrote:
To Richard's point, though, the ability right now to have e.g. Cofree (Compose [] (Either b)) is in direct conflict with not allowing much simpler terms that no one would ever want to call, e.g.:

sum ([1,2,3], 1) == 1

At the moment, we're picking points on the expressiveness-correctness spectrum.

Would David's proposal of making Foldable a qualified import not allow us to have our cake and eat it too?

Tom


El 3 mar 2017, a las 23:10, Edward Kmett <[hidden email]> escribió:

100% this. Cofree Maybe is a a nicely general encoding of a non-empty list that shows how closely related it is to a rose tree Cofree []. It'd lose its ability to be folded if Maybe ceased to be Foldable. 

When I'm showing how the cofree comonad works, I often take time to work up those examples along with Cofree ((->) e) as an (infinite) Moore machine. About 3-4 examples in, it usually clicks.

instances on Either e, and Maybe, Identity, (,) e, etc. are all building blocks that are commonly used for larger things like this.

As you enumerate all the simple functors we have lying around in Haskell, looking at what they do when you compute `Cofree f` or `Free f` tends to be quite informative.

This teaching approach breaks down completely once you start cutting arbitrary holes in instance coverage and making everyone remember where those holes are.

-Edward

On Fri, Mar 3, 2017 at 5:04 PM, David Menendez <[hidden email]> wrote:
On Thu, Mar 2, 2017 at 1:12 PM, Kris Nuttycombe <[hidden email]> wrote:
As with all of these discussions, the point of having Either be Foldable is not that you're going to call foldMap on an Either value directly. Instead, it is that you be able to pass whatever sort of foldable thing you choose (which Either certainly is) to a function that only requires foldability of its input. By removing or damaging the Foldable instance for Either, you don't simply prevent people from encountering problems that will be resolved the first time they test their software - you make a whole universe of nicely polymorphic functions unavailable for them to use without additional effort.

Not just polymorphic functions. Many higher-order type constructors have Foldable instances based on their parameters. For example,

data Cofree f a = a :< f (Cofree f a)

instance Foldable f => Foldable (Cofree f a) where
foldMap f (a :< as) = f a <> foldMap (foldMap f) as

Without the instance for Either b, we lose the instances for Cofree (Either b) and Cofree (Compose [] (Either b)), both of which seem reasonable and useful.

In particular, the idea that one should make all such functions partial by throwing an error is repugnant.

Yes, that seems like the worst possible solution. Better would be some way to give a warning when calling an overloaded function at a particular type.

--

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Dominic Steinitz-2
In reply to this post by Andreas Abel
Is anyone arguing that this is acceptable?

On 5 Mar 2017, at 10:32, [hidden email] wrote:

sum ([1,2,3], 1) == 1

On another note, the change that allowed this has brought discord to a previously harmonious community. I for one regret this.



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

davean
On Mon, Mar 6, 2017 at 5:02 AM, <[hidden email]> wrote:
Is anyone arguing that this is acceptable?

On 5 Mar 2017, at 10:32, [hidden email] wrote:

sum ([1,2,3], 1) == 1

I've used it for that, it has been helpful. I don't know if it was ever the best way to achieve what I wanted.
I think the thing its self is the only logical consistent way for things to be.

It is also fairly clear why people don't like it. Obviously it isn't ideal it doesn't follow some intuitions.


_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Andrew Martin
In reply to this post by Andreas Abel
I am opposed to making this change. I have the same objections that others on this thread do. It's unfortunate that the concat put in scope by the Prelude is the one from Data.Foldable and not the one from GHC.OldList. I do not think that removing Foldable instances is an appropriate solution to this problem though.

On Thu, Mar 2, 2017 at 11:22 AM, Andreas Abel <[hidden email]> wrote:
Today a student came to me wondering why a certain function produced a regular result, where he had expected an error.  Turned out he had used `concat`, but not on a lists of lists as he had thought, but on a lists of `Either a [b]`.

With the Foldable instance for Either, which considers Either a b to be a container of 0-1 elements of b, errors are happily swallowed.

I think this instance is harmful and should be deprecated (and later removed) from base.

There are similarly pointless Foldable instances as well.

See a discussion one year ago, which was heated, but had no consequences.

https://mail.haskell.org/pipermail/libraries/2016-February/026678.html


--
Andreas Abel  <><      Du bist der geliebte Mensch.

Department of Computer Science and Engineering
Chalmers and Gothenburg University, Sweden

[hidden email]
http://www.cse.chalmers.se/~abela/
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



--
-Andrew Thaddeus Martin

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Deprecate Foldable for Either

Tony Morris
I am opposed too.

Aside from the technical reasons, which have already been discussed and decided, confused students dictating language and library design has never worked out well.


On Thu, Mar 9, 2017 at 12:49 PM, Andrew Martin <[hidden email]> wrote:
I am opposed to making this change. I have the same objections that others on this thread do. It's unfortunate that the concat put in scope by the Prelude is the one from Data.Foldable and not the one from GHC.OldList. I do not think that removing Foldable instances is an appropriate solution to this problem though.

On Thu, Mar 2, 2017 at 11:22 AM, Andreas Abel <[hidden email]> wrote:
Today a student came to me wondering why a certain function produced a regular result, where he had expected an error.  Turned out he had used `concat`, but not on a lists of lists as he had thought, but on a lists of `Either a [b]`.

With the Foldable instance for Either, which considers Either a b to be a container of 0-1 elements of b, errors are happily swallowed.

I think this instance is harmful and should be deprecated (and later removed) from base.

There are similarly pointless Foldable instances as well.

See a discussion one year ago, which was heated, but had no consequences.

https://mail.haskell.org/pipermail/libraries/2016-February/026678.html


--
Andreas Abel  <><      Du bist der geliebte Mensch.

Department of Computer Science and Engineering
Chalmers and Gothenburg University, Sweden

[hidden email]
http://www.cse.chalmers.se/~abela/
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



--
-Andrew Thaddeus Martin

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries



_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
1234
Loading...