Re: Proposal: Add conspicuously missing Functor instances for tuples
Strong +1 from me. We derive Eq/Ord/Read/Show/etc. for all tuple types of size up to 15 as it is, we might as well do the same for Functor. (Personally, I'd even argue for adding Foldable and Traversable instances as well, but the Foldable instance for pairs has proven to be pretty controversial...) Ryan S.
I'd be strongly +1 on that too! Traversable is strong magic. On Mon, Jan 18, 2016 at 3:16 PM, Ryan Scott <ryan.gl.scott@gmail.com> wrote:
Strong +1 from me. We derive Eq/Ord/Read/Show/etc. for all tuple types of size up to 15 as it is, we might as well do the same for Functor.
(Personally, I'd even argue for adding Foldable and Traversable instances as well, but the Foldable instance for pairs has proven to be pretty controversial...)
Ryan S. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
On Mon, 18 Jan 2016, David Feuer wrote:
I'd be strongly +1 on that too! Traversable is strong magic.
I am opposed to all these Functor, Foldable, Traversable stuff on tuples (including pairs). Why should the last element of a tuple get a special treatment? I suspect that if you use such instances you are making something dirty. I am afraid that those instance may hide type errors or make type errors incomprehensible. E.g. if you get a stack of fmap's wrong, you do not get a "no instance for Functor ((,) a)" but instead the type mismatch occurs at a different level. I would never use such an instance. Can I be warned if I accidentally use it anyway?
Actually, I currently get a much worse error message: Prelude> fmap (+1) (1,2,3) <interactive>:2:1: Non type-variable argument in the constraint: Functor ((,,) t t) (Use FlexibleContexts to permit this) When checking that ‘it’ has the inferred type it :: forall b t t1. (Functor ((,,) t t1), Num b, Num t, Num t1) => (t, t1, b) That there is a *lousy* error message. I understand that there are newcomers who struggle to understand the difference between tuples and lists; I don't think that's a good enough reason to omit a good and valid instance. On Mon, Jan 18, 2016 at 3:32 PM, Henning Thielemann <lemming@henning-thielemann.de> wrote:
On Mon, 18 Jan 2016, David Feuer wrote:
I'd be strongly +1 on that too! Traversable is strong magic.
I am opposed to all these Functor, Foldable, Traversable stuff on tuples (including pairs). Why should the last element of a tuple get a special treatment? I suspect that if you use such instances you are making something dirty. I am afraid that those instance may hide type errors or make type errors incomprehensible. E.g. if you get a stack of fmap's wrong, you do not get a "no instance for Functor ((,) a)" but instead the type mismatch occurs at a different level.
I would never use such an instance. Can I be warned if I accidentally use it anyway?
On Mon, 18 Jan 2016, David Feuer wrote:
Actually, I currently get a much worse error message:
Prelude> fmap (+1) (1,2,3)
<interactive>:2:1: Non type-variable argument in the constraint: Functor ((,,) t t) (Use FlexibleContexts to permit this) When checking that ‘it’ has the inferred type it :: forall b t t1. (Functor ((,,) t t1), Num b, Num t, Num t1) => (t, t1, b)
That there is a *lousy* error message.
indeed
I understand that there are newcomers who struggle to understand the difference between tuples and lists; I don't think that's a good enough reason to omit a good and valid instance.
I would not qualify myself as a newcomer. For me these instances are a problem, not a help.
I've addressed this here: http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html The thousand-papercuts opposition to typeclass instances on the premise that a Functor for (a, b, c) maps over the final type not making sense is a rejection of how higher kinded types and typeclasses work together. This is natural and predictable if one bothers to explain it. On Mon, Jan 18, 2016 at 2:42 PM, Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Mon, 18 Jan 2016, David Feuer wrote:
Actually, I currently get a much worse error message:
Prelude> fmap (+1) (1,2,3)
<interactive>:2:1: Non type-variable argument in the constraint: Functor ((,,) t t) (Use FlexibleContexts to permit this) When checking that ‘it’ has the inferred type it :: forall b t t1. (Functor ((,,) t t1), Num b, Num t, Num t1) => (t, t1, b)
That there is a *lousy* error message.
indeed
I understand that there are newcomers who struggle to understand the
difference between tuples and lists; I don't think that's a good enough reason to omit a good and valid instance.
I would not qualify myself as a newcomer. For me these instances are a problem, not a help. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Chris Allen Currently working on http://haskellbook.com
A surprising amount has already been written on the topic of Functor/Foldable/Traversable instances (both for and against) for tuples, so I feel it's fair to link them here: * FTP dangers: http://nattermorphisms.blogspot.com/2015/02/ftp-dangers.html * Either and (,) in Haskell are not arbitrary: http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html * Foldable for non-Haskellers: Haskell's controversial FTP proposal: http://tojans.me/blog/2015/10/13/foldable-for-non-haskellers-haskells-contro... * The Not-A-Wat in Haskell: https://www.youtube.com/watch?v=87re_yIQMDw&feature=youtu.be Ryan S. On Mon, Jan 18, 2016 at 3:44 PM, Christopher Allen <cma@bitemyapp.com> wrote:
I've addressed this here:
http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html
The thousand-papercuts opposition to typeclass instances on the premise that a Functor for (a, b, c) maps over the final type not making sense is a rejection of how higher kinded types and typeclasses work together. This is natural and predictable if one bothers to explain it.
On Mon, Jan 18, 2016 at 2:42 PM, Henning Thielemann <lemming@henning-thielemann.de> wrote:
On Mon, 18 Jan 2016, David Feuer wrote:
Actually, I currently get a much worse error message:
Prelude> fmap (+1) (1,2,3)
<interactive>:2:1: Non type-variable argument in the constraint: Functor ((,,) t t) (Use FlexibleContexts to permit this) When checking that ‘it’ has the inferred type it :: forall b t t1. (Functor ((,,) t t1), Num b, Num t, Num t1) => (t, t1, b)
That there is a *lousy* error message.
indeed
I understand that there are newcomers who struggle to understand the difference between tuples and lists; I don't think that's a good enough reason to omit a good and valid instance.
I would not qualify myself as a newcomer. For me these instances are a problem, not a help. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Chris Allen Currently working on http://haskellbook.com
On Mon, 18 Jan 2016, Ryan Scott wrote:
* The Not-A-Wat in Haskell: https://www.youtube.com/watch?v=87re_yIQMDw
I see his examples and draw the opposite conclusions. What he presents are perfect Wats and they have eventually moved Haskell to the MatLab league where everything is allowed and the programming system accepts almost everything the programmer enters. Sure,
length (2,3) = 1 product (2,3) = 3 sum (2,3) = 3 or (True,False) = False
are all consistent but consistently useless, unintuitive (not only to novices) and dangerous. There are alternatives: There was no need to generalize 'Prelude.length' using Foldable. I always opposed to the argument "put the most general variant to Prelude", because there is no clear most general variant or there is one like "length :: Length f => f" and you won't like it. We could reasonably have the Haskell 98 class class Length a where length :: a -> Int instance Length [a] where length = List.length instance Length (a,b) where length _ = 2 This would yield the intuitive length (2,3) = 2 I do not propose to implement this class, because I never encountered a situation where I could equally choose between lists and pairs. If at all, I can see value in a special TupleSize class. However, the Length class proves that the suggestion that the only reasonable result of 'length (2,3)' is 1, is plain wrong. How did we get there? There were three steps that made this Wat possible: 1. Foldable.length added 2. instance Foldable ((,) a) 3. export Foldable.length from Prelude. For me 1. was correct 2. was wrong because a programmer should better define a custom type like "data AdornedSingleton a b = AS a b" 3. Was wrong because there are multiple ways to generalize 'length'. Without 3. you would have to use explicitly 'length' from Foldable and this way you would have been warned, that strange things may happen.
As a less-capable Haskeller, I agree 100%. The whole point of importing Data.List (either directly or from the Prelude) is to get functions that work on lists. A crucial feature of this is that applying these functions to non-lists should generate type errors, so that I can notice that I passed e.g. a tuple where I meant to pass a list. I would be fine with adding Foldable versions of list functions to Data.Foldable: if I want my functions to work on arbitrary Foldables, that's what I would import. As someone who spends some time teaching beginners Haskell, this is a disaster. Trying to explain to a beginner why "Data.List.length ('x', 'y')" returns a number instead of failing is bad enough: trying to explain why it returns 1 is hopeless. (I'm better off with Python: at least there it has the grace to return 2.) And then I have to explain why "length ('x', 'y', 'z')" returns an utterly incomprehensible type error? No thanks. I'm recommending SML over Haskell to beginners a lot more these days. On Wed, Feb 17, 2016 at 3:02 AM Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Mon, 18 Jan 2016, Ryan Scott wrote:
* The Not-A-Wat in Haskell: https://www.youtube.com/watch?v=87re_yIQMDw
I see his examples and draw the opposite conclusions. What he presents are perfect Wats and they have eventually moved Haskell to the MatLab league where everything is allowed and the programming system accepts almost everything the programmer enters.
Sure,
length (2,3) = 1 product (2,3) = 3 sum (2,3) = 3 or (True,False) = False
are all consistent but consistently useless, unintuitive (not only to novices) and dangerous. There are alternatives: There was no need to generalize 'Prelude.length' using Foldable. I always opposed to the argument "put the most general variant to Prelude", because there is no clear most general variant or there is one like "length :: Length f => f" and you won't like it.
We could reasonably have the Haskell 98 class
class Length a where length :: a -> Int
instance Length [a] where length = List.length
instance Length (a,b) where length _ = 2
This would yield the intuitive length (2,3) = 2
I do not propose to implement this class, because I never encountered a situation where I could equally choose between lists and pairs. If at all, I can see value in a special TupleSize class. However, the Length class proves that the suggestion that the only reasonable result of 'length (2,3)' is 1, is plain wrong.
How did we get there? There were three steps that made this Wat possible: 1. Foldable.length added 2. instance Foldable ((,) a) 3. export Foldable.length from Prelude.
For me 1. was correct 2. was wrong because a programmer should better define a custom type like "data AdornedSingleton a b = AS a b" 3. Was wrong because there are multiple ways to generalize 'length'. Without 3. you would have to use explicitly 'length' from Foldable and this way you would have been warned, that strange things may happen. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
There are many of us who agree with you that this is a disaster. It could have been avoided in several ways, but this what we got. From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Bart Massey Sent: 17 February 2016 17:35 To: Henning Thielemann; Ryan Scott Cc: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) As a less-capable Haskeller, I agree 100%. The whole point of importing Data.List (either directly or from the Prelude) is to get functions that work on lists. A crucial feature of this is that applying these functions to non-lists should generate type errors, so that I can notice that I passed e.g. a tuple where I meant to pass a list. I would be fine with adding Foldable versions of list functions to Data.Foldable: if I want my functions to work on arbitrary Foldables, that's what I would import. As someone who spends some time teaching beginners Haskell, this is a disaster. Trying to explain to a beginner why "Data.List.length ('x', 'y')" returns a number instead of failing is bad enough: trying to explain why it returns 1 is hopeless. (I'm better off with Python: at least there it has the grace to return 2.) And then I have to explain why "length ('x', 'y', 'z')" returns an utterly incomprehensible type error? No thanks. I'm recommending SML over Haskell to beginners a lot more these days. On Wed, Feb 17, 2016 at 3:02 AM Henning Thielemann <lemming@henning-thielemann.de<mailto:lemming@henning-thielemann.de>> wrote: On Mon, 18 Jan 2016, Ryan Scott wrote:
* The Not-A-Wat in Haskell: https://www.youtube.com/watch?v=87re_yIQMDw
I see his examples and draw the opposite conclusions. What he presents are perfect Wats and they have eventually moved Haskell to the MatLab league where everything is allowed and the programming system accepts almost everything the programmer enters. Sure,
length (2,3) = 1 product (2,3) = 3 sum (2,3) = 3 or (True,False) = False
are all consistent but consistently useless, unintuitive (not only to novices) and dangerous. There are alternatives: There was no need to generalize 'Prelude.length' using Foldable. I always opposed to the argument "put the most general variant to Prelude", because there is no clear most general variant or there is one like "length :: Length f => f" and you won't like it. We could reasonably have the Haskell 98 class class Length a where length :: a -> Int instance Length [a] where length = List.length instance Length (a,b) where length _ = 2 This would yield the intuitive length (2,3) = 2 I do not propose to implement this class, because I never encountered a situation where I could equally choose between lists and pairs. If at all, I can see value in a special TupleSize class. However, the Length class proves that the suggestion that the only reasonable result of 'length (2,3)' is 1, is plain wrong. How did we get there? There were three steps that made this Wat possible: 1. Foldable.length added 2. instance Foldable ((,) a) 3. export Foldable.length from Prelude. For me 1. was correct 2. was wrong because a programmer should better define a custom type like "data AdornedSingleton a b = AS a b" 3. Was wrong because there are multiple ways to generalize 'length'. Without 3. you would have to use explicitly 'length' from Foldable and this way you would have been warned, that strange things may happen. _______________________________________________ Libraries mailing list Libraries@haskell.org<mailto:Libraries@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
On Wed, 17 Feb 2016, Bart Massey wrote:
The whole point of importing Data.List (either directly or from the Prelude) is to get functions that work on lists.
Foldable and Traversable generalizations in Data.List are an interim solution, driven by the habit of some programmers to import complete Data.List without qualification and expecting that coinciding names in Data.List and Prelude actually refer to the same function. It would have been better to first warn about these cases, eliminate them and then implement FTP (if at all). Summarized, generalizing list functions in Prelude was a concession to programmers who are too lazy to import from Data.Foldable and Data.Traversable and generalizing functions in Data.List was a concession to programmers who are too lazy to import identifiers explicitly or with qualification from Data.List.
El 17 feb 2016, a las 06:02, Henning Thielemann <lemming@henning-thielemann.de> escribió:
On Mon, 18 Jan 2016, Ryan Scott wrote:
* The Not-A-Wat in Haskell: https://www.youtube.com/watch?v=87re_yIQMDw
I see his examples and draw the opposite conclusions. What he presents are perfect Wats and they have eventually moved Haskell to the MatLab league where everything is allowed and the programming system accepts almost everything the programmer enters.
Sure,
length (2,3) = 1 product (2,3) = 3 sum (2,3) = 3 or (True,False) = False
Don't forget maximum(99, 0) = 0
are all consistent but consistently useless, unintuitive (not only to novices) and dangerous. There are alternatives: There was no need to generalize 'Prelude.length' using Foldable. I always opposed to the argument "put the most general variant to Prelude", because there is no clear most general variant or there is one like "length :: Length f => f" and you won't like it.
We could reasonably have the Haskell 98 class
class Length a where length :: a -> Int
instance Length [a] where length = List.length
instance Length (a,b) where length _ = 2
This would yield the intuitive length (2,3) = 2
I do not propose to implement this class, because I never encountered a situation where I could equally choose between lists and pairs. If at all, I can see value in a special TupleSize class. However, the Length class proves that the suggestion that the only reasonable result of 'length (2,3)' is 1, is plain wrong.
How did we get there? There were three steps that made this Wat possible: 1. Foldable.length added 2. instance Foldable ((,) a) 3. export Foldable.length from Prelude.
For me 1. was correct 2. was wrong because a programmer should better define a custom type like "data AdornedSingleton a b = AS a b" 3. Was wrong because there are multiple ways to generalize 'length'. Without 3. you would have to use explicitly 'length' from Foldable and this way you would have been warned, that strange things may happen. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
amindfv <amindfv@gmail.com> writes:
maximum(99, 0) = 0
I don't quite understand; are you saying you expect Foldable to treat a tuple as a 2-element list? If it did, would that better or worse? And if it should, then what would you expect this to mean: maximum("Hello", 0) Or do you want both to be errors? -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
El 17 feb 2016, a las 14:03, John Wiegley <johnw@newartisans.com> escribió:
amindfv <amindfv@gmail.com> writes:
maximum(99, 0) = 0
I don't quite understand; are you saying you expect Foldable to treat a tuple as a 2-element list? If it did, would that better or worse?
And if it should, then what would you expect this to mean:
maximum("Hello", 0)
Or do you want both to be errors?
I wouldn't expect a 2-tuple to be Foldable, particularly if length (1, 2) = 1 fold ("foo", "bar") = "bar" toList (3,4) = [4] elem 1 (1,2) = False etc, etc If I have a tuple foo and a list foo', I'd hope for an error if I write the wrong name, not silently acting wonky. This will cause real bugs. (Also I've seen newcomers accidentally "parenthesize" with functions, so writing "maximum(99,0)" could be an attempt to write "max 99 0") 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. This isn't a criticism of the FTP in general (which I largely supported, and whose ship has sailed). It's about a few "wtf" instances which cause silent errors. Tom
-- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
amindfv <amindfv@gmail.com> writes:
I wouldn't expect a 2-tuple to be Foldable, particularly if
length (1, 2) = 1 fold ("foo", "bar") = "bar" toList (3,4) = [4] elem 1 (1,2) = False etc, etc
I think the fact that toList (3,4) has a meaning that is not obvious to the layman is a teaching matter. I read (x,4), in a Foldable context, as an "annotated 4", and not as some kind of shorthand for a two-element collection. My gut feeling is that the similarity to lists here is a specious argument; and that of all the things that confuse newcomers, restricting our standard library to avoid this scenario is energy spent in the wrong place. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
Hi, John Wiegley wrote:
I think the fact that toList (3,4) has a meaning that is not obvious to the layman is a teaching matter.
Well, I would not characterise many of those who have raised concerns about this as "laymen". With a couple of decades of Haskell and CS teaching experience, and a couple more of general programming experience, I don't consider myself a layman either (and I hope that does not come across as arrogant). Yet, things like:
length (1, 2) = 1 fold ("foo", "bar") = "bar" toList (3,4) = [4] elem 1 (1,2) = False
simply makes no sense to me whatsoever: neither intuitively, nor in terms of compelling practical use cases. And as to teaching this to a class: well, if we want to stop our students from considering Haskell as a serious programming language, I can see no better way than the above. Our students here would be in laughing fits throughout their degrees. I read (x,4), in a Foldable
context, as an "annotated 4", and not as some kind of shorthand for a two-element collection.
Personally, if I wanted to introduce annotated numbers, I'd introduce a new type to clearly convey that idea. Yes, a bit more to write, but the end result is code that conveys the ideas behind it in a clear manner. After all, code is (broadly) written once, but read many times. As to making tuples functor instances, that can only be done by arbitrarily imbuing one of the fields with a special status. I have to ask: Why? After all, taking pairs as an example, the *essence* of a pair is that there are two projection functions, one for each field. So, if I am now interested in applying a function to the fields, why should only one of the fields be granted that privilege? That's just not symmetrical and goes against the very idea of tuples. And whenever I have wanted to map on tuple fields (which I do from time to time), I most certainly want the ability to map on any field. As to tuples as instances of foldable: Why? There isn't any structure to fold! By all means, if some care about making tuples be instances of functor and foldable etc., put those instances in a separate module, thus saving the rest of the (Haskell) world from the cognitive burden of even beginning to make any useful sense of length (1, 2) = 1 And allowing us to spend valuable teaching time on aspects of Haskell that actually might persuade our students to take Haskell seriously. Best, /Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
I'm afraid that ship has sailed. And as the Haskell ship steams towards new glorious horizons, I'm afraid sanity and restraint were left on the shore. What's left now is to either stay with an older version of ghc or fork everything. Or embrace crazy, of course. -----Original Message----- From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Henrik Nilsson Sent: 18 February 2016 10:54 To: amindfv@gmail.com; Henning Thielemann; Haskell Libraries; Ryan Scott; johnw@newartisans.com Subject: Re: Haskell Foldable Wast Hi, John Wiegley wrote:
I think the fact that toList (3,4) has a meaning that is not obvious > to the layman is a teaching matter.
Well, I would not characterise many of those who have raised concerns about this as "laymen". With a couple of decades of Haskell and CS teaching experience, and a couple more of general programming experience, I don't consider myself a layman either (and I hope that does not come across as arrogant). Yet, things like:
length (1, 2) = 1 fold ("foo", "bar") = "bar" toList (3,4) = [4] elem 1 (1,2) = False
simply makes no sense to me whatsoever: neither intuitively, nor in terms of compelling practical use cases. And as to teaching this to a class: well, if we want to stop our students from considering Haskell as a serious programming language, I can see no better way than the above. Our students here would be in laughing fits throughout their degrees. I read (x,4), in a Foldable
context, as an "annotated 4", and not as some kind of shorthand for a > two-element collection.
Personally, if I wanted to introduce annotated numbers, I'd introduce a new type to clearly convey that idea. Yes, a bit more to write, but the end result is code that conveys the ideas behind it in a clear manner. After all, code is (broadly) written once, but read many times. As to making tuples functor instances, that can only be done by arbitrarily imbuing one of the fields with a special status. I have to ask: Why? After all, taking pairs as an example, the *essence* of a pair is that there are two projection functions, one for each field. So, if I am now interested in applying a function to the fields, why should only one of the fields be granted that privilege? That's just not symmetrical and goes against the very idea of tuples. And whenever I have wanted to map on tuple fields (which I do from time to time), I most certainly want the ability to map on any field. As to tuples as instances of foldable: Why? There isn't any structure to fold! By all means, if some care about making tuples be instances of functor and foldable etc., put those instances in a separate module, thus saving the rest of the (Haskell) world from the cognitive burden of even beginning to make any useful sense of length (1, 2) = 1 And allowing us to spend valuable teaching time on aspects of Haskell that actually might persuade our students to take Haskell seriously. Best, /Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
I'm afraid that ship has sailed. And as the Haskell ship steams towards new glorious horizons, I'm afraid sanity and restraint were left on the shore.
What's left now is to either stay with an older version of ghc or fork everything. Or embrace crazy, of course.
As opposed to the crazy of leaving an entire language or staying on old, unsupported versions because of one small piece (a single instance of a single typeclass) you disagree with? On Thu, Feb 18, 2016 at 1:19 PM, Augustsson, Lennart <Lennart.Augustsson@sc.com> wrote:
I'm afraid that ship has sailed. And as the Haskell ship steams towards new glorious horizons, I'm afraid sanity and restraint were left on the shore.
What's left now is to either stay with an older version of ghc or fork everything. Or embrace crazy, of course.
-----Original Message----- From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Henrik Nilsson Sent: 18 February 2016 10:54 To: amindfv@gmail.com; Henning Thielemann; Haskell Libraries; Ryan Scott; johnw@newartisans.com Subject: Re: Haskell Foldable Wast
Hi,
John Wiegley wrote:
I think the fact that toList (3,4) has a meaning that is not obvious > to the layman is a teaching matter.
Well, I would not characterise many of those who have raised concerns about this as "laymen".
With a couple of decades of Haskell and CS teaching experience, and a couple more of general programming experience, I don't consider myself a layman either (and I hope that does not come across as arrogant).
Yet, things like:
length (1, 2) = 1 fold ("foo", "bar") = "bar" toList (3,4) = [4] elem 1 (1,2) = False
simply makes no sense to me whatsoever: neither intuitively, nor in terms of compelling practical use cases.
And as to teaching this to a class: well, if we want to stop our students from considering Haskell as a serious programming language, I can see no better way than the above. Our students here would be in laughing fits throughout their degrees.
I read (x,4), in a Foldable
context, as an "annotated 4", and not as some kind of shorthand for a > two-element collection.
Personally, if I wanted to introduce annotated numbers, I'd introduce a new type to clearly convey that idea. Yes, a bit more to write, but the end result is code that conveys the ideas behind it in a clear manner. After all, code is (broadly) written once, but read many times.
As to making tuples functor instances, that can only be done by arbitrarily imbuing one of the fields with a special status. I have to ask: Why? After all, taking pairs as an example, the *essence* of a pair is that there are two projection functions, one for each field.
So, if I am now interested in applying a function to the fields, why should only one of the fields be granted that privilege? That's just not symmetrical and goes against the very idea of tuples.
And whenever I have wanted to map on tuple fields (which I do from time to time), I most certainly want the ability to map on any field.
As to tuples as instances of foldable: Why? There isn't any structure to fold!
By all means, if some care about making tuples be instances of functor and foldable etc., put those instances in a separate module, thus saving the rest of the (Haskell) world from the cognitive burden of even beginning to make any useful sense of
length (1, 2) = 1
And allowing us to spend valuable teaching time on aspects of Haskell that actually might persuade our students to take Haskell seriously.
Best,
/Henrik
-- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it.
Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html
Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx
Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same.
Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
No, I disagree with Foldable the way it currently looks. -----Original Message----- From: Matthias Hörmann [mailto:mhoermann@gmail.com] Sent: 18 February 2016 12:27 To: Augustsson, Lennart Cc: Henrik Nilsson; amindfv@gmail.com; Henning Thielemann; Haskell Libraries; Ryan Scott; johnw@newartisans.com Subject: Re: Haskell Foldable Wast
I'm afraid that ship has sailed. And as the Haskell ship steams towards new glorious horizons, I'm afraid sanity and restraint were left on the shore.
What's left now is to either stay with an older version of ghc or fork everything. Or embrace crazy, of course.
As opposed to the crazy of leaving an entire language or staying on old, unsupported versions because of one small piece (a single instance of a single typeclass) you disagree with? On Thu, Feb 18, 2016 at 1:19 PM, Augustsson, Lennart <Lennart.Augustsson@sc.com> wrote:
I'm afraid that ship has sailed. And as the Haskell ship steams towards new glorious horizons, I'm afraid sanity and restraint were left on the shore.
What's left now is to either stay with an older version of ghc or fork everything. Or embrace crazy, of course.
-----Original Message----- From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Henrik Nilsson Sent: 18 February 2016 10:54 To: amindfv@gmail.com; Henning Thielemann; Haskell Libraries; Ryan Scott; johnw@newartisans.com Subject: Re: Haskell Foldable Wast
Hi,
John Wiegley wrote:
I think the fact that toList (3,4) has a meaning that is not obvious > to the layman is a teaching matter.
Well, I would not characterise many of those who have raised concerns about this as "laymen".
With a couple of decades of Haskell and CS teaching experience, and a couple more of general programming experience, I don't consider myself a layman either (and I hope that does not come across as arrogant).
Yet, things like:
length (1, 2) = 1 fold ("foo", "bar") = "bar" toList (3,4) = [4] elem 1 (1,2) = False
simply makes no sense to me whatsoever: neither intuitively, nor in terms of compelling practical use cases.
And as to teaching this to a class: well, if we want to stop our students from considering Haskell as a serious programming language, I can see no better way than the above. Our students here would be in laughing fits throughout their degrees.
I read (x,4), in a Foldable
context, as an "annotated 4", and not as some kind of shorthand for a > two-element collection.
Personally, if I wanted to introduce annotated numbers, I'd introduce a new type to clearly convey that idea. Yes, a bit more to write, but the end result is code that conveys the ideas behind it in a clear manner. After all, code is (broadly) written once, but read many times.
As to making tuples functor instances, that can only be done by arbitrarily imbuing one of the fields with a special status. I have to ask: Why? After all, taking pairs as an example, the *essence* of a pair is that there are two projection functions, one for each field.
So, if I am now interested in applying a function to the fields, why should only one of the fields be granted that privilege? That's just not symmetrical and goes against the very idea of tuples.
And whenever I have wanted to map on tuple fields (which I do from time to time), I most certainly want the ability to map on any field.
As to tuples as instances of foldable: Why? There isn't any structure to fold!
By all means, if some care about making tuples be instances of functor and foldable etc., put those instances in a separate module, thus saving the rest of the (Haskell) world from the cognitive burden of even beginning to make any useful sense of
length (1, 2) = 1
And allowing us to spend valuable teaching time on aspects of Haskell that actually might persuade our students to take Haskell seriously.
Best,
/Henrik
-- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it.
Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html
Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.a spx
Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same.
Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
On Thu, Feb 18, 2016 at 6:24 AM, Henrik Nilsson <Henrik.Nilsson@nottingham.ac.uk> wrote:
As to making tuples functor instances, that can only be done by arbitrarily imbuing one of the fields with a special status. I have to ask: Why? After all, taking pairs as an example, the *essence* of a pair is that there are two projection functions, one for each field.
So, if I am now interested in applying a function to the fields, why should only one of the fields be granted that privilege? That's just not symmetrical and goes against the very idea of tuples.
There’s nothing symmetrical about a type constructor with two distinct type variables wherein only one of them is the last. Perhaps you would prefer tuples to be two-element HLists, which would be isomorphic given proper type selections but would work very much differently at the type level. Any type constructor such as data Pair a b = Pair a b will necessarily have the same «privilege» granted to the last type variable. It’s the reason things like data Const a b = Const a behave as they do. Such distinctions are involved in the underlying mechanisms for monad transformers and lenses to work as they do.
And whenever I have wanted to map on tuple fields (which I do from time to time), I most certainly want the ability to map on any field.
Anyone with a couple of decades of Haskell experience ought to understand that the desire to map on any field of a record cannot be served by a typeclass such as Functor. You may reasonably disagree with folding and traversing over degenerate cases such as tuples, but surely you must agree that there cannot be any other way to map over tuple fields with fmap. You may even disagree with the existence of the Functor instance or the pretension to use Functor to map over the last field in a tuple, but this instance is used by a lot of people in contexts where it brings clear benefits and has a very clear meaning.
As to tuples as instances of foldable: Why? There isn't any structure to fold!
Because it is standard practice in mathematics and programming to give uniform treatment to degenerate cases. This does sometimes come in conflict with usability and intuition. This kind of problem occurs in many contexts. There are similar discussions among mathematicians and engineers on the parity of zero, the value of 0⁰, what the first natural number is, etc, with various degrees of consensus and controversy.
By all means, if some care about making tuples be instances of functor and foldable etc., put those instances in a separate module, thus saving the rest of the (Haskell) world from the cognitive burden of even beginning to make any useful sense of
length (1, 2) = 1
I would expect that anyone with a couple of decades of Haskell experience would see without much effort that the transitive, implicit importing of type class instances would entirely defeat the idea of trying to isolate these instances. You would get them in your code if you ever imported anything that has in its transitive closure any module that imports them. Avoiding them would require changing the fundamental mechanism for type class instance visibility (which is one of Haskell’s unique features and brings too many benefits to ignore just over some apparent quirk), or avoiding depending on a large portion of Hackage. Surely you must see how this is unreasonable: instance absence in practice requires community consensus, and these instances have a well-defined, unique, useful, correct definition.
Hi, On 02/18/2016 12:41 PM, Manuel Gómez wrote:
And whenever I have wanted to map on tuple fields (which I do from time to time), I most certainly want the ability to map on any field. Anyone with a couple of decades of Haskell experience ought to understand that the desire to map on any field of a record cannot be served by a typeclass such as Functor.
Yes, that's exactly my point: functor is not the right tool. So why make tuples instances of functor in the first place? And yes, there is arguably an asymmetry of sorts in having to pick an order among type constructor arguments. But that does not change the fact that there is symmetry in having a projection function for each field. So why even entertain a notion of mapping that doesn't grant the same privileges to all fields? Might be useful in some specialist applications, but certainly not what I, at least, would consider particularly useful. Best, /Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
+1. Use of tuples is highly discourageable, except for returning multiple arguments from a function. For everything else, roll your own datatype, to give the reader of your code some semantics, and to introduce more redundancy to avoid erros. I see no point in Functor or Foldable for tuples. I also do not see why (a,a) could not be a container of exactly two elements, as opposed to current GHC which insists it is a container of exactly one element. (Case for the mental institution, I'd say.) Cheers, Andreas On 18.02.2016 14:04, Henrik Nilsson wrote:
Hi,
On 02/18/2016 12:41 PM, Manuel Gómez wrote:
And whenever I have wanted to map on tuple fields (which I do from time to time), I most certainly want the ability to map on any field. Anyone with a couple of decades of Haskell experience ought to understand that the desire to map on any field of a record cannot be served by a typeclass such as Functor.
Yes, that's exactly my point: functor is not the right tool. So why make tuples instances of functor in the first place?
And yes, there is arguably an asymmetry of sorts in having to pick an order among type constructor arguments. But that does not change the fact that there is symmetry in having a projection function for each field. So why even entertain a notion of mapping that doesn't grant the same privileges to all fields?
Might be useful in some specialist applications, but certainly not what I, at least, would consider particularly useful.
Best,
/Henrik
-- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/
On Thu, Feb 18, 2016 at 9:58 AM, Andreas Abel <andreas.abel@ifi.lmu.de> wrote:
I also do not see why (a,a) could not be a container of exactly two elements, as opposed to current GHC which insists it is a container of exactly one element. (Case for the mental institution, I'd say.)
Because, given data T a = T a a data T' a b = T a b these two types have essential structural differences at the type level, despite being isomorphic: forall a. T a forall a. T' a a Type classes exist at the type level. These things are decidedly different at the type level. It’s to be expected that their behavior under Functor differs.
Thanks guys to try to enlighten me. However, nothing contradicts the view of (a,a) as a container of two elements except for your very specific interpretation of "container" in terms of unary type transformers, type classes, and what not. Some delusions have very sophisticated explanations. On 18.02.2016 15:37, Marcin Mrotek wrote:
I also do not see why (a,a) could not be a container of exactly two elements, as opposed to current GHC which insists it is a container of exactly one element. (Case for the mental institution, I'd say.)
Because this isn't how types in Haskell works. `Foo a a` always parsed to `(Foo a) a` and no instance of any class can implement it differently than `(Foo b) a`, unless you want to throw parametricity out of the window. This has been long before `Foldable`.
Best regards, Marcin Mrotek
On 18.02.2016 15:37, Manuel Gómez wrote: On Thu, Feb 18, 2016 at 9:58 AM, Andreas Abel <andreas.abel@ifi.lmu.de> wrote:
I also do not see why (a,a) could not be a container of exactly two elements, as opposed to current GHC which insists it is a container of exactly one element. (Case for the mental institution, I'd say.)
Because, given
data T a = T a a data T' a b = T a b
these two types have essential structural differences at the type level, despite being isomorphic:
forall a. T a forall a. T' a a
Type classes exist at the type level. These things are decidedly different at the type level. It’s to be expected that their behavior under Functor differs.
-- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/
Thanks guys to try to enlighten me. However, nothing contradicts the view of (a,a) as a container of two elements except for your very specific interpretation of "container" in terms of unary type transformers, type classes, and what not.
`(a,a)` "being a container of one element" is only observable when using the `length` method of `Foldable` type class. It's not like GHC is getting into your head to challenge your view of it as a container of two elements.
Some delusions have very sophisticated explanations.
Could you go troll somewhere else? Best regards, Marcin Mrotek
On Thu, 18 Feb 2016, Marcin Mrotek wrote:
Some delusions have very sophisticated explanations.
Could you go troll somewhere else?
I think he is right. Programming should strive for simplicity. The more you must explain, the less obvious it is. You can write programs with unintuitive behavior and document that intensively, but it won't fix the missing intuition.
I think he is right.
I was objecting to the way he argues his point, not to the point itself. There isn't much room for discussion if the opposite side is "delusional" or a "case for the mental institution".
Programming should strive for simplicity. The more you must explain, the less obvious it is.
And the way type classes work right now is rather simple. You could make them take a type lambda or something like that, to point the type argument that is meant to be modified, and perhaps treating tuples like two-element containers could somehow work. But instead they work in a simplistic, but predictable way. The intuition developed for tuples is applicable to any other type in Haskell. Complicated manipulations of data types can be handled with lenses, which compensate by allowing less polymorphism, so that the overall complexity doesn't blow up. Heterogeneous containers are provided by packages like HList or Vinyl, with their own tradeoffs. Etc, etc.
You can write programs with unintuitive behavior and document that intensively, but it won't fix the missing intuition.
As I see it, programming is a discipline of engineering, not humanities. All things being equal, it's better to have things behave in a familiar way, but if a different behavior naturally follows from the formal system underlying the language, then too bad for these arbitrary notions of "common sense". Stripping corner cases (like Functor or Foldable instances for tuples) or making them behave differently for the sake of intuition, actually adds complexity to the language while removing functionality, in my opinion. I think it's like arguing for removal of complex numbers and matrices from mathematics because their arithmetic is confusing. Best regards, Marcin Mrotek
I can assure you that Andreas is not delusional, and I think he makes a very good point. I also think that the design of programming languages and APIs is as much an art as it is engineering. You have to show good taste or you'll end up with a mess that might be logically consistent, but unpleasant to use. -----Original Message----- From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Marcin Mrotek Sent: 23 February 2016 12:31 To: Henning Thielemann Cc: Haskell Libraries Subject: Re: Haskell Foldable Wats
I think he is right.
I was objecting to the way he argues his point, not to the point itself. There isn't much room for discussion if the opposite side is "delusional" or a "case for the mental institution".
Programming should strive for simplicity. The more you must explain, the less obvious it is.
And the way type classes work right now is rather simple. You could make them take a type lambda or something like that, to point the type argument that is meant to be modified, and perhaps treating tuples like two-element containers could somehow work. But instead they work in a simplistic, but predictable way. The intuition developed for tuples is applicable to any other type in Haskell. Complicated manipulations of data types can be handled with lenses, which compensate by allowing less polymorphism, so that the overall complexity doesn't blow up. Heterogeneous containers are provided by packages like HList or Vinyl, with their own tradeoffs. Etc, etc.
You can write programs with unintuitive behavior and document that intensively, but it won't fix the missing intuition.
As I see it, programming is a discipline of engineering, not humanities. All things being equal, it's better to have things behave in a familiar way, but if a different behavior naturally follows from the formal system underlying the language, then too bad for these arbitrary notions of "common sense". Stripping corner cases (like Functor or Foldable instances for tuples) or making them behave differently for the sake of intuition, actually adds complexity to the language while removing functionality, in my opinion. I think it's like arguing for removal of complex numbers and matrices from mathematics because their arithmetic is confusing. Best regards, Marcin Mrotek _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
I can assure you that Andreas is not delusional
I didn't say that. I was referring to his response to my post, that "Some delusions have very sophisticated explanations."
You have to show good taste or you'll end up with a mess that might be logically consistent, but unpleasant to use.
This is entirely subjective, and frankly I don't think that post-FTP Haskell is a "mess" or is "unpleasant to use". If anything, it became more useful to me, because now Prelude functions aren't limited to the one data structure I almost never use. Best regards, Marcin Mrotek
It's a bit bold to simultaneously say "Nobody should use this type," and also "If you use this type, you should do it this way." If you think that it's bad practice to use tuples, that's a fine and respectable opinion, but at that point you should start being a bit more wary about telling those who think otherwise *how* they should use them. On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek <marcin.jan.mrotek@gmail.com> wrote:
I can assure you that Andreas is not delusional
I didn't say that. I was referring to his response to my post, that "Some delusions have very sophisticated explanations."
You have to show good taste or you'll end up with a mess that might be logically consistent, but unpleasant to use.
This is entirely subjective, and frankly I don't think that post-FTP Haskell is a "mess" or is "unpleasant to use". If anything, it became more useful to me, because now Prelude functions aren't limited to the one data structure I almost never use.
Best regards, Marcin Mrotek _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
On 16-02-23 11:23 AM, Nathan Bouscal wrote:
It's a bit bold to simultaneously say "Nobody should use this type," and also "If you use this type, you should do it this way." If you think that it's bad practice to use tuples, that's a fine and respectable opinion, but at that point you should start being a bit more wary about telling those who think otherwise /how/ they should use them.
I believe he was referring to lists, not to tuples. There were few Prelude functions limited to tuples before FTP, and those haven't changed.
On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek <marcin.jan.mrotek@gmail.com <mailto:marcin.jan.mrotek@gmail.com>> wrote:
> I can assure you that Andreas is not delusional
I didn't say that. I was referring to his response to my post, that "Some delusions have very sophisticated explanations."
> You have to show good taste or you'll end up with a mess that might be logically consistent, but unpleasant to use.
This is entirely subjective, and frankly I don't think that post-FTP Haskell is a "mess" or is "unpleasant to use". If anything, it became more useful to me, because now Prelude functions aren't limited to the one data structure I almost never use.
Best regards, Marcin Mrotek
Sorry, poor quoting on my part. I was attempting to reply to Andreas's earlier points:
Use of tuples is highly discourageable… I see no point in Functor or Foldable for tuples.
On Tue, Feb 23, 2016 at 5:18 PM, Mario Blažević <mblazevic@stilo.com> wrote:
On 16-02-23 11:23 AM, Nathan Bouscal wrote:
It's a bit bold to simultaneously say "Nobody should use this type," and also "If you use this type, you should do it this way." If you think that it's bad practice to use tuples, that's a fine and respectable opinion, but at that point you should start being a bit more wary about telling those who think otherwise /how/ they should use them.
I believe he was referring to lists, not to tuples. There were few Prelude functions limited to tuples before FTP, and those haven't changed.
On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek <marcin.jan.mrotek@gmail.com <mailto:marcin.jan.mrotek@gmail.com>> wrote:
> I can assure you that Andreas is not delusional
I didn't say that. I was referring to his response to my post, that "Some delusions have very sophisticated explanations."
> You have to show good taste or you'll end up with a mess that might be logically consistent, but unpleasant to use.
This is entirely subjective, and frankly I don't think that post-FTP Haskell is a "mess" or is "unpleasant to use". If anything, it became more useful to me, because now Prelude functions aren't limited to the one data structure I almost never use.
Best regards, Marcin Mrotek
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
In my n+1 years of participating in a 100kloc Haskell project, I learned that programming with the "categorical" data type building blocks "Either" and tuples leads to code that is hard to read and maintain. It is tempting to use a pair type QNamed a = (QName, a) instead of a hand-rolled data type data QNamed a = QNamed { qname :: QName, qnamedThing :: a } since with pairs, I get lots of operations for free, and even more if I use Functor and Traversable, it seems. However, in the long run, if I come back after months to my original code, or even worse, to someone else's code, I dearly pay for this: 1. Harder to read the code, as I may only see the non-telling "fst" and "snd" instead of the semantics-loaden "qname" and "qnamedThing". 2. Lack of code exploration facilities like grep and tags. I can grep for "QName" and "qname", but grepping for "," and "fst" returns lots of irrelevant locations. 3. Non-telling error messages. And all the arguments of using newtypes over type synonyms apply here as well. So, my advice is to use tuples only for very short-lived data, like returning multiple results from a function. I am speaking here of Haskell as a language for software development, not of Haskell as a realization of category theory. For getting a broader acceptance of Haskell as a language for software development, Foldable on tuples is not helpful. And yes, if I was new to Haskell and learned the GHCI thinks that minimum (1,2) == 1 then I would advice GHCI to visit some mental institution to get its delusions fixed. --Andreas On 23.02.2016 18:29, Nathan Bouscal wrote:
Sorry, poor quoting on my part. I was attempting to reply to Andreas's earlier points:
Use of tuples is highly discourageable… I see no point in Functor or Foldable for tuples.
On Tue, Feb 23, 2016 at 5:18 PM, Mario Blažević <mblazevic@stilo.com <mailto:mblazevic@stilo.com>> wrote:
On 16-02-23 11:23 AM, Nathan Bouscal wrote:
It's a bit bold to simultaneously say "Nobody should use this type," and also "If you use this type, you should do it this way." If you think that it's bad practice to use tuples, that's a fine and respectable opinion, but at that point you should start being a bit more wary about telling those who think otherwise /how/ they should use them.
I believe he was referring to lists, not to tuples. There were few Prelude functions limited to tuples before FTP, and those haven't changed.
On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek <marcin.jan.mrotek@gmail.com <mailto:marcin.jan.mrotek@gmail.com> <mailto:marcin.jan.mrotek@gmail.com <mailto:marcin.jan.mrotek@gmail.com>>> wrote:
> I can assure you that Andreas is not delusional
I didn't say that. I was referring to his response to my post, that "Some delusions have very sophisticated explanations."
> You have to show good taste or you'll end up with a mess that might be logically consistent, but unpleasant to use.
This is entirely subjective, and frankly I don't think that post-FTP Haskell is a "mess" or is "unpleasant to use". If anything, it became more useful to me, because now Prelude functions aren't limited to the one data structure I almost never use.
Best regards, Marcin Mrotek
_______________________________________________ Libraries mailing list Libraries@haskell.org <mailto:Libraries@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org 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 andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/
| So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function. I strongly agree, for all the reasons Andreas mentions. GHC's source code has *lots* of data types that are isomorphic to tuples. Crucial! Simon | -----Original Message----- | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | Andreas Abel | Sent: 24 February 2016 08:58 | To: Nathan Bouscal <nbouscal@gmail.com>; libraries@haskell.org | Subject: Re: Haskell Foldable Wats | | In my n+1 years of participating in a 100kloc Haskell project, I | learned that programming with the "categorical" data type building | blocks "Either" and tuples leads to code that is hard to read and | maintain. It is tempting to use a pair | | type QNamed a = (QName, a) | | instead of a hand-rolled data type | | data QNamed a = QNamed { qname :: QName, qnamedThing :: a } | | since with pairs, I get lots of operations for free, and even more if I | use Functor and Traversable, it seems. However, in the long run, if I | come back after months to my original code, or even worse, to someone | else's code, I dearly pay for this: | | 1. Harder to read the code, as I may only see the non-telling "fst" | and "snd" instead of the semantics-loaden "qname" and "qnamedThing". | | 2. Lack of code exploration facilities like grep and tags. I can | grep for "QName" and "qname", but grepping for "," and "fst" returns | lots of irrelevant locations. | | 3. Non-telling error messages. | | And all the arguments of using newtypes over type synonyms apply here | as well. | | So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function. I am speaking here of | Haskell as a language for software development, not of Haskell as a | realization of category theory. | | For getting a broader acceptance of Haskell as a language for software | development, Foldable on tuples is not helpful. | | And yes, if I was new to Haskell and learned the GHCI thinks that | | minimum (1,2) == 1 | | then I would advice GHCI to visit some mental institution to get its | delusions fixed. | | --Andreas | | | On 23.02.2016 18:29, Nathan Bouscal wrote: | > Sorry, poor quoting on my part. I was attempting to reply to | Andreas's | > earlier points: | > | > >> Use of tuples is highly discourageable… | >>>I see no point in Functor or Foldable for tuples. | > | > On Tue, Feb 23, 2016 at 5:18 PM, Mario Blažević <mblazevic@stilo.com | > <mailto:mblazevic@stilo.com>> wrote: | > | > On 16-02-23 11:23 AM, Nathan Bouscal wrote: | > | > It's a bit bold to simultaneously say "Nobody should use this | > type," and | > also "If you use this type, you should do it this way." If | you think | > that it's bad practice to use tuples, that's a fine and | respectable | > opinion, but at that point you should start being a bit more | > wary about | > telling those who think otherwise /how/ they should use them. | > | > | > I believe he was referring to lists, not to tuples. | There | > were few Prelude functions limited to tuples before FTP, and | those | > haven't changed. | > | > | > | > On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek | > <marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com> | > <mailto:marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com>>> wrote: | > | > > I can assure you that Andreas is not delusional | > | > I didn't say that. I was referring to his response to my | > post, that | > "Some delusions have very sophisticated explanations." | > | > > You have to show good taste or you'll end up with a | mess | > that might be logically consistent, but unpleasant to use. | > | > This is entirely subjective, and frankly I don't think | that | > post-FTP | > Haskell is a "mess" or is "unpleasant to use". If | anything, | > it became | > more useful to me, because now Prelude functions aren't | > limited to the | > one data structure I almost never use. | > | > Best regards, | > Marcin Mrotek | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org <mailto:Libraries@haskell.org> | > | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | | | -- | Andreas Abel <>< Du bist der geliebte Mensch. | | Department of Computer Science and Engineering Chalmers and Gothenburg | University, Sweden | | andreas.abel@gu.se | https://na01.safelinks.protection.outlook.com/?url=http:%2f%2fwww2.tcs. | ifi.lmu.de%2f~abel%2f&data=01%7C01%7Csimonpj%40064d.mgd.microsoft.com%7 | Ce4033ee9a03a42eaa97108d33cf89187%7C72f988bf86f141af91ab2d7cd011db47%7C | 1&sdata=kvwlaXofxhQV2ZCD9K%2bemtG4S9oCujNYhn1IXTnSZtc%3d | _______________________________________________ | Libraries mailing list | Libraries@haskell.org | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.ha | skell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries%0a&data=01%7c01%7csimonpj%40064d.m | gd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c72f988bf86f141af9 | 1ab2d7cd011db47%7c1&sdata=gMTA2SOTm1seAHbvHPWnsDjAa7y1gAS681kW6YUx1mQ%3 | d
I seem to be doing a pretty poor job of communicating my point and should maybe quit while I'm ahead, but one more go: I agree that it is good practice to create proper data types rather than using tuples everywhere. I agree with this even more strongly if you're in a 100kloc codebase. It sounds like that's the use case that you're deeply familiar with, Andreas, and it sounds like you've come to correct conclusions *in that context*. My argument is that there exist other contexts, that you are less familiar with those contexts, and that you should not necessarily expect your experience to fully generalize. You're qualified to say that in 100kloc codebases, tuples should exclusively be used for returning multiple values from functions. In that context it's clear that Functor isn't helpful. What you seem to be saying, though, is one of two things. 1: "In all contexts, you should only ever use tuples for this purpose", or 2: "If you find another purpose to use tuples for, you shouldn't use them as Functors" Option 1 requires you to assume that your work on 100kloc codebases generalizes to every use-case of the Haskell programming language. That's pretty bold, especially given that there clearly exist use-cases for which your two stated benefits (readability and maintainability) don't really matter (e.g. writing throwaway scripts). Option 2 is more humble in that it allows for the possibility that there's a use-case you're unfamiliar with, but instead it just makes an arbitrary decision that, whatever this unfamiliar use-case is, surely they shouldn't be using Functor. I don't see any way to justify that position. --- I don't find anything strange about `minimum (1,2) == 2`, any more than I would find it strange that `minimum (F 1 2) == 2` for any other arbitrary F. I think it's really beside the point, though. On Wed, Feb 24, 2016 at 9:04 AM, Simon Peyton Jones <simonpj@microsoft.com> wrote:
| So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function.
I strongly agree, for all the reasons Andreas mentions. GHC's source code has *lots* of data types that are isomorphic to tuples. Crucial!
Simon
| -----Original Message----- | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | Andreas Abel | Sent: 24 February 2016 08:58 | To: Nathan Bouscal <nbouscal@gmail.com>; libraries@haskell.org | Subject: Re: Haskell Foldable Wats | | In my n+1 years of participating in a 100kloc Haskell project, I | learned that programming with the "categorical" data type building | blocks "Either" and tuples leads to code that is hard to read and | maintain. It is tempting to use a pair | | type QNamed a = (QName, a) | | instead of a hand-rolled data type | | data QNamed a = QNamed { qname :: QName, qnamedThing :: a } | | since with pairs, I get lots of operations for free, and even more if I | use Functor and Traversable, it seems. However, in the long run, if I | come back after months to my original code, or even worse, to someone | else's code, I dearly pay for this: | | 1. Harder to read the code, as I may only see the non-telling "fst" | and "snd" instead of the semantics-loaden "qname" and "qnamedThing". | | 2. Lack of code exploration facilities like grep and tags. I can | grep for "QName" and "qname", but grepping for "," and "fst" returns | lots of irrelevant locations. | | 3. Non-telling error messages. | | And all the arguments of using newtypes over type synonyms apply here | as well. | | So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function. I am speaking here of | Haskell as a language for software development, not of Haskell as a | realization of category theory. | | For getting a broader acceptance of Haskell as a language for software | development, Foldable on tuples is not helpful. | | And yes, if I was new to Haskell and learned the GHCI thinks that | | minimum (1,2) == 1 | | then I would advice GHCI to visit some mental institution to get its | delusions fixed. | | --Andreas | | | On 23.02.2016 18:29, Nathan Bouscal wrote: | > Sorry, poor quoting on my part. I was attempting to reply to | Andreas's | > earlier points: | > | > >> Use of tuples is highly discourageable… | >>>I see no point in Functor or Foldable for tuples. | > | > On Tue, Feb 23, 2016 at 5:18 PM, Mario Blažević <mblazevic@stilo.com | > <mailto:mblazevic@stilo.com>> wrote: | > | > On 16-02-23 11:23 AM, Nathan Bouscal wrote: | > | > It's a bit bold to simultaneously say "Nobody should use this | > type," and | > also "If you use this type, you should do it this way." If | you think | > that it's bad practice to use tuples, that's a fine and | respectable | > opinion, but at that point you should start being a bit more | > wary about | > telling those who think otherwise /how/ they should use them. | > | > | > I believe he was referring to lists, not to tuples. | There | > were few Prelude functions limited to tuples before FTP, and | those | > haven't changed. | > | > | > | > On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek | > <marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com> | > <mailto:marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com>>> wrote: | > | > > I can assure you that Andreas is not delusional | > | > I didn't say that. I was referring to his response to my | > post, that | > "Some delusions have very sophisticated explanations." | > | > > You have to show good taste or you'll end up with a | mess | > that might be logically consistent, but unpleasant to use. | > | > This is entirely subjective, and frankly I don't think | that | > post-FTP | > Haskell is a "mess" or is "unpleasant to use". If | anything, | > it became | > more useful to me, because now Prelude functions aren't | > limited to the | > one data structure I almost never use. | > | > Best regards, | > Marcin Mrotek | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org <mailto:Libraries@haskell.org> | > | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | | | -- | Andreas Abel <>< Du bist der geliebte Mensch. | | Department of Computer Science and Engineering Chalmers and Gothenburg | University, Sweden | | andreas.abel@gu.se | https://na01.safelinks.protection.outlook.com/?url=http:%2f%2fwww2.tcs. | ifi.lmu.de%2f~abel%2f&data=01%7C01%7Csimonpj%40064d.mgd.microsoft.com%7 | Ce4033ee9a03a42eaa97108d33cf89187%7C72f988bf86f141af91ab2d7cd011db47%7C | 1&sdata=kvwlaXofxhQV2ZCD9K%2bemtG4S9oCujNYhn1IXTnSZtc%3d | _______________________________________________ | Libraries mailing list | Libraries@haskell.org | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.ha | skell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries%0a&data=01%7c01%7csimonpj%40064d.m | gd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c72f988bf86f141af9 | 1ab2d7cd011db47%7c1&sdata=gMTA2SOTm1seAHbvHPWnsDjAa7y1gAS681kW6YUx1mQ%3 | d
Nathan Bouscal <nbouscal@gmail.com> writes:
What you seem to be saying, though, is one of two things. 1: "In all contexts, you should only ever use tuples for this purpose", or 2: "If you find another purpose to use tuples for, you shouldn't use them as Functors" .. Option 2 is more humble in that it allows for the possibility that there's a use-case you're unfamiliar with, but instead it just makes an arbitrary decision that, whatever this unfamiliar use-case is, surely they shouldn't be using Functor. I don't see any way to justify that position.
This kind of argument is defeatable by replacing Functor with Monad (which, I'm sure, we can find a some instance of), or some other, even more specific type class -- the argument becomes absurd, without having its structure changed. Where do we stop? -- с уважениeм / respectfully, Косырев Сергей
Nathan Bouscal <nbouscal@gmail.com> writes:
What you seem to be saying, though, is one of two things. 1: "In all contexts, you should only ever use tuples for this purpose", or 2: "If you find another purpose to use tuples for, you shouldn't use them as Functors" .. Option 2 is more humble in that it allows for the possibility that there's a use-case you're unfamiliar with, but instead it just makes an arbitrary decision that, whatever this unfamiliar use-case is, surely they shouldn't be using Functor. I don't see any way to justify that position.
Crucially -- this is a strawman -- nobody is arguing that Functor should never be defined for tuples. The argument is against forcing one specific instance of Functor on everybody. -- с уважениeм / respectfully, Косырев Сергей
On Wed, Feb 24, 2016 at 3:24 PM, Kosyrev Serge <_deepfire@feelingofgreen.ru> wrote:
Nathan Bouscal <nbouscal@gmail.com> writes:
What you seem to be saying, though, is one of two things. 1: "In all contexts, you should only ever use tuples for this purpose", or 2: "If you find another purpose to use tuples for, you shouldn't use them as Functors" .. Option 2 is more humble in that it allows for the possibility that there's a use-case you're unfamiliar with, but instead it just makes an arbitrary decision that, whatever this unfamiliar use-case is, surely they shouldn't be using Functor. I don't see any way to justify that position.
Crucially -- this is a strawman -- nobody is arguing that Functor should never be defined for tuples.
The argument is against forcing one specific instance of Functor on everybody.
As opposed to what other instance??
-- с уважениeм / respectfully, Косырев Сергей
You can wish for such an instance all you want, but it can't exist. The definition of Functor is forced on you by the a combination of the laws, and the way the type system works. You can't have this "other" instance even if you want it, even if the instance we have today wasn't there. (,) e :: * -> * That is a legal choice of 'f' for class Functor f where fmap :: (a -> b) -> f a -> f b We don't (and can't) have a "type lambda" that lets you talk about instance Functor (\x -> (x,x)) With it instance resolution would go to hell. There is only one solitary degree of freedom in the design, which comes down to whether or not the instance should use a strict or a lazy pattern match on the tuple. -Edward On Wed, Feb 24, 2016 at 10:28 AM, Kosyrev Serge <_deepfire@feelingofgreen.ru
wrote:
Nathan Bouscal <nbouscal@gmail.com> writes:
As opposed to what other instance??
I expect there to be N similarly-structured Functor instances for a N-ary tuple.
-- с уважениeм, Косырев Сергей _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Edward Kmett <ekmett@gmail.com> writes:
You can wish for such an instance all you want, but it can't exist.
The definition of Functor is forced on you by the a combination of the laws, and the way the type system works. You can't have this "other" instance even if you want it, even if the instance we have today wasn't there.
(,) e :: * -> *
That is a legal choice of 'f' for
class Functor f where fmap :: (a -> b) -> f a -> f b
I see where I made a mistake, yes. Are you also saying that this cannot be resolved by some kind of a type families-based type-level 'flip'? -- с уважениeм / respectfully, Косырев Сергей
On Wed, Feb 24, 2016 at 11:22 AM, Kosyrev Serge <_deepfire@feelingofgreen.ru
wrote:
Are you also saying that this cannot be resolved by some kind of a type families-based type-level 'flip'?
It really can't, no. You can define type family FlipF f a b where FlipF f a b = f b a but FlipF, being a type family, is not first-class. You can't make any instances whatsoever for FlipF f a -- you'll probably get an error about a partially applied type family. What you *can* do is make a Flip newtype: newtype Flip f a b = Flip {unflip :: f b a} This behaves perfectly: instance Bifunctor f => Functor (Flip f a) where fmap f = Flip . first f . unflip instance Profunctor f => Contravariant (Flip f a) where contramap f = Flip . lmap f . unflip instance Bifunctor f => Bifunctor (Flip f) where bimap f g (Flip x) = Flip (bimap g f x)
It seems like very few people are changing their minds, after a lot of discussion -- maybe it's time to agree to disagree, in the form of a vote on whether to include the tuple instances. If so, I'd think we'd want to come to the users with a discussion of both sides and a poll, a la FTP. Tom
El 24 feb 2016, a las 11:38, David Feuer <david.feuer@gmail.com> escribió:
On Wed, Feb 24, 2016 at 11:22 AM, Kosyrev Serge <_deepfire@feelingofgreen.ru> wrote:
Are you also saying that this cannot be resolved by some kind of a type families-based type-level 'flip'?
It really can't, no. You can define
type family FlipF f a b where FlipF f a b = f b a
but FlipF, being a type family, is not first-class. You can't make any instances whatsoever for FlipF f a -- you'll probably get an error about a partially applied type family. What you *can* do is make a Flip newtype:
newtype Flip f a b = Flip {unflip :: f b a}
This behaves perfectly:
instance Bifunctor f => Functor (Flip f a) where fmap f = Flip . first f . unflip instance Profunctor f => Contravariant (Flip f a) where contramap f = Flip . lmap f . unflip instance Bifunctor f => Bifunctor (Flip f) where bimap f g (Flip x) = Flip (bimap g f x) _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think. On 02/24/2016 11:17 AM, amindfv@gmail.com wrote:
It seems like very few people are changing their minds, after a lot of discussion -- maybe it's time to agree to disagree, in the form of a vote on whether to include the tuple instances.
If so, I'd think we'd want to come to the users with a discussion of both sides and a poll, a la FTP.
Tom
El 24 feb 2016, a las 11:38, David Feuer <david.feuer@gmail.com <mailto:david.feuer@gmail.com>> escribió:
On Wed, Feb 24, 2016 at 11:22 AM, Kosyrev Serge <_deepfire@feelingofgreen.ru <mailto:_deepfire@feelingofgreen.ru>> wrote:
Are you also saying that this cannot be resolved by some kind of a type families-based type-level 'flip'?
It really can't, no. You can define
type family FlipF f a b where FlipF f a b = f b a
but FlipF, being a type family, is not first-class. You can't make any instances whatsoever for FlipF f a -- you'll probably get an error about a partially applied type family. What you *can* do is make a Flip newtype:
newtype Flip f a b = Flip {unflip :: f b a}
This behaves perfectly:
instance Bifunctor f => Functor (Flip f a) where fmap f = Flip . first f . unflip instance Profunctor f => Contravariant (Flip f a) where contramap f = Flip . lmap f . unflip instance Bifunctor f => Bifunctor (Flip f) where bimap f g (Flip x) = Flip (bimap g f x) _______________________________________________ Libraries mailing list Libraries@haskell.org <mailto:Libraries@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
I don't know what this means -- can you elaborate? (What I'm proposing is, since there is a sizeable number of people on both sides of the issue who don't seem to be coming closer to an agreement, we bring a vote *to the users* on whether to provide Foldable/Traversable instances for tuples of size 2 and greater. If users say they're useful, we keep/add 'em. If they find them confusing/not useful, we remove/don't add 'em) Tom
El 24 feb 2016, a las 12:27, Chris Allen <cma@bitemyapp.com> escribió:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
On 02/24/2016 11:17 AM, amindfv@gmail.com wrote: It seems like very few people are changing their minds, after a lot of discussion -- maybe it's time to agree to disagree, in the form of a vote on whether to include the tuple instances.
If so, I'd think we'd want to come to the users with a discussion of both sides and a poll, a la FTP.
Tom
El 24 feb 2016, a las 11:38, David Feuer <david.feuer@gmail.com> escribió:
On Wed, Feb 24, 2016 at 11:22 AM, Kosyrev Serge <_deepfire@feelingofgreen.ru> wrote:
Are you also saying that this cannot be resolved by some kind of a type families-based type-level 'flip'?
It really can't, no. You can define
type family FlipF f a b where FlipF f a b = f b a
but FlipF, being a type family, is not first-class. You can't make any instances whatsoever for FlipF f a -- you'll probably get an error about a partially applied type family. What you *can* do is make a Flip newtype:
newtype Flip f a b = Flip {unflip :: f b a}
This behaves perfectly:
instance Bifunctor f => Functor (Flip f a) where fmap f = Flip . first f . unflip instance Profunctor f => Contravariant (Flip f a) where contramap f = Flip . lmap f . unflip instance Bifunctor f => Bifunctor (Flip f) where bimap f g (Flip x) = Flip (bimap g f x) _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
amindfv <amindfv@gmail.com> writes:
(What I'm proposing is, since there is a sizeable number of people on both sides of the issue who don't seem to be coming closer to an agreement, we bring a vote *to the users* on whether to provide Foldable/Traversable instances for tuples of size 2 and greater. If users say they're useful, we keep/add 'em. If they find them confusing/not useful, we remove/don't add 'em)
Also, would we still have access to the instances if we directly import Data.Foldable? Some of us do use them. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
Is that possible with the open world assumption? I personally would definitely be in favor of that if it's technically possible. Tom El 24 feb 2016, a las 13:17, John Wiegley <johnw@newartisans.com> escribió:
amindfv <amindfv@gmail.com> writes:
(What I'm proposing is, since there is a sizeable number of people on both sides of the issue who don't seem to be coming closer to an agreement, we bring a vote *to the users* on whether to provide Foldable/Traversable instances for tuples of size 2 and greater. If users say they're useful, we keep/add 'em. If they find them confusing/not useful, we remove/don't add 'em)
Also, would we still have access to the instances if we directly import Data.Foldable? Some of us do use them.
-- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
El 24 feb 2016, a las 12:27, Chris Allen <cma@bitemyapp.com> escribió:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
On Wed, Feb 24, 2016 at 1:41 PM, <amindfv@gmail.com> wrote:
I don't know what this means -- can you elaborate?
(What I'm proposing is, since there is a sizeable number of people on both sides of the issue who don't seem to be coming closer to an agreement, we bring a vote *to the users* on whether to provide Foldable/Traversable instances for tuples of size 2 and greater. If users say they're useful, we keep/add 'em. If they find them confusing/not useful, we remove/don't add 'em)
If these instances were not included in base, then these instances would nonetheless be made available to a large amount of code because somebody will make a base-orphans library that will define these instances, and many libraries written by authors who believe these instances to be useful will depend on this package (or, worse yet, define their own instances in their own packages which will clash with each other and break things). If any of these libraries end up in the transitive closure of your packages’ dependencies, then you will have these instances defined, regardless of your opinion of them, and regardless of their exclusion from base. To avoid this unhelpful outcome, if the community decided to forbid these instances, some language extension would have to be designed to forbid instance definitions. This has been discussed previously. If the community did this, it would break a lot of code that does use these instances, and there would be no workaround, as forbidding instances would have to be as global as defining instances. Changing the fundamental property of type class instances that makes them not opt-in/opt-out, but automatically imported from transitive dependencies, would remove one of the properties of the language that (as Edward often argues) is a significant part of what makes Haskell more useful and healthy than some of its kin. This is not a matter that can be resolved but by consensus, at least not with the solutions that have been thus far proposed (simply removing the instances or accepting the instances as they are). We do not appear to be approaching consensus on these particular solutions. Accepting the instances as they are does have the benefit of already being implemented and being used by a lot of code (but «we’ve always done things this way» is not a good design criterion). Adding more instances for tuples would make the current situation more consistent, although perhaps proponents of removing these instances would prefer the current status quo: inconsistency, but less instances whose existence they reject.
What happened in the FTP was that the libraries@ had a heated discussion, the issue was taken to the users and to a vote, and we ended up with a clear message from users: 80% voted in one direction. My suspicion is that on this issue too, libraries@ is more divided than the community is. I suggest we try to put this issue to bed, and if ~80% of the community says they don't want these instances, then yes -- core libraries should use Writer instead of redefining their own instance for (,). Similarly, if ~80% want the instances, we can grumble that users are wrong but democracy has spoken. Tom El 24 feb 2016, a las 13:27, Manuel Gómez <targen@gmail.com> escribió:
El 24 feb 2016, a las 12:27, Chris Allen <cma@bitemyapp.com> escribió:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
On Wed, Feb 24, 2016 at 1:41 PM, <amindfv@gmail.com> wrote: I don't know what this means -- can you elaborate?
(What I'm proposing is, since there is a sizeable number of people on both sides of the issue who don't seem to be coming closer to an agreement, we bring a vote *to the users* on whether to provide Foldable/Traversable instances for tuples of size 2 and greater. If users say they're useful, we keep/add 'em. If they find them confusing/not useful, we remove/don't add 'em)
If these instances were not included in base, then these instances would nonetheless be made available to a large amount of code because somebody will make a base-orphans library that will define these instances, and many libraries written by authors who believe these instances to be useful will depend on this package (or, worse yet, define their own instances in their own packages which will clash with each other and break things). If any of these libraries end up in the transitive closure of your packages’ dependencies, then you will have these instances defined, regardless of your opinion of them, and regardless of their exclusion from base.
To avoid this unhelpful outcome, if the community decided to forbid these instances, some language extension would have to be designed to forbid instance definitions. This has been discussed previously. If the community did this, it would break a lot of code that does use these instances, and there would be no workaround, as forbidding instances would have to be as global as defining instances. Changing the fundamental property of type class instances that makes them not opt-in/opt-out, but automatically imported from transitive dependencies, would remove one of the properties of the language that (as Edward often argues) is a significant part of what makes Haskell more useful and healthy than some of its kin.
This is not a matter that can be resolved but by consensus, at least not with the solutions that have been thus far proposed (simply removing the instances or accepting the instances as they are). We do not appear to be approaching consensus on these particular solutions. Accepting the instances as they are does have the benefit of already being implemented and being used by a lot of code (but «we’ve always done things this way» is not a good design criterion). Adding more instances for tuples would make the current situation more consistent, although perhaps proponents of removing these instances would prefer the current status quo: inconsistency, but less instances whose existence they reject.
(Sorry, I should have said: "core libraries *may* need to use Writer instead of redefining an instance for (,)" -- I don't mean to rule out other technical solutions if they exist) Tom
El 24 feb 2016, a las 14:10, amindfv@gmail.com escribió:
What happened in the FTP was that the libraries@ had a heated discussion, the issue was taken to the users and to a vote, and we ended up with a clear message from users: 80% voted in one direction. My suspicion is that on this issue too, libraries@ is more divided than the community is. I suggest we try to put this issue to bed, and if ~80% of the community says they don't want these instances, then yes -- core libraries should use Writer instead of redefining their own instance for (,). Similarly, if ~80% want the instances, we can grumble that users are wrong but democracy has spoken.
Tom
El 24 feb 2016, a las 13:27, Manuel Gómez <targen@gmail.com> escribió:
El 24 feb 2016, a las 12:27, Chris Allen <cma@bitemyapp.com> escribió:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
On Wed, Feb 24, 2016 at 1:41 PM, <amindfv@gmail.com> wrote: I don't know what this means -- can you elaborate?
(What I'm proposing is, since there is a sizeable number of people on both sides of the issue who don't seem to be coming closer to an agreement, we bring a vote *to the users* on whether to provide Foldable/Traversable instances for tuples of size 2 and greater. If users say they're useful, we keep/add 'em. If they find them confusing/not useful, we remove/don't add 'em)
If these instances were not included in base, then these instances would nonetheless be made available to a large amount of code because somebody will make a base-orphans library that will define these instances, and many libraries written by authors who believe these instances to be useful will depend on this package (or, worse yet, define their own instances in their own packages which will clash with each other and break things). If any of these libraries end up in the transitive closure of your packages’ dependencies, then you will have these instances defined, regardless of your opinion of them, and regardless of their exclusion from base.
To avoid this unhelpful outcome, if the community decided to forbid these instances, some language extension would have to be designed to forbid instance definitions. This has been discussed previously. If the community did this, it would break a lot of code that does use these instances, and there would be no workaround, as forbidding instances would have to be as global as defining instances. Changing the fundamental property of type class instances that makes them not opt-in/opt-out, but automatically imported from transitive dependencies, would remove one of the properties of the language that (as Edward often argues) is a significant part of what makes Haskell more useful and healthy than some of its kin.
This is not a matter that can be resolved but by consensus, at least not with the solutions that have been thus far proposed (simply removing the instances or accepting the instances as they are). We do not appear to be approaching consensus on these particular solutions. Accepting the instances as they are does have the benefit of already being implemented and being used by a lot of code (but «we’ve always done things this way» is not a good design criterion). Adding more instances for tuples would make the current situation more consistent, although perhaps proponents of removing these instances would prefer the current status quo: inconsistency, but less instances whose existence they reject.
El 24 feb 2016, a las 14:10, amindfv@gmail.com escribió: What happened in the FTP was that the libraries@ had a heated discussion, the issue was taken to the users and to a vote, and we ended up with a clear message from users: 80% voted in one direction. My suspicion is that on this issue too, libraries@ is more divided than the community is. I suggest we try to put this issue to bed, and if ~80% of the community says they don't want these instances, then yes -- core libraries should use Writer instead of redefining their own instance for (,). Similarly, if ~80% want the instances, we can grumble that users are wrong but democracy has spoken.
On Wed, Feb 24, 2016 at 2:46 PM, <amindfv@gmail.com> wrote:
(Sorry, I should have said: "core libraries *may* need to use Writer instead of redefining an instance for (,)" -- I don't mean to rule out other technical solutions if they exist)
I must insist: even if 80% don’t want these instances and they are removed, they will very often get these instances. Even if they are removed from base, people will define instances for them in packages most everyone will transitively depend on. The only ways to ensure you don’t touch these instances are 1. to remove them from base and hope you never depend on any package, **transitively**, that defines them, or 2. to implement a language extension in GHC that allows source language to specify a certain instance will never be defined and a type error shall be thrown statically at any use site, or 3. to implement a radical, fundamental change in the design for type class instance visibility rules that allows them to be selectively imported or excluded, or 4. to avoid tuples and/or Foldable/Traversable altogether. This cannot be solved with a vote. A vote would only serve as a distraction. This was not the case with the FTP: the FTP implied generalized signatures for terms bound to names in the Prelude and Data.List, and you *can* control what names you import. You can’t do this with instances.
On Wed, Feb 24, 2016 at 3:53 PM, Manuel Gómez <targen@gmail.com> wrote:
2. to implement a language extension in GHC that allows source language to specify a certain instance will never be defined and a type error shall be thrown statically at any use site, or
I misspoke: this should read «at any instance definition site for the forbidden instance» or somesuch.
El 24 feb 2016, a las 15:23, Manuel Gómez <targen@gmail.com> escribió:
El 24 feb 2016, a las 14:10, amindfv@gmail.com escribió: What happened in the FTP was that the libraries@ had a heated discussion, the issue was taken to the users and to a vote, and we ended up with a clear message from users: 80% voted in one direction. My suspicion is that on this issue too, libraries@ is more divided than the community is. I suggest we try to put this issue to bed, and if ~80% of the community says they don't want these instances, then yes -- core libraries should use Writer instead of redefining their own instance for (,). Similarly, if ~80% want the instances, we can grumble that users are wrong but democracy has spoken.
On Wed, Feb 24, 2016 at 2:46 PM, <amindfv@gmail.com> wrote: (Sorry, I should have said: "core libraries *may* need to use Writer instead of redefining an instance for (,)" -- I don't mean to rule out other technical solutions if they exist)
I must insist: even if 80% don’t want these instances and they are removed, they will very often get these instances. Even if they are removed from base, people will define instances for them in packages most everyone will transitively depend on. The only ways to ensure you don’t touch these instances are
When I said "core libraries" I meant the libraries that everyone depends on, not just base. If (if!) we have a strong majority of users saying they don't like this instance, we should allow them to not have it. Not by rule of iron fist but of "it would be impolite to slip that instance into users' code now that we know they don't want it." Recall the switch to Writer from (,) is pretty trivial. Re: the idea of this being a rehash of FTP: I'm an example of someone who supported FTP but would like to be able to not have this instance. Stories like Andrew Farmer's -- of not being able to make a change to your types and have the typechecker tell you what's broken -- are compelling to many of us. Tom
1. to remove them from base and hope you never depend on any package, **transitively**, that defines them, or
2. to implement a language extension in GHC that allows source language to specify a certain instance will never be defined and a type error shall be thrown statically at any use site, or
3. to implement a radical, fundamental change in the design for type class instance visibility rules that allows them to be selectively imported or excluded, or
4. to avoid tuples and/or Foldable/Traversable altogether.
This cannot be solved with a vote. A vote would only serve as a distraction. This was not the case with the FTP: the FTP implied generalized signatures for terms bound to names in the Prelude and Data.List, and you *can* control what names you import. You can’t do this with instances.
2. to implement a language extension in GHC that allows source language to specify a certain instance will never be defined and a type error shall be thrown statically at any use site, or
How about a feature that allows GHC to warn whenever a certain instance is used? That way, if you don't like a certain instance, you can put {-# FORBIDINSTANCE Foldable ((,) a) #-} in your modules and get warnings whenever that instance is used.
Yes, at this point I think the best we can do is to make sure we get good warnings. I'd suggest that we can attach a warning to a method in each instance. So when using length on a tuple we'd get a warning. I don't even want to upgrade ghc to get the FTP until such a warning is in place (we are still on 7.8). -----Original Message----- From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Phil Ruffwind Sent: 25 February 2016 13:01 To: Manuel Gómez Cc: Haskell Libraries Subject: Re: Haskell Foldable Wats
2. to implement a language extension in GHC that allows source language to specify a certain instance will never be defined and a type error shall be thrown statically at any use site, or
How about a feature that allows GHC to warn whenever a certain instance is used? That way, if you don't like a certain instance, you can put {-# FORBIDINSTANCE Foldable ((,) a) #-} in your modules and get warnings whenever that instance is used. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
Perhaps such warnings could be added to a tool like HLint? I do not think they belong in GHC. On Thu, Feb 25, 2016 at 5:40 AM, Augustsson, Lennart < Lennart.Augustsson@sc.com> wrote:
Yes, at this point I think the best we can do is to make sure we get good warnings. I'd suggest that we can attach a warning to a method in each instance. So when using length on a tuple we'd get a warning. I don't even want to upgrade ghc to get the FTP until such a warning is in place (we are still on 7.8).
-----Original Message----- From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Phil Ruffwind Sent: 25 February 2016 13:01 To: Manuel Gómez Cc: Haskell Libraries Subject: Re: Haskell Foldable Wats
2. to implement a language extension in GHC that allows source language to specify a certain instance will never be defined and a type error shall be thrown statically at any use site, or
How about a feature that allows GHC to warn whenever a certain instance is used? That way, if you don't like a certain instance, you can put {-# FORBIDINSTANCE Foldable ((,) a) #-} in your modules and get warnings whenever that instance is used. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html
Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx
Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same.
Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Mark Roberts <markandrusroberts@gmail.com> writes:
Perhaps such warnings could be added to a tool like HLint? I do not think they belong in GHC.
People have circulated somewhat convincing examples that show how these Functor instances lead to real bugs. I doubt they would agree. Besides -- these warning are supposed to be opt-in at the use sites, aren't they? -- с уважениeм / respectfully, Косырев Сергей
these warning are supposed to be opt-in at the use sites, aren't they?
As I read it, Phil's suggestion of a FORBIDINSTANCE language extension would be opt-in per module. Lennart's suggestion of attaching warnings to methods in the instance does not seem opt-in. Lennart, have I misinterpreted? People have circulated somewhat convincing examples that show how these
Functor instances lead to real bugs.
And there are those who are fine with these instances, too. You could imagine many more disagreements which are a consequence of polymorphism. So this feels more like a code-style/linting issue to me, and I think that using a tool like HLint would be more appropriate than introducing a language extension or other change to GHC. On Thu, Feb 25, 2016 at 1:35 PM, Kosyrev Serge <_deepfire@feelingofgreen.ru> wrote:
Mark Roberts <markandrusroberts@gmail.com> writes:
Perhaps such warnings could be added to a tool like HLint? I do not think they belong in GHC.
People have circulated somewhat convincing examples that show how these Functor instances lead to real bugs.
I doubt they would agree.
Besides -- these warning are supposed to be opt-in at the use sites, aren't they?
-- с уважениeм / respectfully, Косырев Сергей
On Thu, 25 Feb 2016, Mark Roberts wrote:
Perhaps such warnings could be added to a tool like HLint? I do not think they belong in GHC.
HLint is intended for simplifying complicated code, but not for finding bugs. It emits several false positives, thus I only run it occassionally. I know I can disable certain HLint warnings, but there are really ones that I respect at one place and ignore at other places.
On Thu, 25 Feb 2016, Augustsson, Lennart wrote:
Yes, at this point I think the best we can do is to make sure we get good warnings. I'd suggest that we can attach a warning to a method in each instance. So when using length on a tuple we'd get a warning. I don't even want to upgrade ghc to get the FTP until such a warning is in place (we are still on 7.8).
Me too. I have earlier written about the wish for such warnings. A general solution would be close to explicit import of instances and is certainly far away. If we can agree on warnings on 'length' on tuples this would be simpler and might already help.
If I'm reading these threads correctly - and if I'm horribly mistaken then I apologise - they mostly are people from the 20% against FTP grumbling that the users are wrong, while a large chunk of the people from the 80% for FTP not wanting to spend that sizeable amount of energy again to debate an old argument. If that is the case then libraries@ may not be as divided as it seems. To take it all back a step, unless I've missed a mail in this thread, we only have a proposal for adding Functor instances for tuples of larger size than 2. If someone wants to put forward a proposal on how to remove the Functor / Foldable / Traversable instances for tuples - including how to deal with breakage in existing code and other migration issues - surely that's another thread, that would start when someone properly fleshes out the proposal. Dave On Thu, Feb 25, 2016 at 5:10 AM, <amindfv@gmail.com> wrote:
What happened in the FTP was that the libraries@ had a heated discussion, the issue was taken to the users and to a vote, and we ended up with a clear message from users: 80% voted in one direction. My suspicion is that on this issue too, libraries@ is more divided than the community is. I suggest we try to put this issue to bed, and if ~80% of the community says they don't want these instances, then yes -- core libraries should use Writer instead of redefining their own instance for (,). Similarly, if ~80% want the instances, we can grumble that users are wrong but democracy has spoken.
Tom
El 24 feb 2016, a las 13:27, Manuel Gómez <targen@gmail.com> escribió:
El 24 feb 2016, a las 12:27, Chris Allen <cma@bitemyapp.com> escribió:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
On Wed, Feb 24, 2016 at 1:41 PM, <amindfv@gmail.com> wrote: I don't know what this means -- can you elaborate?
(What I'm proposing is, since there is a sizeable number of people on both sides of the issue who don't seem to be coming closer to an agreement, we bring a vote *to the users* on whether to provide Foldable/Traversable instances for tuples of size 2 and greater. If users say they're useful, we keep/add 'em. If they find them confusing/not useful, we remove/don't add 'em)
If these instances were not included in base, then these instances would nonetheless be made available to a large amount of code because somebody will make a base-orphans library that will define these instances, and many libraries written by authors who believe these instances to be useful will depend on this package (or, worse yet, define their own instances in their own packages which will clash with each other and break things). If any of these libraries end up in the transitive closure of your packages’ dependencies, then you will have these instances defined, regardless of your opinion of them, and regardless of their exclusion from base.
To avoid this unhelpful outcome, if the community decided to forbid these instances, some language extension would have to be designed to forbid instance definitions. This has been discussed previously. If the community did this, it would break a lot of code that does use these instances, and there would be no workaround, as forbidding instances would have to be as global as defining instances. Changing the fundamental property of type class instances that makes them not opt-in/opt-out, but automatically imported from transitive dependencies, would remove one of the properties of the language that (as Edward often argues) is a significant part of what makes Haskell more useful and healthy than some of its kin.
This is not a matter that can be resolved but by consensus, at least not with the solutions that have been thus far proposed (simply removing the instances or accepting the instances as they are). We do not appear to be approaching consensus on these particular solutions. Accepting the instances as they are does have the benefit of already being implemented and being used by a lot of code (but «we’ve always done things this way» is not a good design criterion). Adding more instances for tuples would make the current situation more consistent, although perhaps proponents of removing these instances would prefer the current status quo: inconsistency, but less instances whose existence they reject.
Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
amindfv@gmail.com writes:
I suggest we try to put this issue to bed, and if ~80% of the community says they don't want these instances, then yes -- core libraries should use Writer instead of redefining their own instance for (,). Similarly, if ~80% want the instances, we can grumble that users are wrong but democracy has spoken.
If it comes to suggestions, I think the first step should be a Wiki page, that would sufficiently exhaustively describe the overall problem, and enumerate various options of dealing with the situation, with their pros and cons. As it stands, any kind of vote wouldn't be quite informed, I believe. -- с уважениeм / respectfully, Косырев Сергей
In my opinion, democracy is the wrong way to design a programming language. -----Original Message----- From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of amindfv@gmail.com Sent: 24 February 2016 19:11 To: Manuel Gómez Cc: Haskell Libraries Subject: Re: Haskell Foldable Wats What happened in the FTP was that the libraries@ had a heated discussion, the issue was taken to the users and to a vote, and we ended up with a clear message from users: 80% voted in one direction. My suspicion is that on this issue too, libraries@ is more divided than the community is. I suggest we try to put this issue to bed, and if ~80% of the community says they don't want these instances, then yes -- core libraries should use Writer instead of redefining their own instance for (,). Similarly, if ~80% want the instances, we can grumble that users are wrong but democracy has spoken. Tom El 24 feb 2016, a las 13:27, Manuel Gómez <targen@gmail.com> escribió:
El 24 feb 2016, a las 12:27, Chris Allen <cma@bitemyapp.com> escribió:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
On Wed, Feb 24, 2016 at 1:41 PM, <amindfv@gmail.com> wrote: I don't know what this means -- can you elaborate?
(What I'm proposing is, since there is a sizeable number of people on both sides of the issue who don't seem to be coming closer to an agreement, we bring a vote *to the users* on whether to provide Foldable/Traversable instances for tuples of size 2 and greater. If users say they're useful, we keep/add 'em. If they find them confusing/not useful, we remove/don't add 'em)
If these instances were not included in base, then these instances would nonetheless be made available to a large amount of code because somebody will make a base-orphans library that will define these instances, and many libraries written by authors who believe these instances to be useful will depend on this package (or, worse yet, define their own instances in their own packages which will clash with each other and break things). If any of these libraries end up in the transitive closure of your packages’ dependencies, then you will have these instances defined, regardless of your opinion of them, and regardless of their exclusion from base.
To avoid this unhelpful outcome, if the community decided to forbid these instances, some language extension would have to be designed to forbid instance definitions. This has been discussed previously. If the community did this, it would break a lot of code that does use these instances, and there would be no workaround, as forbidding instances would have to be as global as defining instances. Changing the fundamental property of type class instances that makes them not opt-in/opt-out, but automatically imported from transitive dependencies, would remove one of the properties of the language that (as Edward often argues) is a significant part of what makes Haskell more useful and healthy than some of its kin.
This is not a matter that can be resolved but by consensus, at least not with the solutions that have been thus far proposed (simply removing the instances or accepting the instances as they are). We do not appear to be approaching consensus on these particular solutions. Accepting the instances as they are does have the benefit of already being implemented and being used by a lot of code (but «we’ve always done things this way» is not a good design criterion). Adding more instances for tuples would make the current situation more consistent, although perhaps proponents of removing these instances would prefer the current status quo: inconsistency, but less instances whose existence they reject.
Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
On Wed, 24 Feb 2016, amindfv@gmail.com wrote:
What happened in the FTP was that the libraries@ had a heated discussion, the issue was taken to the users and to a vote, and we ended up with a clear message from users: 80% voted in one direction.
And the community as a whole is still not happy.
My suspicion is that on this issue too, libraries@ is more divided than the community is. I suggest we try to put this issue to bed, and if ~80% of the community says they don't want these instances, then yes -- core libraries should use Writer instead of redefining their own instance for (,). Similarly, if ~80% want the instances, we can grumble that users are wrong but democracy has spoken.
That's not democracy, but majority. I think we need other ways for making decisions. I had already proposed one.
To pile on a bit, I'm somewhat of the opinion that if one doesn't like the consistency that demands typeclass instances for such "degenerate" types, that one simply *doesn't like Haskell.* Typeclass coherence, the prohibition on orphan instances, and uniformity of abstraction of this sort are so central to the language that to add corner cases which *exclude* legitimate use of existing types would be to choose a different (and in my opinion less pleasant and flexible) language entirely. I don't presume to speak for anyone but myself, but in off-list discussion with other Haskellers essentially everyone is simply boggled by the idea that there's a group of users that wants to make Haskell *less* internally consistent, just so that they can call `length (foo, bar)`. All in all, the complaints I've seen here strike me as very reminiscent of those who complain about type erasure on the JVM - blithely unaware that it's one of the few things that that community got *right.* Kris On Wed, Feb 24, 2016 at 11:27 AM, Manuel Gómez <targen@gmail.com> wrote:
El 24 feb 2016, a las 12:27, Chris Allen <cma@bitemyapp.com> escribió:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
On Wed, Feb 24, 2016 at 1:41 PM, <amindfv@gmail.com> wrote:
I don't know what this means -- can you elaborate?
(What I'm proposing is, since there is a sizeable number of people on both sides of the issue who don't seem to be coming closer to an agreement, we bring a vote *to the users* on whether to provide Foldable/Traversable instances for tuples of size 2 and greater. If users say they're useful, we keep/add 'em. If they find them confusing/not useful, we remove/don't add 'em)
If these instances were not included in base, then these instances would nonetheless be made available to a large amount of code because somebody will make a base-orphans library that will define these instances, and many libraries written by authors who believe these instances to be useful will depend on this package (or, worse yet, define their own instances in their own packages which will clash with each other and break things). If any of these libraries end up in the transitive closure of your packages’ dependencies, then you will have these instances defined, regardless of your opinion of them, and regardless of their exclusion from base.
To avoid this unhelpful outcome, if the community decided to forbid these instances, some language extension would have to be designed to forbid instance definitions. This has been discussed previously. If the community did this, it would break a lot of code that does use these instances, and there would be no workaround, as forbidding instances would have to be as global as defining instances. Changing the fundamental property of type class instances that makes them not opt-in/opt-out, but automatically imported from transitive dependencies, would remove one of the properties of the language that (as Edward often argues) is a significant part of what makes Haskell more useful and healthy than some of its kin.
This is not a matter that can be resolved but by consensus, at least not with the solutions that have been thus far proposed (simply removing the instances or accepting the instances as they are). We do not appear to be approaching consensus on these particular solutions. Accepting the instances as they are does have the benefit of already being implemented and being used by a lot of code (but «we’ve always done things this way» is not a good design criterion). Adding more instances for tuples would make the current situation more consistent, although perhaps proponents of removing these instances would prefer the current status quo: inconsistency, but less instances whose existence they reject. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
On Wed, 24 Feb 2016, Manuel Gómez wrote:
To avoid this unhelpful outcome, if the community decided to forbid these instances, some language extension would have to be designed to forbid instance definitions. This has been discussed previously.
It's possible to achieve this without language extensions.
If the community did this, it would break a lot of code that does use these instances, and there would be no workaround,
The backwards-compatible work-around would be simple: Don't use fmap, but mapThd3 and friends. It would be a good opportunity to cleanup code.
On Wed, Feb 24, 2016 at 11:27:48AM -0600, Chris Allen wrote:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
What was the design decision behind orphans? Why were they considered a good idea? Has there ever been a discussion to only allow instance definitions in the same library as the data type definition or the class definition? Greetings, Daniel
Has there ever been a discussion to only allow instance definitions in the same library as the data type definition or the class definition?
Not allowing orphans at all would be problematic in the presence of type classes and data types in packages which are hard to impossible to upgrade (like base). You couldn't even locally experiment with new instances that way. On Thu, Feb 25, 2016 at 10:21 AM, Daniel Trstenjak <daniel.trstenjak@gmail.com> wrote:
On Wed, Feb 24, 2016 at 11:27:48AM -0600, Chris Allen wrote:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
What was the design decision behind orphans? Why were they considered a good idea?
Has there ever been a discussion to only allow instance definitions in the same library as the data type definition or the class definition?
Greetings, Daniel _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
On 2016-02-25 at 10:21:20 +0100, Daniel Trstenjak wrote:
What was the design decision behind orphans? Why were they considered a good idea?
In Haskell 1.2 there was a so-called "C-T Rule" which was relaxed for Haskell 1.3 [1]: | C-T Rule relaxation | | The C-T rule restricts the placement of instance declarations to the | module containing either the class or data type definition associated | with an instance. This is unnecessarily restrictive and will be relaxed | in Haskell 1.3. The new restriction will be that no more than one | instance for a given class - datatype pair is allowed in a | program. (Sadly, there's little hope of detecting violations of this | rule before link time.) | | The visibility of instance declarations presents a problem. Unlike | classes or types, instances cannot be mentioned explicitly in export | lists. Instead of changing the syntax of the export list, we have | adopted a simple rule: all instances are exported regardless of the | export list. All imports bring in the full set of instances from the | imported module. An instance is in scope when a chainof import | statements leads to the module defining the instance. With some luck you may be able to find the discussions leading up to that decision in old email archives. Maybe relevant to this discussion: the rejected paper "Controlling the scope of instances in Haskell" submitted for the 2011 Haskell Symposium together with the rejecting referee reports[2] [1]: https://www.haskell.org/definition/from12to13.html [2]: https://mail.haskell.org/pipermail/ghc-devs/2014-October/006876.html
Herbert Valerio Riedel <hvr@gnu.org> writes:
Maybe relevant to this discussion: the rejected paper "Controlling the scope of instances in Haskell" submitted for the 2011 Haskell Symposium together with the rejecting referee reports[2]
[1]: https://www.haskell.org/definition/from12to13.html
[2]: https://mail.haskell.org/pipermail/ghc-devs/2014-October/006876.html
Interestingly, the Review 4 states: ,---- | At a higher level, the paper did not address what could be described as | the "philosophy" behind type classes, which were built with the intent | of being used when there was only a single interpretation of an operator | on a type. `---- While this sounds intuitive to me, I have never heard it stated explicitly, and moreso, actually being specifically intended at design level. Is it possible to know more about this? It does seem relevant to this discussion.. -- с уважениeм / respectfully, Косырев Сергей
My personal view on instances is that when there _is_ exactly one possible instance it is almost always useful to define it. You get a good set of questions and learn new connections to old concepts this way. However, not every instance is of this sort. This isn't the same thing being said by reviewer #4. I would disagree with reviewer 4 and say that the much much stronger claim that every instance must be the only possible instance simply isn't true. It is very desirable, but not true. This is equivalent to saying that every instance must be "property-like-structure" <https://ncatlab.org/nlab/show/stuff,+structure,+property#generalization_to_categories_and_higher_categories> . The Monoid instance for [a] isn't forced. It could after all, go the other way. There are also two possible Applicative instances -- one based on ZipList. That said, given the Monad, the Applicative is forced. If we take [a] to be the 'free monoid' and give it the obvious flattening Monad, then the other properties of lists are uniquely defined though. Show/Read are "mostly unique" in that the code they round-trip through could vary somewhat. Ord is defined by arbitrary convention. Similarly other constructions such as Traversable are "mostly unique" up to ordering issues and conventions. A somewhat weaker claim can be made that when you define a data type: you usually define it for some purpose, and supply instances that reflect that intent, but then adding other instances that go beyond your initial intent so long as they are uniquely defined, simply tells you more about the data type and permit users to use a larger, consistent, vocabulary. Many of these issues that are being rehashed in this thread arise when people disagree is on "what is the data type's stated purpose". When the instance is uniquely determined it is usually easily sold to the community. When it isn't, there is a lot more room for discussion. -Edward On Thu, Feb 25, 2016 at 5:53 AM, Kosyrev Serge <_deepfire@feelingofgreen.ru> wrote:
Herbert Valerio Riedel <hvr@gnu.org> writes:
Maybe relevant to this discussion: the rejected paper "Controlling the scope of instances in Haskell" submitted for the 2011 Haskell Symposium together with the rejecting referee reports[2]
[1]: https://www.haskell.org/definition/from12to13.html
[2]: https://mail.haskell.org/pipermail/ghc-devs/2014-October/006876.html
Interestingly, the Review 4 states:
,---- | At a higher level, the paper did not address what could be described as | the "philosophy" behind type classes, which were built with the intent | of being used when there was only a single interpretation of an operator | on a type. `----
While this sounds intuitive to me, I have never heard it stated explicitly, and moreso, actually being specifically intended at design level.
Is it possible to know more about this?
It does seem relevant to this discussion..
-- с уважениeм / respectfully, Косырев Сергей _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
On Wed, 24 Feb 2016, Chris Allen wrote:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
We could define instance Impossible a => Functor ((,,) a b) where where Impossible is a non exported class.
Even better might be to use GHC 8 custom type errors in the constraint head to explain what 'Impossible' means. On Tue, 22 Mar 2016 10:21 am Henning Thielemann, < lemming@henning-thielemann.de> wrote:
On Wed, 24 Feb 2016, Chris Allen wrote:
You can't not-include the instances because we'll just end up with orphans so that's not cricket I think.
We could define
instance Impossible a => Functor ((,,) a b) where
where Impossible is a non exported class. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
David Feuer <david.feuer@gmail.com> writes:
On Wed, Feb 24, 2016 at 11:22 AM, Kosyrev Serge <_deepfire@feelingofgreen.ru> wrote:
Are you also saying that this cannot be resolved by some kind of a type families-based type-level 'flip'?
It really can't, no. You can define
type family FlipF f a b where FlipF f a b = f b a
but FlipF, being a type family, is not first-class. You can't make any instances whatsoever for FlipF f a -- you'll probably get an error about a partially applied type family. What you *can* do is make a Flip newtype:
newtype Flip f a b = Flip {unflip :: f b a}
How wrong would it be to say that the conceptually arbitrary choice of the Functor instance is "saved" by a technical limitation, making it the only choice? How likely is a proper type-level 'flip' tomorrow -- for some value of "proper" and "tomorrow"? -- с уважениeм / respectfully, Косырев Сергей
Haskell's notion of Functor is in fact somewhat arbitrary from the standpoint of mathematical functors. It's not at all arbitrary from the standpoint of the general variety of type system Haskell uses. I'd call it a "deep design choice" rather than a "technical limitation". I think the newtype I gave for Flip and the type family I gave for FlipF are the best you're ever likely to see. I do hope that the status of type families will improve somewhat in the future (e.g., I'd love to be able to map a type family over a list of types), but that won't get you the sorts of instances you're dreaming of. On Wed, Feb 24, 2016 at 4:56 PM, Kosyrev Serge <_deepfire@feelingofgreen.ru> wrote:
David Feuer <david.feuer@gmail.com> writes:
On Wed, Feb 24, 2016 at 11:22 AM, Kosyrev Serge <_ deepfire@feelingofgreen.ru> wrote:
Are you also saying that this cannot be resolved by some kind of a type families-based type-level 'flip'?
It really can't, no. You can define
type family FlipF f a b where FlipF f a b = f b a
but FlipF, being a type family, is not first-class. You can't make any instances whatsoever for FlipF f a -- you'll probably get an error about a partially applied type family. What you *can* do is make a Flip newtype:
newtype Flip f a b = Flip {unflip :: f b a}
How wrong would it be to say that the conceptually arbitrary choice of the Functor instance is "saved" by a technical limitation, making it the only choice?
How likely is a proper type-level 'flip' tomorrow -- for some value of "proper" and "tomorrow"?
-- с уважениeм / respectfully, Косырев Сергей
David Feuer <david.feuer@gmail.com> writes:
Haskell's notion of Functor is in fact somewhat arbitrary from the standpoint of mathematical functors. It's not at all arbitrary from the standpoint of the general variety of type system Haskell uses.
This fact that we can't partially apply a type constructor in an arbitrary way -- is it really all that fundamental to the Haskell type system? Is it truly something more than an implementation detail? If so, why? -- с уважениeм / respectfully, Косырев Сергей
Several suggestions have been made in this thread. The one with the highest cost-to-benefit ratio would seem to be removing the Foldable constraint from Traversable, as it is simply not required by the Traversable definition. Lennart actually tried recompiling base with this "and it hardly needed any changes". I suggest that we consider this change first, as it brings the benefit of allowing Traversable types without having to define possibly nonsensical Foldable instances, and according to Lennart's experiment, has trivial impact. Lennart, what changes did you have to make? Anybody care to recompile their pet project with this change and see if there's any significant impact? -- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func... Sent from the Haskell - Libraries mailing list archive at Nabble.com.
This is getting ridiculous. The main problem with the `Foldable` instance for tuples seems to be that it's asymmetric (takes only the second element into account). Yet tuples are already asymmetric given their `Functor` instance! No one seems to complain about that although for a beginner it's a total WAT (judging from my own experience and people that I explained Haskell to). Why does `succ <$> (1, 2)` evaluate to `(1, 3)` and not `(2, 3)`? Current definitions are entirely consistent, and consistency is the most valuable property. And given that `Traversable` gives a rise to a `Foldable` similarly to how a `Monad` gives a rise to an `Applicative`, it is the same stupid mistake not to reflect this relation in the type system. The ship has sailed, but not when the `Foldable` instance defined. It has sailed when the `Functor` instance was defined, everything else is a follow-up. Just get over it already. On Thu, Feb 25, 2016 at 11:28 AM, Jeremy <voldermort@hotmail.com> wrote:
Several suggestions have been made in this thread. The one with the highest cost-to-benefit ratio would seem to be removing the Foldable constraint from Traversable, as it is simply not required by the Traversable definition. Lennart actually tried recompiling base with this "and it hardly needed any changes".
I suggest that we consider this change first, as it brings the benefit of allowing Traversable types without having to define possibly nonsensical Foldable instances, and according to Lennart's experiment, has trivial impact.
Lennart, what changes did you have to make? Anybody care to recompile their pet project with this change and see if there's any significant impact?
-- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func... Sent from the Haskell - Libraries mailing list archive at Nabble.com. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Index Int wrote
This is getting ridiculous. The main problem with the `Foldable` instance for tuples seems to be that it's asymmetric (takes only the second element into account). Yet tuples are already asymmetric given their `Functor` instance! No one seems to complain about that although for a beginner it's a total WAT (judging from my own experience and people that I explained Haskell to). Why does `succ <$> (1, 2)` evaluate to `(1, 3)` and not `(2, 3)`? Current definitions are entirely consistent, and consistency is the most valuable property.
The difference is that Functor over tuples has some debatable, although arguably misleading uses, but Foldable has no sensible uses whatsoever. Index Int wrote
And given that `Traversable` gives a rise to a `Foldable` similarly to how a `Monad` gives a rise to an `Applicative`, it is the same stupid mistake not to reflect this relation in the type system.
The Monad definition actually uses the Applicative instance. Traversable makes no use of Foldable. -- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func... Sent from the Haskell - Libraries mailing list archive at Nabble.com.
On 2016-02-25 at 12:12:33 +0100, Jeremy wrote: [...]
Index Int wrote
And given that `Traversable` gives a rise to a `Foldable` similarly to how a `Monad` gives a rise to an `Applicative`, it is the same stupid mistake not to reflect this relation in the type system.
The Monad definition actually uses the Applicative instance. Traversable makes no use of Foldable.
What do you mean by that exactly? Haskell 2010 defines the `Monad` class as: class Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b (>>) :: m a -> m b -> m b m >> k = m >>= \_ -> k fail :: String -> m a fail = error whereas with AMP+MRP+MFP we would end up with the following quite minimal `Monad` class definition: class Applicative m => Monad m where (>>=) :: m a -> (a -> m b) -> m b In neither case `Applicative`'s methods are used. Maybe a better example you could argue is that the `Ord` class *currently* uses its `Eq` superclass to support its default implementation of `compare`. But other than that you could just as easily define an `Ord` class which does not use `(==)` in any of its default method implementations, and therefore would exhibit a redundant superclass constraint on `Eq`. But even then I guess nobody would want to remove the `Eq` superclass from `Ord` either?
I like this argumentation! Consistency is really the most valuable property! Which contra-arguments is?
It is unintuitive { maximum (100,4) == 4; length (1,2) == 1 }
Intuition could be different. If we understand asymmetry of tuple than it is completely natural.
It is hard to explain to students
You don't need to explain it. Tuples are one of the first things to discuss. No classes in scope yet. Later when you go through (Functor, Applicative) to (Foldable, Traversable) there will be no problem.
It is useless
I suppose that use cases are close to use cases for Functor instances.
It provoke to use tuples extensively
I don't think that exactly these instances provoke this.
It can produce errors in runtime
Yes, and so avoid tuples in most cases. These instances just provoke not to use tuples!
What else? I suppose that either tuples are symmetric and have no Functor instances or they are assymetric with all consequences. And there is absolutely no reason to change natural class hierarchy due to imaginary newbie confusion. 2016-02-25 11:43 GMT+03:00 Index Int <vlad.z.4096@gmail.com>:
This is getting ridiculous. The main problem with the `Foldable` instance for tuples seems to be that it's asymmetric (takes only the second element into account). Yet tuples are already asymmetric given their `Functor` instance! No one seems to complain about that although for a beginner it's a total WAT (judging from my own experience and people that I explained Haskell to). Why does `succ <$> (1, 2)` evaluate to `(1, 3)` and not `(2, 3)`? Current definitions are entirely consistent, and consistency is the most valuable property.
And given that `Traversable` gives a rise to a `Foldable` similarly to how a `Monad` gives a rise to an `Applicative`, it is the same stupid mistake not to reflect this relation in the type system.
The ship has sailed, but not when the `Foldable` instance defined. It has sailed when the `Functor` instance was defined, everything else is a follow-up. Just get over it already.
On Thu, Feb 25, 2016 at 11:28 AM, Jeremy <voldermort@hotmail.com> wrote:
Several suggestions have been made in this thread. The one with the highest cost-to-benefit ratio would seem to be removing the Foldable constraint from Traversable, as it is simply not required by the Traversable definition. Lennart actually tried recompiling base with this "and it hardly needed any changes".
I suggest that we consider this change first, as it brings the benefit of allowing Traversable types without having to define possibly nonsensical Foldable instances, and according to Lennart's experiment, has trivial impact.
Lennart, what changes did you have to make? Anybody care to recompile their pet project with this change and see if there's any significant impact?
-- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func... Sent from the Haskell - Libraries mailing list archive at Nabble.com. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
I had to add a couple of Foldable to contexts, and some other minor changes. They were so simple that I don't recall what they were anymore. -----Original Message----- From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Jeremy Sent: 25 February 2016 08:29 To: libraries@haskell.org Subject: Remove Foldable from Traversable (was Haskell Foldable Wats) Several suggestions have been made in this thread. The one with the highest cost-to-benefit ratio would seem to be removing the Foldable constraint from Traversable, as it is simply not required by the Traversable definition. Lennart actually tried recompiling base with this "and it hardly needed any changes". I suggest that we consider this change first, as it brings the benefit of allowing Traversable types without having to define possibly nonsensical Foldable instances, and according to Lennart's experiment, has trivial impact. Lennart, what changes did you have to make? Anybody care to recompile their pet project with this change and see if there's any significant impact? -- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func... Sent from the Haskell - Libraries mailing list archive at Nabble.com. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
It is actually quite fundamental. Instance resolution works on pattern matching on the type and we need all instances to be "global" and not able to be hidden or locally overridden to avoid coherence problems. There have been attempts to relax this restriction in the past, none of which are particularly satisfactory. * http://dspace.library.uu.nl/handle/1874/294072 is probably the most recent, but some are quite old. But basically all of them have run afoul of other ways to get "stuck" when resolving instances, or needing a vocabulary to track provenance of instances, or violate the open world assumptions. Scala's "implicits" break one way on this, Haskell breaks another. The moment you can even qualify the set of instances you get you lose safety for a lot of things like Data.Set, and many refactorings you can do to code today without care become fraught with danger. -Edward On Wed, Feb 24, 2016 at 6:14 PM, Kosyrev Serge <_deepfire@feelingofgreen.ru> wrote:
David Feuer <david.feuer@gmail.com> writes:
Haskell's notion of Functor is in fact somewhat arbitrary from the standpoint of mathematical functors. It's not at all arbitrary from the standpoint of the general variety of type system Haskell uses.
This fact that we can't partially apply a type constructor in an arbitrary way -- is it really all that fundamental to the Haskell type system?
Is it truly something more than an implementation detail?
If so, why?
-- с уважениeм / respectfully, Косырев Сергей
Edward Kmett <ekmett@gmail.com> writes:
It is actually quite fundamental.
Instance resolution works on pattern matching on the type and we need all instances to be "global" and not able to be hidden or locally overridden to avoid coherence problems.
There have been attempts to relax this restriction in the past, none of which are particularly satisfactory.
* http://dspace.library.uu.nl/handle/1874/294072 is probably the most recent, but some are quite old.
Thank you for the education!
But basically all of them have run afoul of other ways to get "stuck" when resolving instances, or needing a vocabulary to track provenance of instances, or violate the open world assumptions.
To my undeducated guess, the paper appears to do a decent job on covering the alternatives. One thing changed since that paper -- type families gained injectivity, the lack of which was listed as the issue with the associated type families approach. Barring the (huge) question of it changing the kind of Functor, are there any other problems with it? -- с уважениeм / respectfully, Косырев Сергей
Perhaps such warnings could be added to a tool like HLint? I do not think they belong in GHC.
HLint does not do typechecking so it can only catch operations on tuple literals (which the latest version does), not very useful unfortunately. On Thu, Feb 25, 2016 at 11:28 PM, Kosyrev Serge <_deepfire@feelingofgreen.ru
wrote:
Edward Kmett <ekmett@gmail.com> writes:
It is actually quite fundamental.
Instance resolution works on pattern matching on the type and we need all instances to be "global" and not able to be hidden or locally overridden to avoid coherence problems.
There have been attempts to relax this restriction in the past, none of which are particularly satisfactory.
* http://dspace.library.uu.nl/handle/1874/294072 is probably the most recent, but some are quite old.
Thank you for the education!
But basically all of them have run afoul of other ways to get "stuck" when resolving instances, or needing a vocabulary to track provenance of instances, or violate the open world assumptions.
To my undeducated guess, the paper appears to do a decent job on covering the alternatives.
One thing changed since that paper -- type families gained injectivity, the lack of which was listed as the issue with the associated type families approach.
Barring the (huge) question of it changing the kind of Functor, are there any other problems with it?
-- с уважениeм / respectfully, Косырев Сергей _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Even this is problematic. Simplifying a bit, I managed to do this recently: module A (foo) where foo :: Bar -> [Int] foo = ... some hacky explicit recursion ... module B where import A bar :: Bar -> Int bar = ... expression containing 'sum . foo' ... Then I noticed I had some calls to 'maximum' on the result of 'foo', and wanted to just modify 'foo' to return the maximum value directly, along with the list: foo :: Bar -> ([Int], Int) foo = ... I went through and replaced the calls to 'maximum' with 'snd', but forgot about 'sum'. GHC happily compiled my code, but was now returning the maximum value instead of the sum of the values. This, of course, caused some other bit to behave strangely, and took some calls to 'trace' to figure out what was going on. There are lots of ways to avoid this... richer return type, use Data.OldList, write some tests, more conscientious search and replace refactoring... but the ease of refactoring code is one of the things I love about Haskell. Normally, I can just change a type signature and hit :r in ghci and start fixing type errors, confident that I've covered my bases when it eventually compiles. Now I feel like I can't rely on the typechecker as much. And yes, explaining the difference between maximum (2,1) and maximum [2,1] to a beginner is a pain, and really weakens your claim that the type system will prevent a lot of bugs in your code (at least in the beginner's eyes). I don't know what the solution is... the instances are already there and a lot of code relies on them, but I do feel like they fall on the wrong side of the expressivity/safety line. On Wed, Feb 24, 2016 at 1:04 AM, Simon Peyton Jones <simonpj@microsoft.com> wrote:
| So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function.
I strongly agree, for all the reasons Andreas mentions. GHC's source code has *lots* of data types that are isomorphic to tuples. Crucial!
Simon
| -----Original Message----- | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | Andreas Abel | Sent: 24 February 2016 08:58 | To: Nathan Bouscal <nbouscal@gmail.com>; libraries@haskell.org | Subject: Re: Haskell Foldable Wats | | In my n+1 years of participating in a 100kloc Haskell project, I | learned that programming with the "categorical" data type building | blocks "Either" and tuples leads to code that is hard to read and | maintain. It is tempting to use a pair | | type QNamed a = (QName, a) | | instead of a hand-rolled data type | | data QNamed a = QNamed { qname :: QName, qnamedThing :: a } | | since with pairs, I get lots of operations for free, and even more if I | use Functor and Traversable, it seems. However, in the long run, if I | come back after months to my original code, or even worse, to someone | else's code, I dearly pay for this: | | 1. Harder to read the code, as I may only see the non-telling "fst" | and "snd" instead of the semantics-loaden "qname" and "qnamedThing". | | 2. Lack of code exploration facilities like grep and tags. I can | grep for "QName" and "qname", but grepping for "," and "fst" returns | lots of irrelevant locations. | | 3. Non-telling error messages. | | And all the arguments of using newtypes over type synonyms apply here | as well. | | So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function. I am speaking here of | Haskell as a language for software development, not of Haskell as a | realization of category theory. | | For getting a broader acceptance of Haskell as a language for software | development, Foldable on tuples is not helpful. | | And yes, if I was new to Haskell and learned the GHCI thinks that | | minimum (1,2) == 1 | | then I would advice GHCI to visit some mental institution to get its | delusions fixed. | | --Andreas | | | On 23.02.2016 18:29, Nathan Bouscal wrote: | > Sorry, poor quoting on my part. I was attempting to reply to | Andreas's | > earlier points: | > | > >> Use of tuples is highly discourageable… | >>>I see no point in Functor or Foldable for tuples. | > | > On Tue, Feb 23, 2016 at 5:18 PM, Mario Blažević <mblazevic@stilo.com | > <mailto:mblazevic@stilo.com>> wrote: | > | > On 16-02-23 11:23 AM, Nathan Bouscal wrote: | > | > It's a bit bold to simultaneously say "Nobody should use this | > type," and | > also "If you use this type, you should do it this way." If | you think | > that it's bad practice to use tuples, that's a fine and | respectable | > opinion, but at that point you should start being a bit more | > wary about | > telling those who think otherwise /how/ they should use them. | > | > | > I believe he was referring to lists, not to tuples. | There | > were few Prelude functions limited to tuples before FTP, and | those | > haven't changed. | > | > | > | > On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek | > <marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com> | > <mailto:marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com>>> wrote: | > | > > I can assure you that Andreas is not delusional | > | > I didn't say that. I was referring to his response to my | > post, that | > "Some delusions have very sophisticated explanations." | > | > > You have to show good taste or you'll end up with a | mess | > that might be logically consistent, but unpleasant to use. | > | > This is entirely subjective, and frankly I don't think | that | > post-FTP | > Haskell is a "mess" or is "unpleasant to use". If | anything, | > it became | > more useful to me, because now Prelude functions aren't | > limited to the | > one data structure I almost never use. | > | > Best regards, | > Marcin Mrotek | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org <mailto:Libraries@haskell.org> | > | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | | | -- | Andreas Abel <>< Du bist der geliebte Mensch. | | Department of Computer Science and Engineering Chalmers and Gothenburg | University, Sweden | | andreas.abel@gu.se | https://na01.safelinks.protection.outlook.com/?url=http:%2f%2fwww2.tcs. | ifi.lmu.de%2f~abel%2f&data=01%7C01%7Csimonpj%40064d.mgd.microsoft.com%7 | Ce4033ee9a03a42eaa97108d33cf89187%7C72f988bf86f141af91ab2d7cd011db47%7C | 1&sdata=kvwlaXofxhQV2ZCD9K%2bemtG4S9oCujNYhn1IXTnSZtc%3d | _______________________________________________ | Libraries mailing list | Libraries@haskell.org | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.ha | skell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries%0a&data=01%7c01%7csimonpj%40064d.m | gd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c72f988bf86f141af9 | 1ab2d7cd011db47%7c1&sdata=gMTA2SOTm1seAHbvHPWnsDjAa7y1gAS681kW6YUx1mQ%3 | d _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Your example gives enough incentive to row back "the ship that has sailed" (to quote the favorite idiom on this list). It is very unfortunate that we did not see these Wats when we decided about FTP. 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. 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.) --Andreas On 24.02.2016 20:15, Andrew Farmer wrote:
Even this is problematic. Simplifying a bit, I managed to do this recently:
module A (foo) where foo :: Bar -> [Int] foo = ... some hacky explicit recursion ...
module B where import A bar :: Bar -> Int bar = ... expression containing 'sum . foo' ...
Then I noticed I had some calls to 'maximum' on the result of 'foo', and wanted to just modify 'foo' to return the maximum value directly, along with the list:
foo :: Bar -> ([Int], Int) foo = ...
I went through and replaced the calls to 'maximum' with 'snd', but forgot about 'sum'. GHC happily compiled my code, but was now returning the maximum value instead of the sum of the values. This, of course, caused some other bit to behave strangely, and took some calls to 'trace' to figure out what was going on.
There are lots of ways to avoid this... richer return type, use Data.OldList, write some tests, more conscientious search and replace refactoring... but the ease of refactoring code is one of the things I love about Haskell. Normally, I can just change a type signature and hit :r in ghci and start fixing type errors, confident that I've covered my bases when it eventually compiles. Now I feel like I can't rely on the typechecker as much.
And yes, explaining the difference between maximum (2,1) and maximum [2,1] to a beginner is a pain, and really weakens your claim that the type system will prevent a lot of bugs in your code (at least in the beginner's eyes).
I don't know what the solution is... the instances are already there and a lot of code relies on them, but I do feel like they fall on the wrong side of the expressivity/safety line.
On Wed, Feb 24, 2016 at 1:04 AM, Simon Peyton Jones <simonpj@microsoft.com> wrote:
| So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function.
I strongly agree, for all the reasons Andreas mentions. GHC's source code has *lots* of data types that are isomorphic to tuples. Crucial!
Simon
| -----Original Message----- | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | Andreas Abel | Sent: 24 February 2016 08:58 | To: Nathan Bouscal <nbouscal@gmail.com>; libraries@haskell.org | Subject: Re: Haskell Foldable Wats | | In my n+1 years of participating in a 100kloc Haskell project, I | learned that programming with the "categorical" data type building | blocks "Either" and tuples leads to code that is hard to read and | maintain. It is tempting to use a pair | | type QNamed a = (QName, a) | | instead of a hand-rolled data type | | data QNamed a = QNamed { qname :: QName, qnamedThing :: a } | | since with pairs, I get lots of operations for free, and even more if I | use Functor and Traversable, it seems. However, in the long run, if I | come back after months to my original code, or even worse, to someone | else's code, I dearly pay for this: | | 1. Harder to read the code, as I may only see the non-telling "fst" | and "snd" instead of the semantics-loaden "qname" and "qnamedThing". | | 2. Lack of code exploration facilities like grep and tags. I can | grep for "QName" and "qname", but grepping for "," and "fst" returns | lots of irrelevant locations. | | 3. Non-telling error messages. | | And all the arguments of using newtypes over type synonyms apply here | as well. | | So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function. I am speaking here of | Haskell as a language for software development, not of Haskell as a | realization of category theory. | | For getting a broader acceptance of Haskell as a language for software | development, Foldable on tuples is not helpful. | | And yes, if I was new to Haskell and learned the GHCI thinks that | | minimum (1,2) == 1 | | then I would advice GHCI to visit some mental institution to get its | delusions fixed. | | --Andreas | | | On 23.02.2016 18:29, Nathan Bouscal wrote: | > Sorry, poor quoting on my part. I was attempting to reply to | Andreas's | > earlier points: | > | > >> Use of tuples is highly discourageable… | >>>I see no point in Functor or Foldable for tuples. | > | > On Tue, Feb 23, 2016 at 5:18 PM, Mario Blažević <mblazevic@stilo.com | > <mailto:mblazevic@stilo.com>> wrote: | > | > On 16-02-23 11:23 AM, Nathan Bouscal wrote: | > | > It's a bit bold to simultaneously say "Nobody should use this | > type," and | > also "If you use this type, you should do it this way." If | you think | > that it's bad practice to use tuples, that's a fine and | respectable | > opinion, but at that point you should start being a bit more | > wary about | > telling those who think otherwise /how/ they should use them. | > | > | > I believe he was referring to lists, not to tuples. | There | > were few Prelude functions limited to tuples before FTP, and | those | > haven't changed. | > | > | > | > On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek | > <marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com> | > <mailto:marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com>>> wrote: | > | > > I can assure you that Andreas is not delusional | > | > I didn't say that. I was referring to his response to my | > post, that | > "Some delusions have very sophisticated explanations." | > | > > You have to show good taste or you'll end up with a | mess | > that might be logically consistent, but unpleasant to use. | > | > This is entirely subjective, and frankly I don't think | that | > post-FTP | > Haskell is a "mess" or is "unpleasant to use". If | anything, | > it became | > more useful to me, because now Prelude functions aren't | > limited to the | > one data structure I almost never use. | > | > Best regards, | > Marcin Mrotek | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org <mailto:Libraries@haskell.org> | > | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | | | -- | Andreas Abel <>< Du bist der geliebte Mensch. | | Department of Computer Science and Engineering Chalmers and Gothenburg | University, Sweden | | andreas.abel@gu.se | https://na01.safelinks.protection.outlook.com/?url=http:%2f%2fwww2.tcs. | ifi.lmu.de%2f~abel%2f&data=01%7C01%7Csimonpj%40064d.mgd.microsoft.com%7 | Ce4033ee9a03a42eaa97108d33cf89187%7C72f988bf86f141af91ab2d7cd011db47%7C | 1&sdata=kvwlaXofxhQV2ZCD9K%2bemtG4S9oCujNYhn1IXTnSZtc%3d | _______________________________________________ | Libraries mailing list | Libraries@haskell.org | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.ha | skell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries%0a&data=01%7c01%7csimonpj%40064d.m | gd.microsoft.com%7ce4033ee9a03a42eaa97108d33cf89187%7c72f988bf86f141af9 | 1ab2d7cd011db47%7c1&sdata=gMTA2SOTm1seAHbvHPWnsDjAa7y1gAS681kW6YUx1mQ%3 | d _______________________________________________ Libraries mailing list Libraries@haskell.org 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 andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/
There are 4 different issues being brought up and conflated in this thread: * Some people are complaining about the FTP entirely. * Some people are complaining about adding instances they don't use. * Some people are complaining about length. Re: FTP as a whole 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? Re: length 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. 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. 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. 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. 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. 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. Re: instances you don't use It has already been covered in this thread that the instances in question are the only possible instance for the types involved. 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. 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, http://packdeps.haskellers.com/reverse/base-orphans 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. We'd wind up in a similar situation for these instances. Removing these instances would accomplish little other than ecosystem fragmentation. -Edward On Wed, Feb 24, 2016 at 4:21 PM, Andreas Abel <abela@chalmers.se> wrote:
Your example gives enough incentive to row back "the ship that has sailed" (to quote the favorite idiom on this list).
It is very unfortunate that we did not see these Wats when we decided about FTP.
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.
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.)
--Andreas
On 24.02.2016 20:15, Andrew Farmer wrote:
Even this is problematic. Simplifying a bit, I managed to do this recently:
module A (foo) where foo :: Bar -> [Int] foo = ... some hacky explicit recursion ...
module B where import A bar :: Bar -> Int bar = ... expression containing 'sum . foo' ...
Then I noticed I had some calls to 'maximum' on the result of 'foo', and wanted to just modify 'foo' to return the maximum value directly, along with the list:
foo :: Bar -> ([Int], Int) foo = ...
I went through and replaced the calls to 'maximum' with 'snd', but forgot about 'sum'. GHC happily compiled my code, but was now returning the maximum value instead of the sum of the values. This, of course, caused some other bit to behave strangely, and took some calls to 'trace' to figure out what was going on.
There are lots of ways to avoid this... richer return type, use Data.OldList, write some tests, more conscientious search and replace refactoring... but the ease of refactoring code is one of the things I love about Haskell. Normally, I can just change a type signature and hit :r in ghci and start fixing type errors, confident that I've covered my bases when it eventually compiles. Now I feel like I can't rely on the typechecker as much.
And yes, explaining the difference between maximum (2,1) and maximum [2,1] to a beginner is a pain, and really weakens your claim that the type system will prevent a lot of bugs in your code (at least in the beginner's eyes).
I don't know what the solution is... the instances are already there and a lot of code relies on them, but I do feel like they fall on the wrong side of the expressivity/safety line.
On Wed, Feb 24, 2016 at 1:04 AM, Simon Peyton Jones <simonpj@microsoft.com> wrote:
| So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function.
I strongly agree, for all the reasons Andreas mentions. GHC's source code has *lots* of data types that are isomorphic to tuples. Crucial!
Simon
| -----Original Message----- | From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of | Andreas Abel | Sent: 24 February 2016 08:58 | To: Nathan Bouscal <nbouscal@gmail.com>; libraries@haskell.org | Subject: Re: Haskell Foldable Wats | | In my n+1 years of participating in a 100kloc Haskell project, I | learned that programming with the "categorical" data type building | blocks "Either" and tuples leads to code that is hard to read and | maintain. It is tempting to use a pair | | type QNamed a = (QName, a) | | instead of a hand-rolled data type | | data QNamed a = QNamed { qname :: QName, qnamedThing :: a } | | since with pairs, I get lots of operations for free, and even more if I | use Functor and Traversable, it seems. However, in the long run, if I | come back after months to my original code, or even worse, to someone | else's code, I dearly pay for this: | | 1. Harder to read the code, as I may only see the non-telling "fst" | and "snd" instead of the semantics-loaden "qname" and "qnamedThing". | | 2. Lack of code exploration facilities like grep and tags. I can | grep for "QName" and "qname", but grepping for "," and "fst" returns | lots of irrelevant locations. | | 3. Non-telling error messages. | | And all the arguments of using newtypes over type synonyms apply here | as well. | | So, my advice is to use tuples only for very short-lived data, like | returning multiple results from a function. I am speaking here of | Haskell as a language for software development, not of Haskell as a | realization of category theory. | | For getting a broader acceptance of Haskell as a language for software | development, Foldable on tuples is not helpful. | | And yes, if I was new to Haskell and learned the GHCI thinks that | | minimum (1,2) == 1 | | then I would advice GHCI to visit some mental institution to get its | delusions fixed. | | --Andreas | | | On 23.02.2016 18:29, Nathan Bouscal wrote: | > Sorry, poor quoting on my part. I was attempting to reply to | Andreas's | > earlier points: | > | > >> Use of tuples is highly discourageable… | >>>I see no point in Functor or Foldable for tuples. | > | > On Tue, Feb 23, 2016 at 5:18 PM, Mario Blažević < mblazevic@stilo.com | > <mailto:mblazevic@stilo.com>> wrote: | > | > On 16-02-23 11:23 AM, Nathan Bouscal wrote: | > | > It's a bit bold to simultaneously say "Nobody should use this | > type," and | > also "If you use this type, you should do it this way." If | you think | > that it's bad practice to use tuples, that's a fine and | respectable | > opinion, but at that point you should start being a bit more | > wary about | > telling those who think otherwise /how/ they should use them. | > | > | > I believe he was referring to lists, not to tuples. | There | > were few Prelude functions limited to tuples before FTP, and | those | > haven't changed. | > | > | > | > On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek | > <marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com> | > <mailto:marcin.jan.mrotek@gmail.com | > <mailto:marcin.jan.mrotek@gmail.com>>> wrote: | > | > > I can assure you that Andreas is not delusional | > | > I didn't say that. I was referring to his response to my | > post, that | > "Some delusions have very sophisticated explanations." | > | > > You have to show good taste or you'll end up with a | mess | > that might be logically consistent, but unpleasant to use. | > | > This is entirely subjective, and frankly I don't think | that | > post-FTP | > Haskell is a "mess" or is "unpleasant to use". If | anything, | > it became | > more useful to me, because now Prelude functions aren't | > limited to the | > one data structure I almost never use. | > | > Best regards, | > Marcin Mrotek | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org <mailto:Libraries@haskell.org> | > | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com %7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | > | > | > | > _______________________________________________ | > Libraries mailing list | > Libraries@haskell.org | > | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.h | > askell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries&data=01%7c01%7cs | > | imonpj%40064d.mgd.microsoft.com %7ce4033ee9a03a42eaa97108d33cf89187%7c7 | > | 2f988bf86f141af91ab2d7cd011db47%7c1&sdata=hgiQqaz1dUG2aUrmeYETcy6loEMf | > xosR3yBA09CQaZs%3d | > | | | -- | Andreas Abel <>< Du bist der geliebte Mensch. | | Department of Computer Science and Engineering Chalmers and Gothenburg | University, Sweden | | andreas.abel@gu.se | https://na01.safelinks.protection.outlook.com/?url=http:%2f%2fwww2.tcs. | ifi.lmu.de%2f~abel%2f&data=01%7C01%7Csimonpj%40064d.mgd.microsoft.com %7 | Ce4033ee9a03a42eaa97108d33cf89187%7C72f988bf86f141af91ab2d7cd011db47%7C | 1&sdata=kvwlaXofxhQV2ZCD9K%2bemtG4S9oCujNYhn1IXTnSZtc%3d | _______________________________________________ | Libraries mailing list | Libraries@haskell.org | https://na01.safelinks.protection.outlook.com/?url=http%3a%2f%2fmail.ha | skell.org%2fcgi- | bin%2fmailman%2flistinfo%2flibraries%0a&data=01%7c01%7csimonpj%40064d.m | gd.microsoft.com %7ce4033ee9a03a42eaa97108d33cf89187%7c72f988bf86f141af9 | 1ab2d7cd011db47%7c1&sdata=gMTA2SOTm1seAHbvHPWnsDjAa7y1gAS681kW6YUx1mQ%3 | d _______________________________________________ Libraries mailing list Libraries@haskell.org 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
andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
On Thu, 25 Feb 2016, Edward Kmett wrote:
Re: FTP as a whole
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?
It's certainly comfortable to argue this way if your opinion is that of the majority. In the library submissions process [1] it is acknowledged that a majority vote needs not to be the final criterion. I think it would be better to work towards a consensus. The consensus here could be: We acknowledge different styles of programming and therefore different expectations to the compiler. Some programmers consider it a bug if 'length' is defined on tuples, other ones consider it a useful feature. In order to serve both sides we add warnings for those who want them. But these warnings should be bundled together with the instance additions and not deferred indefinitely. [1] https://wiki.haskell.org/Library_submissions
In my n+1 years of participating in a 100kloc Haskell project, I learned that programming with the "categorical" data type building blocks "Either" and tuples leads to code that is hard to read and maintain. It is tempting to use a pair type QNamed a = (QName, a) instead of a hand-rolled data type data QNamed a = QNamed { qname :: QName, qnamedThing :: a } since with pairs, I get lots of operations for free, and even more if I use Functor and Traversable, it seems. However, in the long run, if I come back after months to my original code, or even worse, to someone else's code, I dearly pay for this: 1. Harder to read the code, as I may only see the non-telling "fst" and "snd" instead of the semantics-loaden "qname" and "qnamedThing". 2. Lack of code exploration facilities like grep and tags. I can grep for "QName" and "qname", but grepping for "," and "fst" returns lots of irrelevant locations. 3. Non-telling error messages. And all the arguments of using newtypes over type synonyms apply here as well. So, my advice is to use tuples only for very short-lived data, like returning multiple results from a function. I am speaking here of Haskell as a language for software development, not of Haskell as a realization of category theory. For getting a broader acceptance of Haskell as a language for software development, Foldable on tuples is not helpful. And yes, if I was new to Haskell and learned the GHCI thinks that minimum (1,2) == 2 then I would advice GHCI to visit some mental institution to get its delusions fixed. --Andreas P.S.: I spoiled my pun in a previous version of this email. Thank God, my subconscious is not deluded yet. On 23.02.2016 18:29, Nathan Bouscal wrote:
Sorry, poor quoting on my part. I was attempting to reply to Andreas's earlier points:
Use of tuples is highly discourageable… I see no point in Functor or Foldable for tuples.
On Tue, Feb 23, 2016 at 5:18 PM, Mario Blažević <mblazevic@stilo.com <mailto:mblazevic@stilo.com>> wrote:
On 16-02-23 11:23 AM, Nathan Bouscal wrote:
It's a bit bold to simultaneously say "Nobody should use this type," and also "If you use this type, you should do it this way." If you think that it's bad practice to use tuples, that's a fine and respectable opinion, but at that point you should start being a bit more wary about telling those who think otherwise /how/ they should use them.
I believe he was referring to lists, not to tuples. There were few Prelude functions limited to tuples before FTP, and those haven't changed.
On Tue, Feb 23, 2016 at 1:10 PM, Marcin Mrotek <marcin.jan.mrotek@gmail.com <mailto:marcin.jan.mrotek@gmail.com> <mailto:marcin.jan.mrotek@gmail.com <mailto:marcin.jan.mrotek@gmail.com>>> wrote:
> I can assure you that Andreas is not delusional
I didn't say that. I was referring to his response to my post, that "Some delusions have very sophisticated explanations."
> You have to show good taste or you'll end up with a mess that might be logically consistent, but unpleasant to use.
This is entirely subjective, and frankly I don't think that post-FTP Haskell is a "mess" or is "unpleasant to use". If anything, it became more useful to me, because now Prelude functions aren't limited to the one data structure I almost never use.
Best regards, Marcin Mrotek
_______________________________________________ Libraries mailing list Libraries@haskell.org <mailto:Libraries@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org 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 andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/ _______________________________________________ Libraries mailing list Libraries@haskell.org 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 andreas.abel@gu.se http://www2.tcs.ifi.lmu.de/~abel/
I also do not see why (a,a) could not be a container of exactly two elements, as opposed to current GHC which insists it is a container of exactly one element. (Case for the mental institution, I'd say.)
Because this isn't how types in Haskell works. `Foo a a` always parsed to `(Foo a) a` and no instance of any class can implement it differently than `(Foo b) a`, unless you want to throw parametricity out of the window. This has been long before `Foldable`. Best regards, Marcin Mrotek
Henrik Nilsson <Henrik.Nilsson@nottingham.ac.uk> writes:
Well, I would not characterise many of those who have raised concerns about this as "laymen".
With a couple of decades of Haskell and CS teaching experience, and a couple more of general programming experience, I don't consider myself a layman either (and I hope that does not come across as arrogant).
My apologies, Henrik, I did not mean to insult those who have considerable experience, and are certainly not 'layman'. Permit me to retract that remark.
Personally, if I wanted to introduce annotated numbers, I'd introduce a new type to clearly convey that idea. Yes, a bit more to write, but the end result is code that conveys the ideas behind it in a clear manner. After all, code is (broadly) written once, but read many times.
This is indeed the sanest approach, but sometimes I receive such tuples from libraries, and it can be convenient to treat them as annotated values.
As to making tuples functor instances, that can only be done by arbitrarily imbuing one of the fields with a special status. I have to ask: Why? After all, taking pairs as an example, the *essence* of a pair is that there are two projection functions, one for each field.
Maybe because we don't have type-level flip? Lens does solve this problem, by allowing us fold on any type variable we like (provided the appropriate folding definition is given), but type classes don't allow it.
As to tuples as instances of foldable: Why? There isn't any structure to fold!
Well, I've used the Traversable instance of ((,) e) countless times, and right now Traversable requires Foldable. I'd hate to lose both by removing one.
And allowing us to spend valuable teaching time on aspects of Haskell that actually might persuade our students to take Haskell seriously.
Isn't it possible to use a Prelude in your class that restricts Haskell to the parts you want to focus on? -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
Let us consider some of the functions that Foldable actually provides for tuples: length Useless and wrong. Unless "length" means "the number of items which fmap will operate over", in which case it's just useless and misleading. maximum Useless and wrong/misleading. minimum Useless and wrong/misleading. product Useless and wrong/misleading. sum Useless and wrong/misleading. etc It may be that some of the Foldable methods for tuples happen to be useful, but this does not mean that tuples are foldable. It means that there are some potentially useful helper methods which could be defined for tuples, and included in the Prelude. It may be that the same methods are applicable to Either, in which case there could be a new class ApplyFunctionToArbitraryPreDeterminedComponent. It may even make sense for this class to be a super-class of Foldable. But it does not make sense for tuples or Either to be instances of Foldable, because they aren't foldable. -- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func... Sent from the Haskell - Libraries mailing list archive at Nabble.com.
It may be that some of the Foldable methods for tuples happen to be useful, but this does not mean that tuples are foldable.
I think that, as far as Foldable is concerned, a tuple is equivalent to Identity, so this instance is indeed useless. However, Foldable is a superclass of Traversable (and it wouldn't make much sense to make these classes unrelated, as one can always define folds with `traverse`), so I've always found it a necessary evil. Either's instance for Foldable is a little more useful, but equivalent to Maybe's, I think? But there are, in general, at least two separate use cases for these instances: a) Using Foldable methods directly on tuples or Eithers - I think it's usually pointless, as I wrote above. b) Passing a tuple/Either/Maybe/whatever to a more complicated function that requires a Foldable constraint. This is potentially much more useful, and at least saves some wrapping/unwrapping. Best regards, Marcin Mrotek
Marcin Mrotek wrote
I think that, as far as Foldable is concerned, a tuple is equivalent to Identity, so this instance is indeed useless. However, Foldable is a superclass of Traversable (and it wouldn't make much sense to make these classes unrelated, as one can always define folds with `traverse`), so I've always found it a necessary evil.
Perhaps the case of tuple is evidence that Foldable should *not* be a superclass of Traversable? -- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func... Sent from the Haskell - Libraries mailing list archive at Nabble.com.
I think the ship has sailed on big breaking changes to Foldable/Traversable -- an argument could be made to remove a wonky instance, but removing Foldable as a superclass seems to me like a much bigger change. Tom
El 21 feb 2016, a las 07:57, Jeremy <voldermort@hotmail.com> escribió:
Marcin Mrotek wrote
I think that, as far as Foldable is concerned, a tuple is equivalent to Identity, so this instance is indeed useless. However, Foldable is a superclass of Traversable (and it wouldn't make much sense to make these classes unrelated, as one can always define folds with `traverse`), so I've always found it a necessary evil.
Perhaps the case of tuple is evidence that Foldable should *not* be a superclass of Traversable?
-- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func... Sent from the Haskell - Libraries mailing list archive at Nabble.com. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
That leads to a ton of ever MORE nonsensical consequences like not being to weaken calls to mapM (which uses Traversable) to mapM_(which needs only Foldable) or doubling the number of combinators we have all over again for random prescriptive reasons, right after we just starting finally healing the last source of needless duplication (Applicative not being a superclass of Monad). -Edward On Sun, Feb 21, 2016 at 7:57 AM, Jeremy <voldermort@hotmail.com> wrote:
Marcin Mrotek wrote
I think that, as far as Foldable is concerned, a tuple is equivalent to Identity, so this instance is indeed useless. However, Foldable is a superclass of Traversable (and it wouldn't make much sense to make these classes unrelated, as one can always define folds with `traverse`), so I've always found it a necessary evil.
Perhaps the case of tuple is evidence that Foldable should *not* be a superclass of Traversable?
-- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func... Sent from the Haskell - Libraries mailing list archive at Nabble.com. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
I don’t believe the practical consequences will be severe. I know you do, but you have provided no proof. I did an experiment and removed it, and recompiled base. And it hardly needed any changes. From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Edward Kmett Sent: 21 February 2016 23:51 To: Jeremy Cc: Haskell Libraries Subject: Re: Haskell Foldable Wast That leads to a ton of ever MORE nonsensical consequences like not being to weaken calls to mapM (which uses Traversable) to mapM_(which needs only Foldable) or doubling the number of combinators we have all over again for random prescriptive reasons, right after we just starting finally healing the last source of needless duplication (Applicative not being a superclass of Monad). -Edward On Sun, Feb 21, 2016 at 7:57 AM, Jeremy <voldermort@hotmail.com<mailto:voldermort@hotmail.com>> wrote: Marcin Mrotek wrote
I think that, as far as Foldable is concerned, a tuple is equivalent to Identity, so this instance is indeed useless. However, Foldable is a superclass of Traversable (and it wouldn't make much sense to make these classes unrelated, as one can always define folds with `traverse`), so I've always found it a necessary evil.
Perhaps the case of tuple is evidence that Foldable should *not* be a superclass of Traversable? -- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func... Sent from the Haskell - Libraries mailing list archive at Nabble.com. _______________________________________________ Libraries mailing list Libraries@haskell.org<mailto:Libraries@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
What will the signature of things like 'mapM_' be then? Will there be two versions, one with a Foldable constraint and one with a Traversable constraint? I don't think base will be the area with the most impact here, by the way. The biggest impact will be libraries using these classes, where suddenly more class constraints need to be added to the signature. Erik On 22 February 2016 at 08:33, Augustsson, Lennart <Lennart.Augustsson@sc.com> wrote:
I don’t believe the practical consequences will be severe. I know you do, but you have provided no proof.
I did an experiment and removed it, and recompiled base. And it hardly needed any changes.
From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Edward Kmett Sent: 21 February 2016 23:51 To: Jeremy Cc: Haskell Libraries Subject: Re: Haskell Foldable Wast
That leads to a ton of ever MORE nonsensical consequences like not being to weaken calls to mapM (which uses Traversable) to mapM_(which needs only Foldable) or doubling the number of combinators we have all over again for random prescriptive reasons, right after we just starting finally healing the last source of needless duplication (Applicative not being a superclass of Monad).
-Edward
On Sun, Feb 21, 2016 at 7:57 AM, Jeremy <voldermort@hotmail.com> wrote:
Marcin Mrotek wrote
I think that, as far as Foldable is concerned, a tuple is equivalent to Identity, so this instance is indeed useless. However, Foldable is a superclass of Traversable (and it wouldn't make much sense to make these classes unrelated, as one can always define folds with `traverse`), so I've always found it a necessary evil.
Perhaps the case of tuple is evidence that Foldable should *not* be a superclass of Traversable?
-- View this message in context: http://haskell.1045720.n5.nabble.com/Proposal-Add-conspicuously-missing-Func...
Sent from the Haskell - Libraries mailing list archive at Nabble.com. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html
Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx
Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same.
Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
On Sun, 21 Feb 2016, Jeremy wrote:
Marcin Mrotek wrote
I think that, as far as Foldable is concerned, a tuple is equivalent to Identity, so this instance is indeed useless. However, Foldable is a superclass of Traversable (and it wouldn't make much sense to make these classes unrelated, as one can always define folds with `traverse`), so I've always found it a necessary evil.
Perhaps the case of tuple is evidence that Foldable should *not* be a superclass of Traversable?
For me, pairs should also not be Traversable. I have Writer monad for this purpose.
Foldable doesn’t have to be a superclass of Traversable. Removing it only requires a few minor changes to existing code. From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Marcin Mrotek Sent: 21 February 2016 09:05 To: Jeremy Cc: Haskell Libraries Subject: Re: Haskell Foldable Wast It may be that some of the Foldable methods for tuples happen to be useful, but this does not mean that tuples are foldable. I think that, as far as Foldable is concerned, a tuple is equivalent to Identity, so this instance is indeed useless. However, Foldable is a superclass of Traversable (and it wouldn't make much sense to make these classes unrelated, as one can always define folds with `traverse`), so I've always found it a necessary evil. Either's instance for Foldable is a little more useful, but equivalent to Maybe's, I think? But there are, in general, at least two separate use cases for these instances: a) Using Foldable methods directly on tuples or Eithers - I think it's usually pointless, as I wrote above. b) Passing a tuple/Either/Maybe/whatever to a more complicated function that requires a Foldable constraint. This is potentially much more useful, and at least saves some wrapping/unwrapping. Best regards, Marcin Mrotek This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
On Sun, 21 Feb 2016, Jeremy wrote:
Let us consider some of the functions that Foldable actually provides for tuples:
length Useless and wrong. Unless "length" means "the number of items which fmap will operate over", in which case it's just useless and misleading.
maximum Useless and wrong/misleading.
minimum Useless and wrong/misleading.
product Useless and wrong/misleading.
sum Useless and wrong/misleading.
An alternative to custom types is to stay with pairs but use lenses instead of type class methods: http://www.haskellforall.com/2015/10/explicit-is-better-than-implicit.html
The big problem was the goal of allowing Data.Foldable and Data.Traversable to be imported unqualified. This was fine for Data.Traversable, but not for Data.Foldable. There are relatively few cases where the Traversable generalization is confusing or otherwise problematic, but Foldable is just too "wild". Once that dubious goal was set, consistency and efficiency demanded some of the other changes. On Feb 17, 2016 6:02 AM, "Henning Thielemann" <lemming@henning-thielemann.de> wrote:
On Mon, 18 Jan 2016, Ryan Scott wrote:
* The Not-A-Wat in Haskell:
I see his examples and draw the opposite conclusions. What he presents are perfect Wats and they have eventually moved Haskell to the MatLab league where everything is allowed and the programming system accepts almost everything the programmer enters.
Sure,
length (2,3) = 1
product (2,3) = 3 sum (2,3) = 3 or (True,False) = False
are all consistent but consistently useless, unintuitive (not only to novices) and dangerous. There are alternatives: There was no need to generalize 'Prelude.length' using Foldable. I always opposed to the argument "put the most general variant to Prelude", because there is no clear most general variant or there is one like "length :: Length f => f" and you won't like it.
We could reasonably have the Haskell 98 class
class Length a where length :: a -> Int
instance Length [a] where length = List.length
instance Length (a,b) where length _ = 2
This would yield the intuitive length (2,3) = 2
I do not propose to implement this class, because I never encountered a situation where I could equally choose between lists and pairs. If at all, I can see value in a special TupleSize class. However, the Length class proves that the suggestion that the only reasonable result of 'length (2,3)' is 1, is plain wrong.
How did we get there? There were three steps that made this Wat possible: 1. Foldable.length added 2. instance Foldable ((,) a) 3. export Foldable.length from Prelude.
For me 1. was correct 2. was wrong because a programmer should better define a custom type like "data AdornedSingleton a b = AS a b" 3. Was wrong because there are multiple ways to generalize 'length'. Without 3. you would have to use explicitly 'length' from Foldable and this way you would have been warned, that strange things may happen.
On Wed, 17 Feb 2016, David Feuer wrote:
The big problem was the goal of allowing Data.Foldable and Data.Traversable to be imported unqualified. This was fine for Data.Traversable, but not for Data.Foldable. There are relatively few cases where the Traversable generalization is confusing or otherwise problematic, but Foldable is just too "wild".
Once that dubious goal was set, consistency and efficiency demanded some of the other changes.
If step A requires step B, step C and step D that become worse and worse, then for me this proves that already step A was wrong. Importing Data.Foldable and Data.Traversable without any notice is a slight simplification in some cases, but the consequences are a big pain.
The easiest way to import Data.Foldable unqualified is to rename the functions in it. And, IMO, there is the original problem: Data.Foldable is full of Prelude name clashes. -----Original Message----- From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Henning Thielemann Sent: 23 February 2016 08:25 To: David Feuer Cc: Haskell Libraries; Ryan Scott Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) On Wed, 17 Feb 2016, David Feuer wrote:
The big problem was the goal of allowing Data.Foldable and Data.Traversable to be imported unqualified. This was fine for Data.Traversable, but not for Data.Foldable. There are relatively few cases where the Traversable generalization is confusing or otherwise problematic, but Foldable is just too "wild".
Once that dubious goal was set, consistency and efficiency demanded some of the other changes.
If step A requires step B, step C and step D that become worse and worse, then for me this proves that already step A was wrong. Importing Data.Foldable and Data.Traversable without any notice is a slight simplification in some cases, but the consequences are a big pain. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
On Tue, 23 Feb 2016, Augustsson, Lennart wrote:
The easiest way to import Data.Foldable unqualified is to rename the functions in it. And, IMO, there is the original problem: Data.Foldable is full of Prelude name clashes.
If you accept to write foldLength instead of 'length', then you can as well leave the names in Data.Foldable, import with qualification Fold and write Fold.length. That's how I did it before FTP and continue to do.
On 2016-02-23 at 10:23:18 +0100, Augustsson, Lennart wrote:
And, IMO, there is the original problem: Data.Foldable is full of Prelude name clashes.
Or, dually, the Prelude is full of Foldable clashes... ;-) Here's a proposal from 10 years ago you may remember: https://prime.haskell.org/wiki/Prelude
I'd be happy so the automatic import of Prelude totally gone. And then have a couple of standardized preludes to choose from, with none of them having a special blessed status. -----Original Message----- From: Herbert Valerio Riedel [mailto:hvriedel@gmail.com] Sent: 23 February 2016 11:21 To: Augustsson, Lennart Cc: Haskell Libraries Subject: Re: Haskell Foldable Wats On 2016-02-23 at 10:23:18 +0100, Augustsson, Lennart wrote:
And, IMO, there is the original problem: Data.Foldable is full of Prelude name clashes.
Or, dually, the Prelude is full of Foldable clashes... ;-) Here's a proposal from 10 years ago you may remember: https://prime.haskell.org/wiki/Prelude This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b'; as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'. data TwoThree a b = TwoThree a a b b b What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be? Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type. 2016-02-17 20:02 GMT+09:00 Henning Thielemann <lemming@henning-thielemann.de
:
On Mon, 18 Jan 2016, Ryan Scott wrote:
* The Not-A-Wat in Haskell:
I see his examples and draw the opposite conclusions. What he presents are perfect Wats and they have eventually moved Haskell to the MatLab league where everything is allowed and the programming system accepts almost everything the programmer enters.
Sure,
length (2,3) = 1
product (2,3) = 3 sum (2,3) = 3 or (True,False) = False
are all consistent but consistently useless, unintuitive (not only to novices) and dangerous. There are alternatives: There was no need to generalize 'Prelude.length' using Foldable. I always opposed to the argument "put the most general variant to Prelude", because there is no clear most general variant or there is one like "length :: Length f => f" and you won't like it.
We could reasonably have the Haskell 98 class
class Length a where length :: a -> Int
instance Length [a] where length = List.length
instance Length (a,b) where length _ = 2
This would yield the intuitive length (2,3) = 2
I do not propose to implement this class, because I never encountered a situation where I could equally choose between lists and pairs. If at all, I can see value in a special TupleSize class. However, the Length class proves that the suggestion that the only reasonable result of 'length (2,3)' is 1, is plain wrong.
How did we get there? There were three steps that made this Wat possible: 1. Foldable.length added 2. instance Foldable ((,) a) 3. export Foldable.length from Prelude.
For me 1. was correct 2. was wrong because a programmer should better define a custom type like "data AdornedSingleton a b = AS a b" 3. Was wrong because there are multiple ways to generalize 'length'. Without 3. you would have to use explicitly 'length' from Foldable and this way you would have been warned, that strange things may happen. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Hi, On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote:
Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b';
Which, to me, at least, very much sounds like a container of two elements? Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.)
as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'.
data TwoThree a b = TwoThree a a b b b
What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be?
A static type error, perhaps? (As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.)
Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type.
Best, /Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
On Wed, Feb 24, 2016 at 1:04 PM, Henrik Nilsson < Henrik.Nilsson@nottingham.ac.uk> wrote:
Hi,
On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote:
Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b';
Which, to me, at least, very much sounds like a container of two elements?
You can use essentially the same argument to say that [a] sounds like a container of any number of elements, therefore there shouldn't be anything wrong with [1, 'foo']. It's not uncommon in programming for "what a thing naively sounds like" to be quite different from "what a thing actually is". *Tuples are not lists*. I agree that there's room for confusion, but there is room for confusion in *a lot* of parts of Haskell, especially for people who bring a lot of preconceived notions with them. We should try to make the transition easier for them, but to me that looks a lot more like "really good error messages" and less like pointedly ignoring the structure of types that might be confusing.
Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.)
as Foldable works on
values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'.
data TwoThree a b = TwoThree a a b b b
What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be?
A static type error, perhaps?
(As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.)
Looking at only
the expression, 5 might seem to make sense, but is not meaningful considering the type.
Best,
/Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Of course a pair is a container of two things (which can have different types). You can come up with some different definition of what it means to be a container, so that a pair is no longer a container of two things, but this is just obfuscation. From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Nathan Bouscal Sent: 24 February 2016 13:29 To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) On Wed, Feb 24, 2016 at 1:04 PM, Henrik Nilsson <Henrik.Nilsson@nottingham.ac.uk<mailto:Henrik.Nilsson@nottingham.ac.uk>> wrote: Hi, On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote: Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b'; Which, to me, at least, very much sounds like a container of two elements? You can use essentially the same argument to say that [a] sounds like a container of any number of elements, therefore there shouldn't be anything wrong with [1, 'foo']. It's not uncommon in programming for "what a thing naively sounds like" to be quite different from "what a thing actually is". Tuples are not lists. I agree that there's room for confusion, but there is room for confusion in a lot of parts of Haskell, especially for people who bring a lot of preconceived notions with them. We should try to make the transition easier for them, but to me that looks a lot more like "really good error messages" and less like pointedly ignoring the structure of types that might be confusing. Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.) as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'. data TwoThree a b = TwoThree a a b b b What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be? A static type error, perhaps? (As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.) Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type. Best, /Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk<mailto:nhn@cs.nott.ac.uk> This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. _______________________________________________ Libraries mailing list Libraries@haskell.org<mailto:Libraries@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
I'm not trying to say that a pair is not a container of two things. I'm saying that that description is insufficiently specific to be useful for the purposes of the discussion. There are many ways to be a container of two things, and if we are to have functions whose behavior depends on the structure of the data they're working on, it's inevitable that those functions will behave differently for different of those ways of being a container. If the issue is that "containers" don't always behave the way one might naively expect containers to behave, then I'm just pointing out that this isn't the only place that holds, and that in other areas we've already accepted this. On Wed, Feb 24, 2016 at 1:38 PM, Augustsson, Lennart < Lennart.Augustsson@sc.com> wrote:
Of course a pair is a container of two things (which can have different types).
You can come up with some different definition of what it means to be a container, so that a pair is no longer a container of two things, but this is just obfuscation.
*From:* Libraries [mailto:libraries-bounces@haskell.org] *On Behalf Of *Nathan Bouscal *Sent:* 24 February 2016 13:29 *To:* Haskell Libraries *Subject:* Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples)
On Wed, Feb 24, 2016 at 1:04 PM, Henrik Nilsson < Henrik.Nilsson@nottingham.ac.uk> wrote:
Hi,
On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote:
Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b';
Which, to me, at least, very much sounds like a container of two elements?
You can use essentially the same argument to say that [a] sounds like a container of any number of elements, therefore there shouldn't be anything wrong with [1, 'foo']. It's not uncommon in programming for "what a thing naively sounds like" to be quite different from "what a thing actually is". *Tuples are not lists*.
I agree that there's room for confusion, but there is room for confusion in *a lot* of parts of Haskell, especially for people who bring a lot of preconceived notions with them. We should try to make the transition easier for them, but to me that looks a lot more like "really good error messages" and less like pointedly ignoring the structure of types that might be confusing.
Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.)
as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'.
data TwoThree a b = TwoThree a a b b b
What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be?
A static type error, perhaps?
(As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.)
Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type.
Best,
/Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html
Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx
Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same.
Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
I am totally with Lennart here: something that used to be conceptually very simple, clear, and, not the least, easy to teach, has become complex and muddled for little if any good reason at all. What is that if not obfuscation? And I am not just drawing on my own experience here, but also from that of many colleagues with years and years of teaching experience. /Henrik Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk -------- Original message -------- From: Nathan Bouscal Date:2016/02/24 13:43 (GMT+00:00) To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) I'm not trying to say that a pair is not a container of two things. I'm saying that that description is insufficiently specific to be useful for the purposes of the discussion. There are many ways to be a container of two things, and if we are to have functions whose behavior depends on the structure of the data they're working on, it's inevitable that those functions will behave differently for different of those ways of being a container. If the issue is that "containers" don't always behave the way one might naively expect containers to behave, then I'm just pointing out that this isn't the only place that holds, and that in other areas we've already accepted this. On Wed, Feb 24, 2016 at 1:38 PM, Augustsson, Lennart <Lennart.Augustsson@sc.com<mailto:Lennart.Augustsson@sc.com>> wrote: Of course a pair is a container of two things (which can have different types). You can come up with some different definition of what it means to be a container, so that a pair is no longer a container of two things, but this is just obfuscation. From: Libraries [mailto:libraries-bounces@haskell.org<mailto:libraries-bounces@haskell.org>] On Behalf Of Nathan Bouscal Sent: 24 February 2016 13:29 To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) On Wed, Feb 24, 2016 at 1:04 PM, Henrik Nilsson <Henrik.Nilsson@nottingham.ac.uk<mailto:Henrik.Nilsson@nottingham.ac.uk>> wrote: Hi, On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote: Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b'; Which, to me, at least, very much sounds like a container of two elements? You can use essentially the same argument to say that [a] sounds like a container of any number of elements, therefore there shouldn't be anything wrong with [1, 'foo']. It's not uncommon in programming for "what a thing naively sounds like" to be quite different from "what a thing actually is". Tuples are not lists. I agree that there's room for confusion, but there is room for confusion in a lot of parts of Haskell, especially for people who bring a lot of preconceived notions with them. We should try to make the transition easier for them, but to me that looks a lot more like "really good error messages" and less like pointedly ignoring the structure of types that might be confusing. Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.) as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'. data TwoThree a b = TwoThree a a b b b What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be? A static type error, perhaps? (As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.) Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type. Best, /Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk<mailto:nhn@cs.nott.ac.uk> This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. _______________________________________________ Libraries mailing list Libraries@haskell.org<mailto:Libraries@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products. This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
A pair is a certainly a container of two things, but an (a, b) is a container of only one b. The length function is not named sufficiently descriptively to explain it's behavior here, but that doesn't make the behavior nonsensical. On Wed, Feb 24, 2016, 9:20 AM Henrik Nilsson < Henrik.Nilsson@nottingham.ac.uk> wrote:
I am totally with Lennart here: something that used to be conceptually very simple, clear, and, not the least, easy to teach, has become complex and muddled for little if any good reason at all. What is that if not obfuscation?
And I am not just drawing on my own experience here, but also from that of many colleagues with years and years of teaching experience.
/Henrik
Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
-------- Original message -------- From: Nathan Bouscal Date:2016/02/24 13:43 (GMT+00:00) To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples)
I'm not trying to say that a pair is not a container of two things. I'm saying that that description is insufficiently specific to be useful for the purposes of the discussion. There are many ways to be a container of two things, and if we are to have functions whose behavior depends on the structure of the data they're working on, it's inevitable that those functions will behave differently for different of those ways of being a container. If the issue is that "containers" don't always behave the way one might naively expect containers to behave, then I'm just pointing out that this isn't the only place that holds, and that in other areas we've already accepted this.
On Wed, Feb 24, 2016 at 1:38 PM, Augustsson, Lennart < Lennart.Augustsson@sc.com> wrote:
Of course a pair is a container of two things (which can have different types).
You can come up with some different definition of what it means to be a container, so that a pair is no longer a container of two things, but this is just obfuscation.
*From:* Libraries [mailto:libraries-bounces@haskell.org] *On Behalf Of *Nathan Bouscal *Sent:* 24 February 2016 13:29 *To:* Haskell Libraries *Subject:* Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples)
On Wed, Feb 24, 2016 at 1:04 PM, Henrik Nilsson < Henrik.Nilsson@nottingham.ac.uk> wrote:
Hi,
On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote:
Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b';
Which, to me, at least, very much sounds like a container of two elements?
You can use essentially the same argument to say that [a] sounds like a container of any number of elements, therefore there shouldn't be anything wrong with [1, 'foo']. It's not uncommon in programming for "what a thing naively sounds like" to be quite different from "what a thing actually is". *Tuples are not lists*.
I agree that there's room for confusion, but there is room for confusion in *a lot* of parts of Haskell, especially for people who bring a lot of preconceived notions with them. We should try to make the transition easier for them, but to me that looks a lot more like "really good error messages" and less like pointedly ignoring the structure of types that might be confusing.
Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.)
as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'.
data TwoThree a b = TwoThree a a b b b
What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be?
A static type error, perhaps?
(As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.)
Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type.
Best,
/Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html
Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx
Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same.
Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it.
Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
And of only one a. So what exactly is the point being made? /Henrik Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk -------- Original message -------- From: Jake McArthur Date:2016/02/24 14:34 (GMT+00:00) To: Henrik Nilsson ,Nathan Bouscal ,Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) A pair is a certainly a container of two things, but an (a, b) is a container of only one b. The length function is not named sufficiently descriptively to explain it's behavior here, but that doesn't make the behavior nonsensical. On Wed, Feb 24, 2016, 9:20 AM Henrik Nilsson <Henrik.Nilsson@nottingham.ac.uk<mailto:Henrik.Nilsson@nottingham.ac.uk>> wrote: I am totally with Lennart here: something that used to be conceptually very simple, clear, and, not the least, easy to teach, has become complex and muddled for little if any good reason at all. What is that if not obfuscation? And I am not just drawing on my own experience here, but also from that of many colleagues with years and years of teaching experience. /Henrik Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk<mailto:nhn@cs.nott.ac.uk> -------- Original message -------- From: Nathan Bouscal Date:2016/02/24 13:43 (GMT+00:00) To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) I'm not trying to say that a pair is not a container of two things. I'm saying that that description is insufficiently specific to be useful for the purposes of the discussion. There are many ways to be a container of two things, and if we are to have functions whose behavior depends on the structure of the data they're working on, it's inevitable that those functions will behave differently for different of those ways of being a container. If the issue is that "containers" don't always behave the way one might naively expect containers to behave, then I'm just pointing out that this isn't the only place that holds, and that in other areas we've already accepted this. On Wed, Feb 24, 2016 at 1:38 PM, Augustsson, Lennart <Lennart.Augustsson@sc.com<mailto:Lennart.Augustsson@sc.com>> wrote: Of course a pair is a container of two things (which can have different types). You can come up with some different definition of what it means to be a container, so that a pair is no longer a container of two things, but this is just obfuscation. From: Libraries [mailto:libraries-bounces@haskell.org<mailto:libraries-bounces@haskell.org>] On Behalf Of Nathan Bouscal Sent: 24 February 2016 13:29 To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) On Wed, Feb 24, 2016 at 1:04 PM, Henrik Nilsson <Henrik.Nilsson@nottingham.ac.uk<mailto:Henrik.Nilsson@nottingham.ac.uk>> wrote: Hi, On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote: Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b'; Which, to me, at least, very much sounds like a container of two elements? You can use essentially the same argument to say that [a] sounds like a container of any number of elements, therefore there shouldn't be anything wrong with [1, 'foo']. It's not uncommon in programming for "what a thing naively sounds like" to be quite different from "what a thing actually is". Tuples are not lists. I agree that there's room for confusion, but there is room for confusion in a lot of parts of Haskell, especially for people who bring a lot of preconceived notions with them. We should try to make the transition easier for them, but to me that looks a lot more like "really good error messages" and less like pointedly ignoring the structure of types that might be confusing. Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.) as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'. data TwoThree a b = TwoThree a a b b b What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be? A static type error, perhaps? (As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.) Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type. Best, /Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk<mailto:nhn@cs.nott.ac.uk> This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. _______________________________________________ Libraries mailing list Libraries@haskell.org<mailto:Libraries@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products. This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. _______________________________________________ Libraries mailing list Libraries@haskell.org<mailto:Libraries@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
I don't see any additional complexity. I see an additional way for an unwary learner to discover complexity that was already there, by passing a value that they weren't previously able to pass to a function that they don't yet have a complete model of. That will definitely cause some confusion, but I'm not convinced it will cause marginal confusion, nor that such confusion is bad. This is not the only way that learners can mix up tuples and lists, and that distinction is something every learner has to understand at some point. You can still teach tuples exactly the same way that you used to teach tuples, and you can still teach finding the length of a list exactly the same way that you used to teach it. Unless your curriculum previously included an explicit demonstration of `length (1, 2)` causing an error, I don't see why it would need to change. On Wed, Feb 24, 2016 at 2:20 PM, Henrik Nilsson < Henrik.Nilsson@nottingham.ac.uk> wrote:
I am totally with Lennart here: something that used to be conceptually very simple, clear, and, not the least, easy to teach, has become complex and muddled for little if any good reason at all. What is that if not obfuscation?
And I am not just drawing on my own experience here, but also from that of many colleagues with years and years of teaching experience.
/Henrik
Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
-------- Original message -------- From: Nathan Bouscal Date:2016/02/24 13:43 (GMT+00:00) To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples)
I'm not trying to say that a pair is not a container of two things. I'm saying that that description is insufficiently specific to be useful for the purposes of the discussion. There are many ways to be a container of two things, and if we are to have functions whose behavior depends on the structure of the data they're working on, it's inevitable that those functions will behave differently for different of those ways of being a container. If the issue is that "containers" don't always behave the way one might naively expect containers to behave, then I'm just pointing out that this isn't the only place that holds, and that in other areas we've already accepted this.
On Wed, Feb 24, 2016 at 1:38 PM, Augustsson, Lennart < Lennart.Augustsson@sc.com> wrote:
Of course a pair is a container of two things (which can have different types).
You can come up with some different definition of what it means to be a container, so that a pair is no longer a container of two things, but this is just obfuscation.
*From:* Libraries [mailto:libraries-bounces@haskell.org] *On Behalf Of *Nathan Bouscal *Sent:* 24 February 2016 13:29 *To:* Haskell Libraries *Subject:* Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples)
On Wed, Feb 24, 2016 at 1:04 PM, Henrik Nilsson < Henrik.Nilsson@nottingham.ac.uk> wrote:
Hi,
On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote:
Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b';
Which, to me, at least, very much sounds like a container of two elements?
You can use essentially the same argument to say that [a] sounds like a container of any number of elements, therefore there shouldn't be anything wrong with [1, 'foo']. It's not uncommon in programming for "what a thing naively sounds like" to be quite different from "what a thing actually is". *Tuples are not lists*.
I agree that there's room for confusion, but there is room for confusion in *a lot* of parts of Haskell, especially for people who bring a lot of preconceived notions with them. We should try to make the transition easier for them, but to me that looks a lot more like "really good error messages" and less like pointedly ignoring the structure of types that might be confusing.
Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.)
as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'.
data TwoThree a b = TwoThree a a b b b
What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be?
A static type error, perhaps?
(As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.)
Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type.
Best,
/Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html
Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx
Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same.
Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it.
Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
Hi, Sorry Nathan, I am not following your argument: you seem to be arguing two ways at the same time. Maybe "marginal" should have been "major"? However:
I see an additional way for an unwary learner to discover complexity that was already there, by passing a value that they weren't previously able to pass to a function
No, that specific complexity were *not* there previously. Applying length or maximum etc. to a tuple used to be a type error. End of story. And that was a good thing for many reasons, including that length or maximum on tuples are not particularly useful: the former being a roundabout way to compute 1, the latter being a rather obscurely named projection function. /Henrik Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk -------- Original message -------- From: Nathan Bouscal Date:2016/02/24 14:42 (GMT+00:00) To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) I don't see any additional complexity. I see an additional way for an unwary learner to discover complexity that was already there, by passing a value that they weren't previously able to pass to a function that they don't yet have a complete model of. That will definitely cause some confusion, but I'm not convinced it will cause marginal confusion, nor that such confusion is bad. This is not the only way that learners can mix up tuples and lists, and that distinction is something every learner has to understand at some point. You can still teach tuples exactly the same way that you used to teach tuples, and you can still teach finding the length of a list exactly the same way that you used to teach it. Unless your curriculum previously included an explicit demonstration of `length (1, 2)` causing an error, I don't see why it would need to change. On Wed, Feb 24, 2016 at 2:20 PM, Henrik Nilsson <Henrik.Nilsson@nottingham.ac.uk<mailto:Henrik.Nilsson@nottingham.ac.uk>> wrote: I am totally with Lennart here: something that used to be conceptually very simple, clear, and, not the least, easy to teach, has become complex and muddled for little if any good reason at all. What is that if not obfuscation? And I am not just drawing on my own experience here, but also from that of many colleagues with years and years of teaching experience. /Henrik Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk<mailto:nhn@cs.nott.ac.uk> -------- Original message -------- From: Nathan Bouscal Date:2016/02/24 13:43 (GMT+00:00) To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) I'm not trying to say that a pair is not a container of two things. I'm saying that that description is insufficiently specific to be useful for the purposes of the discussion. There are many ways to be a container of two things, and if we are to have functions whose behavior depends on the structure of the data they're working on, it's inevitable that those functions will behave differently for different of those ways of being a container. If the issue is that "containers" don't always behave the way one might naively expect containers to behave, then I'm just pointing out that this isn't the only place that holds, and that in other areas we've already accepted this. On Wed, Feb 24, 2016 at 1:38 PM, Augustsson, Lennart <Lennart.Augustsson@sc.com<mailto:Lennart.Augustsson@sc.com>> wrote: Of course a pair is a container of two things (which can have different types). You can come up with some different definition of what it means to be a container, so that a pair is no longer a container of two things, but this is just obfuscation. From: Libraries [mailto:libraries-bounces@haskell.org<mailto:libraries-bounces@haskell.org>] On Behalf Of Nathan Bouscal Sent: 24 February 2016 13:29 To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples) On Wed, Feb 24, 2016 at 1:04 PM, Henrik Nilsson <Henrik.Nilsson@nottingham.ac.uk<mailto:Henrik.Nilsson@nottingham.ac.uk>> wrote: Hi, On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote: Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b'; Which, to me, at least, very much sounds like a container of two elements? You can use essentially the same argument to say that [a] sounds like a container of any number of elements, therefore there shouldn't be anything wrong with [1, 'foo']. It's not uncommon in programming for "what a thing naively sounds like" to be quite different from "what a thing actually is". Tuples are not lists. I agree that there's room for confusion, but there is room for confusion in a lot of parts of Haskell, especially for people who bring a lot of preconceived notions with them. We should try to make the transition easier for them, but to me that looks a lot more like "really good error messages" and less like pointedly ignoring the structure of types that might be confusing. Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.) as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'. data TwoThree a b = TwoThree a a b b b What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be? A static type error, perhaps? (As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.) Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type. Best, /Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk<mailto:nhn@cs.nott.ac.uk> This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. _______________________________________________ Libraries mailing list Libraries@haskell.org<mailto:Libraries@haskell.org> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products. This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham. This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
Apologies for being unclear. By marginal, I meant that I expect many learners who end up confused by this would have otherwise come across the same confusion by other paths. So, the long-run net amount of confusion would be the same. That's obviously a complete guess on my part, but it does seem somewhat reasonable. Learners definitely have to understand the difference between lists and tuples at some point. They also ought to understand how constructor classes work at some point. If we want to reduce the friction in that process, we should focus our energy on creating better educational material, not on removing certain instances that we think are particularly opaque. On Wed, Feb 24, 2016 at 3:24 PM, Henrik Nilsson < Henrik.Nilsson@nottingham.ac.uk> wrote:
Hi,
Sorry Nathan, I am not following your argument: you seem to be arguing two ways at the same time. Maybe "marginal" should have been "major"?
However:
I see an additional way for an unwary learner to discover complexity that was already there, by passing a value that they weren't previously able to pass to a function
No, that specific complexity were *not* there previously. Applying length or maximum etc. to a tuple used to be a type error. End of story. And that was a good thing for many reasons, including that length or maximum on tuples are not particularly useful: the former being a roundabout way to compute 1, the latter being a rather obscurely named projection function.
One could similarly argue that `id` is not particularly useful, being a roundabout way to compute something you already have. We're clearly talking about different specific complexities. As I see it, the complexity is in how constructor classes work (as Chris helpfully pointed out). They work the same regardless of what instance of them you focus on. If a learner happens to come across their existence sooner because they accidentally called length on a tuple and became confused, we can either 1) take the opportunity to teach them about a useful concept, or 2) postpone the explanation for later. In either case, the concept itself is exactly as complex as it ever was.
/Henrik
Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
-------- Original message -------- From: Nathan Bouscal Date:2016/02/24 14:42 (GMT+00:00) To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples)
I don't see any additional complexity. I see an additional way for an unwary learner to discover complexity that was already there, by passing a value that they weren't previously able to pass to a function that they don't yet have a complete model of. That will definitely cause some confusion, but I'm not convinced it will cause marginal confusion, nor that such confusion is bad. This is not the only way that learners can mix up tuples and lists, and that distinction is something every learner has to understand at some point.
You can still teach tuples exactly the same way that you used to teach tuples, and you can still teach finding the length of a list exactly the same way that you used to teach it. Unless your curriculum previously included an explicit demonstration of `length (1, 2)` causing an error, I don't see why it would need to change.
On Wed, Feb 24, 2016 at 2:20 PM, Henrik Nilsson < Henrik.Nilsson@nottingham.ac.uk> wrote:
I am totally with Lennart here: something that used to be conceptually very simple, clear, and, not the least, easy to teach, has become complex and muddled for little if any good reason at all. What is that if not obfuscation?
And I am not just drawing on my own experience here, but also from that of many colleagues with years and years of teaching experience.
/Henrik
Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
-------- Original message -------- From: Nathan Bouscal Date:2016/02/24 13:43 (GMT+00:00) To: Haskell Libraries Subject: Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples)
I'm not trying to say that a pair is not a container of two things. I'm saying that that description is insufficiently specific to be useful for the purposes of the discussion. There are many ways to be a container of two things, and if we are to have functions whose behavior depends on the structure of the data they're working on, it's inevitable that those functions will behave differently for different of those ways of being a container. If the issue is that "containers" don't always behave the way one might naively expect containers to behave, then I'm just pointing out that this isn't the only place that holds, and that in other areas we've already accepted this.
On Wed, Feb 24, 2016 at 1:38 PM, Augustsson, Lennart < Lennart.Augustsson@sc.com> wrote:
Of course a pair is a container of two things (which can have different types).
You can come up with some different definition of what it means to be a container, so that a pair is no longer a container of two things, but this is just obfuscation.
*From:* Libraries [mailto:libraries-bounces@haskell.org] *On Behalf Of *Nathan Bouscal *Sent:* 24 February 2016 13:29 *To:* Haskell Libraries *Subject:* Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples)
On Wed, Feb 24, 2016 at 1:04 PM, Henrik Nilsson < Henrik.Nilsson@nottingham.ac.uk> wrote:
Hi,
On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote:
Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b';
Which, to me, at least, very much sounds like a container of two elements?
You can use essentially the same argument to say that [a] sounds like a container of any number of elements, therefore there shouldn't be anything wrong with [1, 'foo']. It's not uncommon in programming for "what a thing naively sounds like" to be quite different from "what a thing actually is". *Tuples are not lists*.
I agree that there's room for confusion, but there is room for confusion in *a lot* of parts of Haskell, especially for people who bring a lot of preconceived notions with them. We should try to make the transition easier for them, but to me that looks a lot more like "really good error messages" and less like pointedly ignoring the structure of types that might be confusing.
Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.)
as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'.
data TwoThree a b = TwoThree a a b b b
What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be?
A static type error, perhaps?
(As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.)
Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type.
Best,
/Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html
Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx
Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same.
Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it.
Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it.
Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
Nathan Bouscal <nbouscal@gmail.com> writes:
Apologies for being unclear. By marginal, I meant that I expect many learners who end up confused by this would have otherwise come across the same confusion by other paths.
This sounds odd to me in two ways: 1. it is not "the same" confusion -- it is a worse confusion, for several reasons: - the questionable Functor instance gives a cognitive dissonance for not transforming the entirety of the tuple (for good reasons, but still!) - the questionable Functor is a puzzlingly arbitrary choice among a N-family of options that an N-tuple provides. 2. but even if the confusion itself wasn't made worse -- its impact has increased, because exposure to it has increased -- с уважениeм / respectfully, Косырев Сергей
On Wed, Feb 24, 2016 at 3:49 PM, Kosyrev Serge <_deepfire@feelingofgreen.ru> wrote:
Nathan Bouscal <nbouscal@gmail.com> writes:
Apologies for being unclear. By marginal, I meant that I expect many learners who end up confused by this would have otherwise come across the same confusion by other paths.
This sounds odd to me in two ways:
1. it is not "the same" confusion -- it is a worse confusion, for several reasons: - the questionable Functor instance gives a cognitive dissonance for not transforming the entirety of the tuple (for good reasons, but still!) - the questionable Functor is a puzzlingly arbitrary choice among a N-family of options that an N-tuple provides.
As Ed pointed out, there is nothing arbitrary about the choice. This actually makes tuples in some sense a uniquely good way of explaining how things work, because you can show why this restriction exists.
2. but even if the confusion itself wasn't made worse -- its impact has increased, because exposure to it has increased
To the extent that exposure has increased, I would think it would be caused by confusion of the "lists vs tuples" type, which seems important to resolve early. That resolution doesn't really need to say anything about how Functor works, and can instead be more along the lines of "What problem were you trying to solve by taking the length of a tuple? Should you have been using a list instead?"
-- с уважениeм / respectfully, Косырев Сергей
Having length of a tuple not be a type error is not only confusing for beginners. It can also mask bugs in real code written by experts. And it’s already happened. Since length of a tuple returning 1 is nonsensical and useless, it should simply not be legal. From: Libraries [mailto:libraries-bounces@haskell.org] On Behalf Of Nathan Bouscal Sent: 24 February 2016 15:56 To: Kosyrev Serge Cc: Haskell Libraries Subject: Re: Haskell Foldable Wats On Wed, Feb 24, 2016 at 3:49 PM, Kosyrev Serge <_deepfire@feelingofgreen.ru<mailto:_deepfire@feelingofgreen.ru>> wrote: Nathan Bouscal <nbouscal@gmail.com<mailto:nbouscal@gmail.com>> writes:
Apologies for being unclear. By marginal, I meant that I expect many learners who end up confused by this would have otherwise come across the same confusion by other paths.
This sounds odd to me in two ways: 1. it is not "the same" confusion -- it is a worse confusion, for several reasons: - the questionable Functor instance gives a cognitive dissonance for not transforming the entirety of the tuple (for good reasons, but still!) - the questionable Functor is a puzzlingly arbitrary choice among a N-family of options that an N-tuple provides. As Ed pointed out, there is nothing arbitrary about the choice. This actually makes tuples in some sense a uniquely good way of explaining how things work, because you can show why this restriction exists. 2. but even if the confusion itself wasn't made worse -- its impact has increased, because exposure to it has increased To the extent that exposure has increased, I would think it would be caused by confusion of the "lists vs tuples" type, which seems important to resolve early. That resolution doesn't really need to say anything about how Functor works, and can instead be more along the lines of "What problem were you trying to solve by taking the length of a tuple? Should you have been using a list instead?" -- с уважениeм / respectfully, Косырев Сергей This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same. Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
Aren't these sorts of mistakes impossible with ML sigs and structs? On 02/24/2016 10:08 AM, Augustsson, Lennart wrote:
Having length of a tuple not be a type error is not only confusing for beginners.
It can also mask bugs in real code written by experts. And it’s already happened.
Since length of a tuple returning 1 is nonsensical and useless, it should simply not be legal.
*From:*Libraries [mailto:libraries-bounces@haskell.org] *On Behalf Of *Nathan Bouscal *Sent:* 24 February 2016 15:56 *To:* Kosyrev Serge *Cc:* Haskell Libraries *Subject:* Re: Haskell Foldable Wats
On Wed, Feb 24, 2016 at 3:49 PM, Kosyrev Serge <_deepfire@feelingofgreen.ru <mailto:_deepfire@feelingofgreen.ru>> wrote:
Nathan Bouscal <nbouscal@gmail.com <mailto:nbouscal@gmail.com>> writes:
Apologies for being unclear. By marginal, I meant that I expect many learners who end up confused by this would have otherwise come across the same confusion by other paths.
This sounds odd to me in two ways:
1. it is not "the same" confusion -- it is a worse confusion, for several reasons: - the questionable Functor instance gives a cognitive dissonance for not transforming the entirety of the tuple (for good reasons, but still!) - the questionable Functor is a puzzlingly arbitrary choice among a N-family of options that an N-tuple provides.
As Ed pointed out, there is nothing arbitrary about the choice. This actually makes tuples in some sense a uniquely good way of explaining how things work, because you can show why this restriction exists.
2. but even if the confusion itself wasn't made worse -- its impact has increased, because exposure to it has increased
To the extent that exposure has increased, I would think it would be caused by confusion of the "lists vs tuples" type, which seems important to resolve early. That resolution doesn't really need to say anything about how Functor works, and can instead be more along the lines of "What problem were you trying to solve by taking the length of a tuple? Should you have been using a list instead?"
-- с уважениeм / respectfully, Косырев Сергей
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html
Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx
Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same.
Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Were any of these objections put forward in 1993 when Mark P. Jones published on constructor classes [1] ? Everything about this follows directly and uniquely from that design. [1]: http://web.cecs.pdx.edu/~mpj/pubs/fpca93.pdf On Wed, Feb 24, 2016 at 7:38 AM, Augustsson, Lennart < Lennart.Augustsson@sc.com> wrote:
Of course a pair is a container of two things (which can have different types).
You can come up with some different definition of what it means to be a container, so that a pair is no longer a container of two things, but this is just obfuscation.
*From:* Libraries [mailto:libraries-bounces@haskell.org] *On Behalf Of *Nathan Bouscal *Sent:* 24 February 2016 13:29 *To:* Haskell Libraries *Subject:* Re: Haskell Foldable Wats (Was: Add conspicuously missing Functor instances for tuples)
On Wed, Feb 24, 2016 at 1:04 PM, Henrik Nilsson < Henrik.Nilsson@nottingham.ac.uk> wrote:
Hi,
On 02/24/2016 11:08 AM, Fumiaki Kinoshita wrote:
Thinking tuples of as multi-element containers is not recommended. A tuple (a, b) is, a pair of one 'a' and one 'b';
Which, to me, at least, very much sounds like a container of two elements?
You can use essentially the same argument to say that [a] sounds like a container of any number of elements, therefore there shouldn't be anything wrong with [1, 'foo']. It's not uncommon in programming for "what a thing naively sounds like" to be quite different from "what a thing actually is". *Tuples are not lists*.
I agree that there's room for confusion, but there is room for confusion in *a lot* of parts of Haskell, especially for people who bring a lot of preconceived notions with them. We should try to make the transition easier for them, but to me that looks a lot more like "really good error messages" and less like pointedly ignoring the structure of types that might be confusing.
Seriosuly, if, as a result of tuples being instances of Functor and Foldable etc., the end result is confusion to the point that many no longer understand a tuple simply as a container of a certain number of elements, then that's another case in point against this whole design. (In particular the Foldable part: while I personally don't find the functor instances particularly compelling or useful, they seem less likely to seriously bite.)
as Foldable works on values pointed by the rightmost type argument, 1 should be the only reasonable result of 'length'.
data TwoThree a b = TwoThree a a b b b
What should 'length (TwoThree "Foo" "Bar" 0 1 2)' be?
A static type error, perhaps?
(As indeed it will be unless the appropriate instances are made for TwoThree. But I am guessing we should understand TwoThree as a tuple here.)
Looking at only the expression, 5 might seem to make sense, but is not meaningful considering the type.
Best,
/Henrik -- Henrik Nilsson School of Computer Science The University of Nottingham nhn@cs.nott.ac.uk
This message and any attachment are intended solely for the addressee and may contain confidential information. If you have received this message in error, please send it back to me, and immediately delete it. Please do not use, copy or disclose the information contained in this message or in any attachment. Any views or opinions expressed by the author of this email do not necessarily reflect the views of the University of Nottingham.
This message has been checked for viruses but the contents of an attachment may still contain software viruses which could damage your computer system, you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This email and any attachments are confidential and may also be privileged. If you are not the intended recipient, please delete all copies and notify the sender immediately. You may wish to refer to the incorporation details of Standard Chartered PLC, Standard Chartered Bank and their subsidiaries at http://www.standardchartered.com/en/incorporation-details.html
Insofar as this communication contains any market commentary, the market commentary has been prepared by sales and/or trading desk of Standard Chartered Bank or its affiliate. It is not and does not constitute research material, independent research, recommendation or financial advice. Any market commentary is for information purpose only and shall not be relied for any other purpose, and is subject to the relevant disclaimers available at http://wholesalebanking.standardchartered.com/en/utility/Pages/d-mkt.aspx
Insofar as this e-mail contains the term sheet for a proposed transaction, by responding affirmatively to this e-mail, you agree that you have understood the terms and conditions in the attached term sheet and evaluated the merits and risks of the transaction. We may at times also request you to sign on the term sheet to acknowledge in respect of the same.
Please visit http://wholesalebanking.standardchartered.com/en/capabilities/financialmarke... for important information with respect to derivative products.
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
-- Chris Allen Currently working on http://haskellbook.com
On Wed, 24 Feb 2016, Christopher Allen wrote:
Were any of these objections put forward in 1993 when Mark P. Jones published on constructor classes [1] ? Everything about this follows directly and uniquely from that design. [1]: http://web.cecs.pdx.edu/~mpj/pubs/fpca93.pdf
I don't think so. As I have shown there could have been generalizations of 'length' where 'length (a,b) = 2'. That would not be a generalization via Foldable, though. And again, I do not propose to implement 'length (a,b) = 2'.
On Mon, Jan 18, 2016, at 12:44, Christopher Allen wrote:
I've addressed this here:
http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html
The thousand-papercuts opposition to typeclass instances on the premise that a Functor for (a, b, c) maps over the final type not making sense is a rejection of how higher kinded types and typeclasses work together. This is natural and predictable if one bothers to explain it.
The behavior is indeed predictable, but I think Henning is arguing (and I would agree) that it is *undesirable*. That being said, I think the ship has sailed on the "should tuples be a Functor/etc" discussion. The current proposal is aimed at making the set of available instances more consistent across tuples, which I'd argue is a good thing regardless of one's position on the specific class.
I share Henning's concerns. Can someone provide a realistic example of where an instance for (,,) or (,,,) *is* desirable? Tom
El 18 ene 2016, a las 15:59, Eric Seidel <eric@seidel.io> escribió:
On Mon, Jan 18, 2016, at 12:44, Christopher Allen wrote: I've addressed this here:
http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html
The thousand-papercuts opposition to typeclass instances on the premise that a Functor for (a, b, c) maps over the final type not making sense is a rejection of how higher kinded types and typeclasses work together. This is natural and predictable if one bothers to explain it.
The behavior is indeed predictable, but I think Henning is arguing (and I would agree) that it is *undesirable*.
That being said, I think the ship has sailed on the "should tuples be a Functor/etc" discussion. The current proposal is aimed at making the set of available instances more consistent across tuples, which I'd argue is a good thing regardless of one's position on the specific class. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
On 16-01-18 04:17 PM, amindfv@gmail.com wrote:
I share Henning's concerns. Can someone provide a realistic example of where an instance for (,,) or (,,,) *is* desirable?
I'm looking at some examples in production code here at work:
firstOfThree (a, b, c) = a onFirstOfThree f = changeNode (\(a, b, c)-> (f a, b, c))
The triple that's being manipulated is local to a bigger function, and the order of its a, b, c parameters is arbitrary. If this code was written in presence of the proposed instances, the first parameter would likely become the last, and at least the latter function would be dropped:
onLastOfThree = fmap
I'm not convinced there's any downside, so I'm +1 on the proposal.
On Wed, 20 Jan 2016, Mario Blažević wrote:
On 16-01-18 04:17 PM, amindfv@gmail.com wrote:
I share Henning's concerns. Can someone provide a realistic example of where an instance for (,,) or (,,,) *is* desirable?
I'm looking at some examples in production code here at work:
firstOfThree (a, b, c) = a onFirstOfThree f = changeNode (\(a, b, c)-> (f a, b, c))
I have fst3 and mapFst3 in my utilities package: https://hackage.haskell.org/package/utility-ht-0.0.11/docs/Data-Tuple-HT.htm...
I don't know why "I wouldn't use it" should extend to "it shouldn't exist".
I'm in favor of these instances, if only for the sake of consistency. However, I don't agree with this reasoning. Typeclass instances in Haskell are an inherently global construct: once an instance is defined, you can't do anything about it. You can't replace it or redefine it or even not import it. At the same time, it affects type inference and type error messages even if you're *not* using it. As a slightly more extreme example, there's a reason we don't have a Num instance for functions or Applicatives by default: while perfectly well-formed and even useful, having these instances would lead to worse error messages or even code typechecking when it shouldn't with weird results—even if you never rely on them yourself. On Mon, Jan 18, 2016 at 12:59 PM, Eric Seidel <eric@seidel.io> wrote:
On Mon, Jan 18, 2016, at 12:44, Christopher Allen wrote:
I've addressed this here:
http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html
The thousand-papercuts opposition to typeclass instances on the premise that a Functor for (a, b, c) maps over the final type not making sense is a rejection of how higher kinded types and typeclasses work together. This is natural and predictable if one bothers to explain it.
The behavior is indeed predictable, but I think Henning is arguing (and I would agree) that it is *undesirable*.
That being said, I think the ship has sailed on the "should tuples be a Functor/etc" discussion. The current proposal is aimed at making the set of available instances more consistent across tuples, which I'd argue is a good thing regardless of one's position on the specific class. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
In every case I can think of where an instance turned out to be a problem, that was because there were multiple law-abiding options and the designers chose the wrong one. Examples that at least some people disagree with: instance Monoid a => Monoid (Maybe a) -- McBride has argued for mappend = (<|>) here instead. instance Monoid b => Monoid (a -> b) -- McBride again, IIRC, dislikes this, weakly preferring -- instance a ~ b => Monoid (a -> b) instance (Eq k, Hashable k) => Monoid (HashMap k v) -- Almost everyone wants -- instance (Semigroup v, Hashable k) => Monoid (HashMap k v) A Num instance for functions is a bad idea because it leads to terrible error messages, but I would argue that's a poor example. The (->) constructor has a sufficiently special, and sufficiently silent, role in the language that it requires a *uniquely* high level of care. When that care is taken (as with the Monad ((->) a) instance), things generally work out just fine. On Jan 18, 2016 4:21 PM, "Tikhon Jelvis" <tikhon@jelv.is> wrote:
I don't know why "I wouldn't use it" should extend to "it shouldn't exist".
I'm in favor of these instances, if only for the sake of consistency. However, I don't agree with this reasoning. Typeclass instances in Haskell are an inherently global construct: once an instance is defined, you can't do anything about it. You can't replace it or redefine it or even not import it. At the same time, it affects type inference and type error messages even if you're *not* using it.
As a slightly more extreme example, there's a reason we don't have a Num instance for functions or Applicatives by default: while perfectly well-formed and even useful, having these instances would lead to worse error messages or even code typechecking when it shouldn't with weird results—even if you never rely on them yourself.
On Mon, Jan 18, 2016 at 12:59 PM, Eric Seidel <eric@seidel.io> wrote:
On Mon, Jan 18, 2016, at 12:44, Christopher Allen wrote:
I've addressed this here:
http://bitemyapp.com/posts/2015-10-19-either-is-not-arbitrary.html
The thousand-papercuts opposition to typeclass instances on the premise that a Functor for (a, b, c) maps over the final type not making sense is a rejection of how higher kinded types and typeclasses work together. This is natural and predictable if one bothers to explain it.
The behavior is indeed predictable, but I think Henning is arguing (and I would agree) that it is *undesirable*.
That being said, I think the ship has sailed on the "should tuples be a Functor/etc" discussion. The current proposal is aimed at making the set of available instances more consistent across tuples, which I'd argue is a good thing regardless of one's position on the specific class. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Henning Thielemann <lemming@henning-thielemann.de> writes:
I would never use such an instance. Can I be warned if I accidentally use it anyway?
I don't know why "I wouldn't use it" should extend to "it shouldn't exist". +1 on having such instances. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
On Mon, 18 Jan 2016, John Wiegley wrote:
Henning Thielemann <lemming@henning-thielemann.de> writes:
I would never use such an instance. Can I be warned if I accidentally use it anyway?
I don't know why "I wouldn't use it" should extend to "it shouldn't exist".
Because I cannot turn it off and I cannot get warning. It is inserted by GHC whenever it matches, even if I made a mistake when programming.
I can sympathize with your sentiment. Normally, if there's a datatype whose instance I don't want to use, I just make my own replacement. However, it's hard to do that with tuples given their special syntactic treatment. It might be worth looking into adding RebindableSyntax for tuples [1] to address scenarios like this. Ryan S. ----- [1] https://ghc.haskell.org/trac/ghc/ticket/7845 On Mon, Jan 18, 2016 at 4:22 PM, Henning Thielemann <lemming@henning-thielemann.de> wrote:
On Mon, 18 Jan 2016, John Wiegley wrote:
> Henning Thielemann <lemming@henning-thielemann.de> writes:
I would never use such an instance. Can I be warned if I accidentally use it anyway?
I don't know why "I wouldn't use it" should extend to "it shouldn't exist".
Because I cannot turn it off and I cannot get warning. It is inserted by GHC whenever it matches, even if I made a mistake when programming.
On Mon, Jan 18, 2016, at 13:22, Henning Thielemann wrote:
On Mon, 18 Jan 2016, John Wiegley wrote:
> Henning Thielemann <lemming@henning-thielemann.de> writes:
I would never use such an instance. Can I be warned if I accidentally use it anyway?
I don't know why "I wouldn't use it" should extend to "it shouldn't exist".
Because I cannot turn it off and I cannot get warning. It is inserted by GHC whenever it matches, even if I made a mistake when programming.
There may be an easier way, but one could write a Core-to-Core plugin that kills the build if it sees an expression like `fmap @(,)`.
I love the idea of adding support for such a warning, but I think core2core is likely too late to do the job properly. The instance resolution information is (currently, at least) thrown out altogether once the type checker finishes its job. And even the slightest bit of inlining of external modules could give false positives. I would think the easiest way would be to add a "suppressed instance" structure to the type checker. It would basically be a stripped-down analogue of the big instance database the type checker uses for instance resolution. When resolving an instance, the type checker would first check the suppressed instance set for it; if it found it there, it would fail or warn as appropriate. So I could write something like {-# SuppressInstance Functor ((,) a) #-} But I could also write something more subtle like {-# WarnInstance Semigroup v => Monoid (HashMap k v) #-} which would only warn me if I use the Monoid instance for a HashMap whose values form a semigroup. On Jan 18, 2016 4:31 PM, "Eric Seidel" <eric@seidel.io> wrote:
On Mon, Jan 18, 2016, at 13:22, Henning Thielemann wrote:
On Mon, 18 Jan 2016, John Wiegley wrote:
>> Henning Thielemann <lemming@henning-thielemann.de> writes:
I would never use such an instance. Can I be warned if I accidentally
use it
anyway?
I don't know why "I wouldn't use it" should extend to "it shouldn't exist".
Because I cannot turn it off and I cannot get warning. It is inserted by GHC whenever it matches, even if I made a mistake when programming.
There may be an easier way, but one could write a Core-to-Core plugin that kills the build if it sees an expression like `fmap @(,)`. _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
On Mon, Jan 18, 2016, at 15:19, David Feuer wrote:
I love the idea of adding support for such a warning, but I think core2core is likely too late to do the job properly. The instance resolution information is (currently, at least) thrown out altogether once the type checker finishes its job. And even the slightest bit of inlining of external modules could give false positives.
This was my main concern as well. I don't recall if ghc performs any inlining before running the core2core pipeline, but it's certainly fragile even wrt the pipeline order.
I would think the easiest way would be to add a "suppressed instance" structure to the type checker. It would basically be a stripped-down analogue of the big instance database the type checker uses for instance resolution. When resolving an instance, the type checker would first check the suppressed instance set for it; if it found it there, it would fail or warn as appropriate. So I could write something like
{-# SuppressInstance Functor ((,) a) #-}
But I could also write something more subtle like
{-# WarnInstance Semigroup v => Monoid (HashMap k v) #-}
which would only warn me if I use the Monoid instance for a HashMap whose values form a semigroup.
We might be able to make this work as a type-checker plugin (which would be quite nice at least for experimentation). I don't recall off the top of my head if the constraint solver calls plugins before or after it tries to discharge the constraints on its own, but if plugins get access to constraints first we could write one that simply marks undesired instances as insoluble.
On Mon, Jan 18, 2016, at 15:31, Eric Seidel wrote:
On Mon, Jan 18, 2016, at 15:19, David Feuer wrote:
I would think the easiest way would be to add a "suppressed instance" structure to the type checker. It would basically be a stripped-down analogue of the big instance database the type checker uses for instance resolution. When resolving an instance, the type checker would first check the suppressed instance set for it; if it found it there, it would fail or warn as appropriate. So I could write something like
{-# SuppressInstance Functor ((,) a) #-}
But I could also write something more subtle like
{-# WarnInstance Semigroup v => Monoid (HashMap k v) #-}
which would only warn me if I use the Monoid instance for a HashMap whose values form a semigroup.
We might be able to make this work as a type-checker plugin (which would be quite nice at least for experimentation). I don't recall off the top of my head if the constraint solver calls plugins before or after it tries to discharge the constraints on its own, but if plugins get access to constraints first we could write one that simply marks undesired instances as insoluble.
Ah, plugins are run after the built-in solver, bummer.
On Mon, 18 Jan 2016, Eric Seidel wrote:
We might be able to make this work as a type-checker plugin (which would be quite nice at least for experimentation). I don't recall off the top of my head if the constraint solver calls plugins before or after it tries to discharge the constraints on its own, but if plugins get access to constraints first we could write one that simply marks undesired instances as insoluble.
Nice to see that you have concrete suggestions how to implement such a warning. Once I proposed an extension for forbidding certain instances: https://ghc.haskell.org/trac/ghc/ticket/7775 I was forwarded to the "instance chain" proposal that would solve my problem: https://ghc.haskell.org/trac/ghc/ticket/9334 This ticket also contains a solution that requires only existing extensions. However this solution does not allow to only warn about a problematic instance or to prevent the use of such an instance only locally. A proper solution would allow to define a set of forbidden instances and import that in other packages, but does not affect packages later in the import chain. A way for explicit import of instances was discussed every now and then. This might also provide a way to get rid of specific instances. However, every solution seems to be a long way to go. Eventually, it looks wrong to me to add security holes first and then start to fix them, or defer that for an indefinite time. Btw. I see that the problem was already discussed on Reddit: https://www.reddit.com/r/haskell/comments/3qcg2d/proposal_forbidden_instance...
IMHO managing import of instances using the normal module import mechanisms is the only sane way to go. I seem to recall SPJ wanting to do this many years ago: I don't remember the details of the discussion or why it wasn't actually done. It does seem hard, but would be so worth it. On Wed, Feb 17, 2016 at 2:30 AM Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Mon, 18 Jan 2016, Eric Seidel wrote:
We might be able to make this work as a type-checker plugin (which would be quite nice at least for experimentation). I don't recall off the top of my head if the constraint solver calls plugins before or after it tries to discharge the constraints on its own, but if plugins get access to constraints first we could write one that simply marks undesired instances as insoluble.
Nice to see that you have concrete suggestions how to implement such a warning. Once I proposed an extension for forbidding certain instances: https://ghc.haskell.org/trac/ghc/ticket/7775
I was forwarded to the "instance chain" proposal that would solve my problem: https://ghc.haskell.org/trac/ghc/ticket/9334
This ticket also contains a solution that requires only existing extensions. However this solution does not allow to only warn about a problematic instance or to prevent the use of such an instance only locally.
A proper solution would allow to define a set of forbidden instances and import that in other packages, but does not affect packages later in the import chain. A way for explicit import of instances was discussed every now and then. This might also provide a way to get rid of specific instances.
However, every solution seems to be a long way to go. Eventually, it looks wrong to me to add security holes first and then start to fix them, or defer that for an indefinite time.
Btw. I see that the problem was already discussed on Reddit:
https://www.reddit.com/r/haskell/comments/3qcg2d/proposal_forbidden_instance... _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Sadly Bart, Once you do allow explicit qualification of what imports you get you lose the global coherence property that we have about the uniqueness of instances. This isn't just an academic concern. Little libraries like Data.Set cease be well behaved, because nothing ensures that the instance you pass to the call to lookup is the same as was used to build the library. It then forces you to start carrying all sorts of instances around inside of data, and use one off methods to manipulate structures rather than use many of the classes and tools we can use today. Haskell is the only language in wide use that has this property (modulo some incoherent instance / orphan instance concerns). It'd be a damn shame to lose it. -Edward On Wed, Feb 17, 2016 at 12:38 PM, Bart Massey <bart.massey@gmail.com> wrote:
IMHO managing import of instances using the normal module import mechanisms is the only sane way to go. I seem to recall SPJ wanting to do this many years ago: I don't remember the details of the discussion or why it wasn't actually done. It does seem hard, but would be so worth it.
On Wed, Feb 17, 2016 at 2:30 AM Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Mon, 18 Jan 2016, Eric Seidel wrote:
We might be able to make this work as a type-checker plugin (which would be quite nice at least for experimentation). I don't recall off the top of my head if the constraint solver calls plugins before or after it tries to discharge the constraints on its own, but if plugins get access to constraints first we could write one that simply marks undesired instances as insoluble.
Nice to see that you have concrete suggestions how to implement such a warning. Once I proposed an extension for forbidding certain instances: https://ghc.haskell.org/trac/ghc/ticket/7775
I was forwarded to the "instance chain" proposal that would solve my problem: https://ghc.haskell.org/trac/ghc/ticket/9334
This ticket also contains a solution that requires only existing extensions. However this solution does not allow to only warn about a problematic instance or to prevent the use of such an instance only locally.
A proper solution would allow to define a set of forbidden instances and import that in other packages, but does not affect packages later in the import chain. A way for explicit import of instances was discussed every now and then. This might also provide a way to get rid of specific instances.
However, every solution seems to be a long way to go. Eventually, it looks wrong to me to add security holes first and then start to fix them, or defer that for an indefinite time.
Btw. I see that the problem was already discussed on Reddit:
https://www.reddit.com/r/haskell/comments/3qcg2d/proposal_forbidden_instance... _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
This is why I like the forbidden instance idea. It doesn't allow us to shadow one instance of eg 'Ord Int' with another, it just disables 'Ord Int' altogether in the current module, thus leaving coherence intact. On Wed, Feb 17, 2016, at 13:28, Edward Kmett wrote:
Sadly Bart,
Once you do allow explicit qualification of what imports you get you lose the global coherence property that we have about the uniqueness of instances.
This isn't just an academic concern. Little libraries like Data.Set cease be well behaved, because nothing ensures that the instance you pass to the call to lookup is the same as was used to build the library. It then forces you to start carrying all sorts of instances around inside of data, and use one off methods to manipulate structures rather than use many of the classes and tools we can use today.
Haskell is the only language in wide use that has this property (modulo some incoherent instance / orphan instance concerns). It'd be a damn shame to lose it.
-Edward
On Wed, Feb 17, 2016 at 12:38 PM, Bart Massey <bart.massey@gmail.com> wrote:
IMHO managing import of instances using the normal module import mechanisms is the only sane way to go. I seem to recall SPJ wanting to do this many years ago: I don't remember the details of the discussion or why it wasn't actually done. It does seem hard, but would be so worth it.
On Wed, Feb 17, 2016 at 2:30 AM Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Mon, 18 Jan 2016, Eric Seidel wrote:
We might be able to make this work as a type-checker plugin (which would be quite nice at least for experimentation). I don't recall off the top of my head if the constraint solver calls plugins before or after it tries to discharge the constraints on its own, but if plugins get access to constraints first we could write one that simply marks undesired instances as insoluble.
Nice to see that you have concrete suggestions how to implement such a warning. Once I proposed an extension for forbidding certain instances: https://ghc.haskell.org/trac/ghc/ticket/7775
I was forwarded to the "instance chain" proposal that would solve my problem: https://ghc.haskell.org/trac/ghc/ticket/9334
This ticket also contains a solution that requires only existing extensions. However this solution does not allow to only warn about a problematic instance or to prevent the use of such an instance only locally.
A proper solution would allow to define a set of forbidden instances and import that in other packages, but does not affect packages later in the import chain. A way for explicit import of instances was discussed every now and then. This might also provide a way to get rid of specific instances.
However, every solution seems to be a long way to go. Eventually, it looks wrong to me to add security holes first and then start to fix them, or defer that for an indefinite time.
Btw. I see that the problem was already discussed on Reddit:
https://www.reddit.com/r/haskell/comments/3qcg2d/proposal_forbidden_instance... _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Henning Thielemann <lemming@henning-thielemann.de> writes:
Because I cannot turn it off and I cannot get warning. It is inserted by GHC whenever it matches, even if I made a mistake when programming.
OK, that's a pretty sound argument against, since this could affect everyone everywhere, and not just those who opt-in. -- John Wiegley GPG fingerprint = 4710 CF98 AF9B 327B B80F http://newartisans.com 60E1 46C4 BD1A 7AC1 4BA2
participants (39)
-
Adam Bergmark -
amindfv@gmail.com -
Andreas Abel -
Andreas Abel -
Andrew Farmer -
Augustsson, Lennart -
Bart Massey -
Chris Allen -
Christopher Allen -
Daniel Trstenjak -
David Feuer -
David Laing -
Dmitry Olshansky -
Edward Kmett -
Eric Seidel -
Erik Hesselink -
Fumiaki Kinoshita -
Henning Thielemann -
Henrik Nilsson -
Herbert Valerio Riedel -
Herbert Valerio Riedel -
Index Int -
Jake McArthur -
Jeremy -
John Wiegley -
Kosyrev Serge -
Kris Nuttycombe -
M Farkas-Dyck -
Manuel Gómez -
Marcin Mrotek -
Mario Blažević -
Mark Roberts -
Matthias Hörmann -
Nathan Bouscal -
Oliver Charles -
Phil Ruffwind -
Ryan Scott -
Simon Peyton Jones -
Tikhon Jelvis