-
Notifications
You must be signed in to change notification settings - Fork 276
Make Symbol a newtype over String #562
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
With @adamgundry's suggestions, especially the notice on |
Co-authored-by: Adam Gundry <[email protected]>
Co-authored-by: Adam Gundry <[email protected]>
This all look pretty good, but I just have a tangentially related question: what are the performance implications of having |
The credit here really goes to @phadej, I'm just interpreting. 😄
At the moment, GHC represents type-level |
Co-authored-by: Adam Gundry <[email protected]>
Co-authored-by: Georgi Lyubenov <[email protected]>
Chris says
Here is the (accepted) Nat/Natural proposal But in fact under these proposal we'd ahve
Question: why do we need a newtype. What goes wrong if we have Or should we have |
Co-authored-by: Jakob Brünker <[email protected]>
If GHC actually does And frankly this is not so bad because at the term level we also don't want to promote the use of I suspect at some point we we will settle on |
In the hope of not burning up too much precious attention, can I suggest that folks focus on destroying this proposal as is rather than an extended discussion of all of our options and their various merits and demerits. I know that isn't what we usually do but I think it might be the best here. |
I don't want to re-open the discssion. I just want a reason for the difference. John has given one. OK, I'm in support. |
Yes I was just trying to summarize it. And perhaps the apartness part (which admittedly did not come up before) is worth adding to this proposal. If making it apart from all types is too inconvenient for users, it could just be apart from |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fail to see how the proposed change addresses the motivations. The Effects and interactions section doesn't address this point either. Could you elaborate?
(Note: ``singletons-base`` demotes ``Symbol`` to ``Text`` which is | ||
incorrect, as ``Text`` cannot represent all ``String`` values) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't it? Do you have a reference for this claim? I'm infinitely curious now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the haddock of text
:
A Text value is a sequence of Unicode scalar values, as defined in §3.9, definition D76 of the Unicode 5.2 standard. As such, a Text cannot contain values in the range U+D800 to U+DFFF inclusive. Haskell implementations admit all Unicode code points (§3.4, definition D10) as Char values, including code points from this invalid range. This means that there are some Char values (corresponding to Surrogate category) that are not valid Unicode scalar values, and the functions in this module must handle those cases.
Within this module, many functions construct a Text from one or more Char values. Those functions will substitute Char values that are not valid Unicode scalar values with the replacement character "�" (U+FFFD). Functions that perform this inspection and replacement are documented with the phrase "Performs replacement on invalid scalar values". The functions replace invalid scalar values, instead of dropping them, as a security measure. For details, see Unicode Technical Report 36, §3.5.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice.
That being said, is it relevant here? I don't think we can create Symbol
values with surrogate code points in them, can we?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can?
ghci> :set -XDataKinds
ghci> type A = "\xd800"
ghci> :i A
type A :: GHC.Types.Symbol
type A = "\55296" :: GHC.Types.Symbol
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a tangentially related idea, but we can make type Symbol = Text
if we do replacement on Symbol
literals. Text
is uninhabited at type level so that isn't a problem either. Indeed this is breaking, so it's not very desirable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arfglbl. Indeed!
Though while Symbol = Text
is technically breaking, it is probably not in a way that is depended upon in practice. So probably alright? Possibly maybe? But Text
is not in base (yet?) so it's actually a pretty hard change to effect.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But Text is not in base (yet?)
It shouldn't be hard to move the type declaration to base
(GHC.Types.Text
maybe?) but keep all the combinators for working on it in text
. Just move these few lines of code:
data Text = Text
{-# UNPACK #-} !Array -- bytearray encoded as UTF-8
{-# UNPACK #-} !Int -- offset in bytes (not in Char!), pointing to a start of UTF-8 sequence
{-# UNPACK #-} !Int -- length in bytes (not in Char!), pointing to an end of UTF-8 sequence
data Array = ByteArray ByteArray#
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It wouldn't even need to be base
; ghc-prim
is enough. text
also depends on ghc-prim
already, so all of this can be done without CLC.
I think this proposal just prepares for a future CLC proposal where we add |
Yes, this proposal addresses the motivation by allowing |
@re-xyr agreed; i am going to be afk until later — like to have a stab at clarifying; your input not the draft would be great; @Ericson2314 also, of course |
My concern here echoes @aspiwack's: the proposal does not seem to address the motivation. But, I do see how, if we had |
@goldfirere I think that reflects the sum of the discussion on the proposal — it is really initiating a process. I will add some language accordingly. |
In the light of the new consensus at haskellfoundation/tech-proposals#51, I think we should perhaps close this proposal as out-of-scope for the GHC Steering Committee? As a change to GHC internal implementation details it almost doesn't require a proposal at all. However, it will necessarily make a very slight change to the |
The proposal says
Does this patch exist somewhere? Maybe even as open merge request? |
I don't know if @phadej has pushed a branch anywhere, but I believe literally the entire change envisaged here is replacing |
@cdornan, @adamgundry is anyone working on this? Is anyone writing a CLC proposal, which apparently this change requires after all? EDIT: happy anniversary to this feature request. |
Sorry for the delay @phadej. I'm not working on this, and thinking it over, I'm not convinced it needs a CLC proposal. The CLC seems to be quite burdened with the workload of responding to proposals, so I think it's better not to refer things that are not strictly in scope. Assuming the constructor is exposed only from |
Or at least a missing feature. It's impossible to hide the fact that an empty type is empty. (There is no constructors to hide in export declaration, and even if there are constructors of GADTs, the pattern match exhaustiveness check still sees the emptyness at particular indices). Similarly, there is no way to make an empty module FastFin (Fin) where
import GHC.TypeNats
newtype Fin (n :: Nat) = MkFin Integer
{-# COMPLETE :: Fin 0 #-} |
I'd be happy with just exporting it from EDIT: In comparison, |
@phadej agreed on all counts. I wasn't meaning to imply a |
I am restoring #546 to see if it can be rescued as it seemed to be a good idea.
Rendered.