Proposal: rename Data.Map.fromAscList to Data.Map.unsafeFromAscList

Hey all, I had some code where the function elems said a certain key was present, but looking it up returned a Nothing. After some debugging I found out that it did work if I used Prelude's lookup in combination with toList. After even more debugging it turned out there was a fromAscList somewhere deep down in my code where it should have been a fromList. Now, I know that I shouldn't have used fromAscList and that it was totally my fault. I also realize this is something that can't easily be checked using the type system, so I propose we do the next best thing: prefix the name with 'unsafe'. -chris

I disagree. There are plenty of non-total functions in various libraries.
Prefixing all of them with "unsafe" seems like overkill. Consider fromJust:
it should be called unsafeFromJust, same for head, tail, init...
Best regards
Christopher Skrzętnicki
On Fri, Apr 24, 2009 at 13:58, Chris Eidhof
Hey all,
I had some code where the function elems said a certain key was present, but looking it up returned a Nothing. After some debugging I found out that it did work if I used Prelude's lookup in combination with toList. After even more debugging it turned out there was a fromAscList somewhere deep down in my code where it should have been a fromList.
Now, I know that I shouldn't have used fromAscList and that it was totally my fault. I also realize this is something that can't easily be checked using the type system, so I propose we do the next best thing: prefix the name with 'unsafe'.
-chris
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

On the second thought, another thing can be made. Since we know that
fromAscList should take a list of ascending items, we can check whether it
is sorted. If this precondition is not met, we simply call error. We also
rename current fromAscList to unsafeFromAscList. This is similar to index
and unsafeIndex from arrays code.
What do you think about this solution?
Best regards
Christopher Skrzętnicki
On Fri, Apr 24, 2009 at 13:58, Chris Eidhof
Hey all,
I had some code where the function elems said a certain key was present, but looking it up returned a Nothing. After some debugging I found out that it did work if I used Prelude's lookup in combination with toList. After even more debugging it turned out there was a fromAscList somewhere deep down in my code where it should have been a fromList.
Now, I know that I shouldn't have used fromAscList and that it was totally my fault. I also realize this is something that can't easily be checked using the type system, so I propose we do the next best thing: prefix the name with 'unsafe'.
-chris
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

I really like that, Krzysztof. That way there's still the power to do it efficiently but at least you know when you're doing things in an erroneous way. My problem with the current way of doing this is that you get errors in a place where you didn't expect them. -chris On 24 apr 2009, at 14:14, Krzysztof Skrzętnicki wrote:
On the second thought, another thing can be made. Since we know that fromAscList should take a list of ascending items, we can check whether it is sorted. If this precondition is not met, we simply call error. We also rename current fromAscList to unsafeFromAscList. This is similar to index and unsafeIndex from arrays code.
What do you think about this solution?
Best regards
Christopher Skrzętnicki
On Fri, Apr 24, 2009 at 13:58, Chris Eidhof
wrote: Hey all, I had some code where the function elems said a certain key was present, but looking it up returned a Nothing. After some debugging I found out that it did work if I used Prelude's lookup in combination with toList. After even more debugging it turned out there was a fromAscList somewhere deep down in my code where it should have been a fromList.
Now, I know that I shouldn't have used fromAscList and that it was totally my fault. I also realize this is something that can't easily be checked using the type system, so I propose we do the next best thing: prefix the name with 'unsafe'.
-chris
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Chris Eidhof wrote:
I really like that, Krzysztof. That way there's still the power to do it efficiently but at least you know when you're doing things in an erroneous way. My problem with the current way of doing this is that you get errors in a place where you didn't expect them.
-chris
On 24 apr 2009, at 14:14, Krzysztof Skrzętnicki wrote:
On the second thought, another thing can be made. Since we know that fromAscList should take a list of ascending items, we can check whether it is sorted. If this precondition is not met, we simply call error. We also rename current fromAscList to unsafeFromAscList. This is similar to index and unsafeIndex from arrays code.
What do you think about this solution?
+1 Depending on the strictness qualities of (un-)safeFromAscList[1], the safeFromAscList version could do this check "online" rather than scanning the list to verify and then calling unsafeFromAscList[2], which would be helpful for list fusion (assuming foldr is used). [1] Which I think are already strict enough to give the behavior we want. [2] Impl: just keep a copy of the previous key, if the next key isn't monotone then error. -- Live well, ~wren

There is an old thread about this, where Daan suggested "unchecked" instead of "unsafe". http://www.haskell.org/pipermail/haskell/2004-March/013787.html "unsafe" reminds to "IO" stuff. Didn't you read the comment about fromAscList? Isn't the name long enough to scare you? Would you have not taken "unsafeFromAscList" under the same circumstances you've chosen "fromAscList"? Cheers Christian Chris Eidhof wrote:
Hey all,
I had some code where the function elems said a certain key was present, but looking it up returned a Nothing. After some debugging I found out that it did work if I used Prelude's lookup in combination with toList. After even more debugging it turned out there was a fromAscList somewhere deep down in my code where it should have been a fromList.
Now, I know that I shouldn't have used fromAscList and that it was totally my fault. I also realize this is something that can't easily be checked using the type system, so I propose we do the next best thing: prefix the name with 'unsafe'.
-chris

Hi,
I totally disagree. unsafe/unchecked means nothing other than "beware
of the bogey monster", or for most Haskell users, "just another
function that might launch missiles". fromAscList has the specific
precondition for this function in the name. Should we call unsafeHead?
uncheckedHead? mightCrashIfNotConsHead?
Adding a check for the precondition would be the ideal thing to do,
but I wouldn't want to do it if it added an extra comparison or was
any runtime cost at all. Perhaps adding checkedFromAscList might be
acceptable, but I can't imagine anyone would call it until they'd got
it wrong the first time, at which point the chances of them getting it
wrong again are quite low.
Thanks
Neil
On Fri, Apr 24, 2009 at 1:36 PM, Christian Maeder
There is an old thread about this, where Daan suggested "unchecked" instead of "unsafe". http://www.haskell.org/pipermail/haskell/2004-March/013787.html
"unsafe" reminds to "IO" stuff.
Didn't you read the comment about fromAscList? Isn't the name long enough to scare you?
Would you have not taken "unsafeFromAscList" under the same circumstances you've chosen "fromAscList"?
Cheers Christian
Chris Eidhof wrote:
Hey all,
I had some code where the function elems said a certain key was present, but looking it up returned a Nothing. After some debugging I found out that it did work if I used Prelude's lookup in combination with toList. After even more debugging it turned out there was a fromAscList somewhere deep down in my code where it should have been a fromList.
Now, I know that I shouldn't have used fromAscList and that it was totally my fault. I also realize this is something that can't easily be checked using the type system, so I propose we do the next best thing: prefix the name with 'unsafe'.
-chris
Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Neil Mitchell wrote:
Hi,
I totally disagree. unsafe/unchecked means nothing other than "beware of the bogey monster", or for most Haskell users, "just another function that might launch missiles". fromAscList has the specific precondition for this function in the name. Should we call unsafeHead? uncheckedHead? mightCrashIfNotConsHead?
Do I really need to point out the difference between head and fromAscList? fromAscList is total but may badly destroy the internal (invariant of the) representation. head at least crashes (hopefully fairly soon) when called wrongly. C.

Hello Christian, Friday, April 24, 2009, 5:10:57 PM, you wrote:
fromAscList is total but may badly destroy the internal (invariant of the) representation. head at least crashes (hopefully fairly soon) when called wrongly.
well, using id for list sorting may also give wrong result. that's implied by its name, not it? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

Hi
Do I really need to point out the difference between head and fromAscList?
fromAscList is total but may badly destroy the internal (invariant of the) representation. head at least crashes (hopefully fairly soon) when called wrongly.
Better example, sortBy f, where f isn't a valid ordering function. It works, but destroyed internal invariants. Should it be uncheckedSortBy f ? Thanks Neil

There are two kinds of functions that might be callled unsafe:
- non-total functions like head
- functions that require some precondition is met like fromAscList
First kind is too common to be prefixed with "unsafe". I has also a very
*nice* property: they crash program if they fail. Which is a good thing,
because it makes them always correct. Now, there is a second type. Those
functions may not crash the program, but they could go wrong without notice.
This is a very dangereous situation, since user may run across some strange
results in random places. So we make those functions safe by adding runtime
check. Surely there are times where the user is so much concerned about
performance they might as well choose to omit the check. But IMO Haskell
should be correct in the first place. There is no point in doing wrong
calculcations, even if we do them fast.
Best regards
Christopher Skrzętnicki
On Fri, Apr 24, 2009 at 14:51, Neil Mitchell
Hi,
I totally disagree. unsafe/unchecked means nothing other than "beware of the bogey monster", or for most Haskell users, "just another function that might launch missiles". fromAscList has the specific precondition for this function in the name. Should we call unsafeHead? uncheckedHead? mightCrashIfNotConsHead?
Adding a check for the precondition would be the ideal thing to do, but I wouldn't want to do it if it added an extra comparison or was any runtime cost at all. Perhaps adding checkedFromAscList might be acceptable, but I can't imagine anyone would call it until they'd got it wrong the first time, at which point the chances of them getting it wrong again are quite low.
Thanks
Neil
On Fri, Apr 24, 2009 at 1:36 PM, Christian Maeder
wrote: There is an old thread about this, where Daan suggested "unchecked" instead of "unsafe". http://www.haskell.org/pipermail/haskell/2004-March/013787.html
"unsafe" reminds to "IO" stuff.
Didn't you read the comment about fromAscList? Isn't the name long enough to scare you?
Would you have not taken "unsafeFromAscList" under the same circumstances you've chosen "fromAscList"?
Cheers Christian
Chris Eidhof wrote:
Hey all,
I had some code where the function elems said a certain key was present, but looking it up returned a Nothing. After some debugging I found out that it did work if I used Prelude's lookup in combination with toList. After even more debugging it turned out there was a fromAscList somewhere deep down in my code where it should have been a fromList.
Now, I know that I shouldn't have used fromAscList and that it was totally my fault. I also realize this is something that can't easily be checked using the type system, so I propose we do the next best thing: prefix the name with 'unsafe'.
-chris
Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Hi, On 24 apr 2009, at 14:51, Neil Mitchell wrote:
I totally disagree. unsafe/unchecked means nothing other than "beware of the bogey monster", or for most Haskell users, "just another function that might launch missiles". fromAscList has the specific precondition for this function in the name. Should we call unsafeHead? uncheckedHead? mightCrashIfNotConsHead?
No, but the functions you mentioned do fail immediately. If I use a head on an empty list I get an error immediately. If I use fromAscList incorrectly I get an error only when I try to lookup elements. This makes it hard to debug if you didn't make this error before. I don't mind a runtime error in this case, but I very much want to know where my bug is. Thanks, -chris
Thanks
Neil
On Fri, Apr 24, 2009 at 1:36 PM, Christian Maeder
wrote: There is an old thread about this, where Daan suggested "unchecked" instead of "unsafe". http://www.haskell.org/pipermail/haskell/2004-March/013787.html
"unsafe" reminds to "IO" stuff.
Didn't you read the comment about fromAscList? Isn't the name long enough to scare you?
Would you have not taken "unsafeFromAscList" under the same circumstances you've chosen "fromAscList"?
Cheers Christian
Chris Eidhof wrote:
Hey all,
I had some code where the function elems said a certain key was present, but looking it up returned a Nothing. After some debugging I found out that it did work if I used Prelude's lookup in combination with toList. After even more debugging it turned out there was a fromAscList somewhere deep down in my code where it should have been a fromList.
Now, I know that I shouldn't have used fromAscList and that it was totally my fault. I also realize this is something that can't easily be checked using the type system, so I propose we do the next best thing: prefix the name with 'unsafe'.
-chris
Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

Hello Chris, Friday, April 24, 2009, 5:21:20 PM, you wrote:
No, but the functions you mentioned do fail immediately. If I use a head on an empty list I get an error immediately. If I use fromAscList incorrectly I get an error only when I try to lookup elements. This makes it hard to debug if you didn't make this error before. I don't mind a runtime error in this case, but I very much want to know where my bug is.
how about providing such check only in *debugging* version of library? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On 24 apr 2009, at 15:26, Bulat Ziganshin wrote:
Hello Chris,
Friday, April 24, 2009, 5:21:20 PM, you wrote:
No, but the functions you mentioned do fail immediately. If I use a head on an empty list I get an error immediately. If I use fromAscList incorrectly I get an error only when I try to lookup elements. This makes it hard to debug if you didn't make this error before. I don't mind a runtime error in this case, but I very much want to know where my bug is.
how about providing such check only in *debugging* version of library?
That would give different semantics in two cases, suppose:
main = mapM dangerousFunction (toList (fromAscList [(1,0),(0,0)]))
When doing it without checks, this would fail after a couple of IO operations. When doing this with a check the function wouldn't do any IO at all. -chris

On Fri, Apr 24, 2009 at 15:26, Bulat Ziganshin
Hello Chris,
Friday, April 24, 2009, 5:21:20 PM, you wrote:
No, but the functions you mentioned do fail immediately. If I use a head on an empty list I get an error immediately. If I use fromAscList incorrectly I get an error only when I try to lookup elements. This makes it hard to debug if you didn't make this error before. I don't mind a runtime error in this case, but I very much want to know where my bug is.
how about providing such check only in *debugging* version of library?
I think the decision whether to include specific check should be left up to the developer. Perhaps I would like to retain only a subset of checks, while debugging version restricts my freedom and I would end up writing my own version. Giving functions with and without checks is a good way of giving such freedom. Regards Christopher Skrzętnicki

On Apr 24, 2009, at 2:51 PM, Neil Mitchell wrote:
Hi,
I totally disagree. unsafe/unchecked means nothing other than "beware of the bogey monster", or for most Haskell users, "just another function that might launch missiles". fromAscList has the specific precondition for this function in the name. Should we call unsafeHead? uncheckedHead? mightCrashIfNotConsHead?
Adding a check for the precondition would be the ideal thing to do, but I wouldn't want to do it if it added an extra comparison or was any runtime cost at all. Perhaps adding checkedFromAscList might be acceptable, but I can't imagine anyone would call it until they'd got it wrong the first time, at which point the chances of them getting it wrong again are quite low.
Thanks
Neil
On Fri, Apr 24, 2009 at 1:36 PM, Christian Maeder
wrote: ...
Personally I very much hope that Haskell' will change the definition of head to a safe version and include the current head function as unsafeHead. Encouraging developers to use and write total function is probably a good thing and prevents us from having to explain all those messy corners in the Haskell language to our Ruby and Python friends. Adding a new function safeFromAscList that actually checks the precondition and returns a |Maybe (Map a b)| may sound as a nice compromise, but shouldn't all function be safe by default? I'd much rather see to version of which one is called the `unsafe' than two version of which one is called `safe'. Safe feels like a safe default. -- Sebastiaan
participants (7)
-
Bulat Ziganshin
-
Chris Eidhof
-
Christian Maeder
-
Krzysztof Skrzętnicki
-
Neil Mitchell
-
Sebastiaan Visser
-
wren ng thornton