Unsafe aspects of ByteString

Chris Kuklewicz haskell at list.mightyreason.com
Sun Jan 28 14:16:16 EST 2007


Iavor Diatchki wrote:
> Hello,
> The "packCString" function (and other similar functions) in the
> ByteString library break referential transperancy, which is one of the
> big selling points of Haskell (and its libraries).   Here is an
> example:
> 
> main = do x <- newCString "Hello"
>          let s   = packCString x
>              h1  = B.head s
>          print s
>          -- print h1
>          poke x (toEnum 97)
>          print s
>          let h2 = B.head s
>          print h1
>          print h2
> Output:
> "Hello"
> "aello"
> 97
> 97
> 
> This is already confusing because the "pure" value 's' has magically
> changed.   Also notice that the evaluation order of the program
> affects the output.  If we include the commented out statement (which
> forces h1 to be evaluated earlier) the output becomes:
> "Hello"
> 72
> "aello"
> 72
> 97
> 
> I think that because of this we should either remove these functions,
> or at least follow the convention of other libraries and give them
> "unsafe" names.
> 
> -Iavor

The Data.ByteString type is really a fancy interface to ForeignPtr, which leads
to these issues.

I mostly agree.  Perhaps the pack* function should have unsafe* names.  Or at
least very large warnings in the documentation.

>From looking at the Haddock documentation:

The "safe" versions already exist as copyCString and copyCStringLen, which look
like (copy . packCString) and (copy . packCStringLen).

And Data.ByteString.useAsCStringLen also looks "unsafe", but
Data.ByteString.useAsCString is safe.  Even more oddly
Data.ByteString.useAsCStringLen looks identical in the documentation to
Data.ByteString.Base.unsafeUseAsCStringLen but does not call itself "unsafe" and
neither have the same dire warnings as Data.ByteString.Base.unsafeUseAsCString.

-- 
Chris


More information about the Libraries mailing list