No subject


Thu Jul 5 12:38:43 CEST 2012


*.Unsafe modules rather than the *.Safe ones. But this is a signficant
restructuring and the only reason to do it would be to support
SafeHaskell. Moreover, I believe (though I haven't checked) that there are
calls from safe to unsafe functions and vice versa. So now I would have to
have a common base module with both safe and unsafe functions and reexport
those from the right top-level module. No, this just isn't feasible.

>> At the risk of being blunt, I do find SafeHaskell's notion of safety
>> somewhat obscure. In vector, all unsafe functions have the string
>> "unsafe"
>> in their name. Here are two examples of functions that don't do bounds
>> checking:
>>
>> unsafeIndex :: Vector a -> Int -> a
>> unsafeRead :: IOVector a -> Int -> IO a
>>
>> Unless I'm mistaken, SafeHaskell considers the first one unsafe and the
>> second one safe. Personally, I find vector's current notion of safety
>> much
>> more useful and wouldn't want to weaken it.
>
> SafeHaskell's notion of safety is very clear: it is essentially just
> type safety and referential transparency.  It would be impossible to
> have a clear notion of safety that considers some IO operations unsafe
> and others safe: e.g. do you consider reading a file to be unsafe?  Some
> applications would, and others wouldn't.

IO is certainly problematic. However, it is quite possible to have a clear
notion  (or, rather, notions) of safety for IO in a particular problem
domain, such as arrays. For vector, "natural" safety includes bounds
checking.

> Sticking strictly to
> clearly-defined properties like type safety (and a couple of other
> things, including module abstraction) as the definition of safety is the
> only sensible thing you can do.

As I said, I would like to be able to have multiple notions of safety.
What SafeHaskell provides is essentially the lowest common denominator. I
agree that it is useful to have but only in addition to other, tigher and
perhaps more domain-specific concepts which I consider more useful. But
the module-based approach requires me to structure the library around
SafeHaskell, essentially making it the "main" concept of safety in vector
and that's not a design I would be comfortable with.

> But this is beside the point.  Since unsafeRead is considered safe by
> SafeHaskell, you have the option of either putting it in the safe API or
> the unsafe API; it's up to you.

But wouldn't putting it in the unsafe API essentially be "abusing"
SafeHaskell to express a notion of safety different from type safety +
referential transparency? For me, the only sensible structure would be
putting unsafeIndex in the *.Unsafe module and unsafeRead in the safe one.
I strongly dislike this.

>> Additionally,
>> Data.Vector.Storable is entirely unsafe even in the SafeHaskell sense
>> (as
>> in, it unsafePerformIOs essentially arbitrary code) due to the design of
>> the Storable class - there are no safe bits there at all. It still uses
>> "unsafe" to distinguish between functions that do bounds checking and
>> those that don't. What would be the benefit of moving functions like
>> unsafeIndex into a separate module (and would it be called
>> Unsafe.unsafeIndex then? or would it be Unsafe.index?)? Would you
>> advocate
>> renaming Data.Vector.Storable to Data.Vector.Storable.Unsafe?
>
> Since it's the entire module in this case, I think it would be fine to
> just remark in the documentation for the module that the API is unsafe,
> and briefly explain why.

Well, it's not that simple. Data.Vector.Storable exports exactly the same
interface as Data.Vector.Unboxed and Data.Vector (modulo operations it
doesn't support). Now, if I move some functions from Data.Vector.Unboxed
to Data.Vector.Unboxed.Unsafe, I would also have to move the corresponding
functions from Data.Vector.Storable to Data.Vector.Storable.Unsafe even
though neither of these last two modules would be safe. This just seems
wrong to me.

Roman






More information about the Libraries mailing list