I believe that an unsafe function is a function that says that it will return a value of some type, but that it can actually throw an exception and end the execution therefore not returning any value at all, but I'm not sure.
Or could it be that an unsafe function is a function that can return a value of other type than the declared in the signature? Wouldn't that be a weakly typed function?
Or are weakly typed and unsafe synonyms in Haskell?
This may be a silly question, but I couldn't find a straightforward answer.
I checked the documentation of readLn
hoping to see a reference to unsafe functions, but there wasn't any.
This article, Unsafe functions, says something about breaking the type system, but it doesn't specify in which manner; through exceptions?, through returning values of the wrong type?
So, what is an unsafe function in Haskell?
There are several notions of "unsafe" in Haskell.
Calculating the value leads to I/O. The prime suspect here is unsafePerformIO
. It's a bit controversial whether lazy I/O and unsafeInterleaveIO
should be considered unsafe by this definition.
Something breaks the type system. The prime suspect is unsafeCoerce
, but unsafePerformIO
can do it too.
Something breaks memory safety without breaking the type system (thanks to Carl for reminding me). The prime suspects are unsafe
array or vector indexing operations and incorrect use of the foreign function interface.
The result of the calculation depends on the order of evaluation. The prime suspect is unsafePerformIO
but unsafeInterleaveST
can certainly do it too.
Evaluation can lead to an exception or infinite loop. This is a relatively mild sort of unsafety ... except when it's not.
Something breaks the conventions ("laws") Haskell programmers rely on to reason about their code. Whether this should be considered "unsafe" is subject to debate. Examples: applying seq
to a function, using coerce
in such a manner as to change the arity of a function relative to its reference implementation and cause a problem if someone applies seq
to what was previously a partial application and now can possibly be bottom (there are good performance reasons to do this in some cases), writing class instances that break functor, applicative, monad, traversable, etc., laws. Expecting arguments to satisfy pre-conditions but not checking that they do (e.g., functions that quickly turn ascending lists into sets or maps).
To help programmers control some of these forms of unsafety, the Safe Haskell system classifies modules as safe or unsafe depending on the imports and language extensions they use. I haven't studied the details, but GarethR indicates that
I think your notion 1 through 3 would be considered unsafe by Safe Haskell. It may be worth reading up on it because the Safe Haskell authors have clearly thought deeply on safety.
and Ørjan Johansen indicates that
Safe Haskell also disallows some things that fit in point 6, such as extensions that can circumvent module export boundaries (Template Haskell, generalized newtype deriving) or change the behavior of imported code (rules, overlapping instances).
A programmer can mark a module Safe
to indicate that they want GHC to check that it is safe, Unsafe
to indicate that it is not safe, or Trustworthy
to indicate that the author claims to believe that its API is safe to use despite the fact that its implementation uses unsafe features.
from haskell FFI wiki:
If you annotate a foreign import declaration with the unsafe keyword, this indicates to the compiler that (1) the call will not invoke another Haskell function, directly or indirectly, and (2) you don't mind if any other running Haskell threads in the system are blocked for the duration of the call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With