From austin at well-typed.com Mon Dec 9 13:13:54 2013 From: austin at well-typed.com (Austin Seipp) Date: Mon, 9 Dec 2013 07:13:54 -0600 Subject: Better GHC builds for Windows users Message-ID: Hello all, After fiddling around this weekend I've written a quick, comprehensive guide to a Better Build Environment for windows users. It pretty much "Just works" and I think should make it easy to get started with new machines: https://ghc.haskell.org/trac/ghc/wiki/Building/Preparation/Windows/MSYS2 Many thanks to Kyra for pointing this out to us on the GHC developer list. It is a much nicer to use mingw/msys environment with a lot of bugs fixed, and it's easy to install. Following the instructions should mostly be copy-paste. In particular, this resolves some weird issues with `validate` and traditional `make`, including a horrible deadlocking bug with make (and also 'tee', it seems.) So windows users can build in parallel again and everything works as expected. It also gives a simple and complete guide to build for x86_64 users (we didn't really mention it previously.) Please shout if you have problems. I've tested this with both an x86 and x86_64 build. -- Regards, Austin Seipp, Haskell Consultant Well-Typed LLP, http://www.well-typed.com/ From cherry.mui9 at gmail.com Mon Dec 16 03:32:13 2013 From: cherry.mui9 at gmail.com (cherry) Date: Sun, 15 Dec 2013 22:32:13 -0500 Subject: Mips64el Linux Build Message-ID: Hello, I am new to the list, though I have been using GHC for a long time. Just say Hello. I would like to share my experience about building GHC (7.7.20131112) on/for mips64el linux, just in case anybody is interested, as it seems not documented (on Wiki pages of Platforms, CrossCompiling, or Porting). Ignore this email if it is not interesting or too trivial. It bootstrapped by cross compiling on x86_64 linux, with some tweaking on mk/build.mk and the build process. In particular, I needed to specify export CPP="mips64el-unknown-linux-gnu-gcc -E" otherwise the configure script just found to use the native "gcc -E" and it failed in preprocessing rts C files. Also in mk/build.mk I forced GhcThreaded = NO GhcWithInterpreter = YES # so, it can use TH and build happy The make process failed when trying to use ghc-stage2, but at that point the stage 2 compiler is already built, that's enough. With this cross-compiled ghc-stage2, the native build on mips64el machine was done without much interleaving. inplace/lib/unlit was x86_64 binary, and needed to be rebuild. Also manually built alex and happy (and their dependencies). Then it just went through. So, the new way of porting seems just cross compiling followed by native compiling? Somewhat surprisingly, GHCi is also working (forced it to be built), with system's dynamic linker. Is there need to write/update a wiki page for this? Thanks, cherry -------------- next part -------------- An HTML attachment was scrubbed... URL: From voldermort at hotmail.com Wed Dec 18 09:08:02 2013 From: voldermort at hotmail.com (harry) Date: Wed, 18 Dec 2013 01:08:02 -0800 (PST) Subject: --split-objs Message-ID: <1387357681954-5741209.post@n5.nabble.com> The documentation for --split-objs states that "this only makes sense for libraries". How is an executable compiled against a split-objs library? According to https://github.com/haskell/cabal/issues/1611#issuecomment-30750655, this isn't happening by default. -- View this message in context: http://haskell.1045720.n5.nabble.com/split-objs-tp5741209.html Sent from the Haskell - Glasgow-haskell-users mailing list archive at Nabble.com. From allbery.b at gmail.com Wed Dec 18 14:15:31 2013 From: allbery.b at gmail.com (Brandon Allbery) Date: Wed, 18 Dec 2013 09:15:31 -0500 Subject: --split-objs In-Reply-To: <1387357681954-5741209.post@n5.nabble.com> References: <1387357681954-5741209.post@n5.nabble.com> Message-ID: On Wed, Dec 18, 2013 at 4:08 AM, harry wrote: > The documentation for --split-objs states that "this only makes sense for > libraries". How is an executable compiled against a split-objs library? > According to > https://github.com/haskell/cabal/issues/1611#issuecomment-30750655, this > isn't happening by default. > I don't understand the question. Whether a library is split-objs or not does not affect how you link an executable, only the space/time efficiency trade-off of doing so. And while in theory you might see improvements by split-objs-ing an executable, it doesn't make a whole lot of sense to include dead code in an executable in the first place (whereas functionality of a library that you aren't using is dead for *your* use but not for other consumers of the library). -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From voldermort at hotmail.com Wed Dec 18 15:27:44 2013 From: voldermort at hotmail.com (harry) Date: Wed, 18 Dec 2013 07:27:44 -0800 (PST) Subject: --split-objs In-Reply-To: References: <1387357681954-5741209.post@n5.nabble.com> Message-ID: <1387380464300-5741215.post@n5.nabble.com> Brandon Allbery wrote > I don't understand the question. Whether a library is split-objs or not > does not affect how you link an executable, only the space/time efficiency > trade-off of doing so. And while in theory you might see improvements by > split-objs-ing an executable, it doesn't make a whole lot of sense to > include dead code in an executable in the first place (whereas > functionality of a library that you aren't using is dead for *your* use > but > not for other consumers of the library). I don't understand the answer :-) Let's say library A exports functions a1 and a2. I build the library with --split-objs, so a1 and a2 go into separate object files. I also have an executable B that imports A(a1). When I link B, I would expect that it only includes A.a1. However, A.a2 has also got in. (At least that's what's happened according to the bug report on Cabal.) Is this the expected behaviour? Am I doing something wrong? -- View this message in context: http://haskell.1045720.n5.nabble.com/split-objs-tp5741209p5741215.html Sent from the Haskell - Glasgow-haskell-users mailing list archive at Nabble.com. From allbery.b at gmail.com Wed Dec 18 16:04:13 2013 From: allbery.b at gmail.com (Brandon Allbery) Date: Wed, 18 Dec 2013 11:04:13 -0500 Subject: --split-objs In-Reply-To: <1387380464300-5741215.post@n5.nabble.com> References: <1387357681954-5741209.post@n5.nabble.com> <1387380464300-5741215.post@n5.nabble.com> Message-ID: On Wed, Dec 18, 2013 at 10:27 AM, harry wrote: > Brandon Allbery wrote > > I don't understand the question. Whether a library is split-objs or not > > does not affect how you link an executable, only the space/time > efficiency > > trade-off of doing so. And while in theory you might see improvements by > > split-objs-ing an executable, it doesn't make a whole lot of sense to > > include dead code in an executable in the first place (whereas > > functionality of a library that you aren't using is dead for *your* use > > but > > not for other consumers of the library). > > I don't understand the answer :-) > > Let's say library A exports functions a1 and a2. I build the library with > --split-objs, so a1 and a2 go into separate object files. I also have an > executable B that imports A(a1). When I link B, I would expect that it only > includes A.a1. However, A.a2 has also got in. (At least that's what's > happened according to the bug report on Cabal.) > > Is this the expected behaviour? Am I doing something wrong? > If that happens, then there is some dependency between them so that the linker found it necessary to include both. (For example, a1 calls a2.) Alternately, you are using dynamic linking; split-objs only makes sense for static linking, for dynamic linking the generated .so/.dylib/.dll will always include all functions, and is shared between all users (so splitting it up is neither necessary nor desirable). -- brandon s allbery kf8nh sine nomine associates allbery.b at gmail.com ballbery at sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net -------------- next part -------------- An HTML attachment was scrubbed... URL: From glaebhoerl at gmail.com Wed Dec 18 23:38:34 2013 From: glaebhoerl at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Thu, 19 Dec 2013 00:38:34 +0100 Subject: Decomposition of given equalities Message-ID: Hello, The upcoming GHC 7.8 recently gave me this error: Could not deduce (i ~ i1) from the context (f1 i ~ f i1) Which is strange to me: shouldn't (f1 i ~ f i1) exactly imply (f1 ~ f, i ~ i1)? (Or with nicer variable names: (f a ~ g b) => (f ~ g, a ~ b)?) When I inquired about this in #haskell on IRC, a person going by the name xnyhps had this to say: > I've also noticed that, given type equality constraints are never decomposed. I'm quite curious why. and later: > It's especially weird because a given f a ~ g b can not be used to solve a wanted f a ~ g b, because the wanted constraint is decomposed before it can interact with the given constraint. I'm not quite so well versed in the workings of GHC's type checker as she or he is, but I don't understand why it's this way either. Is this a relic of https://ghc.haskell.org/trac/ghc/ticket/5591 and https://ghc.haskell.org/trac/ghc/ticket/7205? Is there a principled reason this shouldn't be true? Is it an intentional limitation of the constraint solver? Or is it just a bug? Thanks in advance, G?bor P.S. I got the error on this line: https://github.com/glaebhoerl/type-eq/blob/master/Type/Eq.hs#L181, possibly after having added kind annotations to `InnerEq` (which also gets a less general kind inferred than the one I expect). If it's important I can try to create a reduced test case. From the.dead.shall.rise at gmail.com Thu Dec 19 03:00:53 2013 From: the.dead.shall.rise at gmail.com (Mikhail Glushenkov) Date: Thu, 19 Dec 2013 04:00:53 +0100 Subject: --split-objs In-Reply-To: References: <1387357681954-5741209.post@n5.nabble.com> <1387380464300-5741215.post@n5.nabble.com> Message-ID: Hi, The problem in https://github.com/haskell/cabal/issues/1611 is with that we have a module (say, A) from which we're only importing a single value, and this module is a part of the cabal-install source tree. It would be nice if the whole contents of A weren't linked with the final executable. So I tried to compile cabal-install with --split-objs, but apparently this doesn't work because in this case the linker's input is A.o instead of A_split_0.o A_split_1.o ... A_split_N.o. And apparently that's why the documentation says that "--split-objs doesn't make sense for executables". Note that if cabal-install was split into an executable and a library, then this would work. So the question is why --split-objs only works for libraries and whether this behaviour can be fixed. -- () ascii ribbon campaign - against html e-mail /\ www.asciiribbon.org - against proprietary attachments From eir at cis.upenn.edu Thu Dec 19 04:30:49 2013 From: eir at cis.upenn.edu (Richard Eisenberg) Date: Wed, 18 Dec 2013 23:30:49 -0500 Subject: Decomposition of given equalities In-Reply-To: References: Message-ID: I'd say GHC has it right in this case. (f a ~ g b) exactly implies (f ~ g) and (a ~ b) if and only if the kinds match up. If, say, (f :: k1 -> *), (g :: k2 -> *), (a :: k1), and (b :: k2), then (f ~ g) and (a ~ b) are ill-kinded. In Gabor's initial problem, we have (with all type, kind, and coercion variables made explicit) > data InnerEq (j :: BOX) (k :: BOX) (i :: j) (a :: k) where > InnerEq :: forall (f :: j -> k). f i ~ a => InnerEq j k i a > > class TypeCompare (k :: BOX) (t :: k -> *) where > maybeInnerEq :: forall (j :: BOX) (f :: j -> k) (i :: j) (a :: k). > t (f i) -> t a -> Maybe (InnerEq j k i a) > > instance forall (j :: BOX) (k :: BOX) (i :: j). TypeCompare k (InnerEq j k i) where > maybeInnerEq :: forall (j2 :: BOX) (f :: j2 -> k) (i2 :: j2) (a :: k). > InnerEq j k i (f i2) -> InnerEq j k i a -> Maybe (InnerEq j2 k i2 a) > maybeInnerEq (InnerEq (f1 :: j -> k) (co1 :: f1 i ~ f i2)) > (InnerEq (f2 :: j -> k) (co2 :: f2 i ~ a)) > = Just (InnerEq (f3 :: j2 -> k) (co3 :: f3 i2 ~ a)) GHC must infer `f3` and `co3`. The only thing of kind `j2 -> k` lying around is f. So, we choose f3 := f. Now, we need to prove `f i2 ~ a`. Using the two equalities we have, we can rewrite this as a need to prove `f1 i ~ f2 i`. I can't see a way of doing this. Now, GHC complains that it cannot (renaming to my variables) deduce (i ~ i2) from (f1 i ~ f i2). But, this is exactly the case where the kinds *don't* match up. So, I agree that GHC can't deduce that equality, but I think that, even if it could, it wouldn't be able to type-check the whole term.... unless I've made a mistake somewhere. I don't see an immediate way to fix the problem, but I haven't thought much about it. Does this help? Does anyone see a mistake in what I've done? Richard On Dec 18, 2013, at 6:38 PM, G?bor Lehel wrote: > Hello, > > The upcoming GHC 7.8 recently gave me this error: > > Could not deduce (i ~ i1) > from the context (f1 i ~ f i1) > > Which is strange to me: shouldn't (f1 i ~ f i1) exactly imply (f1 ~ f, > i ~ i1)? (Or with nicer variable names: (f a ~ g b) => (f ~ g, a ~ > b)?) > > When I inquired about this in #haskell on IRC, a person going by the > name xnyhps had this to say: > >> I've also noticed that, given type equality constraints are never decomposed. I'm quite curious why. > > and later: > >> It's especially weird because a given f a ~ g b can not be used to solve a wanted f a ~ g b, because the wanted constraint is decomposed before it can interact with the given constraint. > > I'm not quite so well versed in the workings of GHC's type checker as > she or he is, but I don't understand why it's this way either. > > Is this a relic of https://ghc.haskell.org/trac/ghc/ticket/5591 and > https://ghc.haskell.org/trac/ghc/ticket/7205? Is there a principled > reason this shouldn't be true? Is it an intentional limitation of the > constraint solver? Or is it just a bug? > > Thanks in advance, > G?bor > > P.S. I got the error on this line: > https://github.com/glaebhoerl/type-eq/blob/master/Type/Eq.hs#L181, > possibly after having added kind annotations to `InnerEq` (which also > gets a less general kind inferred than the one I expect). If it's > important I can try to create a reduced test case. > _______________________________________________ > Glasgow-haskell-users mailing list > Glasgow-haskell-users at haskell.org > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > From glaebhoerl at gmail.com Thu Dec 19 10:40:31 2013 From: glaebhoerl at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Thu, 19 Dec 2013 11:40:31 +0100 Subject: Decomposition of given equalities In-Reply-To: References: Message-ID: Thanks for the reply. Still digesting what you wrote, but in the meantime I did extract the essential parts of the example: {-# LANGUAGE GADTs, PolyKinds, ExplicitForAll #-} data InnerEq (i :: k_i) (a :: k_a) where InnerEq :: forall (f :: k_i -> k_a) (i :: k_i) (a :: k_a). f i ~ a => InnerEq i a maybeInnerEq :: InnerEq i1 (f i2) -> InnerEq i1 a -> Maybe (InnerEq i2 a) maybeInnerEq InnerEq InnerEq = Just InnerEq On Thu, Dec 19, 2013 at 5:30 AM, Richard Eisenberg wrote: > I'd say GHC has it right in this case. > > (f a ~ g b) exactly implies (f ~ g) and (a ~ b) if and only if the kinds match up. If, say, (f :: k1 -> *), (g :: k2 -> *), (a :: k1), and (b :: k2), then (f ~ g) and (a ~ b) are ill-kinded. In Gabor's initial problem, we have (with all type, kind, and coercion variables made explicit) > >> data InnerEq (j :: BOX) (k :: BOX) (i :: j) (a :: k) where >> InnerEq :: forall (f :: j -> k). f i ~ a => InnerEq j k i a >> >> class TypeCompare (k :: BOX) (t :: k -> *) where >> maybeInnerEq :: forall (j :: BOX) (f :: j -> k) (i :: j) (a :: k). >> t (f i) -> t a -> Maybe (InnerEq j k i a) >> >> instance forall (j :: BOX) (k :: BOX) (i :: j). TypeCompare k (InnerEq j k i) where >> maybeInnerEq :: forall (j2 :: BOX) (f :: j2 -> k) (i2 :: j2) (a :: k). >> InnerEq j k i (f i2) -> InnerEq j k i a -> Maybe (InnerEq j2 k i2 a) >> maybeInnerEq (InnerEq (f1 :: j -> k) (co1 :: f1 i ~ f i2)) >> (InnerEq (f2 :: j -> k) (co2 :: f2 i ~ a)) >> = Just (InnerEq (f3 :: j2 -> k) (co3 :: f3 i2 ~ a)) > > GHC must infer `f3` and `co3`. The only thing of kind `j2 -> k` lying around is f. So, we choose f3 := f. Now, we need to prove `f i2 ~ a`. Using the two equalities we have, we can rewrite this as a need > to prove `f1 i ~ f2 i`. I can't see a way of doing this. Now, GHC complains that it cannot (renaming to my variables) deduce (i ~ i2) from (f1 i ~ f i2). But, this is exactly the case where the kinds *don't* match up. So, I agree that GHC can't deduce that equality, but I think that, even if it could, it wouldn't be able to type-check the whole term.... unless I've made a mistake somewhere. > > I don't see an immediate way to fix the problem, but I haven't thought much about it. > > Does this help? Does anyone see a mistake in what I've done? > > Richard > > On Dec 18, 2013, at 6:38 PM, G?bor Lehel wrote: > >> Hello, >> >> The upcoming GHC 7.8 recently gave me this error: >> >> Could not deduce (i ~ i1) >> from the context (f1 i ~ f i1) >> >> Which is strange to me: shouldn't (f1 i ~ f i1) exactly imply (f1 ~ f, >> i ~ i1)? (Or with nicer variable names: (f a ~ g b) => (f ~ g, a ~ >> b)?) >> >> When I inquired about this in #haskell on IRC, a person going by the >> name xnyhps had this to say: >> >>> I've also noticed that, given type equality constraints are never decomposed. I'm quite curious why. >> >> and later: >> >>> It's especially weird because a given f a ~ g b can not be used to solve a wanted f a ~ g b, because the wanted constraint is decomposed before it can interact with the given constraint. >> >> I'm not quite so well versed in the workings of GHC's type checker as >> she or he is, but I don't understand why it's this way either. >> >> Is this a relic of https://ghc.haskell.org/trac/ghc/ticket/5591 and >> https://ghc.haskell.org/trac/ghc/ticket/7205? Is there a principled >> reason this shouldn't be true? Is it an intentional limitation of the >> constraint solver? Or is it just a bug? >> >> Thanks in advance, >> G?bor >> >> P.S. I got the error on this line: >> https://github.com/glaebhoerl/type-eq/blob/master/Type/Eq.hs#L181, >> possibly after having added kind annotations to `InnerEq` (which also >> gets a less general kind inferred than the one I expect). If it's >> important I can try to create a reduced test case. >> _______________________________________________ >> Glasgow-haskell-users mailing list >> Glasgow-haskell-users at haskell.org >> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >> > From me at thijsalkema.de Thu Dec 19 11:32:20 2013 From: me at thijsalkema.de (Thijs Alkemade) Date: Thu, 19 Dec 2013 12:32:20 +0100 Subject: Fwd: Decomposition of given equalities References: <9FDA8E83-8638-479D-BF8A-D171C5376329@xnyhps.nl> Message-ID: <0B19366D-D175-487B-B1B7-8A146987BF11@thijsalkema.de> [Resending to the list, I used the wrong address. Sorry for the duplicate copies.] On 19 dec. 2013, at 05:30, Richard Eisenberg wrote: > I'd say GHC has it right in this case. > > (f a ~ g b) exactly implies (f ~ g) and (a ~ b) if and only if the kinds match up. If, say, (f :: k1 -> *), (g :: k2 -> *), (a :: k1), and (b :: k2), then (f ~ g) and (a ~ b) are ill-kinded. In Gabor's initial problem, we have (with all type, kind, and coercion variables made explicit) But even when it can know the kinds match up it doesn?t decompose it. For example: ? {-# LANGUAGE TypeFamilies #-} foo :: (f a ~ g b) => f a -> g b foo = id ? Ends up with 2 errors (7.6.3): Could not deduce (a ~ b) from the context (f a ~ g b) Could not deduce (f ~ g) from the context (f a ~ g b) So the wanted constraint f a ~ g b was decomposed, meaning the kind of a and b, and f and g were already found to be equal. Even with an explicit kind signature on every variable it doesn't work: foo :: (f a ~ g b) => (f :: * -> *) (a :: *) -> (g :: * -> *) (b :: *) I can?t think of an example where f a ~ g b holds, but the kinds of a and b are different. Thijs (?xnyhps?) -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 841 bytes Desc: Message signed with OpenPGP using GPGMail URL: From eir at cis.upenn.edu Thu Dec 19 15:01:33 2013 From: eir at cis.upenn.edu (Richard Eisenberg) Date: Thu, 19 Dec 2013 10:01:33 -0500 Subject: Decomposition of given equalities In-Reply-To: References: Message-ID: <6A96EC65-BCFA-444A-AB43-982748CB8ACD@cis.upenn.edu> Let me revise slightly. GHC wouldn't guess that f3 would be f just because f is the only well-kinded thing in sight. Instead, it would use (f2 i ~ a) to reduce the target equality, (f3 i2 ~ a), to (f3 i2 ~ f2 i). It would then try to break this down into (f3 ~ f2) and (i2 ~ i). Here is where the kind problem comes in -- these equalities are ill-kinded. So, GHC (rightly, in my view) rejects this code, and reports an appropriate error message. Of course, more context in the error message might be an improvement, but I don't think the current message is wrong. As for Thijs's comment about lack of decomposition in GHC 7.6.3: You're right, that code fails in GHC 7.6.3 because of an attempt (present in GHC 7.6.x) to redesign the Core type system to allow for unsaturated type families (at least in Core, if not in Haskell). There were a few cases that came up that the redesign couldn't handle, like Thijs's. So, the redesign was abandoned. In GHC HEAD, Thijs's code works just fine. (The redesign was to get rid of the "left" and "right" coercions, which allow decomposition of things like (f a ~ g b), in favor of an "nth" coercion, which allows decomposition of things like (T a ~ T b).) Good -- I feel much better about this answer, where there's no guess for the value of f3! Richard On Dec 18, 2013, at 11:30 PM, Richard Eisenberg wrote: > I'd say GHC has it right in this case. > > (f a ~ g b) exactly implies (f ~ g) and (a ~ b) if and only if the kinds match up. If, say, (f :: k1 -> *), (g :: k2 -> *), (a :: k1), and (b :: k2), then (f ~ g) and (a ~ b) are ill-kinded. In Gabor's initial problem, we have (with all type, kind, and coercion variables made explicit) > >> data InnerEq (j :: BOX) (k :: BOX) (i :: j) (a :: k) where >> InnerEq :: forall (f :: j -> k). f i ~ a => InnerEq j k i a >> >> class TypeCompare (k :: BOX) (t :: k -> *) where >> maybeInnerEq :: forall (j :: BOX) (f :: j -> k) (i :: j) (a :: k). >> t (f i) -> t a -> Maybe (InnerEq j k i a) >> >> instance forall (j :: BOX) (k :: BOX) (i :: j). TypeCompare k (InnerEq j k i) where >> maybeInnerEq :: forall (j2 :: BOX) (f :: j2 -> k) (i2 :: j2) (a :: k). >> InnerEq j k i (f i2) -> InnerEq j k i a -> Maybe (InnerEq j2 k i2 a) >> maybeInnerEq (InnerEq (f1 :: j -> k) (co1 :: f1 i ~ f i2)) >> (InnerEq (f2 :: j -> k) (co2 :: f2 i ~ a)) >> = Just (InnerEq (f3 :: j2 -> k) (co3 :: f3 i2 ~ a)) > > GHC must infer `f3` and `co3`. The only thing of kind `j2 -> k` lying around is f. So, we choose f3 := f. Now, we need to prove `f i2 ~ a`. Using the two equalities we have, we can rewrite this as a need > to prove `f1 i ~ f2 i`. I can't see a way of doing this. Now, GHC complains that it cannot (renaming to my variables) deduce (i ~ i2) from (f1 i ~ f i2). But, this is exactly the case where the kinds *don't* match up. So, I agree that GHC can't deduce that equality, but I think that, even if it could, it wouldn't be able to type-check the whole term.... unless I've made a mistake somewhere. > > I don't see an immediate way to fix the problem, but I haven't thought much about it. > > Does this help? Does anyone see a mistake in what I've done? > > Richard > > On Dec 18, 2013, at 6:38 PM, G?bor Lehel wrote: > >> Hello, >> >> The upcoming GHC 7.8 recently gave me this error: >> >> Could not deduce (i ~ i1) >> from the context (f1 i ~ f i1) >> >> Which is strange to me: shouldn't (f1 i ~ f i1) exactly imply (f1 ~ f, >> i ~ i1)? (Or with nicer variable names: (f a ~ g b) => (f ~ g, a ~ >> b)?) >> >> When I inquired about this in #haskell on IRC, a person going by the >> name xnyhps had this to say: >> >>> I've also noticed that, given type equality constraints are never decomposed. I'm quite curious why. >> >> and later: >> >>> It's especially weird because a given f a ~ g b can not be used to solve a wanted f a ~ g b, because the wanted constraint is decomposed before it can interact with the given constraint. >> >> I'm not quite so well versed in the workings of GHC's type checker as >> she or he is, but I don't understand why it's this way either. >> >> Is this a relic of https://ghc.haskell.org/trac/ghc/ticket/5591 and >> https://ghc.haskell.org/trac/ghc/ticket/7205? Is there a principled >> reason this shouldn't be true? Is it an intentional limitation of the >> constraint solver? Or is it just a bug? >> >> Thanks in advance, >> G?bor >> >> P.S. I got the error on this line: >> https://github.com/glaebhoerl/type-eq/blob/master/Type/Eq.hs#L181, >> possibly after having added kind annotations to `InnerEq` (which also >> gets a less general kind inferred than the one I expect). If it's >> important I can try to create a reduced test case. >> _______________________________________________ >> Glasgow-haskell-users mailing list >> Glasgow-haskell-users at haskell.org >> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >> > > _______________________________________________ > Glasgow-haskell-users mailing list > Glasgow-haskell-users at haskell.org > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > From glaebhoerl at gmail.com Thu Dec 19 16:11:49 2013 From: glaebhoerl at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Thu, 19 Dec 2013 17:11:49 +0100 Subject: Decomposition of given equalities In-Reply-To: <6A96EC65-BCFA-444A-AB43-982748CB8ACD@cis.upenn.edu> References: <6A96EC65-BCFA-444A-AB43-982748CB8ACD@cis.upenn.edu> Message-ID: Does this boil down to the fact that GHC doesn't have kind GADTs? I.e. given `(f a ~ g b)` there's no possible way that `a` and `b`, resp. `f` and `g` might have different kinds (how could you ever have constructed `f a ~ g b` if they did?), but GHC isn't equipped to reason about that (to store evidence for it and retrieve it later)? On Thu, Dec 19, 2013 at 4:01 PM, Richard Eisenberg wrote: > Let me revise slightly. GHC wouldn't guess that f3 would be f just because f is the only well-kinded thing in sight. > > Instead, it would use (f2 i ~ a) to reduce the target equality, (f3 i2 ~ a), to (f3 i2 ~ f2 i). It would then try to break this down into (f3 ~ f2) and (i2 ~ i). Here is where the kind problem comes in -- these equalities are ill-kinded. So, GHC (rightly, in my view) rejects this code, and reports an appropriate error message. Of course, more context in the error message might be an improvement, but I don't think the current message is wrong. > > As for Thijs's comment about lack of decomposition in GHC 7.6.3: You're right, that code fails in GHC 7.6.3 because of an attempt (present in GHC 7.6.x) to redesign the Core type system to allow for unsaturated type families (at least in Core, if not in Haskell). There were a few cases that came up that the redesign couldn't handle, like Thijs's. So, the redesign was abandoned. In GHC HEAD, Thijs's code works just fine. > > (The redesign was to get rid of the "left" and "right" coercions, which allow decomposition of things like (f a ~ g b), in favor of an "nth" coercion, which allows decomposition of things like (T a ~ T b).) > > Good -- I feel much better about this answer, where there's no guess for the value of f3! > > Richard > > On Dec 18, 2013, at 11:30 PM, Richard Eisenberg wrote: > >> I'd say GHC has it right in this case. >> >> (f a ~ g b) exactly implies (f ~ g) and (a ~ b) if and only if the kinds match up. If, say, (f :: k1 -> *), (g :: k2 -> *), (a :: k1), and (b :: k2), then (f ~ g) and (a ~ b) are ill-kinded. In Gabor's initial problem, we have (with all type, kind, and coercion variables made explicit) >> >>> data InnerEq (j :: BOX) (k :: BOX) (i :: j) (a :: k) where >>> InnerEq :: forall (f :: j -> k). f i ~ a => InnerEq j k i a >>> >>> class TypeCompare (k :: BOX) (t :: k -> *) where >>> maybeInnerEq :: forall (j :: BOX) (f :: j -> k) (i :: j) (a :: k). >>> t (f i) -> t a -> Maybe (InnerEq j k i a) >>> >>> instance forall (j :: BOX) (k :: BOX) (i :: j). TypeCompare k (InnerEq j k i) where >>> maybeInnerEq :: forall (j2 :: BOX) (f :: j2 -> k) (i2 :: j2) (a :: k). >>> InnerEq j k i (f i2) -> InnerEq j k i a -> Maybe (InnerEq j2 k i2 a) >>> maybeInnerEq (InnerEq (f1 :: j -> k) (co1 :: f1 i ~ f i2)) >>> (InnerEq (f2 :: j -> k) (co2 :: f2 i ~ a)) >>> = Just (InnerEq (f3 :: j2 -> k) (co3 :: f3 i2 ~ a)) >> >> GHC must infer `f3` and `co3`. The only thing of kind `j2 -> k` lying around is f. So, we choose f3 := f. Now, we need to prove `f i2 ~ a`. Using the two equalities we have, we can rewrite this as a need >> to prove `f1 i ~ f2 i`. I can't see a way of doing this. Now, GHC complains that it cannot (renaming to my variables) deduce (i ~ i2) from (f1 i ~ f i2). But, this is exactly the case where the kinds *don't* match up. So, I agree that GHC can't deduce that equality, but I think that, even if it could, it wouldn't be able to type-check the whole term.... unless I've made a mistake somewhere. >> >> I don't see an immediate way to fix the problem, but I haven't thought much about it. >> >> Does this help? Does anyone see a mistake in what I've done? >> >> Richard >> >> On Dec 18, 2013, at 6:38 PM, G?bor Lehel wrote: >> >>> Hello, >>> >>> The upcoming GHC 7.8 recently gave me this error: >>> >>> Could not deduce (i ~ i1) >>> from the context (f1 i ~ f i1) >>> >>> Which is strange to me: shouldn't (f1 i ~ f i1) exactly imply (f1 ~ f, >>> i ~ i1)? (Or with nicer variable names: (f a ~ g b) => (f ~ g, a ~ >>> b)?) >>> >>> When I inquired about this in #haskell on IRC, a person going by the >>> name xnyhps had this to say: >>> >>>> I've also noticed that, given type equality constraints are never decomposed. I'm quite curious why. >>> >>> and later: >>> >>>> It's especially weird because a given f a ~ g b can not be used to solve a wanted f a ~ g b, because the wanted constraint is decomposed before it can interact with the given constraint. >>> >>> I'm not quite so well versed in the workings of GHC's type checker as >>> she or he is, but I don't understand why it's this way either. >>> >>> Is this a relic of https://ghc.haskell.org/trac/ghc/ticket/5591 and >>> https://ghc.haskell.org/trac/ghc/ticket/7205? Is there a principled >>> reason this shouldn't be true? Is it an intentional limitation of the >>> constraint solver? Or is it just a bug? >>> >>> Thanks in advance, >>> G?bor >>> >>> P.S. I got the error on this line: >>> https://github.com/glaebhoerl/type-eq/blob/master/Type/Eq.hs#L181, >>> possibly after having added kind annotations to `InnerEq` (which also >>> gets a less general kind inferred than the one I expect). If it's >>> important I can try to create a reduced test case. >>> _______________________________________________ >>> Glasgow-haskell-users mailing list >>> Glasgow-haskell-users at haskell.org >>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >>> >> >> _______________________________________________ >> Glasgow-haskell-users mailing list >> Glasgow-haskell-users at haskell.org >> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >> > From jwlato at gmail.com Fri Dec 20 01:36:11 2013 From: jwlato at gmail.com (John Lato) Date: Thu, 19 Dec 2013 17:36:11 -0800 Subject: memory ordering Message-ID: Hello, I'm working on a lock-free algorithm that's meant to be used in a concurrent setting, and I've run into a possible issue. The crux of the matter is that a particular function needs to perform the following: > x <- MVector.read vec ix > position <- readIORef posRef and the algorithm is only safe if these two reads are not reordered (both the vector and IORef are written to by other threads). My concern is, according to standard Haskell semantics this should be safe, as IO sequencing should guarantee that the reads happen in-order. Of course this also relies upon the architecture's memory model, but x86 also guarantees that reads happen in order. However doubts remain; I do not have confidence that the code generator will handle this properly. In particular, LLVM may freely re-order loads of NotAtomic and Unordered values. The one hope I have is that ghc will preserve IO semantics through the entire pipeline. This seems like it would be necessary for proper handling of exceptions, for example. So, can anyone tell me if my worries are unfounded, or if there's any way to ensure the behavior I want? I could change the readIORef to an atomicModifyIORef, which should issue an mfence, but that seems a bit heavy-handed as just a read fence would be sufficient (although even that seems more than necessary). Thanks, John L. -------------- next part -------------- An HTML attachment was scrubbed... URL: From choener at tbi.univie.ac.at Fri Dec 20 08:57:17 2013 From: choener at tbi.univie.ac.at (Christian =?iso-8859-1?Q?H=F6ner?= zu Siederdissen) Date: Fri, 20 Dec 2013 09:57:17 +0100 Subject: memory ordering In-Reply-To: References: Message-ID: <20131220085709.GA24919@totalegal.rz.uni-leipzig.de> Hi John, I guess you probably want to "pseq x". See below for an example. Since your 2nd action does not depend on your 1st. Gruss, Christian import Debug.Trace import GHC.Conc main = do x <- return (traceShow "1" $ 1::Int) -- x `pseq` print (2::Int) print (2::Int) print x * John Lato [20.12.2013 02:36]: > Hello, > > I'm working on a lock-free algorithm that's meant to be used in a > concurrent setting, and I've run into a possible issue. > > The crux of the matter is that a particular function needs to perform the > following: > > > x <- MVector.read vec ix > > position <- readIORef posRef > > and the algorithm is only safe if these two reads are not reordered (both > the vector and IORef are written to by other threads). > > My concern is, according to standard Haskell semantics this should be > safe, as IO sequencing should guarantee that the reads happen in-order. > Of course this also relies upon the architecture's memory model, but x86 > also guarantees that reads happen in order. However doubts remain; I do > not have confidence that the code generator will handle this properly. In > particular, LLVM may freely re-order loads of NotAtomic and Unordered > values. > > The one hope I have is that ghc will preserve IO semantics through the > entire pipeline. This seems like it would be necessary for proper > handling of exceptions, for example. So, can anyone tell me if my worries > are unfounded, or if there's any way to ensure the behavior I want? I > could change the readIORef to an atomicModifyIORef, which should issue an > mfence, but that seems a bit heavy-handed as just a read fence would be > sufficient (although even that seems more than necessary). > > Thanks, > John L. > _______________________________________________ > Glasgow-haskell-users mailing list > Glasgow-haskell-users at haskell.org > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 198 bytes Desc: not available URL: From eir at cis.upenn.edu Fri Dec 20 14:34:37 2013 From: eir at cis.upenn.edu (Richard Eisenberg) Date: Fri, 20 Dec 2013 09:34:37 -0500 Subject: Decomposition of given equalities In-Reply-To: References: <6A96EC65-BCFA-444A-AB43-982748CB8ACD@cis.upenn.edu> Message-ID: Yes, that's right. If (f a ~ g b) and `f` and `g` have syntactically different kinds, then we would hope that those kinds are in fact equal. But, GHC has no way of doing this currently -- though it does store kind equalities, it is an invariant that all such equalities must be simply reflexivity. Hopefully, this will change soon. :) Richard On Dec 19, 2013, at 11:11 AM, G?bor Lehel wrote: > Does this boil down to the fact that GHC doesn't have kind GADTs? I.e. > given `(f a ~ g b)` there's no possible way that `a` > and `b`, resp. `f` and `g` might have different kinds (how could you > ever have constructed `f a ~ g b` if they did?), but GHC isn't > equipped to reason about that (to store evidence for it and retrieve > it later)? > > On Thu, Dec 19, 2013 at 4:01 PM, Richard Eisenberg wrote: >> Let me revise slightly. GHC wouldn't guess that f3 would be f just because f is the only well-kinded thing in sight. >> >> Instead, it would use (f2 i ~ a) to reduce the target equality, (f3 i2 ~ a), to (f3 i2 ~ f2 i). It would then try to break this down into (f3 ~ f2) and (i2 ~ i). Here is where the kind problem comes in -- these equalities are ill-kinded. So, GHC (rightly, in my view) rejects this code, and reports an appropriate error message. Of course, more context in the error message might be an improvement, but I don't think the current message is wrong. >> >> As for Thijs's comment about lack of decomposition in GHC 7.6.3: You're right, that code fails in GHC 7.6.3 because of an attempt (present in GHC 7.6.x) to redesign the Core type system to allow for unsaturated type families (at least in Core, if not in Haskell). There were a few cases that came up that the redesign couldn't handle, like Thijs's. So, the redesign was abandoned. In GHC HEAD, Thijs's code works just fine. >> >> (The redesign was to get rid of the "left" and "right" coercions, which allow decomposition of things like (f a ~ g b), in favor of an "nth" coercion, which allows decomposition of things like (T a ~ T b).) >> >> Good -- I feel much better about this answer, where there's no guess for the value of f3! >> >> Richard >> >> On Dec 18, 2013, at 11:30 PM, Richard Eisenberg wrote: >> >>> I'd say GHC has it right in this case. >>> >>> (f a ~ g b) exactly implies (f ~ g) and (a ~ b) if and only if the kinds match up. If, say, (f :: k1 -> *), (g :: k2 -> *), (a :: k1), and (b :: k2), then (f ~ g) and (a ~ b) are ill-kinded. In Gabor's initial problem, we have (with all type, kind, and coercion variables made explicit) >>> >>>> data InnerEq (j :: BOX) (k :: BOX) (i :: j) (a :: k) where >>>> InnerEq :: forall (f :: j -> k). f i ~ a => InnerEq j k i a >>>> >>>> class TypeCompare (k :: BOX) (t :: k -> *) where >>>> maybeInnerEq :: forall (j :: BOX) (f :: j -> k) (i :: j) (a :: k). >>>> t (f i) -> t a -> Maybe (InnerEq j k i a) >>>> >>>> instance forall (j :: BOX) (k :: BOX) (i :: j). TypeCompare k (InnerEq j k i) where >>>> maybeInnerEq :: forall (j2 :: BOX) (f :: j2 -> k) (i2 :: j2) (a :: k). >>>> InnerEq j k i (f i2) -> InnerEq j k i a -> Maybe (InnerEq j2 k i2 a) >>>> maybeInnerEq (InnerEq (f1 :: j -> k) (co1 :: f1 i ~ f i2)) >>>> (InnerEq (f2 :: j -> k) (co2 :: f2 i ~ a)) >>>> = Just (InnerEq (f3 :: j2 -> k) (co3 :: f3 i2 ~ a)) >>> >>> GHC must infer `f3` and `co3`. The only thing of kind `j2 -> k` lying around is f. So, we choose f3 := f. Now, we need to prove `f i2 ~ a`. Using the two equalities we have, we can rewrite this as a need >>> to prove `f1 i ~ f2 i`. I can't see a way of doing this. Now, GHC complains that it cannot (renaming to my variables) deduce (i ~ i2) from (f1 i ~ f i2). But, this is exactly the case where the kinds *don't* match up. So, I agree that GHC can't deduce that equality, but I think that, even if it could, it wouldn't be able to type-check the whole term.... unless I've made a mistake somewhere. >>> >>> I don't see an immediate way to fix the problem, but I haven't thought much about it. >>> >>> Does this help? Does anyone see a mistake in what I've done? >>> >>> Richard >>> >>> On Dec 18, 2013, at 6:38 PM, G?bor Lehel wrote: >>> >>>> Hello, >>>> >>>> The upcoming GHC 7.8 recently gave me this error: >>>> >>>> Could not deduce (i ~ i1) >>>> from the context (f1 i ~ f i1) >>>> >>>> Which is strange to me: shouldn't (f1 i ~ f i1) exactly imply (f1 ~ f, >>>> i ~ i1)? (Or with nicer variable names: (f a ~ g b) => (f ~ g, a ~ >>>> b)?) >>>> >>>> When I inquired about this in #haskell on IRC, a person going by the >>>> name xnyhps had this to say: >>>> >>>>> I've also noticed that, given type equality constraints are never decomposed. I'm quite curious why. >>>> >>>> and later: >>>> >>>>> It's especially weird because a given f a ~ g b can not be used to solve a wanted f a ~ g b, because the wanted constraint is decomposed before it can interact with the given constraint. >>>> >>>> I'm not quite so well versed in the workings of GHC's type checker as >>>> she or he is, but I don't understand why it's this way either. >>>> >>>> Is this a relic of https://ghc.haskell.org/trac/ghc/ticket/5591 and >>>> https://ghc.haskell.org/trac/ghc/ticket/7205? Is there a principled >>>> reason this shouldn't be true? Is it an intentional limitation of the >>>> constraint solver? Or is it just a bug? >>>> >>>> Thanks in advance, >>>> G?bor >>>> >>>> P.S. I got the error on this line: >>>> https://github.com/glaebhoerl/type-eq/blob/master/Type/Eq.hs#L181, >>>> possibly after having added kind annotations to `InnerEq` (which also >>>> gets a less general kind inferred than the one I expect). If it's >>>> important I can try to create a reduced test case. >>>> _______________________________________________ >>>> Glasgow-haskell-users mailing list >>>> Glasgow-haskell-users at haskell.org >>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >>>> >>> >>> _______________________________________________ >>> Glasgow-haskell-users mailing list >>> Glasgow-haskell-users at haskell.org >>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >>> >> > From carter.schonwald at gmail.com Fri Dec 20 17:05:19 2013 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 20 Dec 2013 12:05:19 -0500 Subject: memory ordering In-Reply-To: <20131220085709.GA24919@totalegal.rz.uni-leipzig.de> References: <20131220085709.GA24919@totalegal.rz.uni-leipzig.de> Message-ID: Hey John, so you're wanting atomic reads and writes? I'm pretty sure that you want to use atomic memory operations for this. I believe Ryan Newton has some tooling you can use right now for that. On Fri, Dec 20, 2013 at 3:57 AM, Christian H?ner zu Siederdissen < choener at tbi.univie.ac.at> wrote: > Hi John, > > I guess you probably want to "pseq x". See below for an example. Since > your 2nd > action does not depend on your 1st. > > Gruss, > Christian > > > import Debug.Trace > import GHC.Conc > > main = do > x <- return (traceShow "1" $ 1::Int) > -- x `pseq` print (2::Int) > print (2::Int) > print x > > > * John Lato [20.12.2013 02:36]: > > Hello, > > > > I'm working on a lock-free algorithm that's meant to be used in a > > concurrent setting, and I've run into a possible issue. > > > > The crux of the matter is that a particular function needs to perform > the > > following: > > > > > x <- MVector.read vec ix > > > position <- readIORef posRef > > > > and the algorithm is only safe if these two reads are not reordered > (both > > the vector and IORef are written to by other threads). > > > > My concern is, according to standard Haskell semantics this should be > > safe, as IO sequencing should guarantee that the reads happen > in-order. > > Of course this also relies upon the architecture's memory model, but > x86 > > also guarantees that reads happen in order. However doubts remain; I > do > > not have confidence that the code generator will handle this > properly. In > > particular, LLVM may freely re-order loads of NotAtomic and Unordered > > values. > > > > The one hope I have is that ghc will preserve IO semantics through the > > entire pipeline. This seems like it would be necessary for proper > > handling of exceptions, for example. So, can anyone tell me if my > worries > > are unfounded, or if there's any way to ensure the behavior I want? I > > could change the readIORef to an atomicModifyIORef, which should > issue an > > mfence, but that seems a bit heavy-handed as just a read fence would > be > > sufficient (although even that seems more than necessary). > > > > Thanks, > > John L. > > > _______________________________________________ > > Glasgow-haskell-users mailing list > > Glasgow-haskell-users at haskell.org > > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > > > _______________________________________________ > Glasgow-haskell-users mailing list > Glasgow-haskell-users at haskell.org > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From glaebhoerl at gmail.com Fri Dec 20 18:38:12 2013 From: glaebhoerl at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Fri, 20 Dec 2013 19:38:12 +0100 Subject: Decomposition of given equalities In-Reply-To: References: <6A96EC65-BCFA-444A-AB43-982748CB8ACD@cis.upenn.edu> Message-ID: OK, it all makes sense then. Thanks! On Fri, Dec 20, 2013 at 3:34 PM, Richard Eisenberg wrote: > Yes, that's right. If (f a ~ g b) and `f` and `g` have syntactically > different kinds, then we would hope that those kinds are in fact equal. > But, GHC has no way of doing this currently -- though it does store kind > equalities, it is an invariant that all such equalities must be simply > reflexivity. Hopefully, this will change soon. :) > > Richard > > On Dec 19, 2013, at 11:11 AM, G?bor Lehel wrote: > > > Does this boil down to the fact that GHC doesn't have kind GADTs? I.e. > > given `(f a ~ g b)` there's no possible way that `a` > > and `b`, resp. `f` and `g` might have different kinds (how could you > > ever have constructed `f a ~ g b` if they did?), but GHC isn't > > equipped to reason about that (to store evidence for it and retrieve > > it later)? > > > > On Thu, Dec 19, 2013 at 4:01 PM, Richard Eisenberg > wrote: > >> Let me revise slightly. GHC wouldn't guess that f3 would be f just > because f is the only well-kinded thing in sight. > >> > >> Instead, it would use (f2 i ~ a) to reduce the target equality, (f3 i2 > ~ a), to (f3 i2 ~ f2 i). It would then try to break this down into (f3 ~ > f2) and (i2 ~ i). Here is where the kind problem comes in -- these > equalities are ill-kinded. So, GHC (rightly, in my view) rejects this code, > and reports an appropriate error message. Of course, more context in the > error message might be an improvement, but I don't think the current > message is wrong. > >> > >> As for Thijs's comment about lack of decomposition in GHC 7.6.3: You're > right, that code fails in GHC 7.6.3 because of an attempt (present in GHC > 7.6.x) to redesign the Core type system to allow for unsaturated type > families (at least in Core, if not in Haskell). There were a few cases that > came up that the redesign couldn't handle, like Thijs's. So, the redesign > was abandoned. In GHC HEAD, Thijs's code works just fine. > >> > >> (The redesign was to get rid of the "left" and "right" coercions, which > allow decomposition of things like (f a ~ g b), in favor of an "nth" > coercion, which allows decomposition of things like (T a ~ T b).) > >> > >> Good -- I feel much better about this answer, where there's no guess > for the value of f3! > >> > >> Richard > >> > >> On Dec 18, 2013, at 11:30 PM, Richard Eisenberg wrote: > >> > >>> I'd say GHC has it right in this case. > >>> > >>> (f a ~ g b) exactly implies (f ~ g) and (a ~ b) if and only if the > kinds match up. If, say, (f :: k1 -> *), (g :: k2 -> *), (a :: k1), and (b > :: k2), then (f ~ g) and (a ~ b) are ill-kinded. In Gabor's initial > problem, we have (with all type, kind, and coercion variables made explicit) > >>> > >>>> data InnerEq (j :: BOX) (k :: BOX) (i :: j) (a :: k) where > >>>> InnerEq :: forall (f :: j -> k). f i ~ a => InnerEq j k i a > >>>> > >>>> class TypeCompare (k :: BOX) (t :: k -> *) where > >>>> maybeInnerEq :: forall (j :: BOX) (f :: j -> k) (i :: j) (a :: k). > >>>> t (f i) -> t a -> Maybe (InnerEq j k i a) > >>>> > >>>> instance forall (j :: BOX) (k :: BOX) (i :: j). TypeCompare k > (InnerEq j k i) where > >>>> maybeInnerEq :: forall (j2 :: BOX) (f :: j2 -> k) (i2 :: j2) (a :: k). > >>>> InnerEq j k i (f i2) -> InnerEq j k i a -> Maybe > (InnerEq j2 k i2 a) > >>>> maybeInnerEq (InnerEq (f1 :: j -> k) (co1 :: f1 i ~ f i2)) > >>>> (InnerEq (f2 :: j -> k) (co2 :: f2 i ~ a)) > >>>> = Just (InnerEq (f3 :: j2 -> k) (co3 :: f3 i2 ~ a)) > >>> > >>> GHC must infer `f3` and `co3`. The only thing of kind `j2 -> k` lying > around is f. So, we choose f3 := f. Now, we need to prove `f i2 ~ a`. Using > the two equalities we have, we can rewrite this as a need > >>> to prove `f1 i ~ f2 i`. I can't see a way of doing this. Now, GHC > complains that it cannot (renaming to my variables) deduce (i ~ i2) from > (f1 i ~ f i2). But, this is exactly the case where the kinds *don't* match > up. So, I agree that GHC can't deduce that equality, but I think that, even > if it could, it wouldn't be able to type-check the whole term.... unless > I've made a mistake somewhere. > >>> > >>> I don't see an immediate way to fix the problem, but I haven't thought > much about it. > >>> > >>> Does this help? Does anyone see a mistake in what I've done? > >>> > >>> Richard > >>> > >>> On Dec 18, 2013, at 6:38 PM, G?bor Lehel wrote: > >>> > >>>> Hello, > >>>> > >>>> The upcoming GHC 7.8 recently gave me this error: > >>>> > >>>> Could not deduce (i ~ i1) > >>>> from the context (f1 i ~ f i1) > >>>> > >>>> Which is strange to me: shouldn't (f1 i ~ f i1) exactly imply (f1 ~ f, > >>>> i ~ i1)? (Or with nicer variable names: (f a ~ g b) => (f ~ g, a ~ > >>>> b)?) > >>>> > >>>> When I inquired about this in #haskell on IRC, a person going by the > >>>> name xnyhps had this to say: > >>>> > >>>>> I've also noticed that, given type equality constraints are never > decomposed. I'm quite curious why. > >>>> > >>>> and later: > >>>> > >>>>> It's especially weird because a given f a ~ g b can not be used to > solve a wanted f a ~ g b, because the wanted constraint is decomposed > before it can interact with the given constraint. > >>>> > >>>> I'm not quite so well versed in the workings of GHC's type checker as > >>>> she or he is, but I don't understand why it's this way either. > >>>> > >>>> Is this a relic of https://ghc.haskell.org/trac/ghc/ticket/5591 and > >>>> https://ghc.haskell.org/trac/ghc/ticket/7205? Is there a principled > >>>> reason this shouldn't be true? Is it an intentional limitation of the > >>>> constraint solver? Or is it just a bug? > >>>> > >>>> Thanks in advance, > >>>> G?bor > >>>> > >>>> P.S. I got the error on this line: > >>>> https://github.com/glaebhoerl/type-eq/blob/master/Type/Eq.hs#L181, > >>>> possibly after having added kind annotations to `InnerEq` (which also > >>>> gets a less general kind inferred than the one I expect). If it's > >>>> important I can try to create a reduced test case. > >>>> _______________________________________________ > >>>> Glasgow-haskell-users mailing list > >>>> Glasgow-haskell-users at haskell.org > >>>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > >>>> > >>> > >>> _______________________________________________ > >>> Glasgow-haskell-users mailing list > >>> Glasgow-haskell-users at haskell.org > >>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > >>> > >> > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gergo at erdi.hu Sun Dec 22 14:09:39 2013 From: gergo at erdi.hu (Dr. ERDI Gergo) Date: Sun, 22 Dec 2013 22:09:39 +0800 (SGT) Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types Message-ID: Hi, As part of my work to add pattern synonyms to GHC (https://ghc.haskell.org/trac/ghc/ticket/5144) I initially planned to postpone implementing type signatures (https://ghc.haskell.org/trac/ghc/ticket/8584). However, since adding the feature in the first place requires Haddock support, some syntax will be needed for pattern synonym type signatures so that at least there's something to generate into the docs. The basic problem with pattern synonyms in this regard is that their type is fully described by the following five pieces of information: 1, Universially bound type variables 2, Existentially bound type variables 3, The (tau) type itself 4, Typeclass context required by the pattern synonym 5, Typeclass context provided by the pattern synonym To give you some parallels, functions are described by (1), (3) and (4), e.g. given the following definition: f = map fromIntegral (1) is {a, b} (3) is [a] -> [b] (4) is (Integral a, Num b) Data constructors are described by (1), (2), (3) and (5), e.g. given data T a where MkT :: (Num a, Eq b) => a -> (b, b) -> T a the type of `MkT` is described by (1) Universially bound type variables {a} (2) Existentially bound type variables {b} (3) Tau type a -> (b, b) -> T a (5) Typeclass context provided is (Num a, Eq b) Note that when using `MkT` in an expression, its type is simpler than that, since it simply becomes forall a b. (Num a, Eq b) => a -> (b, b) -> T a which has exactly the same shape as the previous example which had (1), (3) and (4) specified. However, the context has different semantics (and the distinction between (1) and (2) becomes important) when pattern matching on `MkT`. For pattern synonyms, all five axes are present and orthogonal, and all five is something that a user should care about. For example, given the following code: {-# LANGUAGE PatternSynonyms, GADTs, ViewPatterns #-} data T a where MkT :: (Num a, Eq b) => a -> b -> T a f :: (Show a) => a -> Bool f = ... pattern P x <- MkT (f -> True) x to fully describe the type of pattern synonym P, we have: (1) Universially quantified type variables {a} (2) Existentially quantified type variables {b} (3) Tau type b -> T a (4) Required context (Show a) (5) Provided context (Num a, Eq b) So, what I'm looking for, is ideas on what syntax to use to represent these five pieces of information. Note that (1) and (2) can be made implicit, just like for constructor types, simply by noting that type variables that don't occur in the result type are existentially bound. So the tricky part is maintaining the distinction between (4) and (5). The current implementation displays the following if you ask for `:info T`: > :info P pattern P :: b -> T t requires (Show t) provides (Num t, Eq b) but I don't think we would want to use that for syntax that is actually enterred by the user into type signatures (if nothing else, then simply because why would we want to use two extra keywords 'requires' and 'provides'). The one idea I've had so far is to separate (4), (3) and (5) with two double arrows: pattern P :: (Show t) => b -> T t => (Num t, Eq b) As an added extra problem, there are also unidirectional and bidirectional pattern synonyms: unidirectional ones are usable only as patterns, whereas bidirectional ones can also be used as expressions. For example: pattern Single x = [x] pattern Second x <- (_:x:_) in this example, `Single` is bidirectional and `Second` is unidirectional. As you can see, this is indicated by syntax in the definition (`=` vs `<-`). However, I'd like to show this in the type as well, since you'd need to be able to see if you can use a given pattern synonym as a "constructor", not just a "destructor", by just looking at its Haddock-generated docs. What do you think? Bye, Gergo -- .--= ULLA! =-----------------. \ http://gergo.erdi.hu \ `---= gergo at erdi.hu =-------' Either the chocolate in my pocket has melted, or this is something altogether more sinister. From carette at mcmaster.ca Sun Dec 22 14:29:10 2013 From: carette at mcmaster.ca (Jacques Carette) Date: Sun, 22 Dec 2013 09:29:10 -0500 Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: References: Message-ID: <52B6F736.7060308@mcmaster.ca> [Superb summary of pattern synonyms omitted] On 2013-12-22 9:09 AM, Dr. ERDI Gergo wrote: > > The one idea I've had so far is to separate (4), (3) and (5) with two > double arrows: > > pattern P :: (Show t) => b -> T t => (Num t, Eq b) pattern P :: (Show t) => ( (Num t, Eq b) => b -> T t ) perhaps? Given 'Show t', you get what's on the rhs of the first => ? Another idea is pattern P :: (Show t) ~> (Num t, Eq b) => b -> T t which has the drawback of introducing a new 'keyword'. > > As an added extra problem, there are also unidirectional and > bidirectional pattern synonyms: unidirectional ones are usable only as > patterns, whereas bidirectional ones can also be used as expressions. > For example: > > pattern Single x = [x] > pattern Second x <- (_:x:_) > > in this example, `Single` is bidirectional and `Second` is > unidirectional. As you can see, this is indicated by syntax in the > definition (`=` vs `<-`). However, I'd like to show this in the type > as well, since you'd need to be able to see if you can use a given > pattern synonym as a "constructor", not just a "destructor", by just > looking at its Haddock-generated docs. Since the first is an iso, why not pattern Single :: t a ~ [ a ] or pattern Single :: t a <-> [ a ] ? [I definitely prefer the first] Or is your 'type' for Single somehow different than my guess? Jacques From glaebhoerl at gmail.com Sun Dec 22 14:36:58 2013 From: glaebhoerl at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Sun, 22 Dec 2013 15:36:58 +0100 Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: References: Message-ID: Other than being A. displayed in the Haddocks will this syntax also, now or at any later point, be B. explicitly written by the programmer alongside the definition of the pattern, or C. used as a type argument for other types? If it's only A and B, perhaps abominations like these could be considered: -- implicit foralls pattern Show t => P t :: (Num t, Eq b) => b -> T t -- explicit foralls pattern forall t. Show t => P t :: forall b. (Num t, Eq b) => b -> T t where I'm grafting together syntax originally from `DatatypeContexts` and `GADTs`. The foralls could each be either illegal, optional, or necessary. I think the `DatatypeContexts` syntax gives a good intuition: you're required to put something in, but don't get to take it back out. On Sun, Dec 22, 2013 at 3:09 PM, Dr. ERDI Gergo wrote: > Hi, > > As part of my work to add pattern synonyms to GHC ( > https://ghc.haskell.org/trac/ghc/ticket/5144) I initially planned to > postpone implementing type signatures (https://ghc.haskell.org/trac/ > ghc/ticket/8584). However, since adding the feature in the first place > requires Haddock support, some syntax will be needed for pattern synonym > type signatures so that at least there's something to generate into the > docs. > > The basic problem with pattern synonyms in this regard is that their type > is fully described by the following five pieces of information: > > 1, Universially bound type variables > 2, Existentially bound type variables > 3, The (tau) type itself > 4, Typeclass context required by the pattern synonym > 5, Typeclass context provided by the pattern synonym > > To give you some parallels, functions are described by (1), (3) and (4), > e.g. given the following definition: > > f = map fromIntegral > > (1) is {a, b} > (3) is [a] -> [b] > (4) is (Integral a, Num b) > > Data constructors are described by (1), (2), (3) and (5), e.g. given > > data T a where > MkT :: (Num a, Eq b) => a -> (b, b) -> T a > > the type of `MkT` is described by > > (1) Universially bound type variables {a} > (2) Existentially bound type variables {b} > (3) Tau type a -> (b, b) -> T a > (5) Typeclass context provided is (Num a, Eq b) > > Note that when using `MkT` in an expression, its type is simpler than > that, since it simply becomes > > forall a b. (Num a, Eq b) => a -> (b, b) -> T a > > which has exactly the same shape as the previous example which had (1), > (3) and (4) specified. However, the context has different semantics (and > the distinction between (1) and (2) becomes important) when pattern > matching on `MkT`. > > For pattern synonyms, all five axes are present and orthogonal, and all > five is something that a user should care about. For example, given the > following code: > > {-# LANGUAGE PatternSynonyms, GADTs, ViewPatterns #-} > data T a where > MkT :: (Num a, Eq b) => a -> b -> T a > > f :: (Show a) => a -> Bool > f = ... > > pattern P x <- MkT (f -> True) x > > to fully describe the type of pattern synonym P, we have: > > (1) Universially quantified type variables {a} > (2) Existentially quantified type variables {b} > (3) Tau type b -> T a > (4) Required context (Show a) > (5) Provided context (Num a, Eq b) > > So, what I'm looking for, is ideas on what syntax to use to represent > these five pieces of information. > > Note that (1) and (2) can be made implicit, just like for constructor > types, simply by noting that type variables that don't occur in the result > type are existentially bound. So the tricky part is maintaining the > distinction between (4) and (5). > > The current implementation displays the following if you ask for `:info T`: > > > :info P > pattern P :: > b -> T t > requires (Show t) > provides (Num t, Eq b) > > but I don't think we would want to use that for syntax that is actually > enterred by the user into type signatures (if nothing else, then simply > because why would we want to use two extra keywords 'requires' and > 'provides'). > > The one idea I've had so far is to separate (4), (3) and (5) with two > double arrows: > > pattern P :: (Show t) => b -> T t => (Num t, Eq b) > > > As an added extra problem, there are also unidirectional and bidirectional > pattern synonyms: unidirectional ones are usable only as patterns, whereas > bidirectional ones can also be used as expressions. For example: > > pattern Single x = [x] > pattern Second x <- (_:x:_) > > in this example, `Single` is bidirectional and `Second` is unidirectional. > As you can see, this is indicated by syntax in the definition (`=` vs > `<-`). However, I'd like to show this in the type as well, since you'd need > to be able to see if you can use a given pattern synonym as a > "constructor", not just a "destructor", by just looking at its > Haddock-generated docs. > > > What do you think? > > Bye, > Gergo > > -- > > .--= ULLA! =-----------------. > \ http://gergo.erdi.hu \ > `---= gergo at erdi.hu =-------' > Either the chocolate in my pocket has melted, or this is something > altogether more sinister. > _______________________________________________ > Glasgow-haskell-users mailing list > Glasgow-haskell-users at haskell.org > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gergo at erdi.hu Sun Dec 22 15:16:50 2013 From: gergo at erdi.hu (Dr. ERDI Gergo) Date: Sun, 22 Dec 2013 23:16:50 +0800 (SGT) Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: <52B6F736.7060308@mcmaster.ca> References: <52B6F736.7060308@mcmaster.ca> Message-ID: On Sun, 22 Dec 2013, Jacques Carette wrote: > Since the first is an iso, why not > pattern Single :: t a ~ [ a ] > or > pattern Single :: t a <-> [ a ] > ? [I definitely prefer the first] Or is your 'type' for Single somehow > different than my guess? the type of Single would be 'a -> [a]', as in: in an expression context, if x :: a, then Single x :: [a] in a pattern context, if Single x :: [a], then it binds x :: a -- .--= ULLA! =-----------------. \ http://gergo.erdi.hu \ `---= gergo at erdi.hu =-------' The masses are asses. From gergo at erdi.hu Sun Dec 22 15:19:18 2013 From: gergo at erdi.hu (Dr. ERDI Gergo) Date: Sun, 22 Dec 2013 23:19:18 +0800 (SGT) Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: References: Message-ID: On Sun, 22 Dec 2013, G?bor Lehel wrote: > Other than being > > ?A. displayed in the Haddocks > > will this syntax also, now or at any later point, be > > ?B. explicitly written by the programmer alongside the definition of the pattern, or > > ?C. used as a type argument for other types? A and B. > If it's only A and B, perhaps abominations like these could be considered: > > ??? -- implicit foralls > ??? pattern Show t => P t :: (Num t, Eq b) => b -> T t > > ??? -- explicit foralls > ??? pattern forall t. Show t => P t :: forall b. (Num t, Eq b) => b -> T t I'm not 100% sure what that 't' in 'P t' is supposed to be in your example. 'P' is not like a type constructor at all; it's a lot more like a data constructor. -- .--= ULLA! =-----------------. \ http://gergo.erdi.hu \ `---= gergo at erdi.hu =-------' I know KUNG FU, KARATE and 47 other dangerous words. From gergo at erdi.hu Sun Dec 22 16:44:29 2013 From: gergo at erdi.hu (Dr. ERDI Gergo) Date: Mon, 23 Dec 2013 00:44:29 +0800 (SGT) Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: <52B6F736.7060308@mcmaster.ca> References: <52B6F736.7060308@mcmaster.ca> Message-ID: On Sun, 22 Dec 2013, Jacques Carette wrote: > pattern P :: (Show t) => ( (Num t, Eq b) => b -> T t ) > perhaps? Given 'Show t', you get what's on the rhs of the first => ? I like this one; in fact, I originally wanted to go with something like that. But unfortunately, this type is already valid and is parsed simply as (Show t, Num t, Eq b) => b -> T t by GHC: Prelude> :t undefined :: (Show t) => ((Num t, Eq b) => b -> Maybe t) undefined :: (Show t) => ((Num t, Eq b) => b -> Maybe t) :: (Eq b, Num t, Show t) => b -> Maybe t -- .--= ULLA! =-----------------. \ http://gergo.erdi.hu \ `---= gergo at erdi.hu =-------' A pessimist sees the glass half empty, the optimist sees it half full and the blind can't see shit From jwlato at gmail.com Sun Dec 22 23:33:31 2013 From: jwlato at gmail.com (John Lato) Date: Sun, 22 Dec 2013 15:33:31 -0800 Subject: memory ordering In-Reply-To: References: <20131220085709.GA24919@totalegal.rz.uni-leipzig.de> Message-ID: Hi Carter, Atomics are more or less what I'm after. I've taken a look at Ryan's work ( https://github.com/rrnewton/haskell-lockfree/), and there are certainly some very useful items there, but I don't see anything quite like what I'm looking for (except perhaps for a read barrier). The problem is that I don't actually need atomic operations for this. I'm just doing reads after all. My concern is that many optimization pipelines (i.e. LLVM) don't guarantee ordering of reads unless you use atomic variables. The IORef docs warn that IORef operations may appear out-of-order depending on the architecture's memory model. On (newer) x86, loads won't move relative to other loads, so that should be ok, and Haskell's semantics should guarantee that two IO operations will happen in program order. It's the Haskell semantics guarantee I'm concerned about; I guess I'm not entirely sure I believe that it's implemented properly (although I have no reason to believe it's wrong either). Perhaps I'm just overly paranoid. John Lato On Fri, Dec 20, 2013 at 9:05 AM, Carter Schonwald < carter.schonwald at gmail.com> wrote: > Hey John, so you're wanting atomic reads and writes? > > I'm pretty sure that you want to use atomic memory operations for this. I > believe Ryan Newton has some tooling you can use right now for that. > > > On Fri, Dec 20, 2013 at 3:57 AM, Christian H?ner zu Siederdissen < > choener at tbi.univie.ac.at> wrote: > >> Hi John, >> >> I guess you probably want to "pseq x". See below for an example. Since >> your 2nd >> action does not depend on your 1st. >> >> Gruss, >> Christian >> >> >> import Debug.Trace >> import GHC.Conc >> >> main = do >> x <- return (traceShow "1" $ 1::Int) >> -- x `pseq` print (2::Int) >> print (2::Int) >> print x >> >> >> * John Lato [20.12.2013 02:36]: >> > Hello, >> > >> > I'm working on a lock-free algorithm that's meant to be used in a >> > concurrent setting, and I've run into a possible issue. >> > >> > The crux of the matter is that a particular function needs to >> perform the >> > following: >> > >> > > x <- MVector.read vec ix >> > > position <- readIORef posRef >> > >> > and the algorithm is only safe if these two reads are not reordered >> (both >> > the vector and IORef are written to by other threads). >> > >> > My concern is, according to standard Haskell semantics this should be >> > safe, as IO sequencing should guarantee that the reads happen >> in-order. >> > Of course this also relies upon the architecture's memory model, but >> x86 >> > also guarantees that reads happen in order. However doubts remain; >> I do >> > not have confidence that the code generator will handle this >> properly. In >> > particular, LLVM may freely re-order loads of NotAtomic and Unordered >> > values. >> > >> > The one hope I have is that ghc will preserve IO semantics through >> the >> > entire pipeline. This seems like it would be necessary for proper >> > handling of exceptions, for example. So, can anyone tell me if my >> worries >> > are unfounded, or if there's any way to ensure the behavior I want? >> I >> > could change the readIORef to an atomicModifyIORef, which should >> issue an >> > mfence, but that seems a bit heavy-handed as just a read fence would >> be >> > sufficient (although even that seems more than necessary). >> > >> > Thanks, >> > John L. >> >> > _______________________________________________ >> > Glasgow-haskell-users mailing list >> > Glasgow-haskell-users at haskell.org >> > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >> >> >> _______________________________________________ >> Glasgow-haskell-users mailing list >> Glasgow-haskell-users at haskell.org >> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gergo at erdi.hu Mon Dec 23 03:56:40 2013 From: gergo at erdi.hu (Dr. ERDI Gergo) Date: Mon, 23 Dec 2013 11:56:40 +0800 (SGT) Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: References: Message-ID: On Sun, 22 Dec 2013, Dr. ERDI Gergo wrote: >> If it's only A and B, perhaps abominations like these could be considered: >> >> ??? -- implicit foralls >> ??? pattern Show t => P t :: (Num t, Eq b) => b -> T t >> >> ??? -- explicit foralls >> ??? pattern forall t. Show t => P t :: forall b. (Num t, Eq b) => b -> T t > > I'm not 100% sure what that 't' in 'P t' is supposed to be in your example. > 'P' is not like a type constructor at all; it's a lot more like a data > constructor. Thinking further about it, I think this could work, using a syntax similar to data constructor definitions instead of sticking to the function type syntax: pattern (Num a, Eq b) => P a b :: (Show a) => T a or with explicit foralls (using the fact that we can deduce which tyvars are universial vs existential simply by seeing if they occur in 'T a'): pattern forall a b. (Num a, Eq b) => P a b :: (Show a) => T a my only concern with this one is that the direction of the first double arrow doesn't "feel right". Other examples with this syntax: -- Number literal patterns pattern Z :: (Num a, Eq a) => a pattern Z = 0 -- Monomorphic patterns pattern TrueAnd Bool :: [Bool] pattern TrueAnd b = [True, b] -- Infix notation pattern a :< Seq a :: Seq a pattern x :< xs <- (Seq.viewl -> x Seq.:< xs) I'm liking this so far. Bye, Gergo -- .--= ULLA! =-----------------. \ http://gergo.erdi.hu \ `---= gergo at erdi.hu =-------' RICE: Race Inspired Cosmetic Enhancement From carter.schonwald at gmail.com Mon Dec 23 03:58:44 2013 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sun, 22 Dec 2013 22:58:44 -0500 Subject: memory ordering In-Reply-To: References: <20131220085709.GA24919@totalegal.rz.uni-leipzig.de> Message-ID: Well if you hit any weird / surprising / none obvious issues with the memory ordering model, please share! It's also very relevant to some of the ghc hacking I hope to make time for January onwards. On Sunday, December 22, 2013, John Lato wrote: > Hi Carter, > > Atomics are more or less what I'm after. > > I've taken a look at Ryan's work ( > https://github.com/rrnewton/haskell-lockfree/), and there are certainly > some very useful items there, but I don't see anything quite like what I'm > looking for (except perhaps for a read barrier). > > The problem is that I don't actually need atomic operations for this. I'm > just doing reads after all. My concern is that many optimization pipelines > (i.e. LLVM) don't guarantee ordering of reads unless you use atomic > variables. > > The IORef docs warn that IORef operations may appear out-of-order > depending on the architecture's memory model. On (newer) x86, loads won't > move relative to other loads, so that should be ok, and Haskell's semantics > should guarantee that two IO operations will happen in program order. > > It's the Haskell semantics guarantee I'm concerned about; I guess I'm not > entirely sure I believe that it's implemented properly (although I have no > reason to believe it's wrong either). Perhaps I'm just overly paranoid. > > John Lato > > On Fri, Dec 20, 2013 at 9:05 AM, Carter Schonwald < > carter.schonwald at gmail.com 'carter.schonwald at gmail.com');>> wrote: > >> Hey John, so you're wanting atomic reads and writes? >> >> I'm pretty sure that you want to use atomic memory operations for this. >> I believe Ryan Newton has some tooling you can use right now for that. >> >> >> On Fri, Dec 20, 2013 at 3:57 AM, Christian H?ner zu Siederdissen < >> choener at tbi.univie.ac.at > 'choener at tbi.univie.ac.at');>> wrote: >> >>> Hi John, >>> >>> I guess you probably want to "pseq x". See below for an example. Since >>> your 2nd >>> action does not depend on your 1st. >>> >>> Gruss, >>> Christian >>> >>> >>> import Debug.Trace >>> import GHC.Conc >>> >>> main = do >>> x <- return (traceShow "1" $ 1::Int) >>> -- x `pseq` print (2::Int) >>> print (2::Int) >>> print x >>> >>> >>> * John Lato >> 'jwlato at gmail.com');>> [20.12.2013 02:36]: >>> > Hello, >>> > >>> > I'm working on a lock-free algorithm that's meant to be used in a >>> > concurrent setting, and I've run into a possible issue. >>> > >>> > The crux of the matter is that a particular function needs to >>> perform the >>> > following: >>> > >>> > > x <- MVector.read vec ix >>> > > position <- readIORef posRef >>> > >>> > and the algorithm is only safe if these two reads are not reordered >>> (both >>> > the vector and IORef are written to by other threads). >>> > >>> > My concern is, according to standard Haskell semantics this should >>> be >>> > safe, as IO sequencing should guarantee that the reads happen >>> in-order. >>> > Of course this also relies upon the architecture's memory model, >>> but x86 >>> > also guarantees that reads happen in order. However doubts remain; >>> I do >>> > not have confidence that the code generator will handle this >>> properly. In >>> > particular, LLVM may freely re-order loads of NotAtomic and >>> Unordered >>> > values. >>> > >>> > The one hope I have is that ghc will preserve IO semantics through >>> the >>> > entire pipeline. This seems like it would be necessary for proper >>> > handling of exceptions, for example. So, can anyone tell me if my >>> worries >>> > are unfounded, or if there's any way to ensure the behavior I want? >>> I >>> > could change the readIORef to an atomicModifyIORef, which should >>> issue an >>> > mfence, but that seems a bit heavy-handed as just a read fence >>> would be >>> > sufficient (although even that seems more than necessary). >>> > >>> > Thanks, >>> > John L. >>> >>> > _______________________________________________ >>> > Glasgow-haskell-users mailing list >>> > Glasgow-haskell-users at haskell.org >> 'Glasgow-haskell-users at haskell.org');> >>> > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >>> >>> >>> _______________________________________________ >>> Glasgow-haskell-users mailing list >>> Glasgow-haskell-users at haskell.org >> 'Glasgow-haskell-users at haskell.org');> >>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Mon Dec 23 05:45:48 2013 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Mon, 23 Dec 2013 00:45:48 -0500 Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: References: Message-ID: i'm confused, are these types ever human writeable? If not, are they meant to be an operational way of communicating how a pattern works? In which case, wouldn't having the pattern definition visible in the haddocks be a simpler way to communicate it? There have been several projects in the past to have type system for describing lambda calculi with pretty right higher order pattern matching facilities, perhaps that vocabulary could be used here? cheers (i hope my questions make sense, I could merely be confused) -Carter On Sun, Dec 22, 2013 at 10:56 PM, Dr. ERDI Gergo wrote: > On Sun, 22 Dec 2013, Dr. ERDI Gergo wrote: > > If it's only A and B, perhaps abominations like these could be considered: >>> >>> -- implicit foralls >>> pattern Show t => P t :: (Num t, Eq b) => b -> T t >>> >>> -- explicit foralls >>> pattern forall t. Show t => P t :: forall b. (Num t, Eq b) => b -> T >>> t >>> >> >> I'm not 100% sure what that 't' in 'P t' is supposed to be in your >> example. 'P' is not like a type constructor at all; it's a lot more like a >> data constructor. >> > > Thinking further about it, I think this could work, using a syntax similar > to data constructor definitions instead of sticking to the function type > syntax: > > pattern (Num a, Eq b) => P a b :: (Show a) => T a > > or with explicit foralls (using the fact that we can deduce which tyvars > are universial vs existential simply by seeing if they occur in 'T a'): > > pattern forall a b. (Num a, Eq b) => P a b :: (Show a) => T a > > my only concern with this one is that the direction of the first double > arrow doesn't "feel right". > > Other examples with this syntax: > > -- Number literal patterns > pattern Z :: (Num a, Eq a) => a pattern Z = 0 > > -- Monomorphic patterns > pattern TrueAnd Bool :: [Bool] > pattern TrueAnd b = [True, b] > > -- Infix notation > pattern a :< Seq a :: Seq a > pattern x :< xs <- (Seq.viewl -> x Seq.:< xs) > > I'm liking this so far. > > Bye, > Gergo > > > -- > > .--= ULLA! =-----------------. > \ http://gergo.erdi.hu \ > `---= gergo at erdi.hu =-------' > RICE: Race Inspired Cosmetic Enhancement > _______________________________________________ > Glasgow-haskell-users mailing list > Glasgow-haskell-users at haskell.org > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gergo at erdi.hu Mon Dec 23 06:01:10 2013 From: gergo at erdi.hu (Dr. ERDI Gergo) Date: Mon, 23 Dec 2013 14:01:10 +0800 (SGT) Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: References: Message-ID: On Mon, 23 Dec 2013, Carter Schonwald wrote: > i'm confused, are these types ever human writeable?? Yes, this syntax is meant to be also used for giving human-written type signatures for pattern synonym definitions. > If not, are they meant to be an operational way of communicating how a pattern works? > In which case, wouldn't having the pattern definition visible in the haddocks be a > simpler way to communicate it? The pattern definition itself should be abstract for the same reason function definitions are abstract. Imagine if the Haddock docs contained the definition of all functions instead of their types... Bye, Gergo -- .--= ULLA! =-----------------. \ http://gergo.erdi.hu \ `---= gergo at erdi.hu =-------' Post tenebras lux, post fenestras Tux. From juhp at community.haskell.org Tue Dec 24 05:58:00 2013 From: juhp at community.haskell.org (Jens Petersen) Date: Tue, 24 Dec 2013 14:58:00 +0900 Subject: ghc src snapshots In-Reply-To: References: Message-ID: I uploaded a newer source tarball snapshot to: http://petersen.fedorapeople.org/ghc/ghc-7.7.20131217-src.tar.bz2 I think it builds okay. Jens -------------- next part -------------- An HTML attachment was scrubbed... URL: From tsuyoshi.ito.2006 at gmail.com Tue Dec 24 10:57:19 2013 From: tsuyoshi.ito.2006 at gmail.com (Tsuyoshi Ito) Date: Tue, 24 Dec 2013 05:57:19 -0500 Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: References: Message-ID: > pattern (Num a, Eq b) => P a b :: (Show a) => T a Is ?P a b? a typo for ?P b?? Otherwise I cannot see how we can read from this signature that pattern synonym P should be used with one argument, which is a pattern of type b. Is there a reason why the leftmost context is the provided one and the context after :: is the required one, rather than the other way around? I am asking this not because I think the other way is better, but because to me both look equally good (or equally confusing) and I can imagine that I will have trouble remembering which context means which, no matter which way is chosen. One thing I like about the above notation better than > pattern P :: > b -> T t > requires (Show t) > provides (Num t, Eq b) or > pattern P :: (Show t) => b -> T t => (Num t, Eq b) is that it avoids the use of type constructor (->) because P is neither an expression nor a pattern of type ?b -> T t?. At best, P is a ?pattern function? from a pattern of type b to a pattern of type T t, and it has little to do with the function type ?b -> T t? if I am not mistaken. By the way, do you allow higher-order pattern functions such as pattern Q p <- p "Hello" with which Q P evaluates to MkT (f -> True) "Hello" ? I guess they are not allowed, but if they are allowed, I do not know how their types can be expressed in the syntax you proposed. Best regards, Tsuyoshi From gergo at erdi.hu Tue Dec 24 11:44:49 2013 From: gergo at erdi.hu (Dr. ERDI Gergo) Date: Tue, 24 Dec 2013 19:44:49 +0800 (SGT) Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: References: Message-ID: Hi, On Tue, 24 Dec 2013, Tsuyoshi Ito wrote: >> pattern (Num a, Eq b) => P a b :: (Show a) => T a > > Is ?P a b? a typo for ?P b?? Otherwise I cannot see how we can read > from this signature that pattern synonym P should be used with one > argument, which is a pattern of type b. I must have mixed up my examples, sorry. You are right in that it should be "P b". > Is there a reason why the leftmost context is the provided one and the > context after :: is the required one, rather than the other way > around? I am asking this not because I think the other way is better, > but because to me both look equally good (or equally confusing) and I > can imagine that I will have trouble remembering which context means > which, no matter which way is chosen. There's only one reason I went with that ordering instead of the other. Let's go back to the previous example (with the typo fixed): (1) pattern (Num a, Eq b) => P a b :: (Show a) => T a vs. (2) pattern (Show a) => P b :: (Num a, Eq b) => T a it just weirds me out that in (2), (Num a, Eq b) mentions the type variable b, which doesn't occur in 'T a' (since it is existentially bound). Note that this is true in general: only the provided typeclass constraints can mention existentially bound tyvars. > One thing I like about the above notation better than > >> pattern P :: >> b -> T t >> requires (Show t) >> provides (Num t, Eq b) > > or > >> pattern P :: (Show t) => b -> T t => (Num t, Eq b) > > is that it avoids the use of type constructor (->) because P is > neither an expression nor a pattern of type ?b -> T t?. At best, P is > a ?pattern function? from a pattern of type b to a pattern of type T > t, and it has little to do with the function type ?b -> T t? if I am > not mistaken. Yes, I agree 100%, in fact now I really don't want to go back and whatever syntax is eventually agreed upon, it shouldn't use the function type notation. > By the way, do you allow higher-order pattern functions such as > > pattern Q p <- p "Hello" > > with which Q P evaluates to > > MkT (f -> True) "Hello" > > ? I guess they are not allowed, but if they are allowed, I do not > know how their types can be expressed in the syntax you proposed. This is definitely *not* something we're adding. Thanks, Gergo -- .--= ULLA! =-----------------. \ http://gergo.erdi.hu \ `---= gergo at erdi.hu =-------' Make it possible for programmers to write programs in English, and you will find that programmers can not write in English. From tsuyoshi.ito.2006 at gmail.com Tue Dec 24 20:56:28 2013 From: tsuyoshi.ito.2006 at gmail.com (Tsuyoshi Ito) Date: Tue, 24 Dec 2013 15:56:28 -0500 Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: References: Message-ID: Dear Gergo, Thank you for your prompt reply. Now the ordering makes sense. To be honest, I still find it a little confusing even after knowing that the order is logical, but maybe it is just a matter of getting used to it. Also thank you for the clarification that higher-order pattern functions are outside the scope of the current work. Now I am curious about if/how higher-order pattern functions are useful, how their types can be described, and so on. If they have any applications, they may be a candidate for future work. Best regards, Tsuyoshi From gergo at erdi.hu Wed Dec 25 03:59:12 2013 From: gergo at erdi.hu (Dr. ERDI Gergo) Date: Wed, 25 Dec 2013 11:59:12 +0800 (SGT) Subject: Excellent bikeshedding opportunity! Frontend syntax for pattern synonym types In-Reply-To: References: Message-ID: Hi, On Tue, 24 Dec 2013, Tsuyoshi Ito wrote: > Thank you for your prompt reply. Now the ordering makes sense. To be > honest, I still find it a little confusing even after knowing that the > order is logical, but maybe it is just a matter of getting used to it. So just to make my position clear: I don't think that syntax is good, it's just the best we've come up with so far:) And the problem is exactly this, that it's not intuitive at all. One source of solace might be that 'provided' contexts will only pop up when you use GADTs with typeclass-constrained constructors, so for less 'power-user' cases, the signature simplifies to something like this: pattern P Bool t :: (Show t) => [t] > Also thank you for the clarification that higher-order pattern > functions are outside the scope of the current work. Now I am curious > about if/how higher-order pattern functions are useful, how their > types can be described, and so on. If they have any applications, > they may be a candidate for future work. I don't have an insight to offer on this at this point. However, I feel there's a huge qualitative difference between higher-order and non-higher-order pattern synonyms in the amount of new concepts that they introduce. I would even go so far as to recommend waiting until a stable GHC release with pattern synonyms (i.e. GHC 7.10 or 8.0 or whatever the next one will be called), and looking at real world usage of them, before jumping into higher-order patsyns. Thanks, Gergo From ezyang at mit.edu Mon Dec 30 14:04:40 2013 From: ezyang at mit.edu (Edward Z. Yang) Date: Mon, 30 Dec 2013 22:04:40 +0800 Subject: memory ordering In-Reply-To: References: Message-ID: <1388409528-sup-9632@sabre> Hello John, Here are some prior discussions (which I will attempt to summarize below): http://www.haskell.org/pipermail/haskell-cafe/2011-May/091878.html http://www.haskell.org/pipermail/haskell-prime/2006-April/001237.html http://www.haskell.org/pipermail/haskell-prime/2006-March/001079.html The guarantees that Haskell and GHC give in this area are hand-wavy at best; at the moment, I don't think Haskell or GHC have a formal memory model?this seems to be an open research problem. (Unfortunately, AFAICT all the researchers working on relaxed memory models have their hands full with things like C++ :-) If you want to go ahead and build something that /just/ works for a /specific version/ of GHC, you will need to answer this question separately for every phase of the compiler. For Core and STG, monads will preserve ordering, so there is no trouble. However, for C--, we will almost certainly apply optimizations which reorder reads (look at CmmSink.hs). To properly support your algorithm, you will have to add some new read barrier mach-ops, and teach the optimizer to respect them. (This could be fiendishly subtle; it might be better to give C-- a memory model first.) These mach-ops would then translate into appropriate arch-specific assembly or LLVM instructions, preserving the guarantees further. This is not related to your original question, but the situation is a bit better with regards to reordering stores: we have a WriteBarrier MachOp, which in principle, prevents store reordering. In practice, we don't seem to actually have any C-- optimizations that reorder stores. So, at least you can assume these will work OK! Hope this helps (and is not too inaccurate), Edward Excerpts from John Lato's message of 2013-12-20 09:36:11 +0800: > Hello, > > I'm working on a lock-free algorithm that's meant to be used in a > concurrent setting, and I've run into a possible issue. > > The crux of the matter is that a particular function needs to perform the > following: > > > x <- MVector.read vec ix > > position <- readIORef posRef > > and the algorithm is only safe if these two reads are not reordered (both > the vector and IORef are written to by other threads). > > My concern is, according to standard Haskell semantics this should be safe, > as IO sequencing should guarantee that the reads happen in-order. Of > course this also relies upon the architecture's memory model, but x86 also > guarantees that reads happen in order. However doubts remain; I do not > have confidence that the code generator will handle this properly. In > particular, LLVM may freely re-order loads of NotAtomic and Unordered > values. > > The one hope I have is that ghc will preserve IO semantics through the > entire pipeline. This seems like it would be necessary for proper handling > of exceptions, for example. So, can anyone tell me if my worries are > unfounded, or if there's any way to ensure the behavior I want? I could > change the readIORef to an atomicModifyIORef, which should issue an mfence, > but that seems a bit heavy-handed as just a read fence would be sufficient > (although even that seems more than necessary). > > Thanks, > John L. From simonpj at microsoft.com Mon Dec 30 18:00:28 2013 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Mon, 30 Dec 2013 18:00:28 +0000 Subject: Decomposition of given equalities In-Reply-To: References: <6A96EC65-BCFA-444A-AB43-982748CB8ACD@cis.upenn.edu> Message-ID: <59543203684B2244980D7E4057D5FBC1486FE267@DB3EX14MBXC306.europe.corp.microsoft.com> | given `(f a ~ g b)` there's no possible way that `a` and `b`, resp. `f` | and `g` might have different kinds (how could you ever have constructed | `f a ~ g b` if they did?) Wait. It's quite possible for them to have different kinds. E.g. f :: (* -> *) -> * a :: (* -> *) g :: * -> * b :: * Then (f a :: *) and (g b :: *), and it'd be quite reasonable to form the equality (f a ~ g b). Simon | -----Original Message----- | From: Glasgow-haskell-users [mailto:glasgow-haskell-users- | bounces at haskell.org] On Behalf Of G?bor Lehel | Sent: 19 December 2013 16:12 | To: Richard Eisenberg | Cc: glasgow-haskell-users at haskell.org | Subject: Re: Decomposition of given equalities | | Does this boil down to the fact that GHC doesn't have kind GADTs? I.e. | given `(f a ~ g b)` there's no possible way that `a` and `b`, resp. `f` | and `g` might have different kinds (how could you ever have constructed | `f a ~ g b` if they did?), but GHC isn't equipped to reason about that | (to store evidence for it and retrieve it later)? | | On Thu, Dec 19, 2013 at 4:01 PM, Richard Eisenberg | wrote: | > Let me revise slightly. GHC wouldn't guess that f3 would be f just | because f is the only well-kinded thing in sight. | > | > Instead, it would use (f2 i ~ a) to reduce the target equality, (f3 i2 | ~ a), to (f3 i2 ~ f2 i). It would then try to break this down into (f3 ~ | f2) and (i2 ~ i). Here is where the kind problem comes in -- these | equalities are ill-kinded. So, GHC (rightly, in my view) rejects this | code, and reports an appropriate error message. Of course, more context | in the error message might be an improvement, but I don't think the | current message is wrong. | > | > As for Thijs's comment about lack of decomposition in GHC 7.6.3: | You're right, that code fails in GHC 7.6.3 because of an attempt | (present in GHC 7.6.x) to redesign the Core type system to allow for | unsaturated type families (at least in Core, if not in Haskell). There | were a few cases that came up that the redesign couldn't handle, like | Thijs's. So, the redesign was abandoned. In GHC HEAD, Thijs's code works | just fine. | > | > (The redesign was to get rid of the "left" and "right" coercions, | > which allow decomposition of things like (f a ~ g b), in favor of an | > "nth" coercion, which allows decomposition of things like (T a ~ T | > b).) | > | > Good -- I feel much better about this answer, where there's no guess | for the value of f3! | > | > Richard | > | > On Dec 18, 2013, at 11:30 PM, Richard Eisenberg wrote: | > | >> I'd say GHC has it right in this case. | >> | >> (f a ~ g b) exactly implies (f ~ g) and (a ~ b) if and only if the | >> kinds match up. If, say, (f :: k1 -> *), (g :: k2 -> *), (a :: k1), | >> and (b :: k2), then (f ~ g) and (a ~ b) are ill-kinded. In Gabor's | >> initial problem, we have (with all type, kind, and coercion variables | >> made explicit) | >> | >>> data InnerEq (j :: BOX) (k :: BOX) (i :: j) (a :: k) where InnerEq | >>> :: forall (f :: j -> k). f i ~ a => InnerEq j k i a | >>> | >>> class TypeCompare (k :: BOX) (t :: k -> *) where maybeInnerEq :: | >>> forall (j :: BOX) (f :: j -> k) (i :: j) (a :: k). | >>> t (f i) -> t a -> Maybe (InnerEq j k i a) | >>> | >>> instance forall (j :: BOX) (k :: BOX) (i :: j). TypeCompare k | >>> (InnerEq j k i) where maybeInnerEq :: forall (j2 :: BOX) (f :: j2 - | > k) (i2 :: j2) (a :: k). | >>> InnerEq j k i (f i2) -> InnerEq j k i a -> Maybe | >>> (InnerEq j2 k i2 a) maybeInnerEq (InnerEq (f1 :: j -> k) (co1 :: f1 | i ~ f i2)) | >>> (InnerEq (f2 :: j -> k) (co2 :: f2 i ~ a)) | >>> = Just (InnerEq (f3 :: j2 -> k) (co3 :: f3 i2 ~ a)) | >> | >> GHC must infer `f3` and `co3`. The only thing of kind `j2 -> k` lying | >> around is f. So, we choose f3 := f. Now, we need to prove `f i2 ~ a`. | Using the two equalities we have, we can rewrite this as a need to prove | `f1 i ~ f2 i`. I can't see a way of doing this. Now, GHC complains that | it cannot (renaming to my variables) deduce (i ~ i2) from (f1 i ~ f i2). | But, this is exactly the case where the kinds *don't* match up. So, I | agree that GHC can't deduce that equality, but I think that, even if it | could, it wouldn't be able to type-check the whole term.... unless I've | made a mistake somewhere. | >> | >> I don't see an immediate way to fix the problem, but I haven't | thought much about it. | >> | >> Does this help? Does anyone see a mistake in what I've done? | >> | >> Richard | >> | >> On Dec 18, 2013, at 6:38 PM, G?bor Lehel | wrote: | >> | >>> Hello, | >>> | >>> The upcoming GHC 7.8 recently gave me this error: | >>> | >>> Could not deduce (i ~ i1) | >>> from the context (f1 i ~ f i1) | >>> | >>> Which is strange to me: shouldn't (f1 i ~ f i1) exactly imply (f1 ~ | >>> f, i ~ i1)? (Or with nicer variable names: (f a ~ g b) => (f ~ g, a | >>> ~ | >>> b)?) | >>> | >>> When I inquired about this in #haskell on IRC, a person going by the | >>> name xnyhps had this to say: | >>> | >>>> I've also noticed that, given type equality constraints are never | decomposed. I'm quite curious why. | >>> | >>> and later: | >>> | >>>> It's especially weird because a given f a ~ g b can not be used to | solve a wanted f a ~ g b, because the wanted constraint is decomposed | before it can interact with the given constraint. | >>> | >>> I'm not quite so well versed in the workings of GHC's type checker | >>> as she or he is, but I don't understand why it's this way either. | >>> | >>> Is this a relic of https://ghc.haskell.org/trac/ghc/ticket/5591 and | >>> https://ghc.haskell.org/trac/ghc/ticket/7205? Is there a principled | >>> reason this shouldn't be true? Is it an intentional limitation of | >>> the constraint solver? Or is it just a bug? | >>> | >>> Thanks in advance, | >>> G?bor | >>> | >>> P.S. I got the error on this line: | >>> https://github.com/glaebhoerl/type-eq/blob/master/Type/Eq.hs#L181, | >>> possibly after having added kind annotations to `InnerEq` (which | >>> also gets a less general kind inferred than the one I expect). If | >>> it's important I can try to create a reduced test case. | >>> _______________________________________________ | >>> Glasgow-haskell-users mailing list | >>> Glasgow-haskell-users at haskell.org | >>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users | >>> | >> | >> _______________________________________________ | >> Glasgow-haskell-users mailing list | >> Glasgow-haskell-users at haskell.org | >> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users | >> | > | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users at haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users From glaebhoerl at gmail.com Mon Dec 30 18:10:57 2013 From: glaebhoerl at gmail.com (=?ISO-8859-1?Q?G=E1bor_Lehel?=) Date: Mon, 30 Dec 2013 19:10:57 +0100 Subject: Decomposition of given equalities In-Reply-To: <59543203684B2244980D7E4057D5FBC1486FE267@DB3EX14MBXC306.europe.corp.microsoft.com> References: <6A96EC65-BCFA-444A-AB43-982748CB8ACD@cis.upenn.edu> <59543203684B2244980D7E4057D5FBC1486FE267@DB3EX14MBXC306.europe.corp.microsoft.com> Message-ID: On Mon, Dec 30, 2013 at 7:00 PM, Simon Peyton-Jones wrote: > | given `(f a ~ g b)` there's no possible way that `a` and `b`, resp. `f` > | and `g` might have different kinds (how could you ever have constructed > | `f a ~ g b` if they did?) > > Wait. It's quite possible for them to have different kinds. E.g. > > f :: (* -> *) -> * > a :: (* -> *) > g :: * -> * > b :: * > > Then (f a :: *) and (g b :: *), and it'd be quite reasonable to > form the equality (f a ~ g b). > Yes, it's quite possible, given f, a, g, and b of different kinds, to make `f a` and `g b` have the same *kind*. But how could they ever be the same type? Is it not the case that (f a ~ g b) iff (f ~ g) and (a ~ b) (obviously impossible if those are of different kinds)? You would have to worry about this possibility if type constructor variables weren't injective, but they are. > > Simon > > | -----Original Message----- > | From: Glasgow-haskell-users [mailto:glasgow-haskell-users- > | bounces at haskell.org] On Behalf Of G?bor Lehel > | Sent: 19 December 2013 16:12 > | To: Richard Eisenberg > | Cc: glasgow-haskell-users at haskell.org > | Subject: Re: Decomposition of given equalities > | > | Does this boil down to the fact that GHC doesn't have kind GADTs? I.e. > | given `(f a ~ g b)` there's no possible way that `a` and `b`, resp. `f` > | and `g` might have different kinds (how could you ever have constructed > | `f a ~ g b` if they did?), but GHC isn't equipped to reason about that > | (to store evidence for it and retrieve it later)? > | > | On Thu, Dec 19, 2013 at 4:01 PM, Richard Eisenberg > | wrote: > | > Let me revise slightly. GHC wouldn't guess that f3 would be f just > | because f is the only well-kinded thing in sight. > | > > | > Instead, it would use (f2 i ~ a) to reduce the target equality, (f3 i2 > | ~ a), to (f3 i2 ~ f2 i). It would then try to break this down into (f3 ~ > | f2) and (i2 ~ i). Here is where the kind problem comes in -- these > | equalities are ill-kinded. So, GHC (rightly, in my view) rejects this > | code, and reports an appropriate error message. Of course, more context > | in the error message might be an improvement, but I don't think the > | current message is wrong. > | > > | > As for Thijs's comment about lack of decomposition in GHC 7.6.3: > | You're right, that code fails in GHC 7.6.3 because of an attempt > | (present in GHC 7.6.x) to redesign the Core type system to allow for > | unsaturated type families (at least in Core, if not in Haskell). There > | were a few cases that came up that the redesign couldn't handle, like > | Thijs's. So, the redesign was abandoned. In GHC HEAD, Thijs's code works > | just fine. > | > > | > (The redesign was to get rid of the "left" and "right" coercions, > | > which allow decomposition of things like (f a ~ g b), in favor of an > | > "nth" coercion, which allows decomposition of things like (T a ~ T > | > b).) > | > > | > Good -- I feel much better about this answer, where there's no guess > | for the value of f3! > | > > | > Richard > | > > | > On Dec 18, 2013, at 11:30 PM, Richard Eisenberg wrote: > | > > | >> I'd say GHC has it right in this case. > | >> > | >> (f a ~ g b) exactly implies (f ~ g) and (a ~ b) if and only if the > | >> kinds match up. If, say, (f :: k1 -> *), (g :: k2 -> *), (a :: k1), > | >> and (b :: k2), then (f ~ g) and (a ~ b) are ill-kinded. In Gabor's > | >> initial problem, we have (with all type, kind, and coercion variables > | >> made explicit) > | >> > | >>> data InnerEq (j :: BOX) (k :: BOX) (i :: j) (a :: k) where InnerEq > | >>> :: forall (f :: j -> k). f i ~ a => InnerEq j k i a > | >>> > | >>> class TypeCompare (k :: BOX) (t :: k -> *) where maybeInnerEq :: > | >>> forall (j :: BOX) (f :: j -> k) (i :: j) (a :: k). > | >>> t (f i) -> t a -> Maybe (InnerEq j k i a) > | >>> > | >>> instance forall (j :: BOX) (k :: BOX) (i :: j). TypeCompare k > | >>> (InnerEq j k i) where maybeInnerEq :: forall (j2 :: BOX) (f :: j2 - > | > k) (i2 :: j2) (a :: k). > | >>> InnerEq j k i (f i2) -> InnerEq j k i a -> Maybe > | >>> (InnerEq j2 k i2 a) maybeInnerEq (InnerEq (f1 :: j -> k) (co1 :: f1 > | i ~ f i2)) > | >>> (InnerEq (f2 :: j -> k) (co2 :: f2 i ~ a)) > | >>> = Just (InnerEq (f3 :: j2 -> k) (co3 :: f3 i2 ~ a)) > | >> > | >> GHC must infer `f3` and `co3`. The only thing of kind `j2 -> k` lying > | >> around is f. So, we choose f3 := f. Now, we need to prove `f i2 ~ a`. > | Using the two equalities we have, we can rewrite this as a need to prove > | `f1 i ~ f2 i`. I can't see a way of doing this. Now, GHC complains that > | it cannot (renaming to my variables) deduce (i ~ i2) from (f1 i ~ f i2). > | But, this is exactly the case where the kinds *don't* match up. So, I > | agree that GHC can't deduce that equality, but I think that, even if it > | could, it wouldn't be able to type-check the whole term.... unless I've > | made a mistake somewhere. > | >> > | >> I don't see an immediate way to fix the problem, but I haven't > | thought much about it. > | >> > | >> Does this help? Does anyone see a mistake in what I've done? > | >> > | >> Richard > | >> > | >> On Dec 18, 2013, at 6:38 PM, G?bor Lehel > | wrote: > | >> > | >>> Hello, > | >>> > | >>> The upcoming GHC 7.8 recently gave me this error: > | >>> > | >>> Could not deduce (i ~ i1) > | >>> from the context (f1 i ~ f i1) > | >>> > | >>> Which is strange to me: shouldn't (f1 i ~ f i1) exactly imply (f1 ~ > | >>> f, i ~ i1)? (Or with nicer variable names: (f a ~ g b) => (f ~ g, a > | >>> ~ > | >>> b)?) > | >>> > | >>> When I inquired about this in #haskell on IRC, a person going by the > | >>> name xnyhps had this to say: > | >>> > | >>>> I've also noticed that, given type equality constraints are never > | decomposed. I'm quite curious why. > | >>> > | >>> and later: > | >>> > | >>>> It's especially weird because a given f a ~ g b can not be used to > | solve a wanted f a ~ g b, because the wanted constraint is decomposed > | before it can interact with the given constraint. > | >>> > | >>> I'm not quite so well versed in the workings of GHC's type checker > | >>> as she or he is, but I don't understand why it's this way either. > | >>> > | >>> Is this a relic of https://ghc.haskell.org/trac/ghc/ticket/5591 and > | >>> https://ghc.haskell.org/trac/ghc/ticket/7205? Is there a principled > | >>> reason this shouldn't be true? Is it an intentional limitation of > | >>> the constraint solver? Or is it just a bug? > | >>> > | >>> Thanks in advance, > | >>> G?bor > | >>> > | >>> P.S. I got the error on this line: > | >>> https://github.com/glaebhoerl/type-eq/blob/master/Type/Eq.hs#L181, > | >>> possibly after having added kind annotations to `InnerEq` (which > | >>> also gets a less general kind inferred than the one I expect). If > | >>> it's important I can try to create a reduced test case. > | >>> _______________________________________________ > | >>> Glasgow-haskell-users mailing list > | >>> Glasgow-haskell-users at haskell.org > | >>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > | >>> > | >> > | >> _______________________________________________ > | >> Glasgow-haskell-users mailing list > | >> Glasgow-haskell-users at haskell.org > | >> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > | >> > | > > | _______________________________________________ > | Glasgow-haskell-users mailing list > | Glasgow-haskell-users at haskell.org > | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwlato at gmail.com Mon Dec 30 19:01:58 2013 From: jwlato at gmail.com (John Lato) Date: Mon, 30 Dec 2013 11:01:58 -0800 Subject: memory ordering In-Reply-To: <1388409528-sup-9632@sabre> References: <1388409528-sup-9632@sabre> Message-ID: Hi Edward, Thanks very much for this reply, it answers a lot of questions I'd had. I'd hoped that ordering would be preserved through C--, but c'est la vie. Optimizing compilers are ever the bane of concurrent algorithms! stg/SMP.h does define a loadLoadBarrier, which is exposed in Ryan Newton's atomic-primops package. From the docs, I think that's a general read barrier, and should do what I want. Assuming it works properly, of course. If I'm lucky it might even be optimized out. Thanks, John On Mon, Dec 30, 2013 at 6:04 AM, Edward Z. Yang wrote: > Hello John, > > Here are some prior discussions (which I will attempt to summarize > below): > > http://www.haskell.org/pipermail/haskell-cafe/2011-May/091878.html > http://www.haskell.org/pipermail/haskell-prime/2006-April/001237.html > http://www.haskell.org/pipermail/haskell-prime/2006-March/001079.html > > The guarantees that Haskell and GHC give in this area are hand-wavy at > best; at the moment, I don't think Haskell or GHC have a formal memory > model?this seems to be an open research problem. (Unfortunately, AFAICT > all the researchers working on relaxed memory models have their hands > full with things like C++ :-) > > If you want to go ahead and build something that /just/ works for a > /specific version/ of GHC, you will need to answer this question > separately for every phase of the compiler. For Core and STG, monads > will preserve ordering, so there is no trouble. However, for C--, we > will almost certainly apply optimizations which reorder reads (look at > CmmSink.hs). To properly support your algorithm, you will have to add > some new read barrier mach-ops, and teach the optimizer to respect them. > (This could be fiendishly subtle; it might be better to give C-- a > memory model first.) These mach-ops would then translate into > appropriate arch-specific assembly or LLVM instructions, preserving > the guarantees further. > > This is not related to your original question, but the situation is a > bit better with regards to reordering stores: we have a WriteBarrier > MachOp, which in principle, prevents store reordering. In practice, we > don't seem to actually have any C-- optimizations that reorder stores. > So, at least you can assume these will work OK! > > Hope this helps (and is not too inaccurate), > Edward > > Excerpts from John Lato's message of 2013-12-20 09:36:11 +0800: > > Hello, > > > > I'm working on a lock-free algorithm that's meant to be used in a > > concurrent setting, and I've run into a possible issue. > > > > The crux of the matter is that a particular function needs to perform the > > following: > > > > > x <- MVector.read vec ix > > > position <- readIORef posRef > > > > and the algorithm is only safe if these two reads are not reordered (both > > the vector and IORef are written to by other threads). > > > > My concern is, according to standard Haskell semantics this should be > safe, > > as IO sequencing should guarantee that the reads happen in-order. Of > > course this also relies upon the architecture's memory model, but x86 > also > > guarantees that reads happen in order. However doubts remain; I do not > > have confidence that the code generator will handle this properly. In > > particular, LLVM may freely re-order loads of NotAtomic and Unordered > > values. > > > > The one hope I have is that ghc will preserve IO semantics through the > > entire pipeline. This seems like it would be necessary for proper > handling > > of exceptions, for example. So, can anyone tell me if my worries are > > unfounded, or if there's any way to ensure the behavior I want? I could > > change the readIORef to an atomicModifyIORef, which should issue an > mfence, > > but that seems a bit heavy-handed as just a read fence would be > sufficient > > (although even that seems more than necessary). > > > > Thanks, > > John L. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From simonpj at microsoft.com Tue Dec 31 08:26:49 2013 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Tue, 31 Dec 2013 08:26:49 +0000 Subject: Decomposition of given equalities In-Reply-To: References: <6A96EC65-BCFA-444A-AB43-982748CB8ACD@cis.upenn.edu> <59543203684B2244980D7E4057D5FBC1486FE267@DB3EX14MBXC306.europe.corp.microsoft.com> Message-ID: <59543203684B2244980D7E4057D5FBC1486FE57A@DB3EX14MBXC306.europe.corp.microsoft.com> Yes, it's quite possible, given f, a, g, and b of different kinds, to make `f a` and `g b` have the same *kind*. But how could they ever be the same type? Ah I see. Good point. Anyway, the conclusion is that decomposing a well-kinded (f a ~ g b) into ill-kinded goals is indeed a bad thing, so it's good that GHC doesn't do it. Simon From: G?bor Lehel [mailto:glaebhoerl at gmail.com] Sent: 30 December 2013 18:11 To: Simon Peyton-Jones Cc: Richard Eisenberg; glasgow-haskell-users at haskell.org Subject: Re: Decomposition of given equalities On Mon, Dec 30, 2013 at 7:00 PM, Simon Peyton-Jones > wrote: | given `(f a ~ g b)` there's no possible way that `a` and `b`, resp. `f` | and `g` might have different kinds (how could you ever have constructed | `f a ~ g b` if they did?) Wait. It's quite possible for them to have different kinds. E.g. f :: (* -> *) -> * a :: (* -> *) g :: * -> * b :: * Then (f a :: *) and (g b :: *), and it'd be quite reasonable to form the equality (f a ~ g b). Yes, it's quite possible, given f, a, g, and b of different kinds, to make `f a` and `g b` have the same *kind*. But how could they ever be the same type? Is it not the case that (f a ~ g b) iff (f ~ g) and (a ~ b) (obviously impossible if those are of different kinds)? You would have to worry about this possibility if type constructor variables weren't injective, but they are. Simon | -----Original Message----- | From: Glasgow-haskell-users [mailto:glasgow-haskell-users- | bounces at haskell.org] On Behalf Of G?bor Lehel | Sent: 19 December 2013 16:12 | To: Richard Eisenberg | Cc: glasgow-haskell-users at haskell.org | Subject: Re: Decomposition of given equalities | | Does this boil down to the fact that GHC doesn't have kind GADTs? I.e. | given `(f a ~ g b)` there's no possible way that `a` and `b`, resp. `f` | and `g` might have different kinds (how could you ever have constructed | `f a ~ g b` if they did?), but GHC isn't equipped to reason about that | (to store evidence for it and retrieve it later)? | | On Thu, Dec 19, 2013 at 4:01 PM, Richard Eisenberg > | wrote: | > Let me revise slightly. GHC wouldn't guess that f3 would be f just | because f is the only well-kinded thing in sight. | > | > Instead, it would use (f2 i ~ a) to reduce the target equality, (f3 i2 | ~ a), to (f3 i2 ~ f2 i). It would then try to break this down into (f3 ~ | f2) and (i2 ~ i). Here is where the kind problem comes in -- these | equalities are ill-kinded. So, GHC (rightly, in my view) rejects this | code, and reports an appropriate error message. Of course, more context | in the error message might be an improvement, but I don't think the | current message is wrong. | > | > As for Thijs's comment about lack of decomposition in GHC 7.6.3: | You're right, that code fails in GHC 7.6.3 because of an attempt | (present in GHC 7.6.x) to redesign the Core type system to allow for | unsaturated type families (at least in Core, if not in Haskell). There | were a few cases that came up that the redesign couldn't handle, like | Thijs's. So, the redesign was abandoned. In GHC HEAD, Thijs's code works | just fine. | > | > (The redesign was to get rid of the "left" and "right" coercions, | > which allow decomposition of things like (f a ~ g b), in favor of an | > "nth" coercion, which allows decomposition of things like (T a ~ T | > b).) | > | > Good -- I feel much better about this answer, where there's no guess | for the value of f3! | > | > Richard | > | > On Dec 18, 2013, at 11:30 PM, Richard Eisenberg wrote: | > | >> I'd say GHC has it right in this case. | >> | >> (f a ~ g b) exactly implies (f ~ g) and (a ~ b) if and only if the | >> kinds match up. If, say, (f :: k1 -> *), (g :: k2 -> *), (a :: k1), | >> and (b :: k2), then (f ~ g) and (a ~ b) are ill-kinded. In Gabor's | >> initial problem, we have (with all type, kind, and coercion variables | >> made explicit) | >> | >>> data InnerEq (j :: BOX) (k :: BOX) (i :: j) (a :: k) where InnerEq | >>> :: forall (f :: j -> k). f i ~ a => InnerEq j k i a | >>> | >>> class TypeCompare (k :: BOX) (t :: k -> *) where maybeInnerEq :: | >>> forall (j :: BOX) (f :: j -> k) (i :: j) (a :: k). | >>> t (f i) -> t a -> Maybe (InnerEq j k i a) | >>> | >>> instance forall (j :: BOX) (k :: BOX) (i :: j). TypeCompare k | >>> (InnerEq j k i) where maybeInnerEq :: forall (j2 :: BOX) (f :: j2 - | > k) (i2 :: j2) (a :: k). | >>> InnerEq j k i (f i2) -> InnerEq j k i a -> Maybe | >>> (InnerEq j2 k i2 a) maybeInnerEq (InnerEq (f1 :: j -> k) (co1 :: f1 | i ~ f i2)) | >>> (InnerEq (f2 :: j -> k) (co2 :: f2 i ~ a)) | >>> = Just (InnerEq (f3 :: j2 -> k) (co3 :: f3 i2 ~ a)) | >> | >> GHC must infer `f3` and `co3`. The only thing of kind `j2 -> k` lying | >> around is f. So, we choose f3 := f. Now, we need to prove `f i2 ~ a`. | Using the two equalities we have, we can rewrite this as a need to prove | `f1 i ~ f2 i`. I can't see a way of doing this. Now, GHC complains that | it cannot (renaming to my variables) deduce (i ~ i2) from (f1 i ~ f i2). | But, this is exactly the case where the kinds *don't* match up. So, I | agree that GHC can't deduce that equality, but I think that, even if it | could, it wouldn't be able to type-check the whole term.... unless I've | made a mistake somewhere. | >> | >> I don't see an immediate way to fix the problem, but I haven't | thought much about it. | >> | >> Does this help? Does anyone see a mistake in what I've done? | >> | >> Richard | >> | >> On Dec 18, 2013, at 6:38 PM, G?bor Lehel > | wrote: | >> | >>> Hello, | >>> | >>> The upcoming GHC 7.8 recently gave me this error: | >>> | >>> Could not deduce (i ~ i1) | >>> from the context (f1 i ~ f i1) | >>> | >>> Which is strange to me: shouldn't (f1 i ~ f i1) exactly imply (f1 ~ | >>> f, i ~ i1)? (Or with nicer variable names: (f a ~ g b) => (f ~ g, a | >>> ~ | >>> b)?) | >>> | >>> When I inquired about this in #haskell on IRC, a person going by the | >>> name xnyhps had this to say: | >>> | >>>> I've also noticed that, given type equality constraints are never | decomposed. I'm quite curious why. | >>> | >>> and later: | >>> | >>>> It's especially weird because a given f a ~ g b can not be used to | solve a wanted f a ~ g b, because the wanted constraint is decomposed | before it can interact with the given constraint. | >>> | >>> I'm not quite so well versed in the workings of GHC's type checker | >>> as she or he is, but I don't understand why it's this way either. | >>> | >>> Is this a relic of https://ghc.haskell.org/trac/ghc/ticket/5591 and | >>> https://ghc.haskell.org/trac/ghc/ticket/7205? Is there a principled | >>> reason this shouldn't be true? Is it an intentional limitation of | >>> the constraint solver? Or is it just a bug? | >>> | >>> Thanks in advance, | >>> G?bor | >>> | >>> P.S. I got the error on this line: | >>> https://github.com/glaebhoerl/type-eq/blob/master/Type/Eq.hs#L181, | >>> possibly after having added kind annotations to `InnerEq` (which | >>> also gets a less general kind inferred than the one I expect). If | >>> it's important I can try to create a reduced test case. | >>> _______________________________________________ | >>> Glasgow-haskell-users mailing list | >>> Glasgow-haskell-users at haskell.org | >>> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users | >>> | >> | >> _______________________________________________ | >> Glasgow-haskell-users mailing list | >> Glasgow-haskell-users at haskell.org | >> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users | >> | > | _______________________________________________ | Glasgow-haskell-users mailing list | Glasgow-haskell-users at haskell.org | http://www.haskell.org/mailman/listinfo/glasgow-haskell-users -------------- next part -------------- An HTML attachment was scrubbed... URL: From ezyang at mit.edu Tue Dec 31 14:04:22 2013 From: ezyang at mit.edu (Edward Z. Yang) Date: Tue, 31 Dec 2013 22:04:22 +0800 Subject: memory ordering In-Reply-To: References: <1388409528-sup-9632@sabre> Message-ID: <1388496939-sup-1821@sabre> I was thinking about my response, and realized there was one major misleading thing in my description. The load reordering I described applies to load instructions in C-- proper, i.e. things that show up in the C-- dup as: W_ x = I64[...addr...] Reads to IORefs and reads to vectors get compiled inline (as they eventually translate into inline primops), so my admonitions are applicable. However, the story with *foreign primops* (which is how loadLoadBarrier in atomic-primops is defined, how you might imagine defining a custom read function as a primop) is a little different. First, what does a call to an foreign primop compile into? It is *not* inlined, so it will eventually get compiled into a jump (this could be a problem if you're really trying to squeeze out performance!) Second, the optimizer is a bit more conservative when it comes to primop calls (internally referred to as "unsafe foreign calls"); at the moment, the optimizer assumes these foreign calls clobber heap memory, so we *automatically* will not push loads/stores beyond this boundary. (NB: We reserve the right to change this in the future!) This is probably why atomic-primops, as it is written today, seems to work OK, even in the presence of the optimizer. But I also have a hard time believing it gives the speedups you want, due to the current design. (CC'd Ryan Newton, because I would love to be wrong here, and maybe he can correct me on this note.) Cheers, Edward P.S. loadLoadBarrier compiles to a no-op on x86 architectures, but because it's not inlined I think you will still end up with a jump (LLVM might be able to eliminate it). Excerpts from John Lato's message of 2013-12-31 03:01:58 +0800: > Hi Edward, > > Thanks very much for this reply, it answers a lot of questions I'd had. > I'd hoped that ordering would be preserved through C--, but c'est la vie. > Optimizing compilers are ever the bane of concurrent algorithms! > > stg/SMP.h does define a loadLoadBarrier, which is exposed in Ryan Newton's > atomic-primops package. From the docs, I think that's a general read > barrier, and should do what I want. Assuming it works properly, of course. > If I'm lucky it might even be optimized out. > > Thanks, > John > > On Mon, Dec 30, 2013 at 6:04 AM, Edward Z. Yang wrote: > > > Hello John, > > > > Here are some prior discussions (which I will attempt to summarize > > below): > > > > http://www.haskell.org/pipermail/haskell-cafe/2011-May/091878.html > > http://www.haskell.org/pipermail/haskell-prime/2006-April/001237.html > > http://www.haskell.org/pipermail/haskell-prime/2006-March/001079.html > > > > The guarantees that Haskell and GHC give in this area are hand-wavy at > > best; at the moment, I don't think Haskell or GHC have a formal memory > > model?this seems to be an open research problem. (Unfortunately, AFAICT > > all the researchers working on relaxed memory models have their hands > > full with things like C++ :-) > > > > If you want to go ahead and build something that /just/ works for a > > /specific version/ of GHC, you will need to answer this question > > separately for every phase of the compiler. For Core and STG, monads > > will preserve ordering, so there is no trouble. However, for C--, we > > will almost certainly apply optimizations which reorder reads (look at > > CmmSink.hs). To properly support your algorithm, you will have to add > > some new read barrier mach-ops, and teach the optimizer to respect them. > > (This could be fiendishly subtle; it might be better to give C-- a > > memory model first.) These mach-ops would then translate into > > appropriate arch-specific assembly or LLVM instructions, preserving > > the guarantees further. > > > > This is not related to your original question, but the situation is a > > bit better with regards to reordering stores: we have a WriteBarrier > > MachOp, which in principle, prevents store reordering. In practice, we > > don't seem to actually have any C-- optimizations that reorder stores. > > So, at least you can assume these will work OK! > > > > Hope this helps (and is not too inaccurate), > > Edward > > > > Excerpts from John Lato's message of 2013-12-20 09:36:11 +0800: > > > Hello, > > > > > > I'm working on a lock-free algorithm that's meant to be used in a > > > concurrent setting, and I've run into a possible issue. > > > > > > The crux of the matter is that a particular function needs to perform the > > > following: > > > > > > > x <- MVector.read vec ix > > > > position <- readIORef posRef > > > > > > and the algorithm is only safe if these two reads are not reordered (both > > > the vector and IORef are written to by other threads). > > > > > > My concern is, according to standard Haskell semantics this should be > > safe, > > > as IO sequencing should guarantee that the reads happen in-order. Of > > > course this also relies upon the architecture's memory model, but x86 > > also > > > guarantees that reads happen in order. However doubts remain; I do not > > > have confidence that the code generator will handle this properly. In > > > particular, LLVM may freely re-order loads of NotAtomic and Unordered > > > values. > > > > > > The one hope I have is that ghc will preserve IO semantics through the > > > entire pipeline. This seems like it would be necessary for proper > > handling > > > of exceptions, for example. So, can anyone tell me if my worries are > > > unfounded, or if there's any way to ensure the behavior I want? I could > > > change the readIORef to an atomicModifyIORef, which should issue an > > mfence, > > > but that seems a bit heavy-handed as just a read fence would be > > sufficient > > > (although even that seems more than necessary). > > > > > > Thanks, > > > John L. > > From ezyang at mit.edu Tue Dec 31 14:45:03 2013 From: ezyang at mit.edu (Edward Z. Yang) Date: Tue, 31 Dec 2013 22:45:03 +0800 Subject: memory ordering In-Reply-To: <1388496939-sup-1821@sabre> References: <1388409528-sup-9632@sabre> <1388496939-sup-1821@sabre> Message-ID: <1388499948-sup-1713@sabre> > Second, the optimizer is a bit more conservative when it comes to > primop calls (internally referred to as "unsafe foreign calls") Sorry, I need to correct myself here. Foreign primops, and most out-of-line primops, compile into jumps which end basic blocks, which constitute hard boundaries since we don't do really do inter-block optimization. Unsafe foreign calls are generally reserved for function calls which use the C calling convention; primops manage the return convention themselves. Edward From carter.schonwald at gmail.com Tue Dec 31 15:12:06 2013 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Tue, 31 Dec 2013 10:12:06 -0500 Subject: memory ordering In-Reply-To: <1388496939-sup-1821@sabre> References: <1388409528-sup-9632@sabre> <1388496939-sup-1821@sabre> Message-ID: I suspect it's not by design, because there's certainly plans to make them inline primops, and the reordering issue of the cmm optimizer hasn't come up in the design discussion previously. (And I should add those notes to the associated tickets) On Tuesday, December 31, 2013, Edward Z. Yang wrote: > I was thinking about my response, and realized there was one major > misleading thing in my description. The load reordering I described > applies to load instructions in C-- proper, i.e. things that show up > in the C-- dup as: > > W_ x = I64[...addr...] > > Reads to IORefs and reads to vectors get compiled inline (as they > eventually translate into inline primops), so my admonitions are > applicable. > > However, the story with *foreign primops* (which is how loadLoadBarrier > in atomic-primops is defined, how you might imagine defining a custom > read function as a primop) is a little different. First, what does a > call to an foreign primop compile into? It is *not* inlined, so it will > eventually get compiled into a jump (this could be a problem if you're > really trying to squeeze out performance!) Second, the optimizer is a > bit more conservative when it comes to primop calls (internally referred > to as "unsafe foreign calls"); at the moment, the optimizer assumes > these foreign calls clobber heap memory, so we *automatically* will not > push loads/stores beyond this boundary. (NB: We reserve the right to > change this in the future!) > > This is probably why atomic-primops, as it is written today, seems to > work OK, even in the presence of the optimizer. But I also have a hard > time believing it gives the speedups you want, due to the current > design. (CC'd Ryan Newton, because I would love to be wrong here, and > maybe he can correct me on this note.) > > Cheers, > Edward > > P.S. loadLoadBarrier compiles to a no-op on x86 architectures, but > because it's not inlined I think you will still end up with a jump (LLVM > might be able to eliminate it). > > Excerpts from John Lato's message of 2013-12-31 03:01:58 +0800: > > Hi Edward, > > > > Thanks very much for this reply, it answers a lot of questions I'd had. > > I'd hoped that ordering would be preserved through C--, but c'est la > vie. > > Optimizing compilers are ever the bane of concurrent algorithms! > > > > stg/SMP.h does define a loadLoadBarrier, which is exposed in Ryan > Newton's > > atomic-primops package. From the docs, I think that's a general read > > barrier, and should do what I want. Assuming it works properly, of > course. > > If I'm lucky it might even be optimized out. > > > > Thanks, > > John > > > > On Mon, Dec 30, 2013 at 6:04 AM, Edward Z. Yang wrote: > > > > > Hello John, > > > > > > Here are some prior discussions (which I will attempt to summarize > > > below): > > > > > > http://www.haskell.org/pipermail/haskell-cafe/2011-May/091878.html > > > > http://www.haskell.org/pipermail/haskell-prime/2006-April/001237.html > > > > http://www.haskell.org/pipermail/haskell-prime/2006-March/001079.html > > > > > > The guarantees that Haskell and GHC give in this area are hand-wavy at > > > best; at the moment, I don't think Haskell or GHC have a formal memory > > > model?this seems to be an open research problem. (Unfortunately, AFAICT > > > all the researchers working on relaxed memory models have their hands > > > full with things like C++ :-) > > > > > > If you want to go ahead and build something that /just/ works for a > > > /specific version/ of GHC, you will need to answer this question > > > separately for every phase of the compiler. For Core and STG, monads > > > will preserve ordering, so there is no trouble. However, for C--, we > > > will almost certainly apply optimizations which reorder reads (look at > > > CmmSink.hs). To properly support your algorithm, you will have to add > > > some new read barrier mach-ops, and teach the optimizer to respect > them. > > > (This could be fiendishly subtle; it might be better to give C-- a > > > memory model first.) These mach-ops would then translate into > > > appropriate arch-specific assembly or LLVM instructions, preserving > > > the guarantees further. > > > > > > This is not related to your original question, but the situation is a > > > bit better with regards to reordering stores: we have a WriteBarrier > > > MachOp, which in principle, prevents store reordering. In practice, we > > > don't seem to actually have any C-- optimizations that reorder stores. > > > So, at least you can assume these will work OK! > > > > > > Hope this helps (and is not too inaccurate), > > > Edward > > > > > > Excerpts from John Lato's message of 2013-12-20 09:36:11 +0800: > > > > Hello, > > > > > > > > I'm working on a lock-free algorithm that's meant to be used in a > > > > concurrent setting, and I've run into a possible issue. > > > > > > > > The crux of the matter is that a particular function needs to > perform the > > > > following: > > > > > > > > > x <- MVector.read vec ix > > > > > position <- readIORef posRef > > > > > > > > and the algorithm is only safe if these two reads are not reordered > (both > > > > the vector and IORef are written to by other threads). > > > > > > > > My concern is, according to standard Haskell semantics this should be > > > safe, > > > > as IO sequencing should guarantee that the reads happen in-order. Of > > > > course this also relies upon the architecture's memory model, but x86 > > > also > > > > guarantees that reads happen in order. However doubts remain; I do > not > > > > have confidence that the code generator will handle this properly. > In > > > > particular, LLVM may freely re-order loads of NotAtomic and Unordered > > > > values. > > > > > > > > The one hope I have is that ghc will preserve IO semantics through > the > > > > entire pipeline. This > see_______________________________________________ > Glasgow-haskell-users mailing list > Glasgow-haskell-users at haskell.org > http://www.haskell.org/mailman/listinfo/glasgow-haskell-users > -------------- next part -------------- An HTML attachment was scrubbed... URL: