
So I was working on porting my libraries to work for GHC 7.10 and I ran into a snag. Unlike the concrete type Data.Array.Array, the concrete type Data.Array.Unboxed.UArray is defined as being nominal in the second type argument— is this a bug? If not, then why must it be nominal? Shouldn't (UArray a New) and (UArray a Old) have the same representation in memory? Using unsafeCoerce has always been safe here in the past... -- Live well, ~wren

On Tue, Mar 24, 2015 at 9:57 AM, wren romano
So I was working on porting my libraries to work for GHC 7.10 and I ran into a snag. Unlike the concrete type Data.Array.Array, the concrete type Data.Array.Unboxed.UArray is defined as being nominal in the second type argument— is this a bug?
No, see https://ghc.haskell.org/trac/ghc/ticket/9220.
If not, then why must it be nominal? Shouldn't (UArray a New) and (UArray a Old) have the same representation in memory? Using unsafeCoerce has always been safe here in the past...
It wasn't and isn't necessarily safe (though in some cases it is safe). The IArray instances for Old and New could be unrelated (for example, they could use a different amount of space per element). Knowing that Old and New are related by a coercion means that the heap representation of actual values of types Old and New are the same, but that says nothing about how these values are stored in an unboxed array. Regards, Reid Barton

On Tue, Mar 24, 2015 at 10:15 AM, Reid Barton
On Tue, Mar 24, 2015 at 9:57 AM, wren romano
wrote: So I was working on porting my libraries to work for GHC 7.10 and I ran into a snag. Unlike the concrete type Data.Array.Array, the concrete type Data.Array.Unboxed.UArray is defined as being nominal in the second type argument— is this a bug?
Fair enough. To be clearer, my actual goal is to automatically derive the (IArray UArray) instance for a newtype. The newtype has semantic content (like Sum or Product), but no representational content (i.e., New and Old have the same size and the same valid bit patterns). This worked fine in GHC 7.8 and prior, and should still be fine since it doesn't run into the sorts of issues raised by that bug report. Again, the goal is to automatically derive the instance rather than doing it manually, since I really want to just inherit the underlying instance at the new type. -- Live well, ~wren

The notes to #9220 explain this fairly well, I think.
But, Wren's desire is reasonable. The real reason that GND can't work here is that the safety condition lives outside the type system.
It seems to me like one way forward is to allow an unsafe GND, via some pragma. It would be dead-easy to implement (modulo surface syntax): just change `coerce` to `unsafeCoerce` in the produced code.
Richard
On Mar 24, 2015, at 10:25 AM, wren romano
On Tue, Mar 24, 2015 at 10:15 AM, Reid Barton
wrote: On Tue, Mar 24, 2015 at 9:57 AM, wren romano
wrote: So I was working on porting my libraries to work for GHC 7.10 and I ran into a snag. Unlike the concrete type Data.Array.Array, the concrete type Data.Array.Unboxed.UArray is defined as being nominal in the second type argument— is this a bug?
Fair enough.
To be clearer, my actual goal is to automatically derive the (IArray UArray) instance for a newtype. The newtype has semantic content (like Sum or Product), but no representational content (i.e., New and Old have the same size and the same valid bit patterns). This worked fine in GHC 7.8 and prior, and should still be fine since it doesn't run into the sorts of issues raised by that bug report. Again, the goal is to automatically derive the instance rather than doing it manually, since I really want to just inherit the underlying instance at the new type.
-- Live well, ~wren _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I would be very much opposed, personally, to such an unsafe global pragma.
Something like
deriving instance {-# UnsafeNewtypeDerivation #-} Foo Bar
would seem more reasonable. I'd also really like to see a less awkward
story for these unboxed vector types, ideally one that would also enable
unboxed non-vector containers more easily. I imagine I'm not the only one
interested in unboxed priority queues and maps and sets and things.
On Mar 24, 2015 10:45 AM, "Richard Eisenberg"
The notes to #9220 explain this fairly well, I think.
But, Wren's desire is reasonable. The real reason that GND can't work here is that the safety condition lives outside the type system.
It seems to me like one way forward is to allow an unsafe GND, via some pragma. It would be dead-easy to implement (modulo surface syntax): just change `coerce` to `unsafeCoerce` in the produced code.
Richard
On Mar 24, 2015, at 10:25 AM, wren romano
wrote: On Tue, Mar 24, 2015 at 10:15 AM, Reid Barton
wrote: On Tue, Mar 24, 2015 at 9:57 AM, wren romano
wrote: So I was working on porting my libraries to work for GHC 7.10 and I ran into a snag. Unlike the concrete type Data.Array.Array, the concrete type Data.Array.Unboxed.UArray is defined as being nominal in the second type argument— is this a bug?
Fair enough.
To be clearer, my actual goal is to automatically derive the (IArray UArray) instance for a newtype. The newtype has semantic content (like Sum or Product), but no representational content (i.e., New and Old have the same size and the same valid bit patterns). This worked fine in GHC 7.8 and prior, and should still be fine since it doesn't run into the sorts of issues raised by that bug report. Again, the goal is to automatically derive the instance rather than doing it manually, since I really want to just inherit the underlying instance at the new type.
-- Live well, ~wren _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I wasn't thinking of a global pragma -- something much closer to what you propose.
I actually think we should go further and come up with a unified story around different "deriving" mechanisms. GHC currently has 3:
1) Haskell98-style, including extensions like DeriveFunctor. These "derivings" are baked in.
2) GND
3) DeriveAnyClass, a new extension, intended to be used with generics, that produces an empty instance declaration. The methods are intended to be filled in by (perhaps generic) default implementations.
This thread proposes a new mechanism: unsafeGND. And perhaps more are waiting in the wings. Users should be able to specify the mechanism, and if that mechanism is unavailable, GHC should error. When more than one mechanism is non-trivially applicable, GHC should error. (The "non-trivial" is there to rule out errors for, say, deriving Eq via Haskell98 or via GND: both result in the same behavior.)
I leave it to others to bikeshed about syntax. :)
Richard
On Mar 24, 2015, at 10:54 AM, David Feuer
I would be very much opposed, personally, to such an unsafe global pragma. Something like
deriving instance {-# UnsafeNewtypeDerivation #-} Foo Bar
would seem more reasonable. I'd also really like to see a less awkward story for these unboxed vector types, ideally one that would also enable unboxed non-vector containers more easily. I imagine I'm not the only one interested in unboxed priority queues and maps and sets and things.
On Mar 24, 2015 10:45 AM, "Richard Eisenberg"
wrote: The notes to #9220 explain this fairly well, I think. But, Wren's desire is reasonable. The real reason that GND can't work here is that the safety condition lives outside the type system.
It seems to me like one way forward is to allow an unsafe GND, via some pragma. It would be dead-easy to implement (modulo surface syntax): just change `coerce` to `unsafeCoerce` in the produced code.
Richard
On Mar 24, 2015, at 10:25 AM, wren romano
wrote: On Tue, Mar 24, 2015 at 10:15 AM, Reid Barton
wrote: On Tue, Mar 24, 2015 at 9:57 AM, wren romano
wrote: So I was working on porting my libraries to work for GHC 7.10 and I ran into a snag. Unlike the concrete type Data.Array.Array, the concrete type Data.Array.Unboxed.UArray is defined as being nominal in the second type argument— is this a bug?
Fair enough.
To be clearer, my actual goal is to automatically derive the (IArray UArray) instance for a newtype. The newtype has semantic content (like Sum or Product), but no representational content (i.e., New and Old have the same size and the same valid bit patterns). This worked fine in GHC 7.8 and prior, and should still be fine since it doesn't run into the sorts of issues raised by that bug report. Again, the goal is to automatically derive the instance rather than doing it manually, since I really want to just inherit the underlying instance at the new type.
-- Live well, ~wren _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On 24/03/15 16:59, Richard Eisenberg wrote:
When more than one mechanism is non-trivially applicable, GHC should error. (The "non-trivial" is there to rule out errors for, say, deriving Eq via Haskell98 or via GND: both result in the same behavior.)
This happens all the time — Show instance would differ from the standard derived one if GND'ed. But I certainly share your concerns. Roman
participants (5)
-
David Feuer
-
Reid Barton
-
Richard Eisenberg
-
Roman Cheplyaka
-
wren romano