<div dir="ltr">I support this proposal. I think that having newtypes for non-lifted types (e.g., `Int#`) can be quite handy. </div><br><div class="gmail_quote"><div dir="ltr">On Sun, Feb 11, 2018 at 4:28 PM Richard Eisenberg <<a href="mailto:rae@cs.brynmawr.edu">rae@cs.brynmawr.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I have been assigned as the shepherd for proposal #98: Unlifted Newtypes, <a href="https://github.com/ghc-proposals/ghc-proposals/pull/98" rel="noreferrer" target="_blank">https://github.com/ghc-proposals/ghc-proposals/pull/98</a><br>
<br>
Summary:<br>
<br>
This proposal suggests lifting the current restriction that newtype kinds are always Type -- that is, TYPE LiftedRep. At its core, that's the entire proposal; the rest is just motivation (which is quite well-written, if you're feeling unmotivated) and consequences. Here are a few of the twists and turns:<br>
<br>
- The non-Type kinds should be inferred, based on the kind of the wrapped type. In the event of a trivial recursive newtype (e.g., newtype Void = Void Void), the kind would default to lifted, though the user could override this behavior with a kind signature using GADT syntax. The proposal author conjectures that all inhabited unlifted newtypes will have inferrable kinds; I've not tried hard to prove or refute this claim.<br>
<br>
- The proposal suggests that the Coercible mechanism be extended to deal with unlifted types. This could be handled by generalizing the type of `coerce` to be levity-polymorphic. Note that doing so does not violate levity polymorphism restrictions, because coerce always inlines to a cast, and casts are erased before code generation. If `coerce` is generalized, GeneralizedNewtypeDeriving will work over the new unlifted newtypes.<br>
<br>
- The proposal suggests that newtypes can indeed be levity-polymorphic: newtype Id# (r :: RuntimeRep) (a :: TYPE r) = MkId# a. This does not appear to violate levity polymorphism restrictions, either, because the MkId# constructor doesn't appear in Core. Any use of this newtype will have to be specialized to a certain RuntimeRep, but that specialization would already be guaranteed by the existing levity polymorphism restrictions.<br>
<br>
The main drawback in the proposal is that this is the first way users can create their own unlifted types. Accordingly, a user might unwittingly use an unlifted type where they expect laziness; the strictness that, say, an unlifted-variable pattern binding would induce would be a surprise and hard to find.<br>
<br>
Opinion & recommendation:<br>
<br>
I am in support of this proposal and propose acceptance. The motivation section in the proposal is compelling, and this seems a natural generalization of existing structures. There are no concrete syntax ramifications. Given the existing levity polymorphism set-up, this proposal seems like an easy win.<br>
<br>
If we are concerned about unexpected strictness, we could require that all unlifted newtypes be suffixed with one or more hashes, but I do not recommend doing so, instead encouraging library-writers to be sensitive to this problem, giving those authors the latitude to choose the best name for their types.<br>
<br>
Thanks,<br>
Richard<br>
<br>
_______________________________________________<br>
ghc-steering-committee mailing list<br>
<a href="mailto:ghc-steering-committee@haskell.org" target="_blank">ghc-steering-committee@haskell.org</a><br>
<a href="https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee" rel="noreferrer" target="_blank">https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee</a><br>
</blockquote></div>