Proposal (breaking change, but probably not one that will break any real code): strictify genericLength

As far as I can tell, Haskell 2010 does not specify anything about the strictness of genericLength. Currently, it is maximally lazy. This is good, I suppose, if you want to support lists that are very long and are using floating point or some similarly broken Num instance. But this is not something many (any?) people have any interest in doing. As a result, the genericLength function is on a nice little list I found of Haskell functions one should never use. I therefore propose that we change it to something nice and simple, like genericLength = foldl' 0 (\x _ -> x + 1) Admittedly, this may not be optimal for Int8, Int16, Word8, or Word16, so we may need to use rules to rewrite these four to narrow the result of length (or some such).

David Feuer wrote:
As far as I can tell, Haskell 2010 does not specify anything about the strictness of genericLength. Currently, it is maximally lazy. This is good, I suppose, if you want to support lists that are very long and are using floating point or some similarly broken Num instance.
The motivating example I've seen is using lazy natural numbers, data Nat = Z | S Nat instance Num Nat where ... Z + y = y S x + y = S (x + y) instance Ord Nat where compare Z Z = EQ compare Z _ = LT compare _ Z = GT compare (S x) (S y) = compare x y and then foo xs = genericLength xs < (5 :: Nat) which will evaluate no more than 5 conses of xs.
But this is not something many (any?) people have any interest in doing. As a result, the genericLength function is on a nice little list I found of Haskell functions one should never use. I therefore propose that we change it to something nice and simple, like
genericLength = foldl' 0 (\x _ -> x + 1)
Admittedly, this may not be optimal for Int8, Int16, Word8, or Word16, so we may need to use rules to rewrite these four to narrow the result of length (or some such).
That said, I'm neutral on this propsal. Cheers, Bertram

On Aug 2, 2014 10:29 PM, "Bertram Felgenhauer" < bertram.felgenhauer@googlemail.com> wrote:
The motivating example I've seen is using lazy natural numbers,
Natural numbers aren't an entirely legitimate instance of Num either, because they don't support negate. Of course, this is a good argument for the Num class itself being broken, but unless someone *actually* relies on genericLength for lazy Nats, I think it's a good enough excuse not to support it for genericLength when doing so effectively renders genericLength useless for anything else. Calling something "generic" for Num when it's really only generic for things that look like lazy naturals doesn't seem very sane.

Hi, Am Samstag, den 02.08.2014, 22:02 -0400 schrieb David Feuer:
As far as I can tell, Haskell 2010 does not specify anything about the strictness of genericLength. Currently, it is maximally lazy. This is good, I suppose, if you want to support lists that are very long and are using floating point or some similarly broken Num instance.
But this is not something many (any?) people have any interest in doing. As a result, the genericLength function is on a nice little list I found of Haskell functions one should never use.
I think it’s ok to have it this way. Just because you and I don’t like broken Num instances, it doesn’t mean people who do should have to suffer. So in the interest of api stability, -1 from me here. Let’s just continue not to use genericLength in non-broken code and let playful people play. (We could improve the docs if required, of course.) Greetings, Joachim -- Joachim “nomeata” Breitner mail@joachim-breitner.de • http://www.joachim-breitner.de/ Jabber: nomeata@joachim-breitner.de • GPG-Key: 0xF0FBF51F Debian Developer: nomeata@debian.org

I would be -1 on changing genericLength to be strict. I for one _have_ been
known to use genericLength with the one point compactification of the
naturals to get lazy bound comparisons and use this in production code.
However, I would be +1 on adding a separate strict genericLength' to call
attention to the issue.
-Edward
On Sat, Aug 2, 2014 at 10:02 PM, David Feuer
As far as I can tell, Haskell 2010 does not specify anything about the strictness of genericLength. Currently, it is maximally lazy. This is good, I suppose, if you want to support lists that are very long and are using floating point or some similarly broken Num instance.
But this is not something many (any?) people have any interest in doing. As a result, the genericLength function is on a nice little list I found of Haskell functions one should never use. I therefore propose that we change it to something nice and simple, like
genericLength = foldl' 0 (\x _ -> x + 1)
Admittedly, this may not be optimal for Int8, Int16, Word8, or Word16, so we may need to use rules to rewrite these four to narrow the result of length (or some such).
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

That settles it. One is enough. Original proposal retracted. New proposal:
add genericLength'.
On Aug 3, 2014 8:56 AM, "Edward Kmett"
I would be -1 on changing genericLength to be strict. I for one _have_ been known to use genericLength with the one point compactification of the naturals to get lazy bound comparisons and use this in production code.
However, I would be +1 on adding a separate strict genericLength' to call attention to the issue.
-Edward
On Sat, Aug 2, 2014 at 10:02 PM, David Feuer
wrote: As far as I can tell, Haskell 2010 does not specify anything about the strictness of genericLength. Currently, it is maximally lazy. This is good, I suppose, if you want to support lists that are very long and are using floating point or some similarly broken Num instance.
But this is not something many (any?) people have any interest in doing. As a result, the genericLength function is on a nice little list I found of Haskell functions one should never use. I therefore propose that we change it to something nice and simple, like
genericLength = foldl' 0 (\x _ -> x + 1)
Admittedly, this may not be optimal for Int8, Int16, Word8, or Word16, so we may need to use rules to rewrite these four to narrow the result of length (or some such).
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
participants (4)
-
Bertram Felgenhauer
-
David Feuer
-
Edward Kmett
-
Joachim Breitner