
Bruce Stewart wrote:
And unsafeRead/unsafeWrite are too verbose. They are usually (almost always?) safe (since the code does its own checks),
The same can be said about most uses of unsafePerformIO - you wouldn't be using it if you weren't certain that your program will behave properly.
so perhaps this essential-for-performance interface should have nicer names?
Any primitive with can destroy the nice properties of Haskell when *misused* should be marked as unsafe. The point is that you can do anything with other nice, non-unsafe functions and you will still stay within the semantics of the language.
Based on a ShootoutEntry discussion that Don and I had, I was under the mistaken impression that "unsafeWrite" broke an ST assumption because "unsafePerformIO" broke an IO assumption. However, I think that I agree with both of you because we're using multiple definitions of "unsafe". I see these as different degrees of "unsafe": unsafePerformIO - breaks an IO assumption; unsafeWrite - doesn't do a bounds check...
With unsafeWrite you can write to any address in memory, so you can crash the program hmm... If I put an incorrect index into IArray.write, Ix.index errors and the program exits/dies/crashes (without SEGV). This doesn't seem much "safer". To be "safe": readArray :: (MArray a e m, Ix i) => a i e -> i -> m e writeArray :: (MArray a e m, Ix i) => a i e -> i -> e -> m () could be readArray :: (MArray a e m, Ix i) => a i e -> i -> m (Maybe e) writeArray :: (MArray a e m, Ix i) => a i e -> i -> e -> m (Maybe ()) ...but this seems to be carrying it a bit far.
I think that I'd prefer clear markings for different specializations: unsafePerformIO - UNSAFE; use with caution; writeArray - write to an array; returns m (Maybe ()); very safe; writeArray_q - write _quickly without bounds check; moderately less safe; foldl - blah blah; foldl_s - "foldl" made more _strict. - Alson