More death to partial functions: Should -fwarn-incomplete-uni-patterns be enabled with -Wall?

Hello everyone, to my dismay, a -Wall compiled program I deployed today crashed with Exception: Non-exhaustive patterns in lambda and I learned from http://dev.stephendiehl.com/hask/ that A more subtle case is when implicitly pattern matching with a single "uni-pattern" in a lambda expression. The following will fail when given a Nothing. boom = \(Just a) -> something GHC can warn about these cases with the -fwarn-incomplete-uni-patterns flag. And in fact: ghci -Wall
map (\Nothing -> "ok") [Just 'a'] ["*** Exception: <interactive>:2:6-21: Non-exhaustive patterns in lambda :set -fwarn-incomplete-uni-patterns map (\Nothing -> "ok") [Just 'a'] <interactive>:4:6: Warning: Pattern match(es) are non-exhaustive
It really surprised me that -fwarn-incomplete-uni-patterns is not included in -Wall; I've felt really safe with my -Wall so far, especially about totality and similar things that will almost certainly lead to crashes. In an older mail from 2010 (https://mail.haskell.org/pipermail/glasgow-haskell-users/2010-September/0192...) I saw Simon mention that it wasn't planned to warn about inexhaustive patterns like this. I feel like there has been a strong push towards more totality in the last years, and I would like to ask if enabling -fwarn-incomplete-uni-patterns in -Wall may be reconsidered for a coming next GHC version, or if there are still opponents to that. Niklas

I guess the difference between lambdas and top level functions is that it's
more reasonable to assume top level functions must expect to deal with
every value (particularly when they're part of an interface), whereas
inline lambdas often can reasonably make assumptions about their input.
For example, whilst:
capitalise (l:ls) = (toUpper l):ls
you could argue as bad code because it fails on the empty string case,
something like:
capitalisedDictionary = map (\(l:ls) -> (toUpper l):ls) myDictionary where
myDIctionary = ...
you could argue is perfectly reasonable code. when the programmer knows
that "myDictionary" doesn't contain any empty strings (perhaps because of
checking that's already occurred).
You could even go further here, and suggest that GHC should have an option
"don't check incomplete patterns", allowing GHC to assume strings are non
empty in this case, blowing up spectacularly C style at run time if this is
incorrect with either a seg fault or launching the nuclear missiles,
although this could allow optimisation opportunities (does GHC already have
such an option?).
On Sun, Nov 8, 2015 at 11:10 AM, Niklas Hambüchen
Hello everyone,
to my dismay, a -Wall compiled program I deployed today crashed with
Exception: Non-exhaustive patterns in lambda
and I learned from http://dev.stephendiehl.com/hask/ that
A more subtle case is when implicitly pattern matching with a single "uni-pattern" in a lambda expression. The following will fail when given a Nothing.
boom = \(Just a) -> something
GHC can warn about these cases with the -fwarn-incomplete-uni-patterns flag.
And in fact:
ghci -Wall
map (\Nothing -> "ok") [Just 'a'] ["*** Exception: <interactive>:2:6-21: Non-exhaustive patterns in lambda :set -fwarn-incomplete-uni-patterns map (\Nothing -> "ok") [Just 'a'] <interactive>:4:6: Warning: Pattern match(es) are non-exhaustive
It really surprised me that -fwarn-incomplete-uni-patterns is not included in -Wall; I've felt really safe with my -Wall so far, especially about totality and similar things that will almost certainly lead to crashes.
In an older mail from 2010 ( https://mail.haskell.org/pipermail/glasgow-haskell-users/2010-September/0192... ) I saw Simon mention that it wasn't planned to warn about inexhaustive patterns like this.
I feel like there has been a strong push towards more totality in the last years, and I would like to ask if enabling -fwarn-incomplete-uni-patterns in -Wall may be reconsidered for a coming next GHC version, or if there are still opponents to that.
Niklas _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Absolutely agreed. The only time it is generally safe to write pattern
matching lambdas is if the type only has a single constructor. It's very
possible that someone re-factors their code so the type has multiple
constructors, but forgets that they wrote some of these lambda expressions.
-Wall should warn them about this.
--Will
On Sat, Nov 7, 2015 at 6:10 PM, Niklas Hambüchen
Hello everyone,
to my dismay, a -Wall compiled program I deployed today crashed with
Exception: Non-exhaustive patterns in lambda
and I learned from http://dev.stephendiehl.com/hask/ that
A more subtle case is when implicitly pattern matching with a single "uni-pattern" in a lambda expression. The following will fail when given a Nothing.
boom = \(Just a) -> something
GHC can warn about these cases with the -fwarn-incomplete-uni-patterns flag.
And in fact:
ghci -Wall
map (\Nothing -> "ok") [Just 'a'] ["*** Exception: <interactive>:2:6-21: Non-exhaustive patterns in lambda :set -fwarn-incomplete-uni-patterns map (\Nothing -> "ok") [Just 'a'] <interactive>:4:6: Warning: Pattern match(es) are non-exhaustive
It really surprised me that -fwarn-incomplete-uni-patterns is not included in -Wall; I've felt really safe with my -Wall so far, especially about totality and similar things that will almost certainly lead to crashes.
In an older mail from 2010 ( https://mail.haskell.org/pipermail/glasgow-haskell-users/2010-September/0192... ) I saw Simon mention that it wasn't planned to warn about inexhaustive patterns like this.
I feel like there has been a strong push towards more totality in the last years, and I would like to ask if enabling -fwarn-incomplete-uni-patterns in -Wall may be reconsidered for a coming next GHC version, or if there are still opponents to that.
Niklas _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Just learning Haskell here but I also agree. Rust gives a compile error by
default for non-exhaustive patterns.
I expect Haskell to be more secure than Rust.
https://doc.rust-lang.org/book/match.html
On Sun, Nov 8, 2015 at 3:16 AM, William Yager
Absolutely agreed. The only time it is generally safe to write pattern matching lambdas is if the type only has a single constructor. It's very possible that someone re-factors their code so the type has multiple constructors, but forgets that they wrote some of these lambda expressions. -Wall should warn them about this.
--Will
On Sat, Nov 7, 2015 at 6:10 PM, Niklas Hambüchen
wrote: Hello everyone,
to my dismay, a -Wall compiled program I deployed today crashed with
Exception: Non-exhaustive patterns in lambda
and I learned from http://dev.stephendiehl.com/hask/ that
A more subtle case is when implicitly pattern matching with a single "uni-pattern" in a lambda expression. The following will fail when given a Nothing.
boom = \(Just a) -> something
GHC can warn about these cases with the -fwarn-incomplete-uni-patterns flag.
And in fact:
ghci -Wall
map (\Nothing -> "ok") [Just 'a'] ["*** Exception: <interactive>:2:6-21: Non-exhaustive patterns in lambda :set -fwarn-incomplete-uni-patterns map (\Nothing -> "ok") [Just 'a'] <interactive>:4:6: Warning: Pattern match(es) are non-exhaustive
It really surprised me that -fwarn-incomplete-uni-patterns is not included in -Wall; I've felt really safe with my -Wall so far, especially about totality and similar things that will almost certainly lead to crashes.
In an older mail from 2010 ( https://mail.haskell.org/pipermail/glasgow-haskell-users/2010-September/0192... ) I saw Simon mention that it wasn't planned to warn about inexhaustive patterns like this.
I feel like there has been a strong push towards more totality in the last years, and I would like to ask if enabling -fwarn-incomplete-uni-patterns in -Wall may be reconsidered for a coming next GHC version, or if there are still opponents to that.
Niklas _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Clinton:
when the programmer knows that "myDictionary" doesn't contain any empty strings (perhaps because of checking that's already occurred).
I think if the non-empty string invariant is only required for the implementation of one function, it might be safe write a lambda which assumes the invariant, but in general such assumptions are better expressed through the type system (eg, a newtype with only a smart constructor exposed, which checks that the string is nonempty). William:
It's very possible that someone re-factors their code so the type has multiple constructors, but forgets that they wrote some of these lambda expressions. -Wall should warn them about this.
Yikes. This is a very good argument for these warnings to be enabled.
I'll probably modify the `stack new` project template to include
-fwarn-incomplete-uni-patterns in the cabal file for the time being.
On Sat, Nov 7, 2015 at 5:21 PM, Apostolis Xekoukoulotakis
Just learning Haskell here but I also agree. Rust gives a compile error by default for non-exhaustive patterns. I expect Haskell to be more secure than Rust.
https://doc.rust-lang.org/book/match.html
On Sun, Nov 8, 2015 at 3:16 AM, William Yager
wrote: Absolutely agreed. The only time it is generally safe to write pattern matching lambdas is if the type only has a single constructor. It's very possible that someone re-factors their code so the type has multiple constructors, but forgets that they wrote some of these lambda expressions. -Wall should warn them about this.
--Will
On Sat, Nov 7, 2015 at 6:10 PM, Niklas Hambüchen
wrote: Hello everyone,
to my dismay, a -Wall compiled program I deployed today crashed with
Exception: Non-exhaustive patterns in lambda
and I learned from http://dev.stephendiehl.com/hask/ that
A more subtle case is when implicitly pattern matching with a single "uni-pattern" in a lambda expression. The following will fail when given a Nothing.
boom = \(Just a) -> something
GHC can warn about these cases with the -fwarn-incomplete-uni-patterns flag.
And in fact:
ghci -Wall
map (\Nothing -> "ok") [Just 'a'] ["*** Exception: <interactive>:2:6-21: Non-exhaustive patterns in lambda :set -fwarn-incomplete-uni-patterns map (\Nothing -> "ok") [Just 'a'] <interactive>:4:6: Warning: Pattern match(es) are non-exhaustive
It really surprised me that -fwarn-incomplete-uni-patterns is not included in -Wall; I've felt really safe with my -Wall so far, especially about totality and similar things that will almost certainly lead to crashes.
In an older mail from 2010
(https://mail.haskell.org/pipermail/glasgow-haskell-users/2010-September/0192...) I saw Simon mention that it wasn't planned to warn about inexhaustive patterns like this.
I feel like there has been a strong push towards more totality in the last years, and I would like to ask if enabling -fwarn-incomplete-uni-patterns in -Wall may be reconsidered for a coming next GHC version, or if there are still opponents to that.
Niklas _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

I agree that this should be included in -Wall. I've many times added a uni
pattern "temporarily" and sometimes forgotten to fix it later on.
- Adam
On Sun, Nov 8, 2015 at 2:29 AM, Patrick Redmond
Clinton:
when the programmer knows that "myDictionary" doesn't contain any empty strings (perhaps because of checking that's already occurred).
I think if the non-empty string invariant is only required for the implementation of one function, it might be safe write a lambda which assumes the invariant, but in general such assumptions are better expressed through the type system (eg, a newtype with only a smart constructor exposed, which checks that the string is nonempty).
William:
It's very possible that someone re-factors their code so the type has multiple constructors, but forgets that they wrote some of these lambda expressions. -Wall should warn them about this.
Yikes. This is a very good argument for these warnings to be enabled. I'll probably modify the `stack new` project template to include -fwarn-incomplete-uni-patterns in the cabal file for the time being.
On Sat, Nov 7, 2015 at 5:21 PM, Apostolis Xekoukoulotakis
wrote: Just learning Haskell here but I also agree. Rust gives a compile error by default for non-exhaustive patterns. I expect Haskell to be more secure than Rust.
https://doc.rust-lang.org/book/match.html
On Sun, Nov 8, 2015 at 3:16 AM, William Yager
wrote: Absolutely agreed. The only time it is generally safe to write pattern matching lambdas is if the type only has a single constructor. It's very possible that someone re-factors their code so the type has multiple constructors, but forgets that they wrote some of these lambda
expressions.
-Wall should warn them about this.
--Will
On Sat, Nov 7, 2015 at 6:10 PM, Niklas Hambüchen
wrote: Hello everyone,
to my dismay, a -Wall compiled program I deployed today crashed with
Exception: Non-exhaustive patterns in lambda
and I learned from http://dev.stephendiehl.com/hask/ that
A more subtle case is when implicitly pattern matching with a single "uni-pattern" in a lambda expression. The following will fail when given a Nothing.
boom = \(Just a) -> something
GHC can warn about these cases with the -fwarn-incomplete-uni-patterns flag.
And in fact:
ghci -Wall
map (\Nothing -> "ok") [Just 'a'] ["*** Exception: <interactive>:2:6-21: Non-exhaustive patterns in lambda :set -fwarn-incomplete-uni-patterns map (\Nothing -> "ok") [Just 'a'] <interactive>:4:6: Warning: Pattern match(es) are non-exhaustive
It really surprised me that -fwarn-incomplete-uni-patterns is not included in -Wall; I've felt really safe with my -Wall so far, especially about totality and similar things that will almost certainly lead to crashes.
In an older mail from 2010
(
https://mail.haskell.org/pipermail/glasgow-haskell-users/2010-September/0192... )
I saw Simon mention that it wasn't planned to warn about inexhaustive patterns like this.
I feel like there has been a strong push towards more totality in the last years, and I would like to ask if enabling -fwarn-incomplete-uni-patterns in -Wall may be reconsidered for a coming next GHC version, or if there are still opponents to that.
Niklas _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

ne 8. 11. 2015 v 2:16 odesílatel William Yager
Absolutely agreed. The only time it is generally safe to write pattern matching lambdas is if the type only has a single constructor. It's very possible that someone re-factors their code so the type has multiple constructors, but forgets that they wrote some of these lambda expressions. -Wall should warn them about this.
+1
--Will
On Sat, Nov 7, 2015 at 6:10 PM, Niklas Hambüchen
wrote: Hello everyone,
to my dismay, a -Wall compiled program I deployed today crashed with
Exception: Non-exhaustive patterns in lambda
and I learned from http://dev.stephendiehl.com/hask/ that
A more subtle case is when implicitly pattern matching with a single "uni-pattern" in a lambda expression. The following will fail when given a Nothing.
boom = \(Just a) -> something
GHC can warn about these cases with the -fwarn-incomplete-uni-patterns flag.
And in fact:
ghci -Wall
map (\Nothing -> "ok") [Just 'a'] ["*** Exception: <interactive>:2:6-21: Non-exhaustive patterns in lambda :set -fwarn-incomplete-uni-patterns map (\Nothing -> "ok") [Just 'a'] <interactive>:4:6: Warning: Pattern match(es) are non-exhaustive
It really surprised me that -fwarn-incomplete-uni-patterns is not included in -Wall; I've felt really safe with my -Wall so far, especially about totality and similar things that will almost certainly lead to crashes.
In an older mail from 2010 ( https://mail.haskell.org/pipermail/glasgow-haskell-users/2010-September/0192... ) I saw Simon mention that it wasn't planned to warn about inexhaustive patterns like this.
I feel like there has been a strong push towards more totality in the last years, and I would like to ask if enabling -fwarn-incomplete-uni-patterns in -Wall may be reconsidered for a coming next GHC version, or if there are still opponents to that.
Niklas _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

Hi Niklas, Am Sonntag, den 08.11.2015, 01:10 +0100 schrieb Niklas Hambüchen:
In an older mail from 2010 (https://mail.haskell.org/pipermail/glasgow-haskell-users/2010-Septem ber/019237.html) I saw Simon mention that it wasn't planned to warn about inexhaustive patterns like this.
note that in that mail, he refers to patterns in where clauses, which is a different use-case than the lambdas you refer to. GHC is a large code base that traditionally is kept -Wall clean. You could make your proposal a bit more substantial by compiling GHC with -fwarn-incomplete-uni-patterns on and see what breaks, what the usual use-cases are, how to change the code to make it clean again. Then you are in a good position to argue that it is an improvement (or you will find that SPJ, as very often, has a good instinct and making it warn about that prohibits many useful idioms.) Personally, I’m sympathetic to “he who uses -Wall gets to jump through hoops”, but incomplete where patterns that bind variables that are not used in all cases are useful... 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

On Sun, Nov 08, 2015 at 09:36:13AM +0100, Joachim Breitner wrote:
Am Sonntag, den 08.11.2015, 01:10 +0100 schrieb Niklas Hambüchen:
In an older mail from 2010 (https://mail.haskell.org/pipermail/glasgow-haskell-users/2010-Septem ber/019237.html) I saw Simon mention that it wasn't planned to warn about inexhaustive patterns like this.
note that in that mail, he refers to patterns in where clauses, which is a different use-case than the lambdas you refer to.
[...]
Then you are in a good position to argue that it is an improvement (or you will find that SPJ, as very often, has a good instinct and making it warn about that prohibits many useful idioms.)
Simon's code is inadvisable, in my opinion. It is f xs | null xs = blah | otherwise = x+1 where (x:_) = xs where it really should be f xs = case xs of [] -> blah (x:_) -> x + 1 Tom

Hi, Am Sonntag, den 08.11.2015, 09:30 +0000 schrieb Tom Ellis:
Simon's code is inadvisable, in my opinion. It is
f xs | null xs = blah | otherwise = x+1 where (x:_) = xs
where it really should be
f xs = case xs of [] -> blah (x:_) -> x + 1
yes, in this particular, small example But often you have complex decisions in the guards that are not obviously related to the pattern match, and the where-bound and partially-pattern-matched value are used in multiple branches of the guard. 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

On Sun, Nov 08, 2015 at 10:42:35AM +0100, Joachim Breitner wrote:
Am Sonntag, den 08.11.2015, 09:30 +0000 schrieb Tom Ellis:
Simon's code is inadvisable, in my opinion. It is
f xs | null xs = blah | otherwise = x+1 where (x:_) = xs
where it really should be
f xs = case xs of [] -> blah (x:_) -> x + 1
yes, in this particular, small example
But often you have complex decisions in the guards that are not obviously related to the pattern match, and the where-bound and partially-pattern-matched value are used in multiple branches of the guard.
I can't address less particular, larger, examples until I'm shown them, but I am going to make the very bold claim that there's *always* a version without partial pattern matches that is at least as clear as the original. I strongly encourage you to challenge me on this claim! Tom
participants (9)
-
Adam Bergmark
-
Apostolis Xekoukoulotakis
-
Clinton Mead
-
Joachim Breitner
-
Niklas Hambüchen
-
Patrick Redmond
-
Petr Pudlák
-
Tom Ellis
-
William Yager