-
-
Notifications
You must be signed in to change notification settings - Fork 274
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
ExtensibleState map keys are not unique #94
Comments
On Sun, Oct 16, 2016 at 12:04 AM, Bogdan Sinitsyn notifications@github.com
If typeOf is not distinguishing those, then either you have a fairly old You do get one benefit, provided the String we get is in fact correct: And now I wonder if it should be using something other than Show, if that brandon s allbery kf8nh sine nomine associates |
The point is there is no compile time verification. At least I don't notice it(
No, I have 8.0.1
I checked for it: yup, that is broken Show instance(or maybe it's not broken and that behaviour is expected; I haven't found anything that tells that Show instance supports equality like TypeRep) I'm agree that compile-time check of key difference is important but in does not present now. It's only Show instance issue, and TypeRep itself checks for equality better. So, the best option I can offer is to switch to using TypeRep as key(AFAIK nothing uses extensible state without contrib module and TypeRep guarantees good compile-time equality check). |
On Sun, Oct 16, 2016 at 1:12 AM, Bogdan Sinitsyn notifications@github.com
Did you read what I said? It has to be serializable to pass persistent We should stop using the Show instance, though. This may not be possible I'm going to guess compatibility with older ghcs are why this works the way brandon s) allbery kf8nh sine nomine |
From https://ghc.haskell.org/trac/ghc/wiki/TypeableT:
And I've checked that it's the same across compiles(haven't found any info on this). So should we switch to using fingerprints? |
We need to fix. However, we also need a way to migrate from the old As far as GHC goes, I don't think we should officially support anything before 7.6.3. I suppose it would be nice to know which versions of Debian are using older versions of GHC but at some point it's not practical to continue supporting older versions. |
Debian stable (jessie): GHC 7.6.3 (Debian oldstable (wheezy) has GHC 7.4.1, but no one is expecting anyone to support that.) Source: packages.debian.org |
@asjo thanks! |
@f1u77y I've updated the issue title. What do you think? Also, do you have any suggestions for how to update this without breaking a restart after upgrading? |
Transitionally, a The real problem is that we'd be relying on a ghc internal mechanism, which as I tried to hint earlier strikes me as a risky notion regardless of how convenient it would be. (I don't even know if the new type-indexed |
I agree. I'd rather use a stable library that provides what we need instead of a compiler feature. I don't know if anything like that exists though. Worst case, we have to make it a manual process in the instance definition and go through the code and fix everything. That's not a terrible proposition. |
@pjones
Use an commandline option to indicate new format of ExtensibleState serialisation and use old code for deserializing if we need. |
@f1u77y I suppose that depends if we want to introduce TH has a dependency. I'm not convinced that's the right way to go. |
What's wrong with TH as dependency? |
TemplateHaskell introduces portability issues. I may be wrong so please correct me, but I don't think TH works on ARM architectures and it completely breaks cross compiling. It seems to me that this is a really silly use of TH to cause so much breakage. |
Both of those are being worked on in ghc8, but neither is quite stable yet
--- and only ghc8 can even pretend to deal with it. (Cross compiling is
still known to not work reliably, because a splice may run a previously
compiled function and that function will have been compiled for either the
host or the target, not "for the host but generating code for the target".)
And yes, there's been at least one report of someone cross-compiling xmonad
for a RasPi.
…On Thu, Apr 13, 2017 at 11:08 AM, Peter J. Jones ***@***.***> wrote:
TemplateHaskell introduces portability issues. I may be wrong so please
correct me, but I don't think TH works on ARM architectures and it
completely breaks cross compiling. It seems to me that this is a really
silly use of TH to cause so much breakage.
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#94 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AB8SoAkcPGDUNubk2APLcm_hG56E8ksQks5rvjqBgaJpZM4KX4f4>
.
--
brandon s allbery kf8nh sine nomine associates
allbery.b@gmail.com ballbery@sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net
|
Also there's a hidden issue with just using the type name instead of a fingerprint, assuming fingerprints are reproducibly generated from the actual type (not just its name): we should not attempt to deserialize if the type changed. I think this could be hacked up using only |
What about this? > (\t -> tyConModule (typeRepTyCon t) ++ "." ++ show t) (typeOf (1::Integer))
"GHC.Integer.Type.Integer" Seems a good quick fix. Doesn't fix the deserialization issue, though. |
Turns out fingerprints aren't stable. They may be stable across GHC versions, but they're definitely not stable across xmonad versions:
(the fingerprint is constructed from the package name, module name and type name) So I guess we go ahead with my hack ( |
I guess we're stuck with your hack. And probably yes to the fallback or everyone loses upon mod-q into the new version (I'm sure I'm not the only one who has done that… probably everyone who runs git xmonad has done so at least once). |
We've been using the String we get out of `show . typeOf` as key in `extensibleState`, but that has a somewhat serious bug: it shows unqualified type names, so if two modules use the same type name, their extensible states will be stored in one place and get overwritten all the time. To fix this, the `extensibleState` map is now primarily keyed by the TypeRep themselves, with fallback to String for not yet deserialized data. XMonad.Core now exports `showExtType` which serializes type names qualified, and this is used in `writeStateToFile`. A simpler fix would be to just change the serialization of type names in `XMonad.Util.ExtensibleState`, but I'm afraid that might slows things down: Most types used here will start with "XMonad.", and that's a lot of useless linked-list pointer jumping. Fixes: xmonad/xmonad-contrib#94
…ep …" We've been using the String we get out of `show . typeOf` as key in `extensibleState`, but that has a somewhat serious bug: it shows unqualified type names, so if two modules use the same type name, their extensible states will be stored in one place and get overwritten all the time. To fix this, the `extensibleState` map is now primarily keyed by the TypeRep themselves, with fallback to String for not yet deserialized data. XMonad.Core now exports `showExtType` which serializes type names qualified, and this is used in `writeStateToFile`. A simpler fix would be to just change the serialization of type names in `XMonad.Util.ExtensibleState`, but I'm afraid that might slows things down: Most types used here will start with "XMonad.", and that's a lot of useless linked-list pointer jumping. Fixes: xmonad#94
…ep …" We've been using the String we get out of `show . typeOf` as key in `extensibleState`, but that has a somewhat serious bug: it shows unqualified type names, so if two modules use the same type name, their extensible states will be stored in one place and get overwritten all the time. To fix this, the `extensibleState` map is now primarily keyed by the TypeRep themselves, with fallback to String for not yet deserialized data. XMonad.Core now exports `showExtType` which serializes type names qualified, and this is used in `writeStateToFile`. A simpler fix would be to just change the serialization of type names in `XMonad.Util.ExtensibleState`, but I'm afraid that might slows things down: Most types used here will start with "XMonad.", and that's a lot of useless linked-list pointer jumping. Fixes: xmonad#94
We've been using the String we get out of `show . typeOf` as key in `extensibleState`, but that has a somewhat serious bug: it shows unqualified type names, so if two modules use the same type name, their extensible states will be stored in one place and get overwritten all the time. To fix this, the `extensibleState` map is now primarily keyed by the TypeRep themselves, with fallback to String for not yet deserialized data. XMonad.Core now exports `showExtType` which serializes type names qualified, and this is used in `writeStateToFile`. A simpler fix would be to just change the serialization of type names in `XMonad.Util.ExtensibleState`, but I'm afraid that might slows things down: Most types used here will start with "XMonad.", and that's a lot of useless linked-list pointer jumping. Fixes: xmonad/xmonad-contrib#94 Related: xmonad/xmonad-contrib#600
I have some draft PRs: xmonad/xmonad#326, #600 |
This isn't critical for the release so I'm moving this and the associated PRs to the v0.18 milestone. |
It's useless when compared with using just any string as map key because two different modules could have wrapper with the same name, and checking for that is not easier then checking for same string as key. It does also require these annoying wrappers and unwrappers for no benefit. Should we migrate to using any string as keys or is it useless or even wrong?
The text was updated successfully, but these errors were encountered: