[GHC] #13498: More storable instances?

#13498: More storable instances? -------------------------------------+------------------------------------- Reporter: wyager | Owner: (none) Type: feature | Status: new request | Priority: normal | Milestone: Component: | Version: 8.0.1 libraries/base | Keywords: Storable, | Operating System: Unknown/Multiple Foreign, Ptr | Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Is it intentional that we don't have {{{Storable}}} instances for ADTs like {{{Maybe}}} and {{{Either}}}, nor for things like {{{(,)}}}? This approach seems to work: https://gist.github.com/wyager/8443c3f5a9fc9b52dc28346bafdf409f Basically what the C compiler would do for a {{{union}}} type with a tag. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13498 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13498: More storable instances? -------------------------------------+------------------------------------- Reporter: wyager | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 8.0.1 Resolution: | Keywords: Storable, | Foreign, Ptr Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by svenpanne): The reasoning why sum types have no `Storable` instance by default is that the encoding would be quite arbitrary. In your example: Why are the tags 8 bit wide, and why are the tag values `0` and `1`? Do we need a tag at all? For e.g. `Maybe (Ptr a)` a more common encoding is to have no tag at all and represent `Nothing` as a null pointer. For product types things are less arbitrary, but even then there is the issue of alignment. If you need serialization, you can use `Data.Binary`. I think we should close this ticket as `wontfix`, because the lack of these instances was a very deliberate decision. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13498#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13498: More storable instances? -------------------------------------+------------------------------------- Reporter: wyager | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 8.0.1 Resolution: | Keywords: Storable, | Foreign, Ptr Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by wyager):
the encoding would be quite arbitrary
How is this an argument against adding the encodings? If they function correctly, why does it matter that they aren't "fixed" in some sense?
Why are the tags 8 bit wide, and why are the tag values 0 and 1?
Because it makes sense and works. Why, for a {{{Ratio}}}, is the numerator stored before the denominator? Presumably for the same reason. The choice of representation doesn't really matter a whole lot; the point of this feature request isn't to bikeshed over the exact implementation, but to establish if there's some fundamental stumbling block with this approach.
then there is the issue of alignment
I *think* my `lcm` trick solves this for sum types. For product types, there are some obvious approaches.
If you need serialization, you can use `Data.Binary`.
Besides `Data.Binary` being vastly slower than `Storable`, the primary use case here is `Data.Vector.Storable` and `Data.Array.Storable`. You can't write an `Unbox` instance for `Maybe a`, but you can (as I've done here) write a `Storable` instance. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13498#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13498: More storable instances? -------------------------------------+------------------------------------- Reporter: wyager | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 8.0.1 Resolution: | Keywords: Storable, | Foreign, Ptr Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by svenpanne): Replying to [comment:2 wyager]:
the encoding would be quite arbitrary
How is this an argument against adding the encodings? If they function correctly, why does it matter that they aren't "fixed" in some sense?
The general rule of thumb is: The Prelude doesn't make arbitrary choices when there is no obviously "right" way of doing things. Well, there are exceptions, but that's the idea. In our case, there ''are'' various arbitrary choices. Remember that the prime motivation for `Storable` is the FFI, and there are numerous ways used in actual C libraries to encode the equivalent of `Maybe` or `Either`, and none of them is "more correct" than the other.
Why are the tags 8 bit wide, and why are the tag values 0 and 1?
Because it makes sense and works.
`CChar` or `CInt` or `Word` make sense, too, and depending on the circumstances, they would be even better. That was just an example for the arbitrary decisions which would have to be made.
[...]
If you need serialization, you can use `Data.Binary`.
Besides `Data.Binary` being vastly slower than `Storable`, the primary use case here is `Data.Vector.Storable` and `Data.Array.Storable`. You can't write an `Unbox` instance for `Maybe a`, but you can (as I've done here) write a `Storable` instance.
If you directly want to use `Maybe` and `Either` with those containers, nothing is going to stop you from rolling your own. A better approach would probably be `newtype` wrappers for `Maybe` and `Either` with the corresponding `Storable` instances, making your arbitrary decisions explicit. Is using `Binary` really that much slower than your own code? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13498#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13498: More storable instances? -------------------------------------+------------------------------------- Reporter: wyager | Owner: (none) Type: feature request | Status: new Priority: normal | Milestone: Component: libraries/base | Version: 8.0.1 Resolution: | Keywords: Storable, | Foreign, Ptr Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by wyager):
Remember that the prime motivation for Storable is the FFI
That's a fair argument. But I'm curious; how often do people use the various `Storable` array types? I use `Data.Vector.Storable` a fair amount, and if that's a common use case, it makes sense to support it as well.
nothing is going to stop you from rolling your own
Which is precisely what I've done here, although I think it could make sense to use a standardized, agreed-upon representation known to be alignment-safe and have good performance. That said, I think you're right that this would be equally well-served by a library external to `base`, so on that note I'll close the ticket. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13498#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#13498: More storable instances? -------------------------------------+------------------------------------- Reporter: wyager | Owner: (none) Type: feature request | Status: closed Priority: normal | Milestone: Component: libraries/base | Version: 8.0.1 Resolution: worksforme | Keywords: Storable, | Foreign, Ptr Operating System: Unknown/Multiple | Architecture: | Unknown/Multiple Type of failure: None/Unknown | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Changes (by wyager): * status: new => closed * resolution: => worksforme -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13498#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC