Unlifted data types
Edward Z. Yang
ezyang at mit.edu
Fri Sep 4 21:23:33 UTC 2015
Excerpts from Dan Doel's message of 2015-09-04 13:09:26 -0700:
> Okay. That answers another question I had, which was whether MutVar#
> and such would go in the new kind.
>
> So now we have partial, extended natural numbers:
>
> data PNat :: * where
> PZero :: PNat
> PSuc :: PNat -> PNat
>
> A flat domain of natural numbers:
>
> data FNat :: * where
> FZero :: FNat
> FSuc :: !FNat -> FNat
>
> And two sets of natural numbers:
>
> Force FNat :: Unlifted
>
> data UNat :: Unlifted where
> UZero :: UNat
> USuc :: UNat -> UNat
>
> And really perhaps two flat domains (and three sets), if you use Force
> instead of !, which would differ on who ensures the evaluation. That's
> kind of a lot of incompatible definitions of essentially the same
> thing (PNat being the significantly different thing).
>
> I was kind of more enthused about first class !a. For instance, if you
> think about the opening quote by Bob Harper, he's basically wrong. The
> flat domain FNat is the natural numbers (existing in an overall lazy
> language), and has the reasoning properties he wants to teach students
> about with very little complication. It'd be satisfying to recognize
> that unlifting the outer-most part gets you exactly there, with
> whatever performance characteristics that implies. Or to get rid of !
> and use Unlifted definitions instead.
>
> Maybe backwards compatibility mandates the duplication, but it'd be
> nice if some synthesis could be reached.
I would certainly agree that in terms of the data that is representable,
there is not much difference; but there is a lot of difference for the
client between Force and a strict field. If I write:
let x = undefined
y = Strict x
in True
No error occurs with:
data Strict = Strict !a
But an error occurs with:
data Strict = Strict (Force a)
One possibility for how to reconcile the difference for BC is to posit
that there are just two different constructors:
Strict :: a -> Strict a
Strict! :: Force a -> Strict a
But this kind of special handling is a bit bothersome. Consider:
data SPair a b = SPair (!a, !b)
The constructor has what type? Probably
SPair :: (Force a, Force b) -> SPair a
and not:
SPair :: (a, b) -> SPair a
> It'd also be good to think about/specify how this is going to interact
> with unpacked/unboxed sums.
I don't think it interacts any differently than with unpacked/unboxed
products today.
Edward
More information about the ghc-devs
mailing list