Proposal: Don't require users to use undefined

Edward Kmett ekmett at gmail.com
Wed Oct 27 08:29:26 EDT 2010


+1

I'm more than happy to strip the Data.Default instance from Data.Tagged,
I've already had a couple of users complain about how 'heavy' a dependency
it is, since Data.Default has to provide all the definitions for lots of
other libraries that predate it, including the MTL.

-Edward

On Tue, Oct 26, 2010 at 12:15 PM, Bas van Dijk <v.dijk.bas at gmail.com> wrote:

> Dear all,
>
> Users of the sizeOf or alignment methods (:: a -> Int) of the Storable
> class are pushed to use 'undefined' in their programs. Take the
> following function from Foreign.Marshal.Alloc as an example:
>
> malloc :: Storable a => IO (Ptr a)
> malloc  = doMalloc undefined
>  where
>    doMalloc       :: Storable b => b -> IO (Ptr b)
>    doMalloc dummy  = mallocBytes (sizeOf dummy)
>
> I find the use of 'undefined' ugly; its only purpose is to help the
> type-checker by carrying around a type variable. It also makes the job
> of an optimizing compiler harder because, in order to avoid generating
> unnecessary code, the compiler needs to find out if undefined isn't
> used. More importantly however, 'undefined' is dangerous; The
> type-checker will never complain when you accidentally use 'undefined'
> in the wrong place increasing the change that your program will crash.
> Also, instance writers for the Storable class need to be careful not
> to evaluate the argument of sizeOf because it may be undefined.
>
> The use of 'undefined' is not only required by the Storable class.
> Users of the HasResolution class from Data.Fixed also need to use
> 'undefined' in order to get the resolution of a fixed value:
>
> class HasResolution a where
>    resolution :: p a -> Integer
>
> I would like to propose solving this. My proposal consists of 3
> sub-proposals:
>
> 1) Add module Data.Tagged.
> 2) Modify the sizeOf and alignment methods of the Storable class.
> 3) Modify the HasResolution class.
>
> What follows are more detailed explanations of the proposals:
>
>
> 1) Add module Data.Tagged.
>
> My proposal is to move the Data.Tagged module from Edward A. Kmett's
> tagged package to base.
> See: http://hackage.haskell.org/package/tagged
> The only modification that needs to be done is to drop the Default
> instance for Proxy because this will otherwise require that
> Data.Default be moved to base as well which isn't my intention. When
> this proposal is accepted Data.Default can provide the instance
> instead.


> 2) Modify the sizeOf and alignment methods of the Storable class.
>
> I would like to replace the following:
>
> class Storable a where
>   sizeOf      :: a -> Int
>   alignment   :: a -> Int
>
> with:
>
> class Storable a where
>   sizeOf      :: SizeOf a
>   alignment   :: Alignment a
>
> type SizeOf a = Tagged a Int
> type Alignment a = Tagged a Int
>
> To retrieve the actual size of type 'a' use:
> untag (sizeOf :: SizeOf a)
> where: untag :: Tagged s b -> b from Data.Tagged.
>
> See the following for the haddock documentation:
>
> http://code.haskell.org/~basvandijk/doc/ghc/html/libraries/base-4.3.0.0/Foreign-Storable.html
>
> Here's the definition of the previous malloc function to give you an
> impression how code looks when my proposals are accepted:
>
> malloc :: forall a. Storable a => IO (Ptr a)
> malloc = mallocBytes (untag (sizeOf :: SizeOf a))
>
> (Note that this does require the ScopedTypeVariables language extension.)
>
>
> 3) Modify the HasResolution class.
>
> I would like to modify the HasResolution class in the same way. So
> replacing:
>
> class HasResolution a where
>    resolution :: p a -> Integer
>
> with:
>
> class HasResolution a where
>    resolution :: Resolution a
>
> type Resolution a = Tagged a Integer
>
> See the following for the haddock documentation:
>
> http://code.haskell.org/~basvandijk/doc/ghc/html/libraries/base-4.3.0.0/Data-Fixed.html
>
> Note that Fixed also gets a HasResolution instance:
>
> instance HasResolution a => HasResolution (Fixed a) where
>    resolution = retag (resolution :: Resolution a)
>
> where: retag :: Tagged s b -> Tagged t b from Data.Tagged.
>
>
> There's a possible 4th proposal that I'm thinking about: The Bits
> class from Data.Bits has the bitSize :: a -> Int method. Maybe it
> would be a good idea to replace that as well with:
> bitSize :: BitSize a; type BitSize a = Tagged a Int
> However I think bitSize is more often applied to an actual value than
> to 'undefined' so I need to investigate that a little further.
>
>
> A patch for the base package is attached to the ticket. I also
> attached patches for the ghc compiler, bytestring, binary, vector and
> dph. The latter are just some packages that were inside my ghc
> repository. This email is CCed to the maintainers of these packages.
>
>
> Deadline: 3 weeks from now (Tuesday 16 November 2010) but I will shift
> it when the discussion demands it.
>
> Ticket: http://hackage.haskell.org/trac/ghc/ticket/4443
>
>
> Regards,
>
> Bas
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/libraries/attachments/20101027/44a81c7a/attachment-0001.html


More information about the Libraries mailing list