From merijn at inconsistent.nl Mon Sep 1 21:41:33 2014 From: merijn at inconsistent.nl (Merijn Verstraaten) Date: Mon, 1 Sep 2014 14:41:33 -0700 Subject: PROPOSAL: Make Data.Type.Bool.If polykinded Message-ID: <83E4E7CC-3488-4ED0-BDB3-1CDF408187FA@inconsistent.nl> Ola! Currently we have: type family If cond tru fls where If True tru fls = tru If False tru fls = fls Unfortunately, this appears to turned into a monomorphicly kinded type family by GHC, which means it?s impossible to do foo :: If cond () (?Condition does not hold? ~ ??) => Foo -> Bar or similar fancy constraints. I hereby propose altering If to: type family If (cond :: Bool) (tru :: k) (fls :: k) :: k where If True tru fls = tru If False tru fls = fls Allowing it to work with kinds other than *. Discussion period: 2 weeks? Seems like a minor change. Cheers, Merijn -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 801 bytes Desc: Message signed with OpenPGP using GPGMail URL: From ollie at ocharles.org.uk Tue Sep 2 06:11:58 2014 From: ollie at ocharles.org.uk (Oliver Charles) Date: Tue, 2 Sep 2014 07:11:58 +0100 Subject: PROPOSAL: Make Data.Type.Bool.If polykinded In-Reply-To: <83E4E7CC-3488-4ED0-BDB3-1CDF408187FA@inconsistent.nl> References: <83E4E7CC-3488-4ED0-BDB3-1CDF408187FA@inconsistent.nl> Message-ID: +1 - seems natural to me, and I can certainly see myself expecting it to be just that in the near future. - ocharles On Mon, Sep 1, 2014 at 10:41 PM, Merijn Verstraaten wrote: > Ola! > > Currently we have: > > type family If cond tru fls where > If True tru fls = tru > If False tru fls = fls > > Unfortunately, this appears to turned into a monomorphicly kinded type > family by GHC, which means it?s impossible to do > > foo :: If cond () (?Condition does not hold? ~ ??) => Foo -> Bar > > or similar fancy constraints. > > I hereby propose altering If to: > > type family If (cond :: Bool) (tru :: k) (fls :: k) :: k where > If True tru fls = tru > If False tru fls = fls > > Allowing it to work with kinds other than *. > > Discussion period: 2 weeks? Seems like a minor change. > > Cheers, > Merijn > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From eir at cis.upenn.edu Tue Sep 2 08:20:36 2014 From: eir at cis.upenn.edu (Richard Eisenberg) Date: Tue, 2 Sep 2014 10:20:36 +0200 Subject: PROPOSAL: Make Data.Type.Bool.If polykinded In-Reply-To: <83E4E7CC-3488-4ED0-BDB3-1CDF408187FA@inconsistent.nl> References: <83E4E7CC-3488-4ED0-BDB3-1CDF408187FA@inconsistent.nl> Message-ID: Hi Merijn, I believe that `If` is already the way you want: ?> :k If If :: Bool -> k -> k -> k The problem in your code is that GHC is a little... er... unprincipled about the kind of `()`. It basically assumes that `()` is of kind `*` unless it is very, absolutely, abundantly obvious that it should have kind `Constraint`. Your code is not abundantly obvious enough in this regard. If you say `If cond (() :: Constraint) (...) => ...`, I believe your code will work. Does this in fact work for you? Richard On Sep 1, 2014, at 11:41 PM, Merijn Verstraaten wrote: > Ola! > > Currently we have: > > type family If cond tru fls where > If True tru fls = tru > If False tru fls = fls > > Unfortunately, this appears to turned into a monomorphicly kinded type family by GHC, which means it?s impossible to do > > foo :: If cond () (?Condition does not hold? ~ ??) => Foo -> Bar > > or similar fancy constraints. > > I hereby propose altering If to: > > type family If (cond :: Bool) (tru :: k) (fls :: k) :: k where > If True tru fls = tru > If False tru fls = fls > > Allowing it to work with kinds other than *. > > Discussion period: 2 weeks? Seems like a minor change. > > Cheers, > Merijn > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries From ganesh at earth.li Tue Sep 2 21:24:25 2014 From: ganesh at earth.li (Ganesh Sittampalam) Date: Tue, 02 Sep 2014 22:24:25 +0100 Subject: HTTP package - supported GHC versions Message-ID: <54063589.8020503@earth.li> Hi, The HTTP package supports a whole load of old GHCs - the current version should actually work with GHC 6.10. For future releases I plan to drop most of these. Any opinions about how far back it should support? I'm thinking restricting it to either 7.4+ or 7.6+, but I'm open to keeping support for older versions too if there's a real need. Cheers, Ganesh From johan.tibell at gmail.com Wed Sep 3 07:27:47 2014 From: johan.tibell at gmail.com (Johan Tibell) Date: Wed, 3 Sep 2014 09:27:47 +0200 Subject: HTTP package - supported GHC versions In-Reply-To: <54063589.8020503@earth.li> References: <54063589.8020503@earth.li> Message-ID: For the core libraries we typically support the latest 3 major GHC release, so back to 7.4 right now. On Sep 2, 2014 11:24 PM, "Ganesh Sittampalam" wrote: > Hi, > > The HTTP package supports a whole load of old GHCs - the current version > should actually work with GHC 6.10. > > For future releases I plan to drop most of these. Any opinions about how > far back it should support? > > I'm thinking restricting it to either 7.4+ or 7.6+, but I'm open to > keeping support for older versions too if there's a real need. > > Cheers, > > Ganesh > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hvr at gnu.org Wed Sep 3 07:51:36 2014 From: hvr at gnu.org (Herbert Valerio Riedel) Date: Wed, 03 Sep 2014 09:51:36 +0200 Subject: HTTP package - supported GHC versions In-Reply-To: <54063589.8020503@earth.li> (Ganesh Sittampalam's message of "Tue, 02 Sep 2014 22:24:25 +0100") References: <54063589.8020503@earth.li> Message-ID: <87ppfd3zw7.fsf@gnu.org> On 2014-09-02 at 23:24:25 +0200, Ganesh Sittampalam wrote: [...] > For future releases I plan to drop most of these. Any opinions about how > far back it should support? > > I'm thinking restricting it to either 7.4+ or 7.6+, but I'm open to > keeping support for older versions too if there's a real need. Personally, I think supporting GHC 7.0+ is a natural boundary, as GHC 7.0.1 was the first to support Haskell2010. Are there any specific GHC 7.4+ features you want to use, or any other inconveniences (other than keeping an ghc-7.0.4 entry in the travis.yml file) that would increase the cost to keep supporting GHC 7.0.x? Cheers, hvr From johan.tibell at gmail.com Wed Sep 3 08:25:39 2014 From: johan.tibell at gmail.com (Johan Tibell) Date: Wed, 3 Sep 2014 10:25:39 +0200 Subject: HTTP package - supported GHC versions In-Reply-To: <87ppfd3zw7.fsf@gnu.org> References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> Message-ID: On Wed, Sep 3, 2014 at 9:51 AM, Herbert Valerio Riedel wrote: > Are there any specific GHC 7.4+ features you want to use, or any other > inconveniences (other than keeping an ghc-7.0.4 entry in the travis.yml > file) that would increase the cost to keep supporting GHC 7.0.x? > I don't know what the case is for HTTP, but in libraries that I maintain I'm typically able to remove a bunch of ifdefs every time I raise the minimum bar. Now, if we could only stop making breaking changes in GHC/base all the time... -------------- next part -------------- An HTML attachment was scrubbed... URL: From ganesh at earth.li Wed Sep 3 12:25:39 2014 From: ganesh at earth.li (Ganesh Sittampalam) Date: Wed, 03 Sep 2014 13:25:39 +0100 Subject: HTTP package - supported GHC versions In-Reply-To: <87ppfd3zw7.fsf@gnu.org> References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> Message-ID: <540708C3.1090900@earth.li> On 03/09/2014 08:51, Herbert Valerio Riedel wrote: > On 2014-09-02 at 23:24:25 +0200, Ganesh Sittampalam wrote: > > [...] > >> For future releases I plan to drop most of these. Any opinions about how >> far back it should support? >> >> I'm thinking restricting it to either 7.4+ or 7.6+, but I'm open to >> keeping support for older versions too if there's a real need. > > > Personally, I think supporting GHC 7.0+ is a natural boundary, as GHC > 7.0.1 was the first to support Haskell2010. > > Are there any specific GHC 7.4+ features you want to use, or any other > inconveniences (other than keeping an ghc-7.0.4 entry in the travis.yml > file) that would increase the cost to keep supporting GHC 7.0.x? The main burden is the testing overhead. Travis is nice to have but doesn't buy me that much as it doesn't build or run the tests. I'm not aware of any specific GHC 7.4+ features. However the test harness partially depends on warp which I couldn't get to build with GHC<=7.0, so needs an extra flag to disable those tests which it'd be nice to clean out. Generally I find that the older the GHC, the more likely it is that the dependencies will be difficult and require hardcoded constraints in the test script, though GHC 7.0 isn't currently causing any problems there. More generally I'm not too keen on having a lower bound that is "stuck", rather than moving forwards in a routine fashion as new GHC and Haskell Platform releases appear. So I like the "three versions" rule and I don't like "the first Haskell2010-supporting GHC onwards". All that said I do like the general idea of supporting a wide range of GHCs with a low-level library like this and I'm happy to do so if there's some plausible value in it. Cheers, Ganesh From johan.tibell at gmail.com Wed Sep 3 12:37:28 2014 From: johan.tibell at gmail.com (Johan Tibell) Date: Wed, 3 Sep 2014 14:37:28 +0200 Subject: HTTP package - supported GHC versions In-Reply-To: <540708C3.1090900@earth.li> References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> <540708C3.1090900@earth.li> Message-ID: On Wed, Sep 3, 2014 at 2:25 PM, Ganesh Sittampalam wrote: > The main burden is the testing overhead. Travis is nice to have but > doesn't buy me that much as it doesn't build or run the tests. > If I were you I would try to fix this issue, as it saves you a lot of time in the long run. -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Wed Sep 3 13:37:10 2014 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Wed, 3 Sep 2014 15:37:10 +0200 Subject: HTTP package - supported GHC versions In-Reply-To: References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> <540708C3.1090900@earth.li> Message-ID: yeah, its very very easy (and rewarding) to get travis to build/run tests, if you need help let us know! On Wed, Sep 3, 2014 at 2:37 PM, Johan Tibell wrote: > On Wed, Sep 3, 2014 at 2:25 PM, Ganesh Sittampalam > wrote: > >> The main burden is the testing overhead. Travis is nice to have but >> doesn't buy me that much as it doesn't build or run the tests. >> > > If I were you I would try to fix this issue, as it saves you a lot of time > in the long run. > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ganesh at earth.li Wed Sep 3 16:35:22 2014 From: ganesh at earth.li (Ganesh Sittampalam) Date: Wed, 03 Sep 2014 17:35:22 +0100 Subject: HTTP package - supported GHC versions In-Reply-To: References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> <540708C3.1090900@earth.li> Message-ID: <5407434A.3090308@earth.li> I don't really know much about travis. Johan wrote the config for the HTTP package and then disabled the tests because cabal was failing: https://github.com/haskell/HTTP/commit/bbb2867c03a853ce70e1958adc8ddc5ce6bb2918 Perhaps that would be better now, but it does feel like a bit of a black box to me. On 03/09/2014 14:37, Carter Schonwald wrote: > yeah, its very very easy (and rewarding) to get travis to build/run > tests, if you need help let us know! > > > > On Wed, Sep 3, 2014 at 2:37 PM, Johan Tibell > wrote: > > On Wed, Sep 3, 2014 at 2:25 PM, Ganesh Sittampalam > wrote: > > The main burden is the testing overhead. Travis is nice to have but > doesn't buy me that much as it doesn't build or run the tests. > > > If I were you I would try to fix this issue, as it saves you a lot > of time in the long run. > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > From hvr at gnu.org Wed Sep 3 17:09:53 2014 From: hvr at gnu.org (Herbert Valerio Riedel) Date: Wed, 03 Sep 2014 19:09:53 +0200 Subject: HTTP package - supported GHC versions In-Reply-To: <540708C3.1090900@earth.li> (Ganesh Sittampalam's message of "Wed, 03 Sep 2014 13:25:39 +0100") References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> <540708C3.1090900@earth.li> Message-ID: <878um04om6.fsf@gnu.org> Hi, On 2014-09-03 at 14:25:39 +0200, Ganesh Sittampalam wrote: [...] > More generally I'm not too keen on having a lower bound that is "stuck", > rather than moving forwards in a routine fashion as new GHC and Haskell > Platform releases appear. So I like the "three versions" rule and I > don't like "the first Haskell2010-supporting GHC onwards". > > All that said I do like the general idea of supporting a wide range of > GHCs with a low-level library like this and I'm happy to do so if > there's some plausible value in it. I don't have any strong opinion on "last three major GHC versions (with an associated HP release)" vs "the first Haskell2010-supporting GHC on-wards", either are fine with me, as even the latter one would typically span a 3-4 year window (which would be good enough for most Linux distros except certain "enterprise" ones...) However, one should just be aware that the lower your package is in the dependency graph, the larger the transitive avalanche effect of forcing newer lower-bounds on packages depending upon yours is. Otoh, at some point this is bound to happen anyway... Cheers, hvr From merijn at inconsistent.nl Wed Sep 3 17:16:53 2014 From: merijn at inconsistent.nl (Merijn Verstraaten) Date: Wed, 3 Sep 2014 10:16:53 -0700 Subject: PROPOSAL: Make Data.Type.Bool.If polykinded In-Reply-To: References: <83E4E7CC-3488-4ED0-BDB3-1CDF408187FA@inconsistent.nl> Message-ID: <8D77DDD4-46BF-4BA3-9D9B-2B987736D0E6@inconsistent.nl> Hi Richard, It would appear that you?re right! I had expected GHC to infer the kind Constraint for () from the second argument, rather than reporting an error, but adding an explicit annotation works. I would still say that warrants a clearer error message from GHC, but at least it works :) Cheers, Merijn On 02 Sep 2014, at 01:20 , Richard Eisenberg wrote: > Hi Merijn, > > I believe that `If` is already the way you want: > > ?> :k If > If :: Bool -> k -> k -> k > > The problem in your code is that GHC is a little... er... unprincipled about the kind of `()`. It basically assumes that `()` is of kind `*` unless it is very, absolutely, abundantly obvious that it should have kind `Constraint`. Your code is not abundantly obvious enough in this regard. If you say `If cond (() :: Constraint) (...) => ...`, I believe your code will work. > > Does this in fact work for you? > > Richard > > On Sep 1, 2014, at 11:41 PM, Merijn Verstraaten wrote: > >> Ola! >> >> Currently we have: >> >> type family If cond tru fls where >> If True tru fls = tru >> If False tru fls = fls >> >> Unfortunately, this appears to turned into a monomorphicly kinded type family by GHC, which means it?s impossible to do >> >> foo :: If cond () (?Condition does not hold? ~ ??) => Foo -> Bar >> >> or similar fancy constraints. >> >> I hereby propose altering If to: >> >> type family If (cond :: Bool) (tru :: k) (fls :: k) :: k where >> If True tru fls = tru >> If False tru fls = fls >> >> Allowing it to work with kinds other than *. >> >> Discussion period: 2 weeks? Seems like a minor change. >> >> Cheers, >> Merijn >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 801 bytes Desc: Message signed with OpenPGP using GPGMail URL: From eyal.lotem at gmail.com Wed Sep 3 20:56:58 2014 From: eyal.lotem at gmail.com (Eyal Lotem) Date: Wed, 3 Sep 2014 23:56:58 +0300 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception Message-ID: I'd like to propose a change in the behavior of Control.Exception to help guarantee cleanups are not accidentally lost. For example, bracket is defined as: bracket before after thing = mask $ \restore -> do a <- before r <- restore (thing a) `onException` after a _ <- after a return r This definition has a serious problem: "after a" (in either the exception handling case, or the ordinary case) can include interruptible actions which abort the cleanup. This means bracket does not in fact guarantee the cleanup occurs. For example: readMVar = bracket takeMVar putMVar -- If async exception occurs during putMVar, MVar is broken! withFile .. = bracket (openFile ..) hClose -- Async exception during hClose leaks the file handle! Interruptible actions during "before" are fine (as long as "before" handles them properly). Interruptible actions during "after" are virtually always a bug -- at best leaking a resource, and at worst breaking the program's invariants. I propose changing all the cleanup handlers to run under uninterruptibleMask, specifically: *bracket, bracketOnError, bracket_, catch, catchJust, finally, handle, handleJust, onException* should all simply wrap their exception/cancellation handler with uninterruptibleMask. The danger of a deadlock is minimal when compared with the virtually guaranteed buggy incorrect handling of async exceptions during cleanup. -- Eyal -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Wed Sep 3 23:45:48 2014 From: david.feuer at gmail.com (David Feuer) Date: Wed, 3 Sep 2014 19:45:48 -0400 Subject: Proposal: Add strictly filtering filterM' to Control.Monad In-Reply-To: References: Message-ID: We have filterM, that looks like this (although I'm trying to get it changed to use foldr): filterM :: (Monad m) => (a -> m Bool) -> [a] -> m [a] filterM _ [] = return [] filterM p (x:xs) = do flg <- p x ys <- filterM p xs return (if flg then x:ys else ys) This can cause a problem in some cases when used with IO, strict ST, or similar. In particular, it doesn't actually discard any elements of the list until all the predicate computations have run. Rather, it accumulates a chain of closures containing elements of the input and (possibly unevaluated) results of the (p x) computations. If the result of (p x) is usually False, so the input list is much longer than the output list, this can lead a program to run out of memory unnecessarily. This behavior cannot be avoided without changing semantics in some cases, as Dan Doel pointed out to me. In particular, a computation (p x) may run successfully to completion but produce a bottom value. PROPOSAL Add a function like this: filterM' :: (Monad m) => (a -> m Bool) -> [a] -> m [a] filterM' p = go [] where go _ [] = return [] go acc (x:xs) = do flq <- p x ys <- if flq then go (x:acc) xs else go acc xs return (reverse acc) This can be twisted somewhat harder into a right fold if we want: filterM' :: (Monad m) => (a -> m Bool) -> [a] -> m [a] filterM' p xs = foldr go return xs [] where go x r = \acc -> do flq <- p x ys <- if flq then r (x:acc) else r acc return (reverse acc) The advantage of this function is that instead of building a chain of closures proportional to the size of its *input* (but likely larger), it builds a list equal in size to its (possibly much smaller) *output*. -------------- next part -------------- An HTML attachment was scrubbed... URL: From greg at gregorycollins.net Thu Sep 4 00:01:43 2014 From: greg at gregorycollins.net (Gregory Collins) Date: Wed, 3 Sep 2014 17:01:43 -0700 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: Unless I'm mistaken, here the "mask" call inside bracket already makes sure you don't receive asynchronous exceptions unless you call a function that is interruptible (i.e. goes back into the runtime system). The hClose example you give doesn't fall in this category, as something inside the RTS needs to call "allowInterrupt" (or otherwise unmask exceptions) in order for async exceptions to be delivered. The "readMVar" example you give *does* have this issue (because putMVar does an implicit allowInterrupt) but in recent GHC readMVar has been redefined as a primop. The danger of deadlock is *not* minimal here, doing what you suggest will transform many valid programs (i.e. if you block on a "takeMVar" in the cleanup action) into ones that have unkillable orphan threads. G On Wed, Sep 3, 2014 at 1:56 PM, Eyal Lotem wrote: > I'd like to propose a change in the behavior of Control.Exception to help > guarantee cleanups are not accidentally lost. > > For example, bracket is defined as: > > bracket before after thing = mask $ \restore -> do a <- before r <- restore (thing a) `onException` after a _ <- after a return r > > This definition has a serious problem: "after a" (in either the exception > handling case, or the ordinary case) can include interruptible actions > which abort the cleanup. > > This means bracket does not in fact guarantee the cleanup occurs. > > For example: > > readMVar = bracket takeMVar putMVar -- If async exception occurs during > putMVar, MVar is broken! > > withFile .. = bracket (openFile ..) hClose -- Async exception during > hClose leaks the file handle! > > Interruptible actions during "before" are fine (as long as "before" > handles them properly). Interruptible actions during "after" are virtually > always a bug -- at best leaking a resource, and at worst breaking the > program's invariants. > > I propose changing all the cleanup handlers to run under > uninterruptibleMask, specifically: > > *bracket, bracketOnError, bracket_, catch, catchJust, finally, handle, > handleJust, onException* > > should all simply wrap their exception/cancellation handler with > uninterruptibleMask. > > The danger of a deadlock is minimal when compared with the virtually > guaranteed buggy incorrect handling of async exceptions during cleanup. > > -- > Eyal > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -- Gregory Collins -------------- next part -------------- An HTML attachment was scrubbed... URL: From merijn at inconsistent.nl Thu Sep 4 00:03:38 2014 From: merijn at inconsistent.nl (Merijn Verstraaten) Date: Wed, 3 Sep 2014 17:03:38 -0700 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: <46F7BACF-15F9-44E0-8558-FDBDB4CB3D1A@inconsistent.nl> Handles use MVar?s internally, therefore any operation on a Handle can potentially block, making the operation interruptible. FWIW, I?m +1 on this. It?s been a pain to get this correct in my code. Cheers, Merijn On 03 Sep 2014, at 17:01 , Gregory Collins wrote: > Unless I'm mistaken, here the "mask" call inside bracket already makes sure you don't receive asynchronous exceptions unless you call a function that is interruptible (i.e. goes back into the runtime system). The hClose example you give doesn't fall in this category, as something inside the RTS needs to call "allowInterrupt" (or otherwise unmask exceptions) in order for async exceptions to be delivered. The "readMVar" example you give *does* have this issue (because putMVar does an implicit allowInterrupt) but in recent GHC readMVar has been redefined as a primop. > > The danger of deadlock is *not* minimal here, doing what you suggest will transform many valid programs (i.e. if you block on a "takeMVar" in the cleanup action) into ones that have unkillable orphan threads. > > G > > > On Wed, Sep 3, 2014 at 1:56 PM, Eyal Lotem wrote: > I'd like to propose a change in the behavior of Control.Exception to help guarantee cleanups are not accidentally lost. > > For example, bracket is defined as: > bracket before after thing = > mask $ \restore -> do > a <- before > r <- restore (thing a) `onException` after a > _ <- after a > return r > This definition has a serious problem: "after a" (in either the exception handling case, or the ordinary case) can include interruptible actions which abort the cleanup. > > This means bracket does not in fact guarantee the cleanup occurs. > > For example: > > readMVar = bracket takeMVar putMVar -- If async exception occurs during putMVar, MVar is broken! > > withFile .. = bracket (openFile ..) hClose -- Async exception during hClose leaks the file handle! > > Interruptible actions during "before" are fine (as long as "before" handles them properly). Interruptible actions during "after" are virtually always a bug -- at best leaking a resource, and at worst breaking the program's invariants. > > I propose changing all the cleanup handlers to run under uninterruptibleMask, specifically: > > bracket, bracketOnError, bracket_, catch, catchJust, finally, handle, handleJust, onException > > should all simply wrap their exception/cancellation handler with uninterruptibleMask. > > The danger of a deadlock is minimal when compared with the virtually guaranteed buggy incorrect handling of async exceptions during cleanup. > > -- > Eyal > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > > > > -- > Gregory Collins > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 801 bytes Desc: Message signed with OpenPGP using GPGMail URL: From david.feuer at gmail.com Thu Sep 4 02:05:16 2014 From: david.feuer at gmail.com (David Feuer) Date: Wed, 3 Sep 2014 22:05:16 -0400 Subject: Proposal: Add strictly filtering filterM' to Control.Monad In-Reply-To: References: Message-ID: I wrote filterM' rather wrong. Sorry, folks. Here's a fix: > filterM' :: (Monad m) => (a -> m Bool) -> [a] -> m [a] > filterM' p = go [] > where > go acc [] = return (reverse acc) > go acc (x:xs) = > do > flq <- p x > if flq then go (x:acc) xs else go acc xs Or with foldr: > filterM' :: (Monad m) => (a -> m Bool) -> [a] -> m [a] > filterM' p xs = foldr go (return . reverse) xs [] > where > go x r = \acc -> do > flq <- p x > if flq then r (x:acc) else r acc From abela at chalmers.se Thu Sep 4 06:23:43 2014 From: abela at chalmers.se (Andreas Abel) Date: Thu, 4 Sep 2014 08:23:43 +0200 Subject: HTTP package - supported GHC versions In-Reply-To: <878um04om6.fsf@gnu.org> References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> <540708C3.1090900@earth.li> <878um04om6.fsf@gnu.org> Message-ID: <5408056F.80601@chalmers.se> If it is not too much of a hassle, rather support old versions of GHC. As mentioned below, there are long term support versions of Linux that package older GHCs. I was positively surprised that the latest QuickCheck still supports GHC 6.8. Agda aims to support GHC 7.0 for a while still (which keeps me from using some nice syntax extensions to Haskell). Cheers, Andreas On 03.09.2014 19:09, Herbert Valerio Riedel wrote: > Hi, > > On 2014-09-03 at 14:25:39 +0200, Ganesh Sittampalam wrote: > > [...] > >> More generally I'm not too keen on having a lower bound that is "stuck", >> rather than moving forwards in a routine fashion as new GHC and Haskell >> Platform releases appear. So I like the "three versions" rule and I >> don't like "the first Haskell2010-supporting GHC onwards". >> >> All that said I do like the general idea of supporting a wide range of >> GHCs with a low-level library like this and I'm happy to do so if >> there's some plausible value in it. > > I don't have any strong opinion on "last three major GHC versions (with > an associated HP release)" vs "the first Haskell2010-supporting GHC > on-wards", either are fine with me, as even the latter one would > typically span a 3-4 year window (which would be good enough for most > Linux distros except certain "enterprise" ones...) > > However, one should just be aware that the lower your package is in the > dependency graph, the larger the transitive avalanche effect of forcing > newer lower-bounds on packages depending upon yours is. Otoh, at some > point this is bound to happen anyway... > > Cheers, > hvr > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel at gu.se http://www2.tcs.ifi.lmu.de/~abel/ From eyal.lotem at gmail.com Thu Sep 4 07:29:08 2014 From: eyal.lotem at gmail.com (Eyal Lotem) Date: Thu, 4 Sep 2014 10:29:08 +0300 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: In addition to hClose, the majority of cleanup handlers in my programs turned out to be interruptible. Moreover, whether something is interruptible is unclear. You can easily add a putStrLn to a cleanup handler and now it is accidentally interruptible. I'd love to see examples of some code where interruptible cleanup handlers are not a bug. Every single one in my programs that I examined was a bug. Is withMVar also a primop? Because it's buggy in the same way as withFile currently is. The current situation is that virtually all uses of bracket in the entire Haskell ecosystem are subtle bugs. On Sep 4, 2014 3:01 AM, "Gregory Collins" wrote: > Unless I'm mistaken, here the "mask" call inside bracket already makes > sure you don't receive asynchronous exceptions unless you call a function > that is interruptible (i.e. goes back into the runtime system). The hClose > example you give doesn't fall in this category, as something inside the RTS > needs to call "allowInterrupt" (or otherwise unmask exceptions) in order > for async exceptions to be delivered. The "readMVar" example you give > *does* have this issue (because putMVar does an implicit allowInterrupt) > but in recent GHC readMVar has been redefined as a primop. > > The danger of deadlock is *not* minimal here, doing what you suggest will > transform many valid programs (i.e. if you block on a "takeMVar" in the > cleanup action) into ones that have unkillable orphan threads. > > G > > > On Wed, Sep 3, 2014 at 1:56 PM, Eyal Lotem wrote: > >> I'd like to propose a change in the behavior of Control.Exception to help >> guarantee cleanups are not accidentally lost. >> >> For example, bracket is defined as: >> >> bracket before after thing = mask $ \restore -> do a <- before r <- restore (thing a) `onException` after a _ <- after a return r >> >> This definition has a serious problem: "after a" (in either the exception >> handling case, or the ordinary case) can include interruptible actions >> which abort the cleanup. >> >> This means bracket does not in fact guarantee the cleanup occurs. >> >> For example: >> >> readMVar = bracket takeMVar putMVar -- If async exception occurs during >> putMVar, MVar is broken! >> >> withFile .. = bracket (openFile ..) hClose -- Async exception during >> hClose leaks the file handle! >> >> Interruptible actions during "before" are fine (as long as "before" >> handles them properly). Interruptible actions during "after" are virtually >> always a bug -- at best leaking a resource, and at worst breaking the >> program's invariants. >> >> I propose changing all the cleanup handlers to run under >> uninterruptibleMask, specifically: >> >> *bracket, bracketOnError, bracket_, catch, catchJust, finally, handle, >> handleJust, onException* >> >> should all simply wrap their exception/cancellation handler with >> uninterruptibleMask. >> >> The danger of a deadlock is minimal when compared with the virtually >> guaranteed buggy incorrect handling of async exceptions during cleanup. >> >> -- >> Eyal >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > > > -- > Gregory Collins > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwlato at gmail.com Thu Sep 4 07:46:53 2014 From: jwlato at gmail.com (John Lato) Date: Thu, 4 Sep 2014 00:46:53 -0700 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: Being a primop or not has nothing to do with whether an MVar operation is interruptible. What matters is whether or not the operation will block. withMVar (or readMVar in any incarnation) on an empty MVar is interruptible. If the MVar happened to be full, it's not interruptible. I agree this is a problem. I don't think the proposed solution is perfect, but I do think it's possibly better than the status quo. Perhaps the user should be required to use uninterruptibleMask_ on the cleanup action if necessary? I've long thought that using an interruptible operation in a cleanup handler is a programming error. John L. On Thu, Sep 4, 2014 at 12:29 AM, Eyal Lotem wrote: > In addition to hClose, the majority of cleanup handlers in my programs > turned out to be interruptible. Moreover, whether something is > interruptible is unclear. You can easily add a putStrLn to a cleanup > handler and now it is accidentally interruptible. > > I'd love to see examples of some code where interruptible cleanup handlers > are not a bug. > > Every single one in my programs that I examined was a bug. > > Is withMVar also a primop? Because it's buggy in the same way as withFile > currently is. > > The current situation is that virtually all uses of bracket in the entire > Haskell ecosystem are subtle bugs. > On Sep 4, 2014 3:01 AM, "Gregory Collins" wrote: > >> Unless I'm mistaken, here the "mask" call inside bracket already makes >> sure you don't receive asynchronous exceptions unless you call a function >> that is interruptible (i.e. goes back into the runtime system). The hClose >> example you give doesn't fall in this category, as something inside the RTS >> needs to call "allowInterrupt" (or otherwise unmask exceptions) in order >> for async exceptions to be delivered. The "readMVar" example you give >> *does* have this issue (because putMVar does an implicit allowInterrupt) >> but in recent GHC readMVar has been redefined as a primop. >> >> The danger of deadlock is *not* minimal here, doing what you suggest will >> transform many valid programs (i.e. if you block on a "takeMVar" in the >> cleanup action) into ones that have unkillable orphan threads. >> >> G >> >> >> On Wed, Sep 3, 2014 at 1:56 PM, Eyal Lotem wrote: >> >>> I'd like to propose a change in the behavior of Control.Exception to >>> help guarantee cleanups are not accidentally lost. >>> >>> For example, bracket is defined as: >>> >>> bracket before after thing = mask $ \restore -> do a <- before r <- restore (thing a) `onException` after a _ <- after a return r >>> >>> This definition has a serious problem: "after a" (in either the >>> exception handling case, or the ordinary case) can include interruptible >>> actions which abort the cleanup. >>> >>> This means bracket does not in fact guarantee the cleanup occurs. >>> >>> For example: >>> >>> readMVar = bracket takeMVar putMVar -- If async exception occurs during >>> putMVar, MVar is broken! >>> >>> withFile .. = bracket (openFile ..) hClose -- Async exception during >>> hClose leaks the file handle! >>> >>> Interruptible actions during "before" are fine (as long as "before" >>> handles them properly). Interruptible actions during "after" are virtually >>> always a bug -- at best leaking a resource, and at worst breaking the >>> program's invariants. >>> >>> I propose changing all the cleanup handlers to run under >>> uninterruptibleMask, specifically: >>> >>> *bracket, bracketOnError, bracket_, catch, catchJust, finally, handle, >>> handleJust, onException* >>> >>> should all simply wrap their exception/cancellation handler with >>> uninterruptibleMask. >>> >>> The danger of a deadlock is minimal when compared with the virtually >>> guaranteed buggy incorrect handling of async exceptions during cleanup. >>> >>> -- >>> Eyal >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >> >> >> -- >> Gregory Collins >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From abela at chalmers.se Thu Sep 4 08:59:34 2014 From: abela at chalmers.se (Andreas Abel) Date: Thu, 4 Sep 2014 10:59:34 +0200 Subject: Proposal: Add strictly filtering filterM' to Control.Monad In-Reply-To: References: Message-ID: <540829F6.9050808@chalmers.se> I am not sure whether to support your proposal, just want to point out that the original filterM can be generalized to Applicative, while you new filterM' seems to require a monad, since the result of checking the predicate on the first element influences the shape of the recursive call. import Control.Applicative consIf a b as = if b then a:as else as -- Applicative filter filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a] filterM p [] = pure [] filterM p (a:as) = consIf a <$> p a <*> filterM p as -- Monadic filter (D. Feuer) filterM' :: (Functor m, Monad m) => (a -> m Bool) -> [a] -> m [a] filterM' p xs = reverse <$> go [] xs where go acc [] = return acc go acc (a:as) = do b <- p a go (consIf a b acc) as Maybe to support your proposal you should add a compelling test case (i.e. crashes with filterM but succeeds with filterM'). Cheers, Andreas On 04.09.2014 04:05, David Feuer wrote: > I wrote filterM' rather wrong. Sorry, folks. Here's a fix: > >> filterM' :: (Monad m) => (a -> m Bool) -> [a] -> m [a] >> filterM' p = go [] >> where >> go acc [] = return (reverse acc) >> go acc (x:xs) = >> do >> flq <- p x >> if flq then go (x:acc) xs else go acc xs > > Or with foldr: > >> filterM' :: (Monad m) => (a -> m Bool) -> [a] -> m [a] >> filterM' p xs = foldr go (return . reverse) xs [] >> where >> go x r = \acc -> do >> flq <- p x >> if flq then r (x:acc) else r acc > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel at gu.se http://www2.tcs.ifi.lmu.de/~abel/ From eyal.lotem at gmail.com Thu Sep 4 14:01:32 2014 From: eyal.lotem at gmail.com (Eyal Lotem) Date: Thu, 4 Sep 2014 17:01:32 +0300 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: The problem with requiring the user to use uninterruptibleMask_ on their cleanup is how error-prone it is. If we examine some uses of bracket in the GHC repo: compiler/main/GhcMake.hs:992: let withSem sem = bracket_ (waitQSem sem) (*signalQSem sem*) *signalQSem is interruptible, this is a bug!* bracket_ (hSetBinaryMode h False) (*hSetBinaryMode h True*) Is the hSetBinaryMode operation interruptible? Is this a bug? Hard to tell! withExtendedLinkEnv new_env action = gbracket (liftIO $ extendLinkEnv new_env) (\_ -> *reset_old_env*) (\_ -> action) *reset_old_env *uses MVars so is probably interruptible, probably a bug. Lots of manual openFile/hClose duplications of withFile, which are all buggy due to *hClose* being interruptible. InteractiveUI.doLoad: gbracket (liftIO $ do hSetBuffering stdout LineBuffering hSetBuffering stderr LineBuffering) (\_ -> liftIO $ do* hSetBuffering stdout NoBuffering* hSetBuffering stderr NoBuffering) $ \_ -> do hSetBuffering uses hFlush and is thus interruptible(?). If many uses of bracket by the GHC developers are broken, is it not a clear indication that the default behavior is too error prone? If someone wants an interruptible cleanup handler (Very weird thing to want!) they can use "mask" and "onException" directly. Or variants of all the cleanup functions with an "interruptible" suffix can be exported too (bracketInterruptible, catchInterruptible, etc). Keeping the current behavior has only one benefit: Use cases that need to have interruptible cleanups. Does anyone have any such use case at all? I can't imagine one... On Thu, Sep 4, 2014 at 10:46 AM, John Lato wrote: > Being a primop or not has nothing to do with whether an MVar operation is > interruptible. What matters is whether or not the operation will block. > withMVar (or readMVar in any incarnation) on an empty MVar is > interruptible. If the MVar happened to be full, it's not interruptible. > > I agree this is a problem. I don't think the proposed solution is > perfect, but I do think it's possibly better than the status quo. Perhaps > the user should be required to use uninterruptibleMask_ on the cleanup > action if necessary? I've long thought that using an interruptible > operation in a cleanup handler is a programming error. > > John L. > > > On Thu, Sep 4, 2014 at 12:29 AM, Eyal Lotem wrote: > >> In addition to hClose, the majority of cleanup handlers in my programs >> turned out to be interruptible. Moreover, whether something is >> interruptible is unclear. You can easily add a putStrLn to a cleanup >> handler and now it is accidentally interruptible. >> >> I'd love to see examples of some code where interruptible cleanup >> handlers are not a bug. >> >> Every single one in my programs that I examined was a bug. >> >> Is withMVar also a primop? Because it's buggy in the same way as withFile >> currently is. >> >> The current situation is that virtually all uses of bracket in the entire >> Haskell ecosystem are subtle bugs. >> On Sep 4, 2014 3:01 AM, "Gregory Collins" >> wrote: >> >>> Unless I'm mistaken, here the "mask" call inside bracket already makes >>> sure you don't receive asynchronous exceptions unless you call a function >>> that is interruptible (i.e. goes back into the runtime system). The hClose >>> example you give doesn't fall in this category, as something inside the RTS >>> needs to call "allowInterrupt" (or otherwise unmask exceptions) in order >>> for async exceptions to be delivered. The "readMVar" example you give >>> *does* have this issue (because putMVar does an implicit allowInterrupt) >>> but in recent GHC readMVar has been redefined as a primop. >>> >>> The danger of deadlock is *not* minimal here, doing what you suggest >>> will transform many valid programs (i.e. if you block on a "takeMVar" in >>> the cleanup action) into ones that have unkillable orphan threads. >>> >>> G >>> >>> >>> On Wed, Sep 3, 2014 at 1:56 PM, Eyal Lotem wrote: >>> >>>> I'd like to propose a change in the behavior of Control.Exception to >>>> help guarantee cleanups are not accidentally lost. >>>> >>>> For example, bracket is defined as: >>>> >>>> bracket before after thing = mask $ \restore -> do a <- before r <- restore (thing a) `onException` after a _ <- after a return r >>>> >>>> This definition has a serious problem: "after a" (in either the >>>> exception handling case, or the ordinary case) can include interruptible >>>> actions which abort the cleanup. >>>> >>>> This means bracket does not in fact guarantee the cleanup occurs. >>>> >>>> For example: >>>> >>>> readMVar = bracket takeMVar putMVar -- If async exception occurs during >>>> putMVar, MVar is broken! >>>> >>>> withFile .. = bracket (openFile ..) hClose -- Async exception during >>>> hClose leaks the file handle! >>>> >>>> Interruptible actions during "before" are fine (as long as "before" >>>> handles them properly). Interruptible actions during "after" are virtually >>>> always a bug -- at best leaking a resource, and at worst breaking the >>>> program's invariants. >>>> >>>> I propose changing all the cleanup handlers to run under >>>> uninterruptibleMask, specifically: >>>> >>>> *bracket, bracketOnError, bracket_, catch, catchJust, finally, handle, >>>> handleJust, onException* >>>> >>>> should all simply wrap their exception/cancellation handler with >>>> uninterruptibleMask. >>>> >>>> The danger of a deadlock is minimal when compared with the virtually >>>> guaranteed buggy incorrect handling of async exceptions during cleanup. >>>> >>>> -- >>>> Eyal >>>> >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://www.haskell.org/mailman/listinfo/libraries >>>> >>>> >>> >>> >>> -- >>> Gregory Collins >>> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > -- Eyal -------------- next part -------------- An HTML attachment was scrubbed... URL: From roma at ro-che.info Thu Sep 4 14:46:29 2014 From: roma at ro-che.info (Roman Cheplyaka) Date: Thu, 4 Sep 2014 16:46:29 +0200 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: <20140904144629.GA21972@sniper> I find your arguments quite convincing. Count that as +1 from me. Roman -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: From emertens at gmail.com Thu Sep 4 15:16:14 2014 From: emertens at gmail.com (Eric Mertens) Date: Thu, 4 Sep 2014 08:16:14 -0700 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: It's hasn't been noted or I haven't noticed that putMVar is only interruptible when the MVar is full. This means that there isn't a problem in cases like withMVar because the MVar is empty due to the establishing takeMVar, and there is no leak. For hClose if you are closing the handle, presumably the contained MVar is full and there is no block and therefore no interruption. Only if another thread is actively using the handle and you are trying to close the handle out from under it is there potential for failure. In the exotic cases like this there is already a way to make an interruptible operation uninterruptible. I'm -1 until it becomes clear that it is actually an issue in common code. On Sep 4, 2014 12:47 AM, "John Lato" wrote: > Being a primop or not has nothing to do with whether an MVar operation is > interruptible. What matters is whether or not the operation will block. > withMVar (or readMVar in any incarnation) on an empty MVar is > interruptible. If the MVar happened to be full, it's not interruptible. > > I agree this is a problem. I don't think the proposed solution is > perfect, but I do think it's possibly better than the status quo. Perhaps > the user should be required to use uninterruptibleMask_ on the cleanup > action if necessary? I've long thought that using an interruptible > operation in a cleanup handler is a programming error. > > John L. > > > On Thu, Sep 4, 2014 at 12:29 AM, Eyal Lotem wrote: > >> In addition to hClose, the majority of cleanup handlers in my programs >> turned out to be interruptible. Moreover, whether something is >> interruptible is unclear. You can easily add a putStrLn to a cleanup >> handler and now it is accidentally interruptible. >> >> I'd love to see examples of some code where interruptible cleanup >> handlers are not a bug. >> >> Every single one in my programs that I examined was a bug. >> >> Is withMVar also a primop? Because it's buggy in the same way as withFile >> currently is. >> >> The current situation is that virtually all uses of bracket in the entire >> Haskell ecosystem are subtle bugs. >> On Sep 4, 2014 3:01 AM, "Gregory Collins" >> wrote: >> >>> Unless I'm mistaken, here the "mask" call inside bracket already makes >>> sure you don't receive asynchronous exceptions unless you call a function >>> that is interruptible (i.e. goes back into the runtime system). The hClose >>> example you give doesn't fall in this category, as something inside the RTS >>> needs to call "allowInterrupt" (or otherwise unmask exceptions) in order >>> for async exceptions to be delivered. The "readMVar" example you give >>> *does* have this issue (because putMVar does an implicit allowInterrupt) >>> but in recent GHC readMVar has been redefined as a primop. >>> >>> The danger of deadlock is *not* minimal here, doing what you suggest >>> will transform many valid programs (i.e. if you block on a "takeMVar" in >>> the cleanup action) into ones that have unkillable orphan threads. >>> >>> G >>> >>> >>> On Wed, Sep 3, 2014 at 1:56 PM, Eyal Lotem wrote: >>> >>>> I'd like to propose a change in the behavior of Control.Exception to >>>> help guarantee cleanups are not accidentally lost. >>>> >>>> For example, bracket is defined as: >>>> >>>> bracket before after thing = mask $ \restore -> do a <- before r <- restore (thing a) `onException` after a _ <- after a return r >>>> >>>> This definition has a serious problem: "after a" (in either the >>>> exception handling case, or the ordinary case) can include interruptible >>>> actions which abort the cleanup. >>>> >>>> This means bracket does not in fact guarantee the cleanup occurs. >>>> >>>> For example: >>>> >>>> readMVar = bracket takeMVar putMVar -- If async exception occurs during >>>> putMVar, MVar is broken! >>>> >>>> withFile .. = bracket (openFile ..) hClose -- Async exception during >>>> hClose leaks the file handle! >>>> >>>> Interruptible actions during "before" are fine (as long as "before" >>>> handles them properly). Interruptible actions during "after" are virtually >>>> always a bug -- at best leaking a resource, and at worst breaking the >>>> program's invariants. >>>> >>>> I propose changing all the cleanup handlers to run under >>>> uninterruptibleMask, specifically: >>>> >>>> *bracket, bracketOnError, bracket_, catch, catchJust, finally, handle, >>>> handleJust, onException* >>>> >>>> should all simply wrap their exception/cancellation handler with >>>> uninterruptibleMask. >>>> >>>> The danger of a deadlock is minimal when compared with the virtually >>>> guaranteed buggy incorrect handling of async exceptions during cleanup. >>>> >>>> -- >>>> Eyal >>>> >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://www.haskell.org/mailman/listinfo/libraries >>>> >>>> >>> >>> >>> -- >>> Gregory Collins >>> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From eyal.lotem at gmail.com Thu Sep 4 16:03:34 2014 From: eyal.lotem at gmail.com (Eyal Lotem) Date: Thu, 4 Sep 2014 19:03:34 +0300 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: On Thu, Sep 4, 2014 at 6:16 PM, Eric Mertens wrote: > It's hasn't been noted or I haven't noticed that putMVar is only > interruptible when the MVar is full. > > This means that there isn't a problem in cases like withMVar because the > MVar is empty due to the establishing takeMVar, and there is no leak. > It is plausible that another thread will put into the MVar in the mean time. > For hClose if you are closing the handle, presumably the contained MVar is > full and there is no block and therefore no interruption. Only if another > thread is actively using the handle and you are trying to close the handle > out from under it is there potential for failure. > Only in rare cases is this a bug, I agree. But rare bugs are in many ways even worse than frequent bugs. They are harder to debug, detect, etc. > In the exotic cases like this there is already a way to make an > interruptible operation uninterruptible. > > I'm -1 until it becomes clear that it is actually an issue in common code. > I think you're missing an important point. A) Cases that were not interruptible will remain the same. B) Cases that were interruptible *were bugs* and will be fixed. You're claiming that B is rare, but I don't think it is a valid argument against this change, because whether or not you agree B is frequent or not -- the change only affects B and not A. So the question is whether the change is desirable in this circumstance. As an empirical point: My project (buildsome) was very buggy with a lot of leaks and deadlocks, until I replaced my use of Control.Exception with a wrapper that properly used uninterruptible-mask. > On Sep 4, 2014 12:47 AM, "John Lato" wrote: > >> Being a primop or not has nothing to do with whether an MVar operation is >> interruptible. What matters is whether or not the operation will block. >> withMVar (or readMVar in any incarnation) on an empty MVar is >> interruptible. If the MVar happened to be full, it's not interruptible. >> >> I agree this is a problem. I don't think the proposed solution is >> perfect, but I do think it's possibly better than the status quo. Perhaps >> the user should be required to use uninterruptibleMask_ on the cleanup >> action if necessary? I've long thought that using an interruptible >> operation in a cleanup handler is a programming error. >> >> John L. >> >> >> On Thu, Sep 4, 2014 at 12:29 AM, Eyal Lotem wrote: >> >>> In addition to hClose, the majority of cleanup handlers in my programs >>> turned out to be interruptible. Moreover, whether something is >>> interruptible is unclear. You can easily add a putStrLn to a cleanup >>> handler and now it is accidentally interruptible. >>> >>> I'd love to see examples of some code where interruptible cleanup >>> handlers are not a bug. >>> >>> Every single one in my programs that I examined was a bug. >>> >>> Is withMVar also a primop? Because it's buggy in the same way as >>> withFile currently is. >>> >>> The current situation is that virtually all uses of bracket in the >>> entire Haskell ecosystem are subtle bugs. >>> On Sep 4, 2014 3:01 AM, "Gregory Collins" >>> wrote: >>> >>>> Unless I'm mistaken, here the "mask" call inside bracket already makes >>>> sure you don't receive asynchronous exceptions unless you call a function >>>> that is interruptible (i.e. goes back into the runtime system). The hClose >>>> example you give doesn't fall in this category, as something inside the RTS >>>> needs to call "allowInterrupt" (or otherwise unmask exceptions) in order >>>> for async exceptions to be delivered. The "readMVar" example you give >>>> *does* have this issue (because putMVar does an implicit allowInterrupt) >>>> but in recent GHC readMVar has been redefined as a primop. >>>> >>>> The danger of deadlock is *not* minimal here, doing what you suggest >>>> will transform many valid programs (i.e. if you block on a "takeMVar" in >>>> the cleanup action) into ones that have unkillable orphan threads. >>>> >>>> G >>>> >>>> >>>> On Wed, Sep 3, 2014 at 1:56 PM, Eyal Lotem >>>> wrote: >>>> >>>>> I'd like to propose a change in the behavior of Control.Exception to >>>>> help guarantee cleanups are not accidentally lost. >>>>> >>>>> For example, bracket is defined as: >>>>> >>>>> bracket before after thing = mask $ \restore -> do a <- before r <- restore (thing a) `onException` after a _ <- after a return r >>>>> >>>>> This definition has a serious problem: "after a" (in either the >>>>> exception handling case, or the ordinary case) can include interruptible >>>>> actions which abort the cleanup. >>>>> >>>>> This means bracket does not in fact guarantee the cleanup occurs. >>>>> >>>>> For example: >>>>> >>>>> readMVar = bracket takeMVar putMVar -- If async exception occurs >>>>> during putMVar, MVar is broken! >>>>> >>>>> withFile .. = bracket (openFile ..) hClose -- Async exception during >>>>> hClose leaks the file handle! >>>>> >>>>> Interruptible actions during "before" are fine (as long as "before" >>>>> handles them properly). Interruptible actions during "after" are virtually >>>>> always a bug -- at best leaking a resource, and at worst breaking the >>>>> program's invariants. >>>>> >>>>> I propose changing all the cleanup handlers to run under >>>>> uninterruptibleMask, specifically: >>>>> >>>>> *bracket, bracketOnError, bracket_, catch, catchJust, finally, handle, >>>>> handleJust, onException* >>>>> >>>>> should all simply wrap their exception/cancellation handler with >>>>> uninterruptibleMask. >>>>> >>>>> The danger of a deadlock is minimal when compared with the virtually >>>>> guaranteed buggy incorrect handling of async exceptions during cleanup. >>>>> >>>>> -- >>>>> Eyal >>>>> >>>>> _______________________________________________ >>>>> Libraries mailing list >>>>> Libraries at haskell.org >>>>> http://www.haskell.org/mailman/listinfo/libraries >>>>> >>>>> >>>> >>>> >>>> -- >>>> Gregory Collins >>>> >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -- Eyal -------------- next part -------------- An HTML attachment was scrubbed... URL: From spam at scientician.net Thu Sep 4 16:09:04 2014 From: spam at scientician.net (Bardur Arantsson) Date: Thu, 04 Sep 2014 18:09:04 +0200 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: On 2014-09-04 18:03, Eyal Lotem wrote: > On Thu, Sep 4, 2014 at 6:16 PM, Eric Mertens wrote: > [--snip--] >> I'm -1 until it becomes clear that it is actually an issue in common code. >> > I think you're missing an important point. > > A) Cases that were not interruptible will remain the same. > B) Cases that were interruptible *were bugs* and will be fixed. > > You're claiming that B is rare, but I don't think it is a valid argument > against this change, because whether or not you agree B is frequent or not > -- the change only affects B and not A. So the question is whether the > change is desirable in this circumstance. > I'm in *no* way an expert on the finer points of concurrency in Haskell, but if the above is true, then +1. Regards, From felipe.lessa at gmail.com Thu Sep 4 16:51:01 2014 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Thu, 04 Sep 2014 13:51:01 -0300 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: <54089875.6060207@gmail.com> On 04-09-2014 13:09, Bardur Arantsson wrote: > I'm in *no* way an expert on the finer points of concurrency in Haskell, > but if the above is true, then +1. My thoughts, exactly. Eyal's arguments look solid to me, I can't see any flaw, so +1 with the caveat that I'm not an expert here. Assuming he's right, there is a *lot* of broken Haskell code out there! -- Felipe. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From jwlato at gmail.com Thu Sep 4 23:28:43 2014 From: jwlato at gmail.com (John Lato) Date: Fri, 5 Sep 2014 07:28:43 +0800 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: I suspect the main reason someone would want an interruptible cleanup handler is because if the action blocks, it's the only way to kill the thread. I'm not sure how common this case is though. IMHO I think the real problem is that the current exception implementation is far too complex to reason about. Do other languages have this interruptible/uninterruptible distinction? If so, I've yet to encounter it. I'm starting to think that throwing an exception to a thread is the wrong way to kill it, and it should use something other than the exception mechanism. Then I think we could discard the notion of interruptible actions entirely. I guess count me as +0.5 for this proposal. John L. On Thu, Sep 4, 2014 at 10:01 PM, Eyal Lotem wrote: > The problem with requiring the user to use uninterruptibleMask_ on their > cleanup is how error-prone it is. > > If we examine some uses of bracket in the GHC repo: > > compiler/main/GhcMake.hs:992: let withSem sem = bracket_ (waitQSem > sem) (*signalQSem sem*) > *signalQSem is interruptible, this is a bug!* > > bracket_ (hSetBinaryMode h False) (*hSetBinaryMode h True*) > Is the hSetBinaryMode operation interruptible? Is this a bug? Hard to tell! > > withExtendedLinkEnv new_env action > = gbracket (liftIO $ extendLinkEnv new_env) > (\_ -> *reset_old_env*) > (\_ -> action) > > *reset_old_env *uses MVars so is probably interruptible, probably a bug. > > Lots of manual openFile/hClose duplications of withFile, which are all > buggy due to *hClose* being interruptible. > > InteractiveUI.doLoad: > gbracket (liftIO $ do hSetBuffering stdout LineBuffering > hSetBuffering stderr LineBuffering) > (\_ -> > liftIO $ do* hSetBuffering stdout NoBuffering* > hSetBuffering stderr NoBuffering) $ \_ -> do > > hSetBuffering uses hFlush and is thus interruptible(?). > > > If many uses of bracket by the GHC developers are broken, is it not a > clear indication that the default behavior is too error prone? > > If someone wants an interruptible cleanup handler (Very weird thing to > want!) they can use "mask" and "onException" directly. Or variants of all > the cleanup functions with an "interruptible" suffix can be exported too > (bracketInterruptible, catchInterruptible, etc). > > Keeping the current behavior has only one benefit: Use cases that need to > have interruptible cleanups. > Does anyone have any such use case at all? I can't imagine one... > > > On Thu, Sep 4, 2014 at 10:46 AM, John Lato wrote: > >> Being a primop or not has nothing to do with whether an MVar operation is >> interruptible. What matters is whether or not the operation will block. >> withMVar (or readMVar in any incarnation) on an empty MVar is >> interruptible. If the MVar happened to be full, it's not interruptible. >> >> I agree this is a problem. I don't think the proposed solution is >> perfect, but I do think it's possibly better than the status quo. Perhaps >> the user should be required to use uninterruptibleMask_ on the cleanup >> action if necessary? I've long thought that using an interruptible >> operation in a cleanup handler is a programming error. >> >> John L. >> >> >> On Thu, Sep 4, 2014 at 12:29 AM, Eyal Lotem wrote: >> >>> In addition to hClose, the majority of cleanup handlers in my programs >>> turned out to be interruptible. Moreover, whether something is >>> interruptible is unclear. You can easily add a putStrLn to a cleanup >>> handler and now it is accidentally interruptible. >>> >>> I'd love to see examples of some code where interruptible cleanup >>> handlers are not a bug. >>> >>> Every single one in my programs that I examined was a bug. >>> >>> Is withMVar also a primop? Because it's buggy in the same way as >>> withFile currently is. >>> >>> The current situation is that virtually all uses of bracket in the >>> entire Haskell ecosystem are subtle bugs. >>> On Sep 4, 2014 3:01 AM, "Gregory Collins" >>> wrote: >>> >>>> Unless I'm mistaken, here the "mask" call inside bracket already makes >>>> sure you don't receive asynchronous exceptions unless you call a function >>>> that is interruptible (i.e. goes back into the runtime system). The hClose >>>> example you give doesn't fall in this category, as something inside the RTS >>>> needs to call "allowInterrupt" (or otherwise unmask exceptions) in order >>>> for async exceptions to be delivered. The "readMVar" example you give >>>> *does* have this issue (because putMVar does an implicit allowInterrupt) >>>> but in recent GHC readMVar has been redefined as a primop. >>>> >>>> The danger of deadlock is *not* minimal here, doing what you suggest >>>> will transform many valid programs (i.e. if you block on a "takeMVar" in >>>> the cleanup action) into ones that have unkillable orphan threads. >>>> >>>> G >>>> >>>> >>>> On Wed, Sep 3, 2014 at 1:56 PM, Eyal Lotem >>>> wrote: >>>> >>>>> I'd like to propose a change in the behavior of Control.Exception to >>>>> help guarantee cleanups are not accidentally lost. >>>>> >>>>> For example, bracket is defined as: >>>>> >>>>> bracket before after thing = mask $ \restore -> do a <- before r <- restore (thing a) `onException` after a _ <- after a return r >>>>> >>>>> This definition has a serious problem: "after a" (in either the >>>>> exception handling case, or the ordinary case) can include interruptible >>>>> actions which abort the cleanup. >>>>> >>>>> This means bracket does not in fact guarantee the cleanup occurs. >>>>> >>>>> For example: >>>>> >>>>> readMVar = bracket takeMVar putMVar -- If async exception occurs >>>>> during putMVar, MVar is broken! >>>>> >>>>> withFile .. = bracket (openFile ..) hClose -- Async exception during >>>>> hClose leaks the file handle! >>>>> >>>>> Interruptible actions during "before" are fine (as long as "before" >>>>> handles them properly). Interruptible actions during "after" are virtually >>>>> always a bug -- at best leaking a resource, and at worst breaking the >>>>> program's invariants. >>>>> >>>>> I propose changing all the cleanup handlers to run under >>>>> uninterruptibleMask, specifically: >>>>> >>>>> *bracket, bracketOnError, bracket_, catch, catchJust, finally, handle, >>>>> handleJust, onException* >>>>> >>>>> should all simply wrap their exception/cancellation handler with >>>>> uninterruptibleMask. >>>>> >>>>> The danger of a deadlock is minimal when compared with the virtually >>>>> guaranteed buggy incorrect handling of async exceptions during cleanup. >>>>> >>>>> -- >>>>> Eyal >>>>> >>>>> _______________________________________________ >>>>> Libraries mailing list >>>>> Libraries at haskell.org >>>>> http://www.haskell.org/mailman/listinfo/libraries >>>>> >>>>> >>>> >>>> >>>> -- >>>> Gregory Collins >>>> >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >> > > > -- > Eyal > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hvr at gnu.org Fri Sep 5 08:37:07 2014 From: hvr at gnu.org (Herbert Valerio Riedel) Date: Fri, 05 Sep 2014 10:37:07 +0200 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: (Eyal Lotem's message of "Wed, 3 Sep 2014 23:56:58 +0300") References: Message-ID: <874mwm8nv0.fsf@gnu.org> Hello, I'm forwarding this on behalf of Edsko: -------------------- Start of forwarded message -------------------- [...] Hi Herbert, > ...and I'd like to point your attention to yet another related proposal > that came in yesterday: > > Subject: Proposal: Use uninterruptibleMask for cleanup actions in > Control.Exception > > http://thread.gmane.org/gmane.comp.lang.haskell.libraries/22775 Hmmm, I thought I was subscribed to libraries at . It seems I wasn?t. I subscribed earlier today but haven?t got the confirmation email yetI (?). Perhaps you can forward my reply for now? Anyhow, I?m not convinced about this proposal. uninterruptibleMask is rather crude. It would be one thing to block, say, timeout signals during resource cleanup (perhaps), but uninterruptibleMask blocks _all_ asynchronous exceptions, including stack overflow and heap overflow. I don?t think that the _default_ behaviour of bracket should be to disable those. Note also that in the bracket takeMVar putMVar example, the putMVar is _NOT_ interruptible. By definition, putMVar is interruptible _only_ if the resource is not available. Since the takeMVar succeeded, the MVar must be empty at the time of the putMVar and hence it cannot be interrupted. (This is assuming of course that there are no putMVars in the body of the bracket, but if you?re doing that, you have bigger problems..). Incidentally, if that behavior of putMVar is not in fact the case, then that is a bug in putMVar, not in bracket. The hClose example ironically _is_ an example, though it doesn?t look like one ? Merijn is right, it uses an MVar under the hood and in fact it does a withMVar, which is interruptible, of course ? in case somebody else happens to have the file handle at that time. But again, I?m not sure what the right answer is. I sort of feel that these file operations should _not_ be interruptible. The fact that they use MVars under the hood makes them so, but perhaps that could be considered a bug (and they should do some uninterruptibleMasking of their own) ? certainly, as far as I know, it?s nowhere actually _documented_ that these operations are interruptible and most people don?t think of them as such. I?m not sure to be honest. I would like Simon Marlow?s opinion here. But my feeling right now is that I?d vote against this, but to try and make sure that the operations we use in cleanup handlers are, in fact, not interruptible. -E -------------------- End of forwarded message -------------------- From eyal.lotem at gmail.com Fri Sep 5 09:12:18 2014 From: eyal.lotem at gmail.com (Eyal Lotem) Date: Fri, 5 Sep 2014 12:12:18 +0300 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: <874mwm8nv0.fsf@gnu.org> References: <874mwm8nv0.fsf@gnu.org> Message-ID: On Fri, Sep 5, 2014 at 11:37 AM, Herbert Valerio Riedel wrote: > Hello, > > I'm forwarding this on behalf of Edsko: > > -------------------- Start of forwarded message -------------------- > [...] > > Hi Herbert, > > > ...and I'd like to point your attention to yet another related proposal > > that came in yesterday: > > > > Subject: Proposal: Use uninterruptibleMask for cleanup actions in > > Control.Exception > > > > http://thread.gmane.org/gmane.comp.lang.haskell.libraries/22775 > > Hmmm, I thought I was subscribed to libraries at . It seems I wasn?t. I > subscribed earlier today but haven?t got the confirmation email yetI > (?). Perhaps you can forward my reply for now? > > Anyhow, I?m not convinced about this proposal. uninterruptibleMask is > rather crude. It would be one thing to block, say, timeout signals > during resource cleanup (perhaps), but uninterruptibleMask blocks _all_ > asynchronous exceptions, including stack overflow and heap overflow. I > don?t think that the _default_ behaviour of bracket should be to disable > those. > I just tested a little program that stack-overflows within an uninterruptibleMask_. The exception doesn't seem to be blocked. Can you(he?) give an example of the actual problem? > Note also that in the > > bracket takeMVar putMVar > > example, the putMVar is _NOT_ interruptible. By definition, putMVar is > interruptible _only_ if the resource is not available. Since the > takeMVar succeeded, the MVar must be empty at the time of the putMVar > Of course not! Different threads may have putMVar during the bracket. Typical MVar use will not do this, but it's certainly a possible use case that is broken. I think the fact people are missing this bug is more evidence that this behavior is a problem. and hence it cannot be interrupted. (This is assuming of course that > there are no putMVars in the body of the bracket, but if you?re doing > that, you have bigger problems..). Incidentally, if that behavior of > putMVar is not in fact the case, then that is a bug in putMVar, not in > bracket. > > The hClose example ironically _is_ an example, though it doesn?t look > like one ? Merijn is right, it uses an MVar under the hood and in fact > it does a withMVar, which is interruptible, of course ? in case somebody > else happens to have the file handle at that time. But again, I?m not > sure what the right answer is. I sort of feel that these file operations > should _not_ be interruptible. The fact that they use MVars under the > hood makes them so, but perhaps that could be considered a bug (and they > should do some uninterruptibleMasking of their own) ? certainly, as far > as I know, it?s nowhere actually _documented_ that these operations are > interruptible and most people don?t think of them as such. > But this seems like a weird position to have. On the one hand, you are claiming that making the cleanup uninterruptible is too crude. On the other hand, you're claiming that all cleanup handlers that happen to be interruptible are a bug, each. These positions contradict. > > I?m not sure to be honest. I would like Simon Marlow?s opinion here. But > my feeling right now is that I?d vote against this, but to try and make > sure that the operations we use in cleanup handlers are, in fact, not > interruptible. > The question is what do you want to do with cleanup handlers that are still interruptible? I think the only valid solutions are: A) Mask them uninterruptible as I suggest B) Raise a runtime error (or at least a warning) that this is a bug that should be fixed by making sure that the cleanup handlers are not interruptible, manually. Leaving the current behavior is the worst of all worlds. > > -E > -------------------- End of forwarded message -------------------- > -- Eyal -------------- next part -------------- An HTML attachment was scrubbed... URL: From eyal.lotem at gmail.com Fri Sep 5 17:34:50 2014 From: eyal.lotem at gmail.com (Eyal Lotem) Date: Fri, 5 Sep 2014 20:34:50 +0300 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: <5409D931.1030503@gmail.com> References: <20140904144629.GA21972@sniper> <5409D931.1030503@gmail.com> Message-ID: Hey Simon, thanks for the reply! On Fri, Sep 5, 2014 at 6:39 PM, Simon Marlow wrote: > Eyal, thanks for bringing up this issue. It's been at the back of my mind > for a while, but I've never really thought through the issues and > consequences of changes. So this is a good opportunity to do that. You > point out (in another email in the thread) that: > > A) Cases that were not interruptible will remain the same. > B) Cases that were interruptible were bugs and will be fixed. > > However, > > C) Some bugs will turn into deadlocks (unkillable threads) > > Being able to recover from bugs is an important property in large > long-running systems. So this is a serious problem. Hence why I always > treat uninterruptibleMask with the deepest suspicion. > Recovering from various kinds of failures makes a lot of sense. But how can you recover from arbitrary invariants of the program being broken? For example, if you use a bracket on some semaphore monitoring a global resource. How do you recover from a bug of leaking semaphore tokens? Recovering from crashes of whole processes whose internal state can be recovered to a fresh, usable state, is a great feature. Recovering from thread crashes that share arbitrary mutable state with other threads is not practical, I believe. > Let's consider the case where we have an interruptible operation in the > handler, and divide it into two (er three): > > 1. it blocks for a short bounded amount of time. > 2. It blocks for a long time > 3. It blocks indefinitely > > These are all buggy, but in different ways. Only (1) is fixed by adding > uninterruptibleMask. (2) is "fixed", but in exchange for an unresponsive > thread - also undesirable. (3) was a bug in the application code, and > turns into a deadlock with uninterruptibleMask, which is undesirable. > I think that (1) is by far the most common and is very prevalent. I think 0-time interruptible (that can block but almost never do) operations are the most common cleanup handlers. For (2) and (3), we need to choose the lesser evil: A) Deadlocks and/or unresponsiveness B) Arbitrary invariants being broken and leaks In my experience, A tends to manifest exactly where the bug is, and is therefore easy to debug and mostly a "performance bug" . B tends to manifest as difficult to explain behavior elsewhere from where the bug actually is, and is usually a "correctness bug", which is almost always worse. Therefore, I think A is a far far lesser evil than B, when (2) and (3) are involved. I'd like to reemphasize that this change will almost always fix the problem completely since the most common case is (1), and in rare cases, it will convert B to A, which is also, IMO, very desirable. > This is as far as I've got thinking through the issues so far. I wonder > to what extent the programmer can and should mitigate these cases, and how > much we can help them. I don't want unkillable threads, even when caused > by buggy code. > Cheers, > Simon > > > On 04/09/2014 16:46, Roman Cheplyaka wrote: > >> I find your arguments quite convincing. Count that as +1 from me. >> >> Roman >> >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> -- Eyal -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Fri Sep 5 22:07:09 2014 From: david.feuer at gmail.com (David Feuer) Date: Fri, 5 Sep 2014 18:07:09 -0400 Subject: Formal proposal: replace Data.List.inits In-Reply-To: References: <53CBA0D4.2010500@plaimi.net> <20140819164654.GA18869@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> <20140819224234.GB18869@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> Message-ID: The problem I was seeing with initsQ2 was caused by a bad interaction of different things fusing badly. It seems relatively unlikely that the underlying issues with list fusion will be resolved by the next GHC release, so we need to decide what to do about that. Some options, from my favorite to my least favorite: 1. Use the fusing scanl', but mark inits NOINLINE. The proposed implementation wouldn't really wouldn't be such a hot fusion prospect in any case. The only interesting sort of fusion I see is (concat . inits), which we *could* implement with a special rule, but no one else seems to think it's worth the trouble. 2. Use a non-fusing scanl'. 3. Manually inline the scanl' and such, using what GHC compiles initsQ2 into instead of using initsQ2. On Sat, Aug 30, 2014 at 9:27 PM, David Feuer wrote: > What I'm seeing is very different from what you're seeing. In > particular, my tests with print $ sum $ concat $ inits [1..10000] > indicate that your initsT' function is much faster, and allocates much > less than, the initsQ version. Could you explain what your test was > doing? What version of GHC were you running them on? Another thing: I > also see the performance impact of using take' instead of take, but I > can't for the life of me understand why. Do you know? > > If others see similar results, I think we should scrap initsQ and use > your initsT'. > > On Tue, Aug 19, 2014 at 6:42 PM, Bertram Felgenhauer > wrote: > > David Feuer wrote: > >> I don't know why you're looking at initsHO, which is almost the same as > >> initsR but slightly slower. Have you looked at initsQ (preferably > >> implemented with scanl')? That's the one that fixes the bad cases. > > > > No, because I looked at the wrong part of your mail. Adding timings: > > > >> > - using only first elements of result lists: > >> > > >> > > sum' $ map head $ tail $ inits [1..10000] > >> > 10000 > >> > (5.38 secs, 5905331504 bytes) > >> > > sum' $ map head $ tail $ initsR [1..10000] > >> > 10000 > >> > (0.55 secs, 1203045184 bytes) > >> > > sum' $ map head $ tail $ initsHO [1..10000] > >> > 10000 > >> > (1.11 secs, 1205462216 bytes) > >> > > sum' $ map head $ tail $ initsT [1..10000] > >> > 10000 > >> > (0.01 secs, 7226208 bytes) > >> > > sum' $ map head $ tail $ initsT' [1..10000] > >> > 10000 > >> > (0.01 secs, 8119224 bytes) > >> sum' $ map head $ tail $ initsQ [1..10000] > > 10000 > > (0.01 secs, 7309616 bytes) > >> sum' $ map head $ tail $ initsQ' [1..10000] > > 10000 > > (0.01 secs, 8908320 bytes) > > > > All these results are pretty meaningless beyond demonstrating > > that initsT and initsQ are sufficiently lazy. > > > >> > > >> > - using whole result: > >> > > >> > > sum' $ map sum' $ tail $ inits [1..10000] > >> > 166716670000 > >> > (7.79 secs, 7900276296 bytes) > >> > > sum' $ map sum' $ tail $ initsR [1..10000] > >> > 166716670000 > >> > (1.35 secs, 2006560272 bytes) > >> > > sum' $ map sum' $ tail $ initsHO [1..10000] > >> > 166716670000 > >> > (1.93 secs, 2003170216 bytes) > >> > > sum' $ map sum' $ tail $ initsT [1..10000] > >> > 166716670000 > >> > (2.16 secs, 3603697344 bytes) > >> > > sum' $ map sum' $ tail $ initsT' [1..10000] > >> > 166716670000 > >> > (1.61 secs, 3603897320 bytes) > > > >> sum' $ map sum' $ tail $ initsQ [1..10000] > > 166716670000 > > (3.30 secs, 3194869384 bytes) > >> sum' $ map sum' $ tail $ initsQ' [1..10000] > > 166716670000 > > (3.26 secs, 3195015296 bytes) > > > > I've also run some criterion benchmarks, see the html files at > > > > http://int-e.eu/~bf3/haskell/inits/ > > > > (Is there a way to get criterion to split the summary table in > > its html output by groups?) > > > > Inits.hs contains the various inits implementations. > > inits.tar.gz contains everything. > > > > Interestingly, initsQ looks better than initsT in these benchmarks. > > > > Cheers, > > > > Bertram > > > > > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at joachim-breitner.de Sat Sep 6 17:28:35 2014 From: mail at joachim-breitner.de (Joachim Breitner) Date: Sat, 06 Sep 2014 19:28:35 +0200 Subject: Formal proposal: replace Data.List.inits In-Reply-To: References: <53CBA0D4.2010500@plaimi.net> <20140819164654.GA18869@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> <20140819224234.GB18869@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> Message-ID: <1410024515.2145.2.camel@joachim-breitner.de> Hi, Am Freitag, den 05.09.2014, 18:07 -0400 schrieb David Feuer: > The problem I was seeing with initsQ2 was caused by a bad interaction > of different things fusing badly. It seems relatively unlikely that > the underlying issues with list fusion will be resolved by the next > GHC release, so we need to decide what to do about that. Some options, > from my favorite to my least favorite: > > > 1. Use the fusing scanl', but mark inits NOINLINE. The proposed > implementation wouldn't really wouldn't be such a hot fusion prospect > in any case. The only interesting sort of fusion I see is (concat . > inits), which we *could* implement with a special rule, but no one > else seems to think it's worth the trouble. > This seems to be a good way forward. This way, we get a faster inits in, and can then consider the issue of fusing separately. Greetings, Joachim > -- Joachim ?nomeata? Breitner mail at joachim-breitner.de ? http://www.joachim-breitner.de/ Jabber: nomeata at joachim-breitner.de ? GPG-Key: 0xF0FBF51F Debian Developer: nomeata at debian.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: This is a digitally signed message part URL: From bertram.felgenhauer at googlemail.com Sat Sep 6 19:03:15 2014 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Sat, 6 Sep 2014 21:03:15 +0200 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: Message-ID: <20140906190315.GA28353@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> Eyal Lotem wrote: > The problem with requiring the user to use uninterruptibleMask_ on their > cleanup is how error-prone it is. > > If we examine some uses of bracket in the GHC repo: > > compiler/main/GhcMake.hs:992: let withSem sem = bracket_ (waitQSem > sem) (*signalQSem sem*) > *signalQSem is interruptible, this is a bug!* Not really, but signalQSem is a rare exception from the rule. signalQSem :: QSem -> IO () signalQSem (QSem m) = uninterruptibleMask_ $ do -- Note [signal uninterruptible] r <- takeMVar m r' <- signal r putMVar m r' It's tempting to suggest that every cleanup type function should just mask exceptions itself like this. However, that does not solve the problem when several cleanup actions are required: at the end of the first uninterruptibleMask_, any pending exceptions will be delivered. Overall I agree with your assessment that a general uninterruptibleMask_ for cleanup handlers avoids more trouble than it causes. Cheers, Bertram From david.feuer at gmail.com Mon Sep 8 06:58:37 2014 From: david.feuer at gmail.com (David Feuer) Date: Mon, 8 Sep 2014 02:58:37 -0400 Subject: Proposal: (breaking change to avoid fragile breakage) change the definition of foldr2, zip, and zipWith In-Reply-To: References: Message-ID: It's been a couple weeks now, and no one's responded. I'd like to submit a patch for this one ASAP to update source and/or documentation, but I would really like to get some guidance from anyone else who may care. On Sun, Aug 24, 2014 at 3:22 PM, David Feuer wrote: > BACKGROUND > > TRAC: #9495 > > GHC's definition of foldr2 violates the spec of the Haskell Report, making > some programs less defined than they should be, and does so in a way that is > quite fragile, dependent on a number of different factors?that is, it is > likely hard to debug. > > Details: > > The current "baseline" definition of foldr2 (before rewrite rules) does what > the Report requires: > > foldr2 :: (a -> b -> c -> c) -> c -> [a] -> [b] -> c > foldr2 k z = go > where > go [] _ys = z > go _xs [] = z > go (x:xs) (y:ys) = k x y (go xs ys) > > There are two rewrite rules, foldr2/left and foldr2/right, designed to allow > foldr2 to fuse with build appearing in either the first or second list > argument. foldr2/left is perfectly safe (as long as the build argument is > legitimate). foldr2/right is not, as comments in the source partially > explain. The problem shows up if you have something shaped like > > zip [1,7,42,5] (1:8:4:11:undefined) > > but where the second list (ending in undefined) is actually produced using > build, and GHC chooses to fuse foldr2 with it. The Report requires the above > to produce [(1,1),(7,8),(42,4),(5,11)], but GHC will instead produce > (1,1):(7,8):(42,4):(5,11):_|_ > > This issue can make a program that works with -O0 fail with -O, and can > cause fragility depending on exactly what fuses. > > SCOPE > > One obvious question is what kinds of build forms can cause problems. Many, > like map and fromEnumTo, don't have enough power to be likely to cause > trouble. Joachim Breitner, however, realized that the current implementation > of filter has enough power to break things. So here's a complete example of > code that will break with -O but not with -O0: > > {-# NOINLINE don'tFuse #-} > don'tFuse = id > > p x = 100 `mod` x < 20 > > main = print $ zip (don'tFuse [10,9..1]) (filter p [10,9,..]) > > Things will only get worse if I succeed in my plan to bring unfoldr into the > framework. > > SOLUTIONS > > 1. One solution, of course, is to eliminate unfoldr2/right, bringing GHC > into compliance with the Report. I really like this idea, but Joachim thinks > it is not worth the potential performance impact on code written before or > without regard for the change. We both agree that a reasonable alternative > is > > 3. Modify the baseline definition of unfoldr2 as follows: > > foldr2 :: (a -> b -> c -> c) -> c -> [a] -> [b] -> c > foldr2 k z = go > where > go [] ys = ys `seq` z > go _xs [] = z > go (x:xs) (y:ys) = k x y (go xs ys) > > This should, we believe, make the baseline definition fail where the one > fused by foldr2/right would fail, giving consistent semantics. > > WHAT MIGHT BREAK > > Code that currently works but will break with this change has two > properties: > > 1. It relies on the asymmetry in foldr, zipWith, or zip to avoid running > into bottom. > 2. foldr2/right does not fire, either because the second list is not a good > producer or because GHC applies the foldr2/left rule instead. > > That is, most of the code that this change will break is fragile under the > current scheme. > > DISCUSSION PERIOD > > Standard two weeks. From mail at joachim-breitner.de Mon Sep 8 08:24:45 2014 From: mail at joachim-breitner.de (Joachim Breitner) Date: Mon, 08 Sep 2014 10:24:45 +0200 Subject: Proposal: (breaking change to avoid fragile breakage) change the definition of foldr2, zip, and zipWith In-Reply-To: References: Message-ID: <1410164685.2670.3.camel@joachim-breitner.de> Dear David, Am Montag, den 08.09.2014, 02:58 -0400 schrieb David Feuer: > It's been a couple weeks now, and no one's responded. that can happen. Usually not because noone cares, but because noone knows what?s best. And also there was ICFP last week, which probably kept people busy ... so don?t be discouraged by silence, and keep following up on it. > On Sun, Aug 24, 2014 at 3:22 PM, David Feuer wrote: > > BACKGROUND > > > > TRAC: #9495 > > SOLUTIONS > > > > 1. One solution, of course, is to eliminate unfoldr2/right, bringing GHC > > into compliance with the Report. I really like this idea, but Joachim thinks > > it is not worth the potential performance impact on code written before or > > without regard for the change. We both agree that a reasonable alternative > > is > > > > 3. Modify the baseline definition of unfoldr2 as follows: > > > > foldr2 :: (a -> b -> c -> c) -> c -> [a] -> [b] -> c > > foldr2 k z = go > > where > > go [] ys = ys `seq` z > > go _xs [] = z > > go (x:xs) (y:ys) = k x y (go xs ys) > > > > This should, we believe, make the baseline definition fail where the one > > fused by foldr2/right would fail, giving consistent semantics. You already said that I agree with that solution, but I can re-state it here :-) > > WHAT MIGHT BREAK > > > > Code that currently works but will break with this change has two > > properties: > > > > 1. It relies on the asymmetry in foldr, zipWith, or zip to avoid running > > into bottom. > > 2. foldr2/right does not fire, either because the second list is not a good > > producer or because GHC applies the foldr2/left rule instead. > > > > That is, most of the code that this change will break is fragile under the > > current scheme. > > > > DISCUSSION PERIOD > > > > Standard two weeks. Given that nobody complained about the standard-non-conformance so far I think having a symmetric zip where the RULES are semantics-preserving is more useful than strictly following the report. But I could be convinced otherwise. David, I think you can go ahead and prepare a patch. People can still speak up before (and even after) it is applied if they disagree. Greetings, Joachim -- Joachim ?nomeata? Breitner mail at joachim-breitner.de ? http://www.joachim-breitner.de/ Jabber: nomeata at joachim-breitner.de ? GPG-Key: 0xF0FBF51F Debian Developer: nomeata at debian.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: This is a digitally signed message part URL: From ganesh at earth.li Mon Sep 8 21:19:44 2014 From: ganesh at earth.li (Ganesh Sittampalam) Date: Mon, 08 Sep 2014 22:19:44 +0100 Subject: HTTP package - supported GHC versions In-Reply-To: <5408056F.80601@chalmers.se> References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> <540708C3.1090900@earth.li> <878um04om6.fsf@gnu.org> <5408056F.80601@chalmers.se> Message-ID: <540E1D70.60208@earth.li> Do you (or anyone else) have any sense of how common GHC 7.0 usage is in practice? I do like the idea in principle of supporting old compilers, but it does come with a cost even if the code works with them right now. Also, if there's anyone out there that depends on HTTP and wants to support GHC 7.0 for whatever reason, that would swing it for me. On 04/09/2014 07:23, Andreas Abel wrote: > If it is not too much of a hassle, rather support old versions of GHC. > As mentioned below, there are long term support versions of Linux that > package older GHCs. > > I was positively surprised that the latest QuickCheck still supports GHC > 6.8. Agda aims to support GHC 7.0 for a while still (which keeps me > from using some nice syntax extensions to Haskell). > > Cheers, > Andreas > > On 03.09.2014 19:09, Herbert Valerio Riedel wrote: >> Hi, >> >> On 2014-09-03 at 14:25:39 +0200, Ganesh Sittampalam wrote: >> >> [...] >> >>> More generally I'm not too keen on having a lower bound that is "stuck", >>> rather than moving forwards in a routine fashion as new GHC and Haskell >>> Platform releases appear. So I like the "three versions" rule and I >>> don't like "the first Haskell2010-supporting GHC onwards". >>> >>> All that said I do like the general idea of supporting a wide range of >>> GHCs with a low-level library like this and I'm happy to do so if >>> there's some plausible value in it. >> >> I don't have any strong opinion on "last three major GHC versions (with >> an associated HP release)" vs "the first Haskell2010-supporting GHC >> on-wards", either are fine with me, as even the latter one would >> typically span a 3-4 year window (which would be good enough for most >> Linux distros except certain "enterprise" ones...) >> >> However, one should just be aware that the lower your package is in the >> dependency graph, the larger the transitive avalanche effect of forcing >> newer lower-bounds on packages depending upon yours is. Otoh, at some >> point this is bound to happen anyway... >> >> Cheers, >> hvr >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> > > From greg at gregweber.info Mon Sep 8 21:26:57 2014 From: greg at gregweber.info (Greg Weber) Date: Mon, 8 Sep 2014 14:26:57 -0700 Subject: HTTP package - supported GHC versions In-Reply-To: <540E1D70.60208@earth.li> References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> <540708C3.1090900@earth.li> <878um04om6.fsf@gnu.org> <5408056F.80601@chalmers.se> <540E1D70.60208@earth.li> Message-ID: You are probably unlikely to find the person you are looking for on the libraries mail list on this subject, instead you are only going to find advice :) On Mon, Sep 8, 2014 at 2:19 PM, Ganesh Sittampalam wrote: > Do you (or anyone else) have any sense of how common GHC 7.0 usage is in > practice? > > I do like the idea in principle of supporting old compilers, but it does > come with a cost even if the code works with them right now. > > Also, if there's anyone out there that depends on HTTP and wants to > support GHC 7.0 for whatever reason, that would swing it for me. > > On 04/09/2014 07:23, Andreas Abel wrote: > > If it is not too much of a hassle, rather support old versions of GHC. > > As mentioned below, there are long term support versions of Linux that > > package older GHCs. > > > > I was positively surprised that the latest QuickCheck still supports GHC > > 6.8. Agda aims to support GHC 7.0 for a while still (which keeps me > > from using some nice syntax extensions to Haskell). > > > > Cheers, > > Andreas > > > > On 03.09.2014 19:09, Herbert Valerio Riedel wrote: > >> Hi, > >> > >> On 2014-09-03 at 14:25:39 +0200, Ganesh Sittampalam wrote: > >> > >> [...] > >> > >>> More generally I'm not too keen on having a lower bound that is > "stuck", > >>> rather than moving forwards in a routine fashion as new GHC and Haskell > >>> Platform releases appear. So I like the "three versions" rule and I > >>> don't like "the first Haskell2010-supporting GHC onwards". > >>> > >>> All that said I do like the general idea of supporting a wide range of > >>> GHCs with a low-level library like this and I'm happy to do so if > >>> there's some plausible value in it. > >> > >> I don't have any strong opinion on "last three major GHC versions (with > >> an associated HP release)" vs "the first Haskell2010-supporting GHC > >> on-wards", either are fine with me, as even the latter one would > >> typically span a 3-4 year window (which would be good enough for most > >> Linux distros except certain "enterprise" ones...) > >> > >> However, one should just be aware that the lower your package is in the > >> dependency graph, the larger the transitive avalanche effect of forcing > >> newer lower-bounds on packages depending upon yours is. Otoh, at some > >> point this is bound to happen anyway... > >> > >> Cheers, > >> hvr > >> _______________________________________________ > >> Libraries mailing list > >> Libraries at haskell.org > >> http://www.haskell.org/mailman/listinfo/libraries > >> > > > > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From merijn at inconsistent.nl Tue Sep 9 07:30:40 2014 From: merijn at inconsistent.nl (Merijn Verstraaten) Date: Tue, 9 Sep 2014 00:30:40 -0700 Subject: PROPOSAL: Add newBroadcastChan :: IO (Chan a) to Control.Concurrent.Chan Message-ID: <968B00C0-C88B-46ED-BD89-5AC53E611221@inconsistent.nl> Ola! Control.Concurrent.STM.TChan has the ?newBroadcastTChan :: STM (TChan a)?, this creates a ?write-only? TChan to avoid any space leaks when a Chan is written too but never read from (for example, when dupTChan is used to hand a copy to threads). Unfortunately, no such variant seems to exist for the normal Chan? I have the following code: foo :: Chan a -> IO Foo foo broadcast = do newListener <- dupChan broadcast forkIO $ doStuffWith newListener This means the original Chan is never read from and much like the problem with TChan, values keep piling up in the original channel, causing a space leak. I propose adding newBroadcastChan :: IO (Chan a) The obvious Chan equivalent of newBroadcastTChan, which creates a write-only channel without read end, thus avoiding this space leak. Discussion: 2 weeks? Cheers, Merijn -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 801 bytes Desc: Message signed with OpenPGP using GPGMail URL: From hvr at gnu.org Tue Sep 9 07:53:09 2014 From: hvr at gnu.org (Herbert Valerio Riedel) Date: Tue, 09 Sep 2014 09:53:09 +0200 Subject: HTTP package - supported GHC versions In-Reply-To: <540E1D70.60208@earth.li> (Ganesh Sittampalam's message of "Mon, 08 Sep 2014 22:19:44 +0100") References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> <540708C3.1090900@earth.li> <878um04om6.fsf@gnu.org> <5408056F.80601@chalmers.se> <540E1D70.60208@earth.li> Message-ID: <87d2b51b8a.fsf@gnu.org> Hi, On 2014-09-08 at 23:19:44 +0200, Ganesh Sittampalam wrote: > Do you (or anyone else) have any sense of how common GHC 7.0 usage is in > practice? Here's just some rough statistics based on the Hackage access logs of september so far, assuming the heuristic each distinct user can be identified by its IP address (the numbers denote the distinct IP addresses that accessed Hackage with the particular cabal-install version): 89 cabal-install/0.10.2 1 cabal-install/0.10.3 2 cabal-install/0.13.3 780 cabal-install/0.14.0 3 cabal-install/0.17.0 1 cabal-install/0.6.2 28 cabal-install/0.8.0 7 cabal-install/0.8.2 1 cabal-install/0.9.1 2 cabal-install/1.16.0 19 cabal-install/1.16.0.1 2713 cabal-install/1.16.0.2 2 cabal-install/1.17.0 2 cabal-install/1.18.0 16 cabal-install/1.18.0.1 282 cabal-install/1.18.0.2 196 cabal-install/1.18.0.3 45 cabal-install/1.18.0.4 1937 cabal-install/1.18.0.5 1 cabal-install/1.19.0 7 cabal-install/1.19.2 2 cabal-install/1.20.0 77 cabal-install/1.20.0.0 157 cabal-install/1.20.0.1 408 cabal-install/1.20.0.2 4879 cabal-install/1.20.0.3 189 cabal-install/1.21.0.0 32 cabal-install/1.21.1.0 GHC 7.0 shipped with Cabal-1.10 (and so cabal-install-0.10 is the likely version used by GHC 7.0 users); so that should give you a hint about how many users didn't upgrade their cabal-install and stayed with cabal-install-0.10 (and probably GHC 7.0.x). So there are probably still a few users left on GHC 7.0... Otoh, it's nice to see that the latest cabal-install-1.20.0.3 (which uses a newer Cabal major version than is shipped with GHC 7.8) is being used the most for hitting Hackage -- seems the cabal-install "there's a newer version"-reminder is working quite well... Cheers, hvr From ashley at semantic.org Wed Sep 10 08:43:17 2014 From: ashley at semantic.org (Ashley Yakeley) Date: Wed, 10 Sep 2014 01:43:17 -0700 Subject: ANNOUNCE time-1.5 Message-ID: time-1.5 is now available from Hackage. The source for time has now moved to GitHub: . Send bug reports to the associated issue tracker. * Fixed a bug where tzset was not getting called on Windows. The other changes relate to Data.Time.Format: * time no longer depends on old-locale. The TimeLocale from old-locale has been replaced by a new one defined in Data.Time.Format. * The "intervals" field from TimeLocale has been removed, as it's not used. * The way time-zone abbreviations are parsed has changed. The parsing functions parse single-letter military abbreviations, and also time-zones found in the new "knownTimeZones" field of TimeLocale. Note that (knownTimeZones defaultTimeLocale) contains only the ten zone abbreviations mentioned in RFC822 sec. 5. This is the only standardised list of time-zone abbreviations I know of. Since the abbreviations are a many-to-many mapping, this should encourage people to think carefully about what abbreviations they expect. * New parsing functions parseTimeM, parseTimeOrError, readSTime, readPTime replace now-deprecated parseTime, readTime, readsTime. The new functions have a flag to control parsing of leading and trailing whitespace. -- Ashley Yakeley From adam at bergmark.nl Wed Sep 10 09:39:53 2014 From: adam at bergmark.nl (Adam Bergmark) Date: Wed, 10 Sep 2014 11:39:53 +0200 Subject: ANNOUNCE time-1.5 In-Reply-To: References: Message-ID: Hi Ashley, Thanks for making an in depth changelog! It's something that I frequently miss when upgrading other packages. Would you be willing to also give a backwards compatible migration guide for the new version? With a package this deep down in the library stack I think it's very important for people to allow older versions for quite some time. Cheers, Adam On Wed, Sep 10, 2014 at 10:43 AM, Ashley Yakeley wrote: > time-1.5 is now available from Hackage. > > > The source for time has now moved to GitHub: time>. Send bug reports to the associated issue tracker. > > * Fixed a bug where tzset was not getting called on Windows. > > The other changes relate to Data.Time.Format: > > * time no longer depends on old-locale. The TimeLocale from old-locale has > been replaced by a new one defined in Data.Time.Format. > * The "intervals" field from TimeLocale has been removed, as it's not used. > * The way time-zone abbreviations are parsed has changed. The parsing > functions parse single-letter military abbreviations, and also time-zones > found in the new "knownTimeZones" field of TimeLocale. > > Note that (knownTimeZones defaultTimeLocale) contains only the ten zone > abbreviations mentioned in RFC822 sec. 5. This is the only standardised > list of time-zone abbreviations I know of. Since the abbreviations are a > many-to-many mapping, this should encourage people to think carefully about > what abbreviations they expect. > > * New parsing functions parseTimeM, parseTimeOrError, readSTime, readPTime > replace now-deprecated parseTime, readTime, readsTime. The new functions > have a flag to control parsing of leading and trailing whitespace. > > -- Ashley Yakeley > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hvr at gnu.org Wed Sep 10 16:54:42 2014 From: hvr at gnu.org (Herbert Valerio Riedel) Date: Wed, 10 Sep 2014 18:54:42 +0200 Subject: ANNOUNCE time-1.5 In-Reply-To: (Adam Bergmark's message of "Wed, 10 Sep 2014 11:39:53 +0200") References: Message-ID: <87fvfz5sbx.fsf@gnu.org> Hi, On 2014-09-10 at 11:39:53 +0200, Adam Bergmark wrote: > Hi Ashley, > > Thanks for making an in depth changelog! It's something that I frequently > miss when upgrading other packages. Just as a reminder, if you add a text-file named like 'changelog' or 'changelog.md' (see [1] for more variants), and make sure it's contained in the source tarball (e.g. by listing it in 'extra-source-files'), you can have it conveniently linked right below the package description on Hackage (example: [2]) [1]: All supported filename variants can be found here: https://github.com/haskell/hackage-server/blob/master/Distribution/Server/Packages/ChangeLog.hs [2]: http://hackage.haskell.org/package/base has a Changelog link pointing to http://hackage.haskell.org/package/base-4.7.0.1/changelog From mwm at mired.org Wed Sep 10 18:20:15 2014 From: mwm at mired.org (Mike Meyer) Date: Wed, 10 Sep 2014 13:20:15 -0500 Subject: bedandbreakfast needing a release Message-ID: I've got a library that needed some simple matrix computation, so I added the bedandbreakfast package. While my library builds fine on both 7.6 and 7.8, the last released version of that package won't build on 7.8. However, the current HUB was update a couple of weeks ago, and now builds on 7.8. Is there some way to capture that information in a cabal file? That if you're using GHC 7.8, you need bedandbreakfast >= 5.*, but for GHC7.6 you can use bedandbreakfast >= 4.*? I did send an email to the maintainer a little over a week ago asking if he could do a release, and haven't gotten either a reply or a release. Any suggestions on what I should do about releasing the updated version of my library? -------------- next part -------------- An HTML attachment was scrubbed... URL: From adam at bergmark.nl Wed Sep 10 18:41:27 2014 From: adam at bergmark.nl (Adam Bergmark) Date: Wed, 10 Sep 2014 20:41:27 +0200 Subject: bedandbreakfast needing a release In-Reply-To: References: Message-ID: Hi Mike, something like this should do the trick (untested): ``` flag ghc78 description: Using GHC >= 7.8 default: True library if flag(ghc78) build-depends: base >= 4.7 bedandbreakfast >= 5 else build-depends: base < 4.7 bedandbreakfast >= 4 ``` This uses a non-manual flag so cabal will toggle it if it needs to. HTH, Adam On Wed, Sep 10, 2014 at 8:20 PM, Mike Meyer wrote: > I've got a library that needed some simple matrix computation, so I added > the bedandbreakfast package. While my library builds fine on both 7.6 and > 7.8, the last released version of that package won't build on 7.8. However, > the current HUB was update a couple of weeks ago, and now builds on 7.8. > > Is there some way to capture that information in a cabal file? That if > you're using GHC 7.8, you need bedandbreakfast >= 5.*, but for GHC7.6 you > can use bedandbreakfast >= 4.*? > > I did send an email to the maintainer a little over a week ago asking if > he could do a release, and haven't gotten either a reply or a release. > > Any suggestions on what I should do about releasing the updated version of > my library? > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mwm at mired.org Wed Sep 10 18:56:20 2014 From: mwm at mired.org (Mike Meyer) Date: Wed, 10 Sep 2014 13:56:20 -0500 Subject: bedandbreakfast needing a release In-Reply-To: References: Message-ID: Ok, that works fine - except that bedandbreakfast 0.5 hasn't been released yet :-(. Is there anything I can do other than add a note to add the head from github as a sourcce, and send a note to the maintainer asking for a release :-)? Thanks, Mike On Wed, Sep 10, 2014 at 1:41 PM, Adam Bergmark wrote: > Hi Mike, something like this should do the trick (untested): > > ``` > flag ghc78 > description: Using GHC >= 7.8 > default: True > > library > if flag(ghc78) > build-depends: > base >= 4.7 > bedandbreakfast >= 5 > else > build-depends: > base < 4.7 > bedandbreakfast >= 4 > ``` > > This uses a non-manual flag so cabal will toggle it if it needs to. > > HTH, > Adam > > > > On Wed, Sep 10, 2014 at 8:20 PM, Mike Meyer wrote: > >> I've got a library that needed some simple matrix computation, so I added >> the bedandbreakfast package. While my library builds fine on both 7.6 and >> 7.8, the last released version of that package won't build on 7.8. However, >> the current HUB was update a couple of weeks ago, and now builds on 7.8. >> >> Is there some way to capture that information in a cabal file? That if >> you're using GHC 7.8, you need bedandbreakfast >= 5.*, but for GHC7.6 you >> can use bedandbreakfast >= 4.*? >> >> I did send an email to the maintainer a little over a week ago asking if >> he could do a release, and haven't gotten either a reply or a release. >> >> Any suggestions on what I should do about releasing the updated version >> of my library? >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From rwbarton at gmail.com Wed Sep 10 18:56:46 2014 From: rwbarton at gmail.com (Reid Barton) Date: Wed, 10 Sep 2014 14:56:46 -0400 Subject: bedandbreakfast needing a release In-Reply-To: References: Message-ID: On Wed, Sep 10, 2014 at 2:20 PM, Mike Meyer wrote: > I've got a library that needed some simple matrix computation, so I added > the bedandbreakfast package. While my library builds fine on both 7.6 and > 7.8, the last released version of that package won't build on 7.8. However, > the current HUB was update a couple of weeks ago, and now builds on 7.8. > > Is there some way to capture that information in a cabal file? That if > you're using GHC 7.8, you need bedandbreakfast >= 5.*, but for GHC7.6 you > can use bedandbreakfast >= 4.*? > While you can do this, there's really no reason to. All your package depends on is any version of bedandbreakfast that the user can install. cabal will prefer to install newer versions of packages over older ones, so I don't think there's any situation in which adding this information to your cabal file would allow your package to install when it otherwise wouldn't. Your real problem, as you note, is just that bedandbreakfast 5 is not available on hackage. Regards, Reid Barton -------------- next part -------------- An HTML attachment was scrubbed... URL: From adam at bergmark.nl Wed Sep 10 19:08:15 2014 From: adam at bergmark.nl (Adam Bergmark) Date: Wed, 10 Sep 2014 21:08:15 +0200 Subject: bedandbreakfast needing a release In-Reply-To: References: Message-ID: Whoops, missed that part! If you want a new version to be uploaded see http://www.haskell.org/haskellwiki/Taking_over_a_package Taking over a package takes some time, as it should. If you can't wait you can inline the package into yours for the time being. On Wed, Sep 10, 2014 at 8:56 PM, Reid Barton wrote: > On Wed, Sep 10, 2014 at 2:20 PM, Mike Meyer wrote: > >> I've got a library that needed some simple matrix computation, so I added >> the bedandbreakfast package. While my library builds fine on both 7.6 and >> 7.8, the last released version of that package won't build on 7.8. However, >> the current HUB was update a couple of weeks ago, and now builds on 7.8. >> >> Is there some way to capture that information in a cabal file? That if >> you're using GHC 7.8, you need bedandbreakfast >= 5.*, but for GHC7.6 you >> can use bedandbreakfast >= 4.*? >> > > While you can do this, there's really no reason to. All your package > depends on is any version of bedandbreakfast that the user can install. > cabal will prefer to install newer versions of packages over older ones, so > I don't think there's any situation in which adding this information to > your cabal file would allow your package to install when it otherwise > wouldn't. > > Your real problem, as you note, is just that bedandbreakfast 5 is not > available on hackage. > > Regards, > Reid Barton > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From adam at bergmark.nl Thu Sep 11 08:51:47 2014 From: adam at bergmark.nl (Adam Bergmark) Date: Thu, 11 Sep 2014 10:51:47 +0200 Subject: bedandbreakfast needing a release In-Reply-To: <87bnqn5e0d.fsf@gnu.org> References: <87bnqn5e0d.fsf@gnu.org> Message-ID: Wow, I totally forgot about "if impl(ghc>=7.8)". That's the way to go of course! On Thu, Sep 11, 2014 at 12:04 AM, Herbert Valerio Riedel wrote: > On 2014-09-10 at 20:41:27 +0200, Adam Bergmark wrote: > > Hi Mike, something like this should do the trick (untested): > > > > ``` > > flag ghc78 > > description: Using GHC >= 7.8 > > default: True > > > > library > > if flag(ghc78) > > build-depends: > > base >= 4.7 > > bedandbreakfast >= 5 > > else > > build-depends: > > base < 4.7 > > bedandbreakfast >= 4 > > ``` > > > > This uses a non-manual flag so cabal will toggle it if it needs to. > > btw, why not simply use a "if impl(ghc>=7.8)" conditional w/o resorting > to flags? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hvr at gnu.org Thu Sep 11 10:20:11 2014 From: hvr at gnu.org (Herbert Valerio Riedel) Date: Thu, 11 Sep 2014 12:20:11 +0200 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude Message-ID: <87vbou792c.fsf@gmail.com> TL;DR ===== Re-export 'Data.Typeable.Typeable' from 'Prelude' Motivation ========== Since GHC 7.8 the ubiquitous 'Typeable' instances can only be auto-derived via `... deriving Typeable`, moreover there's a new extension `-XAutoDeriveTypeable` which implicitly auto-derives 'Typeable' for all defined types in modules for which that extension is enabled. However, even if you enable `-XAutoDeriveTypeable` you still need to explicitly bring the 'Typeable' class into scope, with e.g. import Data.Typeable (Typeable) otherwise GHC complains with Not in scope: type constructor or class ?Typeable? Since at this point it's become current practice to have 'Typeable' instances for most types, it would be beneficial to save an 'import Data.Typeable (Typeable)' line for the sole purpose of deriving such instances. By having 'Prelude' re-export 'Typeable' from GHC 7.10 on (should this proposal be implemented) it would suffice to have a default-extensions: -XAutoDeriveTypeable` in the Cabal file and have 'Typeable' instance auto-derived for all types defined in a package w/o any source changes (unless there's a name-clash with 'Typeable') Discussion period ================= The usual 2 weeks From michael at snoyman.com Thu Sep 11 10:21:20 2014 From: michael at snoyman.com (Michael Snoyman) Date: Thu, 11 Sep 2014 13:21:20 +0300 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <87vbou792c.fsf@gmail.com> References: <87vbou792c.fsf@gmail.com> Message-ID: On Thu, Sep 11, 2014 at 1:20 PM, Herbert Valerio Riedel wrote: > > TL;DR > ===== > > Re-export 'Data.Typeable.Typeable' from 'Prelude' > > Motivation > ========== > > Since GHC 7.8 the ubiquitous 'Typeable' instances can only be > auto-derived via `... deriving Typeable`, moreover there's a new > extension `-XAutoDeriveTypeable` which implicitly auto-derives > 'Typeable' for all defined types in modules for which that extension is > enabled. > > However, even if you enable `-XAutoDeriveTypeable` you still need to > explicitly bring the 'Typeable' class into scope, with e.g. > > import Data.Typeable (Typeable) > > otherwise GHC complains with > > Not in scope: type constructor or class ?Typeable? > > Since at this point it's become current practice to have 'Typeable' > instances for most types, it would be beneficial to save an 'import > Data.Typeable (Typeable)' line for the sole purpose of deriving such > instances. > > By having 'Prelude' re-export 'Typeable' from GHC 7.10 on (should this > proposal be implemented) it would suffice to have a > > default-extensions: -XAutoDeriveTypeable` > > in the Cabal file and have 'Typeable' instance auto-derived for all > types defined in a package w/o any source changes (unless there's a > name-clash with 'Typeable') > > Discussion period > ================= > > The usual 2 weeks > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > +1 -------------- next part -------------- An HTML attachment was scrubbed... URL: From hvr at gnu.org Thu Sep 11 10:25:42 2014 From: hvr at gnu.org (Herbert Valerio Riedel) Date: Thu, 11 Sep 2014 12:25:42 +0200 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <87vbou792c.fsf@gmail.com> (Herbert Valerio Riedel's message of "Thu, 11 Sep 2014 12:20:11 +0200") References: <87vbou792c.fsf@gmail.com> Message-ID: <87r3zi78t5.fsf@gnu.org> UPDATE: I was just made aware that 'AutoDeriveTypeable' does in fact *not* require 'Typeable' to be in scope. So the proposal still stands, but with less motivation. On 2014-09-11 at 12:20:11 +0200, Herbert Valerio Riedel wrote: > TL;DR > ===== > > Re-export 'Data.Typeable.Typeable' from 'Prelude' > > Motivation > ========== > > Since GHC 7.8 the ubiquitous 'Typeable' instances can only be > auto-derived via `... deriving Typeable`, moreover there's a new > extension `-XAutoDeriveTypeable` which implicitly auto-derives > 'Typeable' for all defined types in modules for which that extension is > enabled. > > However, even if you enable `-XAutoDeriveTypeable` you still need to > explicitly bring the 'Typeable' class into scope, with e.g. > > import Data.Typeable (Typeable) > > otherwise GHC complains with > > Not in scope: type constructor or class ?Typeable? > > Since at this point it's become current practice to have 'Typeable' > instances for most types, it would be beneficial to save an 'import > Data.Typeable (Typeable)' line for the sole purpose of deriving such > instances. > > By having 'Prelude' re-export 'Typeable' from GHC 7.10 on (should this > proposal be implemented) it would suffice to have a > > default-extensions: -XAutoDeriveTypeable` > > in the Cabal file and have 'Typeable' instance auto-derived for all > types defined in a package w/o any source changes (unless there's a > name-clash with 'Typeable') > > Discussion period > ================= > > The usual 2 weeks > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries -- "Elegance is not optional" -- Richard O'Keefe From mail at joachim-breitner.de Thu Sep 11 12:09:16 2014 From: mail at joachim-breitner.de (Joachim Breitner) Date: Thu, 11 Sep 2014 14:09:16 +0200 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <87r3zi78t5.fsf@gnu.org> References: <87vbou792c.fsf@gmail.com> <87r3zi78t5.fsf@gnu.org> Message-ID: <1410437356.2792.9.camel@joachim-breitner.de> Hi, Am Donnerstag, den 11.09.2014, 12:25 +0200 schrieb Herbert Valerio Riedel: > UPDATE: I was just made aware that 'AutoDeriveTypeable' does in fact *not* > require 'Typeable' to be in scope. So the proposal still stands, > but with less motivation. in that case, I?m -1. Typeable is not ?plain, simple Haskell?, which is what I expect to be in the Prelude. I want a Haskell newbie to be able to read through the prelude and understand and make use of all of it. Greetings, Joachim -- Joachim ?nomeata? Breitner mail at joachim-breitner.de ? http://www.joachim-breitner.de/ Jabber: nomeata at joachim-breitner.de ? GPG-Key: 0xF0FBF51F Debian Developer: nomeata at debian.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: This is a digitally signed message part URL: From david.feuer at gmail.com Thu Sep 11 13:25:33 2014 From: david.feuer at gmail.com (David Feuer) Date: Thu, 11 Sep 2014 09:25:33 -0400 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <87r3zi78t5.fsf@gnu.org> References: <87vbou792c.fsf@gmail.com> <87r3zi78t5.fsf@gnu.org> Message-ID: -1. The Prelude is, for the most part, stuff in the standard. I don't think Typeable has much chance of ever getting there. On Sep 11, 2014 6:25 AM, "Herbert Valerio Riedel" wrote: > > UPDATE: I was just made aware that 'AutoDeriveTypeable' does in fact *not* > require 'Typeable' to be in scope. So the proposal still stands, > but with less motivation. > > On 2014-09-11 at 12:20:11 +0200, Herbert Valerio Riedel wrote: > > TL;DR > > ===== > > > > Re-export 'Data.Typeable.Typeable' from 'Prelude' > > > > Motivation > > ========== > > > > Since GHC 7.8 the ubiquitous 'Typeable' instances can only be > > auto-derived via `... deriving Typeable`, moreover there's a new > > extension `-XAutoDeriveTypeable` which implicitly auto-derives > > 'Typeable' for all defined types in modules for which that extension is > > enabled. > > > > However, even if you enable `-XAutoDeriveTypeable` you still need to > > explicitly bring the 'Typeable' class into scope, with e.g. > > > > import Data.Typeable (Typeable) > > > > otherwise GHC complains with > > > > Not in scope: type constructor or class ?Typeable? > > > > Since at this point it's become current practice to have 'Typeable' > > instances for most types, it would be beneficial to save an 'import > > Data.Typeable (Typeable)' line for the sole purpose of deriving such > > instances. > > > > By having 'Prelude' re-export 'Typeable' from GHC 7.10 on (should this > > proposal be implemented) it would suffice to have a > > > > default-extensions: -XAutoDeriveTypeable` > > > > in the Cabal file and have 'Typeable' instance auto-derived for all > > types defined in a package w/o any source changes (unless there's a > > name-clash with 'Typeable') > > > > Discussion period > > ================= > > > > The usual 2 weeks > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://www.haskell.org/mailman/listinfo/libraries > > -- > "Elegance is not optional" -- Richard O'Keefe > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From schlepptop at henning-thielemann.de Thu Sep 11 13:34:18 2014 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Thu, 11 Sep 2014 15:34:18 +0200 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <87vbou792c.fsf@gmail.com> References: <87vbou792c.fsf@gmail.com> Message-ID: <5411A4DA.2040501@henning-thielemann.de> Am 11.09.2014 um 12:20 schrieb Herbert Valerio Riedel: > Since at this point it's become current practice to have 'Typeable' > instances for most types, it would be beneficial to save an 'import > Data.Typeable (Typeable)' line for the sole purpose of deriving such > instances. I have still no use for these Typeable things. Additionally I am tired of moving so many things to Prelude. My preference would be that it becomes practice to use the module system, instead of simulating a non-modular language by putting everything into Prelude. From acowley at seas.upenn.edu Thu Sep 11 13:57:56 2014 From: acowley at seas.upenn.edu (Anthony Cowley) Date: Thu, 11 Sep 2014 09:57:56 -0400 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <87vbou792c.fsf@gmail.com> References: <87vbou792c.fsf@gmail.com> Message-ID: <8BBB2DF2-A517-48C3-901D-53EE36692E36@seas.upenn.edu> I'm -1 on this as I'm not yet convinced that reaching for Typeable should be such a quick decision that it deserves to always be in scope. Anthony > On Sep 11, 2014, at 6:20 AM, Herbert Valerio Riedel wrote: > > > TL;DR > ===== > > Re-export 'Data.Typeable.Typeable' from 'Prelude' > > Motivation > ========== > > Since GHC 7.8 the ubiquitous 'Typeable' instances can only be > auto-derived via `... deriving Typeable`, moreover there's a new > extension `-XAutoDeriveTypeable` which implicitly auto-derives > 'Typeable' for all defined types in modules for which that extension is > enabled. > > However, even if you enable `-XAutoDeriveTypeable` you still need to > explicitly bring the 'Typeable' class into scope, with e.g. > > import Data.Typeable (Typeable) > > otherwise GHC complains with > > Not in scope: type constructor or class ?Typeable? > > Since at this point it's become current practice to have 'Typeable' > instances for most types, it would be beneficial to save an 'import > Data.Typeable (Typeable)' line for the sole purpose of deriving such > instances. > > By having 'Prelude' re-export 'Typeable' from GHC 7.10 on (should this > proposal be implemented) it would suffice to have a > > default-extensions: -XAutoDeriveTypeable` > > in the Cabal file and have 'Typeable' instance auto-derived for all > types defined in a package w/o any source changes (unless there's a > name-clash with 'Typeable') > > Discussion period > ================= > > The usual 2 weeks > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries From michael at snoyman.com Thu Sep 11 14:05:19 2014 From: michael at snoyman.com (Michael Snoyman) Date: Thu, 11 Sep 2014 17:05:19 +0300 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <8BBB2DF2-A517-48C3-901D-53EE36692E36@seas.upenn.edu> References: <87vbou792c.fsf@gmail.com> <8BBB2DF2-A517-48C3-901D-53EE36692E36@seas.upenn.edu> Message-ID: The one case I think Typeable should *always* be around for is creating new instances of Exception. The fact that AutoDeriveTypeable doesn't require Typeable in Prelude lessens my +1 a bit down to a +0.5, but I really want it to be easier for people to define their own exception types. On Thu, Sep 11, 2014 at 4:57 PM, Anthony Cowley wrote: > I'm -1 on this as I'm not yet convinced that reaching for Typeable should > be such a quick decision that it deserves to always be in scope. > > Anthony > > > On Sep 11, 2014, at 6:20 AM, Herbert Valerio Riedel wrote: > > > > > > TL;DR > > ===== > > > > Re-export 'Data.Typeable.Typeable' from 'Prelude' > > > > Motivation > > ========== > > > > Since GHC 7.8 the ubiquitous 'Typeable' instances can only be > > auto-derived via `... deriving Typeable`, moreover there's a new > > extension `-XAutoDeriveTypeable` which implicitly auto-derives > > 'Typeable' for all defined types in modules for which that extension is > > enabled. > > > > However, even if you enable `-XAutoDeriveTypeable` you still need to > > explicitly bring the 'Typeable' class into scope, with e.g. > > > > import Data.Typeable (Typeable) > > > > otherwise GHC complains with > > > > Not in scope: type constructor or class ?Typeable? > > > > Since at this point it's become current practice to have 'Typeable' > > instances for most types, it would be beneficial to save an 'import > > Data.Typeable (Typeable)' line for the sole purpose of deriving such > > instances. > > > > By having 'Prelude' re-export 'Typeable' from GHC 7.10 on (should this > > proposal be implemented) it would suffice to have a > > > > default-extensions: -XAutoDeriveTypeable` > > > > in the Cabal file and have 'Typeable' instance auto-derived for all > > types defined in a package w/o any source changes (unless there's a > > name-clash with 'Typeable') > > > > Discussion period > > ================= > > > > The usual 2 weeks > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://www.haskell.org/mailman/listinfo/libraries > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From felipe.lessa at gmail.com Thu Sep 11 14:11:38 2014 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Thu, 11 Sep 2014 11:11:38 -0300 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: References: <87vbou792c.fsf@gmail.com> <8BBB2DF2-A517-48C3-901D-53EE36692E36@seas.upenn.edu> Message-ID: <5411AD9A.8000206@gmail.com> On 11-09-2014 11:05, Michael Snoyman wrote: > The one case I think Typeable should *always* be around for is creating > new instances of Exception. The fact that AutoDeriveTypeable doesn't > require Typeable in Prelude lessens my +1 a bit down to a +0.5, but I > really want it to be easier for people to define their own exception types. That's an argument for exporting Typeable from Control.Exception, since Prelude does not export Exception and friends. -- Felipe. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From schlepptop at henning-thielemann.de Thu Sep 11 14:17:09 2014 From: schlepptop at henning-thielemann.de (Henning Thielemann) Date: Thu, 11 Sep 2014 16:17:09 +0200 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <5411AD9A.8000206@gmail.com> References: <87vbou792c.fsf@gmail.com> <8BBB2DF2-A517-48C3-901D-53EE36692E36@seas.upenn.edu> <5411AD9A.8000206@gmail.com> Message-ID: <5411AEE5.2040103@henning-thielemann.de> Am 11.09.2014 um 16:11 schrieb Felipe Lessa: > On 11-09-2014 11:05, Michael Snoyman wrote: >> The one case I think Typeable should *always* be around for is creating >> new instances of Exception. The fact that AutoDeriveTypeable doesn't >> require Typeable in Prelude lessens my +1 a bit down to a +0.5, but I >> really want it to be easier for people to define their own exception types. > > That's an argument for exporting Typeable from Control.Exception, since > Prelude does not export Exception and friends. For me the Typeable constraint of the Exception class is just an argument to not use implicit exceptions of IO, but instead use one of the various Exception monads with explicit exception types. From allbery.b at gmail.com Thu Sep 11 14:25:33 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Thu, 11 Sep 2014 10:25:33 -0400 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <5411AEE5.2040103@henning-thielemann.de> References: <87vbou792c.fsf@gmail.com> <8BBB2DF2-A517-48C3-901D-53EE36692E36@seas.upenn.edu> <5411AD9A.8000206@gmail.com> <5411AEE5.2040103@henning-thielemann.de> Message-ID: On Thu, Sep 11, 2014 at 10:17 AM, Henning Thielemann < schlepptop at henning-thielemann.de> wrote: > Am 11.09.2014 um 16:11 schrieb Felipe Lessa: > > On 11-09-2014 11:05, Michael Snoyman wrote: >> >>> The one case I think Typeable should *always* be around for is creating >>> new instances of Exception. The fact that AutoDeriveTypeable doesn't >>> require Typeable in Prelude lessens my +1 a bit down to a +0.5, but I >>> really want it to be easier for people to define their own exception >>> types. >>> >> >> That's an argument for exporting Typeable from Control.Exception, since >> Prelude does not export Exception and friends. >> > > For me the Typeable constraint of the Exception class is just an argument > to not use implicit exceptions of IO, but instead use one of the various > Exception monads with explicit exception types. Not to mention that "...want it to be easier for people to define their own exception types" really makes me think something's gone wrong with the design somewhere. Exceptions ought to be ... exceptional, not common enough that people regularly need to define their own. -- 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 hesselink at gmail.com Thu Sep 11 14:42:08 2014 From: hesselink at gmail.com (Erik Hesselink) Date: Thu, 11 Sep 2014 16:42:08 +0200 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: References: <87vbou792c.fsf@gmail.com> <8BBB2DF2-A517-48C3-901D-53EE36692E36@seas.upenn.edu> <5411AD9A.8000206@gmail.com> <5411AEE5.2040103@henning-thielemann.de> Message-ID: On Thu, Sep 11, 2014 at 4:25 PM, Brandon Allbery wrote: > On Thu, Sep 11, 2014 at 10:17 AM, Henning Thielemann > wrote: >> >> Am 11.09.2014 um 16:11 schrieb Felipe Lessa: >> >>> On 11-09-2014 11:05, Michael Snoyman wrote: >>>> >>>> The one case I think Typeable should *always* be around for is creating >>>> new instances of Exception. The fact that AutoDeriveTypeable doesn't >>>> require Typeable in Prelude lessens my +1 a bit down to a +0.5, but I >>>> really want it to be easier for people to define their own exception >>>> types. >>> >>> >>> That's an argument for exporting Typeable from Control.Exception, since >>> Prelude does not export Exception and friends. >> >> >> For me the Typeable constraint of the Exception class is just an argument >> to not use implicit exceptions of IO, but instead use one of the various >> Exception monads with explicit exception types. > > > Not to mention that "...want it to be easier for people to define their own > exception types" really makes me think something's gone wrong with the > design somewhere. Exceptions ought to be ... exceptional, not common enough > that people regularly need to define their own. I thought the whole point of extensible exceptions was to define your own? That way you can catch them, instead of just piling them all together. I get that there are people who think you shouldn't use exceptions at all, but for the people who *do* use them, I think they should almost always define a new type for each one. Erik From ganesh at earth.li Thu Sep 11 20:38:52 2014 From: ganesh at earth.li (Ganesh Sittampalam) Date: Thu, 11 Sep 2014 21:38:52 +0100 Subject: HTTP package - supported GHC versions In-Reply-To: <87d2b51b8a.fsf@gnu.org> References: <54063589.8020503@earth.li> <87ppfd3zw7.fsf@gnu.org> <540708C3.1090900@earth.li> <878um04om6.fsf@gnu.org> <5408056F.80601@chalmers.se> <540E1D70.60208@earth.li> <87d2b51b8a.fsf@gnu.org> Message-ID: <5412085C.5010608@earth.li> On 09/09/2014 08:53, Herbert Valerio Riedel wrote: > GHC 7.0 shipped with Cabal-1.10 (and so cabal-install-0.10 is the likely > version used by GHC 7.0 users); so that should give you a hint about how > many users didn't upgrade their cabal-install and stayed with > cabal-install-0.10 (and probably GHC 7.0.x). So there are probably still > a few users left on GHC 7.0... Thanks a lot for the analysis! I think I'll keep 7.0 support around for now and review it after there's a Haskell Platform with GHC 7.10. Cheers, Ganesh From dominic at steinitz.org Fri Sep 12 07:45:06 2014 From: dominic at steinitz.org (Dominic Steinitz) Date: Fri, 12 Sep 2014 08:45:06 +0100 Subject: Taking over random-fu Message-ID: <41899898-EEED-4108-B9A5-67E67469C4DA@steinitz.org> Hi James, I have quite a few changes I would like to make to the package and I haven?t heard anything from you. I think they are all for the good. This > http://www.haskell.org/haskellwiki/Taking_over_a_package suggests you can add me as a maintainer by going to > http://hackage.haskell.org/package/random-fu/maintainers/ and clicking on edit. I am DominicSteinitz on hackage. Also you would have to give me permission to update the repo on github where I am idontgetoutmuch. Many thanks, Dominic Steinitz dominic at steinitz.org http://idontgetoutmuch.wordpress.com From alexander at plaimi.net Fri Sep 12 09:58:51 2014 From: alexander at plaimi.net (Alexander Berntsen) Date: Fri, 12 Sep 2014 11:58:51 +0200 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <87vbou792c.fsf@gmail.com> References: <87vbou792c.fsf@gmail.com> Message-ID: <5412C3DB.6030301@plaimi.net> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 - -1. - -- Alexander alexander at plaimi.net https://secure.plaimi.net/~alexander -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/ iF4EAREIAAYFAlQSw9sACgkQRtClrXBQc7WTAQD+Ir7dDzvfvWQ3z2l8OYF5zQmm D16L/e0HJCG0zorYr0QA/isRfKETQ87e2SOdiZ65PvZbbikalRcupp8EZbUzkXQ1 =92Au -----END PGP SIGNATURE----- From ekmett at gmail.com Fri Sep 12 15:13:23 2014 From: ekmett at gmail.com (Edward Kmett) Date: Fri, 12 Sep 2014 11:13:23 -0400 Subject: PROPOSAL: re-export 'Typeable' type-class from Prelude In-Reply-To: <87vbou792c.fsf@gmail.com> References: <87vbou792c.fsf@gmail.com> Message-ID: After some deliberation on this I think I also come down -1 on this proposal. default-extensions: AutoDeriveTypeable doesn't need it, so there is no technical reason to encumber everyone with it. It'd cause a huge spate of warnings that'd force everyone to mangle their import list in different ways with CPP, and without the methods for working with it most users'd have to import more from Data.Typeable anyways. -Edward On Thu, Sep 11, 2014 at 6:20 AM, Herbert Valerio Riedel wrote: > > TL;DR > ===== > > Re-export 'Data.Typeable.Typeable' from 'Prelude' > > Motivation > ========== > > Since GHC 7.8 the ubiquitous 'Typeable' instances can only be > auto-derived via `... deriving Typeable`, moreover there's a new > extension `-XAutoDeriveTypeable` which implicitly auto-derives > 'Typeable' for all defined types in modules for which that extension is > enabled. > > However, even if you enable `-XAutoDeriveTypeable` you still need to > explicitly bring the 'Typeable' class into scope, with e.g. > > import Data.Typeable (Typeable) > > otherwise GHC complains with > > Not in scope: type constructor or class ?Typeable? > > Since at this point it's become current practice to have 'Typeable' > instances for most types, it would be beneficial to save an 'import > Data.Typeable (Typeable)' line for the sole purpose of deriving such > instances. > > By having 'Prelude' re-export 'Typeable' from GHC 7.10 on (should this > proposal be implemented) it would suffice to have a > > default-extensions: -XAutoDeriveTypeable` > > in the Cabal file and have 'Typeable' instance auto-derived for all > types defined in a package w/o any source changes (unless there's a > name-clash with 'Typeable') > > Discussion period > ================= > > The usual 2 weeks > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From merijn at inconsistent.nl Sun Sep 14 01:51:40 2014 From: merijn at inconsistent.nl (Merijn Verstraaten) Date: Sat, 13 Sep 2014 18:51:40 -0700 Subject: PROPOSAL: Add newBroadcastChan :: IO (Chan a) to Control.Concurrent.Chan In-Reply-To: <968B00C0-C88B-46ED-BD89-5AC53E611221@inconsistent.nl> References: <968B00C0-C88B-46ED-BD89-5AC53E611221@inconsistent.nl> Message-ID: <55352C8F-B3F4-4D10-A645-AD71828A0F49@inconsistent.nl> Since some people on IRC asked for an example implementation, two implementations spring to mind: Implementation #1: newBroadcastChan :: IO (Chan a) newBroadcastChan = do hole <- newEmptyMVar readVar <- newMVar (error "reading from a TChan created by newBroadcastTChan; use dupTChan first") writeVar <- newMVar hole return (Chan readVar writeVar) Pros: - Identical to TChan equivalent - Only one extra function to the API Cons: - Accidental reads lead to crash Implementation #2: newtype BroadcastChan a = BChan (MVar (Stream a)) newBroadcastChan :: IO (BroadcastChan a) newBroadcastChan = do hole <- newEmptyMVar writeVar <- newMVar hole return (BChan writeVar) dupFromBroadcastChan :: BroadcastChan a -> IO (Chan a) dupFromBroadcastChan (BChan writeVar) = do hole <- readMVar writeVar newReadVar <- newMVar hole return (Chan newReadVar writeVar) Pros - Prevents accidental reads from write-only Chan Cons - Adds more new stuff to that API? Cheers, Merijn On 09 Sep 2014, at 00:30 , Merijn Verstraaten wrote: > Ola! > > Control.Concurrent.STM.TChan has the ?newBroadcastTChan :: STM (TChan a)?, this creates a ?write-only? TChan to avoid any space leaks when a Chan is written too but never read from (for example, when dupTChan is used to hand a copy to threads). Unfortunately, no such variant seems to exist for the normal Chan? I have the following code: > > foo :: Chan a -> IO Foo > foo broadcast = do > newListener <- dupChan broadcast > forkIO $ doStuffWith newListener > > This means the original Chan is never read from and much like the problem with TChan, values keep piling up in the original channel, causing a space leak. I propose adding > > newBroadcastChan :: IO (Chan a) > > The obvious Chan equivalent of newBroadcastTChan, which creates a write-only channel without read end, thus avoiding this space leak. > > Discussion: 2 weeks? > > Cheers, > Merijn -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 801 bytes Desc: Message signed with OpenPGP using GPGMail URL: From dominic at steinitz.org Sun Sep 14 06:28:56 2014 From: dominic at steinitz.org (Dominic Steinitz) Date: Sun, 14 Sep 2014 07:28:56 +0100 Subject: Taking over random-fu In-Reply-To: <2787D2AC-DB55-4FAD-84BE-C591D6CEB8BA@deepbondi.net> References: <41899898-EEED-4108-B9A5-67E67469C4DA@steinitz.org> <2787D2AC-DB55-4FAD-84BE-C591D6CEB8BA@deepbondi.net> Message-ID: <54DEF3C0-697F-4163-B912-C4133FAD7919@steinitz.org> Thanks very much for this. I should have guessed you had had children as that is one of the main reasons for folks having less time. Enjoy them (the children that is). Dominic Steinitz dominic at steinitz.org http://idontgetoutmuch.wordpress.com On 13 Sep 2014, at 16:58, James Cook wrote: > Sorry about the lack of responsiveness, life has been pretty crazy since I had kids. If you're willing to take it on, that's probably best for the community right now. I will make those changes now. > > -- James > > On Sep 12, 2014, at 12:45 AM, Dominic Steinitz wrote: > >> Hi James, >> >> I have quite a few changes I would like to make to the package and I haven?t heard anything from you. I think they are all for the good. >> >> This >> >>> http://www.haskell.org/haskellwiki/Taking_over_a_package >> >> >> suggests you can add me as a maintainer by going to >> >>> http://hackage.haskell.org/package/random-fu/maintainers/ >> >> >> and clicking on edit. I am DominicSteinitz on hackage. >> >> Also you would have to give me permission to update the repo on github where I am idontgetoutmuch. >> >> Many thanks, >> >> Dominic Steinitz >> dominic at steinitz.org >> http://idontgetoutmuch.wordpress.com >> > From ashley at semantic.org Wed Sep 17 01:33:52 2014 From: ashley at semantic.org (Ashley Yakeley) Date: Tue, 16 Sep 2014 18:33:52 -0700 Subject: old-locale In-Reply-To: References: <20111022212808.GA14424@matrix.chaos.earth.li> <1319442811.4070.8.camel@glastonbury> <1319564851.9419.12.camel@glastonbury> Message-ID: <5418E500.2000203@semantic.org> TimeLocale is now in Data.Time.Format, in time-1.5. -- Ashley On 2013-06-16 08:39, David Virebayre wrote: > Hello, > > I've very sorry to revive such an old discussion, but I was wordering > if there was any follow up to this discussion ? > It doesn't look like TimeLocale ended up in Date.Time.LocalTime, and > time-locale doesn't exist. > > I have to compare two dates, one coming from a string I have to parse, > the other from a file's modification time. I was looking for a way to > get rid of the old-locale dependency; though at this point it's not > that important. > > Thanks, > > David. > > > 2011/10/25 Yitzchak Gale : >> I agree with all that Bas and Ashley wrote. >> >> If Ashley agrees to put TimeLocale into D.T.F, I >> withdraw my two proposals and we'll all celebrate. >> >> We can deprecate old-locale and issue a last version >> that just re-exports from D.T.F. We'll leave it in the >> platform until the handful of other platform packages >> using it migrate to D.T.F, then remove it from the >> platform. >> >> User code that hasn't been able to migrate by then >> can still be compiled by installing old-locale from hackage. >> >> And yes, I agree that a mechanism for deprecation >> warnings via cabal would be really nice. >> >> Thanks, >> Yitz >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries > > From david.feuer at gmail.com Thu Sep 18 21:37:33 2014 From: david.feuer at gmail.com (David Feuer) Date: Thu, 18 Sep 2014 17:37:33 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes Message-ID: To go along with Herbert Valerio Riedel's moving functions from Foldable and Traversable to Prelude, I realized that `null` and `size` make sense for all Foldables; Reid W. Barton noted that these can have optimized implementations for many containers. He also noted that scanl1 and scanr1 make sense for general Traversables. I therefore propose: Add `null` and `size` to the Foldable class. Default implementations: null = foldr (\_ _ -> False) True size = foldl' (\acc _ -> acc+1) 0 Add `scanl1` and `scanr1` to the Traversable class. Default implementations are a little less simple. David -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Thu Sep 18 21:43:27 2014 From: ekmett at gmail.com (Edward Kmett) Date: Thu, 18 Sep 2014 17:43:27 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: Choosing the name `size` isn't free. If we chose `length` then the existing code continues to work, code that was hiding it on import continues to hide it and you don't get conflicts. Picking 'size' is compatible with common practice, but means a ton of modules would break. Given the two solutions, one that doesn't break anything and one that does, with negligible differences between them otherwise, I'd prefer the one that causes the least amount of pain. -Edward On Thu, Sep 18, 2014 at 5:37 PM, David Feuer wrote: > To go along with Herbert Valerio Riedel's moving functions from Foldable > and Traversable to Prelude, I realized that `null` and `size` make sense > for all Foldables; Reid W. Barton noted that these can have optimized > implementations for many containers. He also noted that scanl1 and scanr1 > make sense for general Traversables. I therefore propose: > > Add `null` and `size` to the Foldable class. Default implementations: > > null = foldr (\_ _ -> False) True > > size = foldl' (\acc _ -> acc+1) 0 > > Add `scanl1` and `scanr1` to the Traversable class. Default > implementations are a little less simple. > > David > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Thu Sep 18 21:49:10 2014 From: david.feuer at gmail.com (David Feuer) Date: Thu, 18 Sep 2014 17:49:10 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: R.W. Barton was having trouble spitting out the words "length of a set", and the same holds for all sorts of other things, but unfortunately I think you're right. Proposal amended: put length in the Foldable class. On Thu, Sep 18, 2014 at 5:43 PM, Edward Kmett wrote: > Choosing the name `size` isn't free. > > If we chose `length` then the existing code continues to work, code that > was hiding it on import continues to hide it and you don't get conflicts. > > Picking 'size' is compatible with common practice, but means a ton of > modules would break. > > Given the two solutions, one that doesn't break anything and one that > does, with negligible differences between them otherwise, I'd prefer the > one that causes the least amount of pain. > > -Edward > > On Thu, Sep 18, 2014 at 5:37 PM, David Feuer > wrote: > >> To go along with Herbert Valerio Riedel's moving functions from Foldable >> and Traversable to Prelude, I realized that `null` and `size` make sense >> for all Foldables; Reid W. Barton noted that these can have optimized >> implementations for many containers. He also noted that scanl1 and scanr1 >> make sense for general Traversables. I therefore propose: >> >> Add `null` and `size` to the Foldable class. Default implementations: >> >> null = foldr (\_ _ -> False) True >> >> size = foldl' (\acc _ -> acc+1) 0 >> >> Add `scanl1` and `scanr1` to the Traversable class. Default >> implementations are a little less simple. >> >> David >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Thu Sep 18 22:20:34 2014 From: david.feuer at gmail.com (David Feuer) Date: Thu, 18 Sep 2014 18:20:34 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: I'm sorry to send so many emails, but elem should also be moved into the Foldable class to support optimized versions for searchable containers. We should also move maximum and minimum into the Foldable class to allow optimized versions. We need to settle the semantics of these anyway?Data.List.{maximum,minimum} and Data.Foldable.{maximum,minimum} currently behave differently (left-to-right vs. right-to-left). I think we want "whatever's best", which thankfully leaves the list version with its current semantics. David On Thu, Sep 18, 2014 at 5:49 PM, David Feuer wrote: > R.W. Barton was having trouble spitting out the words "length of a set", > and the same holds for all sorts of other things, but unfortunately I think > you're right. Proposal amended: put length in the Foldable class. > > On Thu, Sep 18, 2014 at 5:43 PM, Edward Kmett wrote: > >> Choosing the name `size` isn't free. >> >> If we chose `length` then the existing code continues to work, code that >> was hiding it on import continues to hide it and you don't get conflicts. >> >> Picking 'size' is compatible with common practice, but means a ton of >> modules would break. >> >> Given the two solutions, one that doesn't break anything and one that >> does, with negligible differences between them otherwise, I'd prefer the >> one that causes the least amount of pain. >> >> -Edward >> >> On Thu, Sep 18, 2014 at 5:37 PM, David Feuer >> wrote: >> >>> To go along with Herbert Valerio Riedel's moving functions from Foldable >>> and Traversable to Prelude, I realized that `null` and `size` make sense >>> for all Foldables; Reid W. Barton noted that these can have optimized >>> implementations for many containers. He also noted that scanl1 and scanr1 >>> make sense for general Traversables. I therefore propose: >>> >>> Add `null` and `size` to the Foldable class. Default implementations: >>> >>> null = foldr (\_ _ -> False) True >>> >>> size = foldl' (\acc _ -> acc+1) 0 >>> >>> Add `scanl1` and `scanr1` to the Traversable class. Default >>> implementations are a little less simple. >>> >>> David >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Thu Sep 18 23:26:22 2014 From: david.feuer at gmail.com (David Feuer) Date: Thu, 18 Sep 2014 19:26:22 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: After discussing these matters some more with Edward Kmett and Reid Barton, it appears the following makes sense: Add the following to Foldable: length?often stored as a separate field for O(1) access null?called very often and slightly faster than foldr (\_ _ -> False) True for some containers toList?may be the identity or nearly so, and this fact may not be statically available to the foldr/id rule sum, product?may be cached internally in tree nodes for fast update, giving O(1) access; may be calculated in parallel. maximum, minimum?O(n) for a search tree; O(1) for a finger tree. elem?O(log n) for search trees; likely better for hash tables and such. Don't add anything to Traversable, because scanl1 and scanr1 are not worth the extra dictionary weight. On Thu, Sep 18, 2014 at 6:20 PM, David Feuer wrote: > I'm sorry to send so many emails, but elem should also be moved into the > Foldable class to support optimized versions for searchable containers. We > should also move maximum and minimum into the Foldable class to allow > optimized versions. We need to settle the semantics of these > anyway?Data.List.{maximum,minimum} and Data.Foldable.{maximum,minimum} > currently behave differently (left-to-right vs. right-to-left). I think we > want "whatever's best", which thankfully leaves the list version with its > current semantics. > > David > > > On Thu, Sep 18, 2014 at 5:49 PM, David Feuer > wrote: > >> R.W. Barton was having trouble spitting out the words "length of a set", >> and the same holds for all sorts of other things, but unfortunately I think >> you're right. Proposal amended: put length in the Foldable class. >> >> On Thu, Sep 18, 2014 at 5:43 PM, Edward Kmett wrote: >> >>> Choosing the name `size` isn't free. >>> >>> If we chose `length` then the existing code continues to work, code that >>> was hiding it on import continues to hide it and you don't get conflicts. >>> >>> Picking 'size' is compatible with common practice, but means a ton of >>> modules would break. >>> >>> Given the two solutions, one that doesn't break anything and one that >>> does, with negligible differences between them otherwise, I'd prefer the >>> one that causes the least amount of pain. >>> >>> -Edward >>> >>> On Thu, Sep 18, 2014 at 5:37 PM, David Feuer >>> wrote: >>> >>>> To go along with Herbert Valerio Riedel's moving functions from >>>> Foldable and Traversable to Prelude, I realized that `null` and `size` make >>>> sense for all Foldables; Reid W. Barton noted that these can have optimized >>>> implementations for many containers. He also noted that scanl1 and scanr1 >>>> make sense for general Traversables. I therefore propose: >>>> >>>> Add `null` and `size` to the Foldable class. Default implementations: >>>> >>>> null = foldr (\_ _ -> False) True >>>> >>>> size = foldl' (\acc _ -> acc+1) 0 >>>> >>>> Add `scanl1` and `scanr1` to the Traversable class. Default >>>> implementations are a little less simple. >>>> >>>> David >>>> >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://www.haskell.org/mailman/listinfo/libraries >>>> >>>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwlato at gmail.com Thu Sep 18 23:49:59 2014 From: jwlato at gmail.com (John Lato) Date: Thu, 18 Sep 2014 16:49:59 -0700 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: Enthusiastically +1 Every package I know that provides something like Foldable (ListLike, mono-traversable, a few others) includes these, largely for performance reasons. I'm not entirely convinced with the reasoning that sum and product may be calculated in parallel though. IMHO for structures that care about parallel reductions, I think foldMap should be the main entry point. But I can see these might be cached. John L. On Thu, Sep 18, 2014 at 4:26 PM, David Feuer wrote: > After discussing these matters some more with Edward Kmett and Reid > Barton, it appears the following makes sense: > > Add the following to Foldable: > length?often stored as a separate field for O(1) access > null?called very often and slightly faster than foldr (\_ _ -> False) True > for some containers > toList?may be the identity or nearly so, and this fact may not be > statically available to the foldr/id rule > sum, product?may be cached internally in tree nodes for fast update, > giving O(1) access; may be calculated in parallel. > maximum, minimum?O(n) for a search tree; O(1) for a finger tree. > elem?O(log n) for search trees; likely better for hash tables and such. > > Don't add anything to Traversable, because scanl1 and scanr1 are not worth > the extra dictionary weight. > > On Thu, Sep 18, 2014 at 6:20 PM, David Feuer > wrote: > >> I'm sorry to send so many emails, but elem should also be moved into the >> Foldable class to support optimized versions for searchable containers. We >> should also move maximum and minimum into the Foldable class to allow >> optimized versions. We need to settle the semantics of these >> anyway?Data.List.{maximum,minimum} and Data.Foldable.{maximum,minimum} >> currently behave differently (left-to-right vs. right-to-left). I think we >> want "whatever's best", which thankfully leaves the list version with its >> current semantics. >> >> David >> >> >> On Thu, Sep 18, 2014 at 5:49 PM, David Feuer >> wrote: >> >>> R.W. Barton was having trouble spitting out the words "length of a set", >>> and the same holds for all sorts of other things, but unfortunately I think >>> you're right. Proposal amended: put length in the Foldable class. >>> >>> On Thu, Sep 18, 2014 at 5:43 PM, Edward Kmett wrote: >>> >>>> Choosing the name `size` isn't free. >>>> >>>> If we chose `length` then the existing code continues to work, code >>>> that was hiding it on import continues to hide it and you don't get >>>> conflicts. >>>> >>>> Picking 'size' is compatible with common practice, but means a ton of >>>> modules would break. >>>> >>>> Given the two solutions, one that doesn't break anything and one that >>>> does, with negligible differences between them otherwise, I'd prefer the >>>> one that causes the least amount of pain. >>>> >>>> -Edward >>>> >>>> On Thu, Sep 18, 2014 at 5:37 PM, David Feuer >>>> wrote: >>>> >>>>> To go along with Herbert Valerio Riedel's moving functions from >>>>> Foldable and Traversable to Prelude, I realized that `null` and `size` make >>>>> sense for all Foldables; Reid W. Barton noted that these can have optimized >>>>> implementations for many containers. He also noted that scanl1 and scanr1 >>>>> make sense for general Traversables. I therefore propose: >>>>> >>>>> Add `null` and `size` to the Foldable class. Default implementations: >>>>> >>>>> null = foldr (\_ _ -> False) True >>>>> >>>>> size = foldl' (\acc _ -> acc+1) 0 >>>>> >>>>> Add `scanl1` and `scanr1` to the Traversable class. Default >>>>> implementations are a little less simple. >>>>> >>>>> David >>>>> >>>>> _______________________________________________ >>>>> Libraries mailing list >>>>> Libraries at haskell.org >>>>> http://www.haskell.org/mailman/listinfo/libraries >>>>> >>>>> >>>> >>> >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Thu Sep 18 23:59:07 2014 From: ekmett at gmail.com (Edward Kmett) Date: Thu, 18 Sep 2014 19:59:07 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: sum and product inclusion mostly allows you do a.) do something smarter than foldl or b.) deal with containers that do things like store prefix sums. In general you can view the operations as being defined as given toList = foldr (:) [] then all the other operations as giving results to match e.g. maximum = maximum . toList with possibly asymptotically much more efficient implementations. Including toList in the class permits lists and many containers that include a list directly to convert to the 'view' type of being a list in O(1). -Edward On Thu, Sep 18, 2014 at 7:49 PM, John Lato wrote: > Enthusiastically +1 > > Every package I know that provides something like Foldable (ListLike, > mono-traversable, a few others) includes these, largely for performance > reasons. > > I'm not entirely convinced with the reasoning that sum and product may be > calculated in parallel though. IMHO for structures that care about > parallel reductions, I think foldMap should be the main entry point. But I > can see these might be cached. > > John L. > > On Thu, Sep 18, 2014 at 4:26 PM, David Feuer > wrote: > >> After discussing these matters some more with Edward Kmett and Reid >> Barton, it appears the following makes sense: >> >> Add the following to Foldable: >> length?often stored as a separate field for O(1) access >> null?called very often and slightly faster than foldr (\_ _ -> False) >> True for some containers >> toList?may be the identity or nearly so, and this fact may not be >> statically available to the foldr/id rule >> sum, product?may be cached internally in tree nodes for fast update, >> giving O(1) access; may be calculated in parallel. >> maximum, minimum?O(n) for a search tree; O(1) for a finger tree. >> elem?O(log n) for search trees; likely better for hash tables and such. >> >> Don't add anything to Traversable, because scanl1 and scanr1 are not >> worth the extra dictionary weight. >> >> On Thu, Sep 18, 2014 at 6:20 PM, David Feuer >> wrote: >> >>> I'm sorry to send so many emails, but elem should also be moved into the >>> Foldable class to support optimized versions for searchable containers. We >>> should also move maximum and minimum into the Foldable class to allow >>> optimized versions. We need to settle the semantics of these >>> anyway?Data.List.{maximum,minimum} and Data.Foldable.{maximum,minimum} >>> currently behave differently (left-to-right vs. right-to-left). I think we >>> want "whatever's best", which thankfully leaves the list version with its >>> current semantics. >>> >>> David >>> >>> >>> On Thu, Sep 18, 2014 at 5:49 PM, David Feuer >>> wrote: >>> >>>> R.W. Barton was having trouble spitting out the words "length of a >>>> set", and the same holds for all sorts of other things, but unfortunately I >>>> think you're right. Proposal amended: put length in the Foldable class. >>>> >>>> On Thu, Sep 18, 2014 at 5:43 PM, Edward Kmett wrote: >>>> >>>>> Choosing the name `size` isn't free. >>>>> >>>>> If we chose `length` then the existing code continues to work, code >>>>> that was hiding it on import continues to hide it and you don't get >>>>> conflicts. >>>>> >>>>> Picking 'size' is compatible with common practice, but means a ton of >>>>> modules would break. >>>>> >>>>> Given the two solutions, one that doesn't break anything and one that >>>>> does, with negligible differences between them otherwise, I'd prefer the >>>>> one that causes the least amount of pain. >>>>> >>>>> -Edward >>>>> >>>>> On Thu, Sep 18, 2014 at 5:37 PM, David Feuer >>>>> wrote: >>>>> >>>>>> To go along with Herbert Valerio Riedel's moving functions from >>>>>> Foldable and Traversable to Prelude, I realized that `null` and `size` make >>>>>> sense for all Foldables; Reid W. Barton noted that these can have optimized >>>>>> implementations for many containers. He also noted that scanl1 and scanr1 >>>>>> make sense for general Traversables. I therefore propose: >>>>>> >>>>>> Add `null` and `size` to the Foldable class. Default implementations: >>>>>> >>>>>> null = foldr (\_ _ -> False) True >>>>>> >>>>>> size = foldl' (\acc _ -> acc+1) 0 >>>>>> >>>>>> Add `scanl1` and `scanr1` to the Traversable class. Default >>>>>> implementations are a little less simple. >>>>>> >>>>>> David >>>>>> >>>>>> _______________________________________________ >>>>>> Libraries mailing list >>>>>> Libraries at haskell.org >>>>>> http://www.haskell.org/mailman/listinfo/libraries >>>>>> >>>>>> >>>>> >>>> >>> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Fri Sep 19 00:37:02 2014 From: david.feuer at gmail.com (David Feuer) Date: Thu, 18 Sep 2014 20:37:02 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: I'm sorry for confusing things. I had wondered why Foldable uses a right fold instead of a left fold, and the parallel thing was the answer to that. On Thu, Sep 18, 2014 at 7:59 PM, Edward Kmett wrote: > sum and product inclusion mostly allows you do a.) do something smarter > than foldl or b.) deal with containers that do things like store prefix > sums. > > In general you can view the operations as being defined as > > given > > toList = foldr (:) [] > > then all the other operations as giving results to match > > e.g. > > maximum = maximum . toList > > with possibly asymptotically much more efficient implementations. > > Including toList in the class permits lists and many containers that > include a list directly to convert to the 'view' type of being a list in > O(1). > > -Edward > > > On Thu, Sep 18, 2014 at 7:49 PM, John Lato wrote: > >> Enthusiastically +1 >> >> Every package I know that provides something like Foldable (ListLike, >> mono-traversable, a few others) includes these, largely for performance >> reasons. >> >> I'm not entirely convinced with the reasoning that sum and product may be >> calculated in parallel though. IMHO for structures that care about >> parallel reductions, I think foldMap should be the main entry point. But I >> can see these might be cached. >> >> John L. >> >> On Thu, Sep 18, 2014 at 4:26 PM, David Feuer >> wrote: >> >>> After discussing these matters some more with Edward Kmett and Reid >>> Barton, it appears the following makes sense: >>> >>> Add the following to Foldable: >>> length?often stored as a separate field for O(1) access >>> null?called very often and slightly faster than foldr (\_ _ -> False) >>> True for some containers >>> toList?may be the identity or nearly so, and this fact may not be >>> statically available to the foldr/id rule >>> sum, product?may be cached internally in tree nodes for fast update, >>> giving O(1) access; may be calculated in parallel. >>> maximum, minimum?O(n) for a search tree; O(1) for a finger tree. >>> elem?O(log n) for search trees; likely better for hash tables and such. >>> >>> Don't add anything to Traversable, because scanl1 and scanr1 are not >>> worth the extra dictionary weight. >>> >>> On Thu, Sep 18, 2014 at 6:20 PM, David Feuer >>> wrote: >>> >>>> I'm sorry to send so many emails, but elem should also be moved into >>>> the Foldable class to support optimized versions for searchable containers. >>>> We should also move maximum and minimum into the Foldable class to allow >>>> optimized versions. We need to settle the semantics of these >>>> anyway?Data.List.{maximum,minimum} and Data.Foldable.{maximum,minimum} >>>> currently behave differently (left-to-right vs. right-to-left). I think we >>>> want "whatever's best", which thankfully leaves the list version with its >>>> current semantics. >>>> >>>> David >>>> >>>> >>>> On Thu, Sep 18, 2014 at 5:49 PM, David Feuer >>>> wrote: >>>> >>>>> R.W. Barton was having trouble spitting out the words "length of a >>>>> set", and the same holds for all sorts of other things, but unfortunately I >>>>> think you're right. Proposal amended: put length in the Foldable class. >>>>> >>>>> On Thu, Sep 18, 2014 at 5:43 PM, Edward Kmett >>>>> wrote: >>>>> >>>>>> Choosing the name `size` isn't free. >>>>>> >>>>>> If we chose `length` then the existing code continues to work, code >>>>>> that was hiding it on import continues to hide it and you don't get >>>>>> conflicts. >>>>>> >>>>>> Picking 'size' is compatible with common practice, but means a ton of >>>>>> modules would break. >>>>>> >>>>>> Given the two solutions, one that doesn't break anything and one that >>>>>> does, with negligible differences between them otherwise, I'd prefer the >>>>>> one that causes the least amount of pain. >>>>>> >>>>>> -Edward >>>>>> >>>>>> On Thu, Sep 18, 2014 at 5:37 PM, David Feuer >>>>>> wrote: >>>>>> >>>>>>> To go along with Herbert Valerio Riedel's moving functions from >>>>>>> Foldable and Traversable to Prelude, I realized that `null` and `size` make >>>>>>> sense for all Foldables; Reid W. Barton noted that these can have optimized >>>>>>> implementations for many containers. He also noted that scanl1 and scanr1 >>>>>>> make sense for general Traversables. I therefore propose: >>>>>>> >>>>>>> Add `null` and `size` to the Foldable class. Default implementations: >>>>>>> >>>>>>> null = foldr (\_ _ -> False) True >>>>>>> >>>>>>> size = foldl' (\acc _ -> acc+1) 0 >>>>>>> >>>>>>> Add `scanl1` and `scanr1` to the Traversable class. Default >>>>>>> implementations are a little less simple. >>>>>>> >>>>>>> David >>>>>>> >>>>>>> _______________________________________________ >>>>>>> Libraries mailing list >>>>>>> Libraries at haskell.org >>>>>>> http://www.haskell.org/mailman/listinfo/libraries >>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Fri Sep 19 02:55:44 2014 From: ekmett at gmail.com (Edward Kmett) Date: Thu, 18 Sep 2014 22:55:44 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: Actually the answer is different. foldMap is used to provide a 'natural' fold regardless of associativity. foldMap and foldr are are mutually definable, by using Endo to get foldr from foldMap, or just accepting a right associated monoidal reduction. This is why foldr or foldMap are the minimal definitions. However, you can't build foldr in terms of foldl with the right behavior on infinite containers, so foldl is _not_ a viable minimal definition for Foldable in a world where you can have infinitely big things to fold! -Edward On Thu, Sep 18, 2014 at 8:37 PM, David Feuer wrote: > I'm sorry for confusing things. I had wondered why Foldable uses a right > fold instead of a left fold, and the parallel thing was the answer to that. > > On Thu, Sep 18, 2014 at 7:59 PM, Edward Kmett wrote: > >> sum and product inclusion mostly allows you do a.) do something smarter >> than foldl or b.) deal with containers that do things like store prefix >> sums. >> >> In general you can view the operations as being defined as >> >> given >> >> toList = foldr (:) [] >> >> then all the other operations as giving results to match >> >> e.g. >> >> maximum = maximum . toList >> >> with possibly asymptotically much more efficient implementations. >> >> Including toList in the class permits lists and many containers that >> include a list directly to convert to the 'view' type of being a list in >> O(1). >> >> -Edward >> >> >> On Thu, Sep 18, 2014 at 7:49 PM, John Lato wrote: >> >>> Enthusiastically +1 >>> >>> Every package I know that provides something like Foldable (ListLike, >>> mono-traversable, a few others) includes these, largely for performance >>> reasons. >>> >>> I'm not entirely convinced with the reasoning that sum and product may >>> be calculated in parallel though. IMHO for structures that care about >>> parallel reductions, I think foldMap should be the main entry point. But I >>> can see these might be cached. >>> >>> John L. >>> >>> On Thu, Sep 18, 2014 at 4:26 PM, David Feuer >>> wrote: >>> >>>> After discussing these matters some more with Edward Kmett and Reid >>>> Barton, it appears the following makes sense: >>>> >>>> Add the following to Foldable: >>>> length?often stored as a separate field for O(1) access >>>> null?called very often and slightly faster than foldr (\_ _ -> False) >>>> True for some containers >>>> toList?may be the identity or nearly so, and this fact may not be >>>> statically available to the foldr/id rule >>>> sum, product?may be cached internally in tree nodes for fast update, >>>> giving O(1) access; may be calculated in parallel. >>>> maximum, minimum?O(n) for a search tree; O(1) for a finger tree. >>>> elem?O(log n) for search trees; likely better for hash tables and such. >>>> >>>> Don't add anything to Traversable, because scanl1 and scanr1 are not >>>> worth the extra dictionary weight. >>>> >>>> On Thu, Sep 18, 2014 at 6:20 PM, David Feuer >>>> wrote: >>>> >>>>> I'm sorry to send so many emails, but elem should also be moved into >>>>> the Foldable class to support optimized versions for searchable containers. >>>>> We should also move maximum and minimum into the Foldable class to allow >>>>> optimized versions. We need to settle the semantics of these >>>>> anyway?Data.List.{maximum,minimum} and Data.Foldable.{maximum,minimum} >>>>> currently behave differently (left-to-right vs. right-to-left). I think we >>>>> want "whatever's best", which thankfully leaves the list version with its >>>>> current semantics. >>>>> >>>>> David >>>>> >>>>> >>>>> On Thu, Sep 18, 2014 at 5:49 PM, David Feuer >>>>> wrote: >>>>> >>>>>> R.W. Barton was having trouble spitting out the words "length of a >>>>>> set", and the same holds for all sorts of other things, but unfortunately I >>>>>> think you're right. Proposal amended: put length in the Foldable class. >>>>>> >>>>>> On Thu, Sep 18, 2014 at 5:43 PM, Edward Kmett >>>>>> wrote: >>>>>> >>>>>>> Choosing the name `size` isn't free. >>>>>>> >>>>>>> If we chose `length` then the existing code continues to work, code >>>>>>> that was hiding it on import continues to hide it and you don't get >>>>>>> conflicts. >>>>>>> >>>>>>> Picking 'size' is compatible with common practice, but means a ton >>>>>>> of modules would break. >>>>>>> >>>>>>> Given the two solutions, one that doesn't break anything and one >>>>>>> that does, with negligible differences between them otherwise, I'd prefer >>>>>>> the one that causes the least amount of pain. >>>>>>> >>>>>>> -Edward >>>>>>> >>>>>>> On Thu, Sep 18, 2014 at 5:37 PM, David Feuer >>>>>>> wrote: >>>>>>> >>>>>>>> To go along with Herbert Valerio Riedel's moving functions from >>>>>>>> Foldable and Traversable to Prelude, I realized that `null` and `size` make >>>>>>>> sense for all Foldables; Reid W. Barton noted that these can have optimized >>>>>>>> implementations for many containers. He also noted that scanl1 and scanr1 >>>>>>>> make sense for general Traversables. I therefore propose: >>>>>>>> >>>>>>>> Add `null` and `size` to the Foldable class. Default >>>>>>>> implementations: >>>>>>>> >>>>>>>> null = foldr (\_ _ -> False) True >>>>>>>> >>>>>>>> size = foldl' (\acc _ -> acc+1) 0 >>>>>>>> >>>>>>>> Add `scanl1` and `scanr1` to the Traversable class. Default >>>>>>>> implementations are a little less simple. >>>>>>>> >>>>>>>> David >>>>>>>> >>>>>>>> _______________________________________________ >>>>>>>> Libraries mailing list >>>>>>>> Libraries at haskell.org >>>>>>>> http://www.haskell.org/mailman/listinfo/libraries >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://www.haskell.org/mailman/listinfo/libraries >>>> >>>> >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dhelta.diaz at gmail.com Fri Sep 19 04:32:04 2014 From: dhelta.diaz at gmail.com (=?UTF-8?Q?Daniel_D=C3=ADaz_Casanueva?=) Date: Fri, 19 Sep 2014 00:32:04 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: +1 from me as well. In a library I wrote recently, I also provided with more efficient alternatives to those provided by the Foldable class. I'd rather point users to use the generic interface of Data.Foldable. Regards, Daniel D?az. On Thu, Sep 18, 2014 at 10:55 PM, Edward Kmett wrote: > Actually the answer is different. > > foldMap is used to provide a 'natural' fold regardless of associativity. > > foldMap and foldr are are mutually definable, by using Endo to get foldr > from foldMap, or just accepting a right associated monoidal reduction. > > This is why foldr or foldMap are the minimal definitions. > > However, you can't build foldr in terms of foldl with the right behavior > on infinite containers, so foldl is _not_ a viable minimal definition for > Foldable in a world where you can have infinitely big things to fold! > > -Edward > > On Thu, Sep 18, 2014 at 8:37 PM, David Feuer > wrote: > >> I'm sorry for confusing things. I had wondered why Foldable uses a right >> fold instead of a left fold, and the parallel thing was the answer to that. >> >> On Thu, Sep 18, 2014 at 7:59 PM, Edward Kmett wrote: >> >>> sum and product inclusion mostly allows you do a.) do something smarter >>> than foldl or b.) deal with containers that do things like store prefix >>> sums. >>> >>> In general you can view the operations as being defined as >>> >>> given >>> >>> toList = foldr (:) [] >>> >>> then all the other operations as giving results to match >>> >>> e.g. >>> >>> maximum = maximum . toList >>> >>> with possibly asymptotically much more efficient implementations. >>> >>> Including toList in the class permits lists and many containers that >>> include a list directly to convert to the 'view' type of being a list in >>> O(1). >>> >>> -Edward >>> >>> >>> On Thu, Sep 18, 2014 at 7:49 PM, John Lato wrote: >>> >>>> Enthusiastically +1 >>>> >>>> Every package I know that provides something like Foldable (ListLike, >>>> mono-traversable, a few others) includes these, largely for performance >>>> reasons. >>>> >>>> I'm not entirely convinced with the reasoning that sum and product may >>>> be calculated in parallel though. IMHO for structures that care about >>>> parallel reductions, I think foldMap should be the main entry point. But I >>>> can see these might be cached. >>>> >>>> John L. >>>> >>>> On Thu, Sep 18, 2014 at 4:26 PM, David Feuer >>>> wrote: >>>> >>>>> After discussing these matters some more with Edward Kmett and Reid >>>>> Barton, it appears the following makes sense: >>>>> >>>>> Add the following to Foldable: >>>>> length?often stored as a separate field for O(1) access >>>>> null?called very often and slightly faster than foldr (\_ _ -> False) >>>>> True for some containers >>>>> toList?may be the identity or nearly so, and this fact may not be >>>>> statically available to the foldr/id rule >>>>> sum, product?may be cached internally in tree nodes for fast update, >>>>> giving O(1) access; may be calculated in parallel. >>>>> maximum, minimum?O(n) for a search tree; O(1) for a finger tree. >>>>> elem?O(log n) for search trees; likely better for hash tables and such. >>>>> >>>>> Don't add anything to Traversable, because scanl1 and scanr1 are not >>>>> worth the extra dictionary weight. >>>>> >>>>> On Thu, Sep 18, 2014 at 6:20 PM, David Feuer >>>>> wrote: >>>>> >>>>>> I'm sorry to send so many emails, but elem should also be moved into >>>>>> the Foldable class to support optimized versions for searchable containers. >>>>>> We should also move maximum and minimum into the Foldable class to allow >>>>>> optimized versions. We need to settle the semantics of these >>>>>> anyway?Data.List.{maximum,minimum} and Data.Foldable.{maximum,minimum} >>>>>> currently behave differently (left-to-right vs. right-to-left). I think we >>>>>> want "whatever's best", which thankfully leaves the list version with its >>>>>> current semantics. >>>>>> >>>>>> David >>>>>> >>>>>> >>>>>> On Thu, Sep 18, 2014 at 5:49 PM, David Feuer >>>>>> wrote: >>>>>> >>>>>>> R.W. Barton was having trouble spitting out the words "length of a >>>>>>> set", and the same holds for all sorts of other things, but unfortunately I >>>>>>> think you're right. Proposal amended: put length in the Foldable class. >>>>>>> >>>>>>> On Thu, Sep 18, 2014 at 5:43 PM, Edward Kmett >>>>>>> wrote: >>>>>>> >>>>>>>> Choosing the name `size` isn't free. >>>>>>>> >>>>>>>> If we chose `length` then the existing code continues to work, code >>>>>>>> that was hiding it on import continues to hide it and you don't get >>>>>>>> conflicts. >>>>>>>> >>>>>>>> Picking 'size' is compatible with common practice, but means a ton >>>>>>>> of modules would break. >>>>>>>> >>>>>>>> Given the two solutions, one that doesn't break anything and one >>>>>>>> that does, with negligible differences between them otherwise, I'd prefer >>>>>>>> the one that causes the least amount of pain. >>>>>>>> >>>>>>>> -Edward >>>>>>>> >>>>>>>> On Thu, Sep 18, 2014 at 5:37 PM, David Feuer >>>>>>> > wrote: >>>>>>>> >>>>>>>>> To go along with Herbert Valerio Riedel's moving functions from >>>>>>>>> Foldable and Traversable to Prelude, I realized that `null` and `size` make >>>>>>>>> sense for all Foldables; Reid W. Barton noted that these can have optimized >>>>>>>>> implementations for many containers. He also noted that scanl1 and scanr1 >>>>>>>>> make sense for general Traversables. I therefore propose: >>>>>>>>> >>>>>>>>> Add `null` and `size` to the Foldable class. Default >>>>>>>>> implementations: >>>>>>>>> >>>>>>>>> null = foldr (\_ _ -> False) True >>>>>>>>> >>>>>>>>> size = foldl' (\acc _ -> acc+1) 0 >>>>>>>>> >>>>>>>>> Add `scanl1` and `scanr1` to the Traversable class. Default >>>>>>>>> implementations are a little less simple. >>>>>>>>> >>>>>>>>> David >>>>>>>>> >>>>>>>>> _______________________________________________ >>>>>>>>> Libraries mailing list >>>>>>>>> Libraries at haskell.org >>>>>>>>> http://www.haskell.org/mailman/listinfo/libraries >>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>>> _______________________________________________ >>>>> Libraries mailing list >>>>> Libraries at haskell.org >>>>> http://www.haskell.org/mailman/listinfo/libraries >>>>> >>>>> >>>> >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://www.haskell.org/mailman/listinfo/libraries >>>> >>>> >>> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hvr at gnu.org Fri Sep 19 11:54:19 2014 From: hvr at gnu.org (Herbert Valerio Riedel) Date: Fri, 19 Sep 2014 13:54:19 +0200 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: (David Feuer's message of "Thu, 18 Sep 2014 19:26:22 -0400") References: Message-ID: <87fvfn4yhg.fsf@gnu.org> On 2014-09-19 at 01:26:22 +0200, David Feuer wrote: > After discussing these matters some more with Edward Kmett and Reid Barton, > it appears the following makes sense: > > Add the following to Foldable: > length?often stored as a separate field for O(1) access > null?called very often and slightly faster than foldr (\_ _ -> False) True > for some containers > toList?may be the identity or nearly so, and this fact may not be > statically available to the foldr/id rule > sum, product?may be cached internally in tree nodes for fast update, giving > O(1) access; may be calculated in parallel. > maximum, minimum?O(n) for a search tree; O(1) for a finger tree. > elem?O(log n) for search trees; likely better for hash tables and such. > > Don't add anything to Traversable, because scanl1 and scanr1 are not worth > the extra dictionary weight. Seems sensible to me, hence +1 From simonpj at microsoft.com Fri Sep 19 12:05:21 2014 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Fri, 19 Sep 2014 12:05:21 +0000 Subject: Proposal: (breaking change to avoid fragile breakage) change the definition of foldr2, zip, and zipWith In-Reply-To: <1410164685.2670.3.camel@joachim-breitner.de> References: <1410164685.2670.3.camel@joachim-breitner.de> Message-ID: <618BE556AADD624C9C918AA5D5911BEF22222341@DB3PRD3001MB020.064d.mgd.msft.net> | David, I think you can go ahead and prepare a patch. People can still | speak up before (and even after) it is applied if they disagree. I'm way behind the curve here, but this is really a matter for the Core Libraries Committee, and I gather you are already in good communication with Edward. You can use GHC's Trac for Core Libraries tickets; just use "Core Libraries" for the "Component" field. Simon | -----Original Message----- | From: Libraries [mailto:libraries-bounces at haskell.org] On Behalf Of | Joachim Breitner | Sent: 08 September 2014 09:25 | To: David Feuer | Cc: Haskell Libraries | Subject: Re: Proposal: (breaking change to avoid fragile breakage) | change the definition of foldr2, zip, and zipWith | | Dear David, | | | Am Montag, den 08.09.2014, 02:58 -0400 schrieb David Feuer: | > It's been a couple weeks now, and no one's responded. | | that can happen. Usually not because noone cares, but because noone | knows what?s best. And also there was ICFP last week, which probably | kept people busy ... so don?t be discouraged by silence, and keep | following up on it. | | > On Sun, Aug 24, 2014 at 3:22 PM, David Feuer | wrote: | > > BACKGROUND | > > | > > TRAC: #9495 | | > > SOLUTIONS | > > | > > 1. One solution, of course, is to eliminate unfoldr2/right, | bringing | > > GHC into compliance with the Report. I really like this idea, but | > > Joachim thinks it is not worth the potential performance impact on | > > code written before or without regard for the change. We both | agree | > > that a reasonable alternative is | > > | > > 3. Modify the baseline definition of unfoldr2 as follows: | > > | > > foldr2 :: (a -> b -> c -> c) -> c -> [a] -> [b] -> c | > > foldr2 k z = go | > > where | > > go [] ys = ys `seq` z | > > go _xs [] = z | > > go (x:xs) (y:ys) = k x y (go xs ys) | > > | > > This should, we believe, make the baseline definition fail where | the | > > one fused by foldr2/right would fail, giving consistent semantics. | | You already said that I agree with that solution, but I can re-state | it here :-) | | > > WHAT MIGHT BREAK | > > | > > Code that currently works but will break with this change has two | > > properties: | > > | > > 1. It relies on the asymmetry in foldr, zipWith, or zip to avoid | > > running into bottom. | > > 2. foldr2/right does not fire, either because the second list is | not | > > a good producer or because GHC applies the foldr2/left rule | instead. | > > | > > That is, most of the code that this change will break is fragile | > > under the current scheme. | > > | > > DISCUSSION PERIOD | > > | > > Standard two weeks. | | Given that nobody complained about the standard-non-conformance so far | I think having a symmetric zip where the RULES are semantics- | preserving is more useful than strictly following the report. But I | could be convinced otherwise. | | | David, I think you can go ahead and prepare a patch. People can still | speak up before (and even after) it is applied if they disagree. | | Greetings, | Joachim | | -- | Joachim ?nomeata? Breitner | mail at joachim-breitner.de ? http://www.joachim-breitner.de/ | Jabber: nomeata at joachim-breitner.de ? GPG-Key: 0xF0FBF51F | Debian Developer: nomeata at debian.org From johnw at newartisans.com Fri Sep 19 12:09:56 2014 From: johnw at newartisans.com (John Wiegley) Date: Fri, 19 Sep 2014 13:09:56 +0100 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: ("Daniel =?utf-8?Q?D=C3=ADaz?= Casanueva"'s message of "Fri, 19 Sep 2014 00:32:04 -0400") References: Message-ID: >>>>> Daniel D?az Casanueva writes: > +1 from me as well. In a library I wrote recently, I also provided with more > efficient alternatives to those provided by the Foldable class. I'd rather > point users to use the generic interface of Data.Foldable. +1 from me. John From abela at chalmers.se Fri Sep 19 13:42:07 2014 From: abela at chalmers.se (Andreas Abel) Date: Fri, 19 Sep 2014 15:42:07 +0200 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: <541C32AF.4020109@chalmers.se> +1, go forward. --Andreas On 19.09.2014 14:09, John Wiegley wrote: >>>>>> Daniel D?az Casanueva writes: > >> +1 from me as well. In a library I wrote recently, I also provided with more >> efficient alternatives to those provided by the Foldable class. I'd rather >> point users to use the generic interface of Data.Foldable. > > +1 from me. > > John > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel at gu.se http://www2.tcs.ifi.lmu.de/~abel/ From mail at joachim-breitner.de Fri Sep 19 20:09:35 2014 From: mail at joachim-breitner.de (Joachim Breitner) Date: Fri, 19 Sep 2014 22:09:35 +0200 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: <1411157375.9147.1.camel@joachim-breitner.de> Hi, Am Donnerstag, den 18.09.2014, 19:26 -0400 schrieb David Feuer: > sum, product?may be cached internally in tree nodes for fast update, I?m a bit doubtful about the real-world impact of having product there, and probably also sum, besides educational code. Are these so much more common than other aggregations? I think if you want to cache something in treenodes for performance, you should use a suitable data structure there that supports this directly, instead of hoping that your operation happens to be one of the two special cases provided by the type class. Slightly off topic: Wouldn?t it be nice if we would not have to have to add these methods to provide optimized behavior, but rather have the user write "sum . toList" or some other idiomatic code (maybe suggested in the docs), and RULES provided by the container implementer would reliable replace this with the optimized version. Wouldn?t help in polymorphic code, but I doubt that much performance critical code is polymorphic in the container. But then he could simply provide a sumTree or sumSet or something else... I should stop mumbling in circles. Greetings, Joachim -- Joachim ?nomeata? Breitner mail at joachim-breitner.de ? http://www.joachim-breitner.de/ Jabber: nomeata at joachim-breitner.de ? GPG-Key: 0xF0FBF51F Debian Developer: nomeata at debian.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: This is a digitally signed message part URL: From lemming at henning-thielemann.de Fri Sep 19 20:29:31 2014 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri, 19 Sep 2014 22:29:31 +0200 (CEST) Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: <1411157375.9147.1.camel@joachim-breitner.de> References: <1411157375.9147.1.camel@joachim-breitner.de> Message-ID: On Fri, 19 Sep 2014, Joachim Breitner wrote: > Slightly off topic: Wouldn?t it be nice if we would not have to have to > add these methods to provide optimized behavior, but rather have the > user write "sum . toList" or some other idiomatic code (maybe suggested > in the docs), and RULES provided by the container implementer would > reliable replace this with the optimized version. Wouldn?t help in > polymorphic code, but I doubt that much performance critical code is > polymorphic in the container. > > But then he could simply provide a sumTree or sumSet or something > else... I should stop mumbling in circles. I am also worried about extending the classes more and more. Where to stop? At which point the API will be stable? A way to optimize non-methods for certain instances would be nice. Unfortunately, it is not only hard to predict when RULES fire, a RULES based solution is also dangerous. If a default method implementation and an actual instance implementation do different things, that's ok. In contrast, if a function is replaced by different functionality via RULES, that's very bad. From david.feuer at gmail.com Fri Sep 19 20:52:45 2014 From: david.feuer at gmail.com (David Feuer) Date: Fri, 19 Sep 2014 16:52:45 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: <1411157375.9147.1.camel@joachim-breitner.de> Message-ID: Joachim, you may be right about sum and product; I really don't know. Henning: this doesn't change the Data.Foldable API at all. Data.Foldable already exports all of these functions, and the class would give each of them a valid default implementation. I thoroughly agree with you about the peril of using RULES to specialize a function to a typeclass instance. As well as being hard to predict, potentially perilous, and inapplicable to polymorphic recursive situations, RULES also privilege "built-in" types over identical user-defined ones. On Fri, Sep 19, 2014 at 4:29 PM, Henning Thielemann < lemming at henning-thielemann.de> wrote: > > On Fri, 19 Sep 2014, Joachim Breitner wrote: > > Slightly off topic: Wouldn?t it be nice if we would not have to have to >> add these methods to provide optimized behavior, but rather have the >> user write "sum . toList" or some other idiomatic code (maybe suggested >> in the docs), and RULES provided by the container implementer would >> reliable replace this with the optimized version. Wouldn?t help in >> polymorphic code, but I doubt that much performance critical code is >> polymorphic in the container. >> >> But then he could simply provide a sumTree or sumSet or something >> else... I should stop mumbling in circles. >> > > I am also worried about extending the classes more and more. Where to > stop? At which point the API will be stable? A way to optimize non-methods > for certain instances would be nice. Unfortunately, it is not only hard to > predict when RULES fire, a RULES based solution is also dangerous. If a > default method implementation and an actual instance implementation do > different things, that's ok. In contrast, if a function is replaced by > different functionality via RULES, that's very bad. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at joachim-breitner.de Fri Sep 19 20:59:08 2014 From: mail at joachim-breitner.de (Joachim Breitner) Date: Fri, 19 Sep 2014 22:59:08 +0200 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: <1411157375.9147.1.camel@joachim-breitner.de> Message-ID: <1411160348.9147.5.camel@joachim-breitner.de> Hi, Am Freitag, den 19.09.2014, 22:29 +0200 schrieb Henning Thielemann: > Unfortunately, it is not only hard to > predict when RULES fire, a RULES based solution is also dangerous. If a > default method implementation and an actual instance implementation do > different things, that's ok. In contrast, if a function is replaced by > different functionality via RULES, that's very bad. I meant rules provided by whoever implements the class: instance Traversable Foo where.. {-# RULES "sum/Foo" forall fx :: Foo Int . sum (toList fx) = sumFoo xs #-} so there would be no worry about soundness. I do _not_ mean adding such rules to where the class is defined. (This assumes that GHC does the right thing when the overloaded toList occurs in a rule, which I am not sure of.) Greetings, Joachim -- Joachim ?nomeata? Breitner mail at joachim-breitner.de ? http://www.joachim-breitner.de/ Jabber: nomeata at joachim-breitner.de ? GPG-Key: 0xF0FBF51F Debian Developer: nomeata at debian.org -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: This is a digitally signed message part URL: From ekmett at gmail.com Fri Sep 19 21:04:16 2014 From: ekmett at gmail.com (Edward Kmett) Date: Fri, 19 Sep 2014 17:04:16 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: <1411160348.9147.5.camel@joachim-breitner.de> References: <1411157375.9147.1.camel@joachim-breitner.de> <1411160348.9147.5.camel@joachim-breitner.de> Message-ID: <2E58591A-C3BA-425C-852D-880702CA436F@gmail.com> The problem with rules here is if the user is working polymorphically then when their code does or doesn't inline then you get varying semantics. You can see this in code that uses realToFrac but doesn't get inlined to specialize to Float/Double today in behavior around NaN. Let's not double down on a design that causes flaky behavior that doesn't scale. Sent from my iPhone > On Sep 19, 2014, at 4:59 PM, Joachim Breitner wrote: > > Hi, > > > Am Freitag, den 19.09.2014, 22:29 +0200 schrieb Henning Thielemann: >> Unfortunately, it is not only hard to >> predict when RULES fire, a RULES based solution is also dangerous. If a >> default method implementation and an actual instance implementation do >> different things, that's ok. In contrast, if a function is replaced by >> different functionality via RULES, that's very bad. > > I meant rules provided by whoever implements the class: > > instance Traversable Foo where.. > > {-# RULES "sum/Foo" forall fx :: Foo Int . sum (toList fx) = sumFoo xs #-} > > so there would be no worry about soundness. > > I do _not_ mean adding such rules to where the class is defined. > > (This assumes that GHC does the right thing when the overloaded toList > occurs in a rule, which I am not sure of.) > > > > Greetings, > Joachim > > > -- > Joachim ?nomeata? Breitner > mail at joachim-breitner.de ? http://www.joachim-breitner.de/ > Jabber: nomeata at joachim-breitner.de ? GPG-Key: 0xF0FBF51F > Debian Developer: nomeata at debian.org > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries From lemming at henning-thielemann.de Fri Sep 19 21:05:28 2014 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri, 19 Sep 2014 23:05:28 +0200 (CEST) Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: <1411157375.9147.1.camel@joachim-breitner.de> Message-ID: On Fri, 19 Sep 2014, David Feuer wrote: > Joachim, you may be right about sum and product; I really don't know. > Henning: this doesn't change the Data.Foldable API at all. Data.Foldable > already exports all of these functions, and the class would give each of > them a valid default implementation. For consumers of the functions it would not change much. However, user instances with custom implementations of the new methods cannot be used with older Prelude versions anymore. From david.feuer at gmail.com Fri Sep 19 21:17:13 2014 From: david.feuer at gmail.com (David Feuer) Date: Fri, 19 Sep 2014 17:17:13 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: <1411157375.9147.1.camel@joachim-breitner.de> Message-ID: On Fri, Sep 19, 2014 at 5:05 PM, Henning Thielemann < lemming at henning-thielemann.de> wrote: > > On Fri, 19 Sep 2014, David Feuer wrote: > > Joachim, you may be right about sum and product; I really don't know. >> Henning: this doesn't change the Data.Foldable API at all. Data.Foldable >> already exports all of these functions, and the class would give each of >> them a valid default implementation. >> > > For consumers of the functions it would not change much. However, user > instances with custom implementations of the new methods cannot be used > with older Prelude versions anymore. > Don't we normally blame the person who wrote code that was incompatible with the library version they wanted to support, rather than the new library for adding something new that they chose to depend on? -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Fri Sep 19 21:25:01 2014 From: ekmett at gmail.com (Edward Kmett) Date: Fri, 19 Sep 2014 17:25:01 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: <1411157375.9147.1.camel@joachim-breitner.de> Message-ID: <25BC67BB-5494-42C2-A4FD-AE9535986712@gmail.com> A secondary reason for their inclusion is explicitly to avoid randomly changing the semantics of the versions supplied by Prelude by changing to the definitions from Foldable. E.g. foldl vs foldr based sum and the like. Sent from my iPhone > On Sep 19, 2014, at 5:05 PM, Henning Thielemann wrote: > > >> On Fri, 19 Sep 2014, David Feuer wrote: >> >> Joachim, you may be right about sum and product; I really don't know. Henning: this doesn't change the Data.Foldable API at all. Data.Foldable already exports all of these functions, and the class would give each of them a valid default implementation. > > For consumers of the functions it would not change much. However, user instances with custom implementations of the new methods cannot be used with older Prelude versions anymore. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries From david.feuer at gmail.com Fri Sep 19 21:26:34 2014 From: david.feuer at gmail.com (David Feuer) Date: Fri, 19 Sep 2014 17:26:34 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: <25BC67BB-5494-42C2-A4FD-AE9535986712@gmail.com> References: <1411157375.9147.1.camel@joachim-breitner.de> <25BC67BB-5494-42C2-A4FD-AE9535986712@gmail.com> Message-ID: I'd forgotten about that, Edward. Yes, without that, one or the other would have to change, and not necessarily for the good. On Fri, Sep 19, 2014 at 5:25 PM, Edward Kmett wrote: > A secondary reason for their inclusion is explicitly to avoid randomly > changing the semantics of the versions supplied by Prelude by changing to > the definitions from Foldable. > > E.g. foldl vs foldr based sum and the like. > > Sent from my iPhone > > > On Sep 19, 2014, at 5:05 PM, Henning Thielemann < > lemming at henning-thielemann.de> wrote: > > > > > >> On Fri, 19 Sep 2014, David Feuer wrote: > >> > >> Joachim, you may be right about sum and product; I really don't know. > Henning: this doesn't change the Data.Foldable API at all. Data.Foldable > already exports all of these functions, and the class would give each of > them a valid default implementation. > > > > For consumers of the functions it would not change much. However, user > instances with custom implementations of the new methods cannot be used > with older Prelude versions anymore. > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Fri Sep 19 21:27:02 2014 From: ekmett at gmail.com (Edward Kmett) Date: Fri, 19 Sep 2014 17:27:02 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: <1411157375.9147.1.camel@joachim-breitner.de> Message-ID: Keep in mind as part of the "burning bridges proposal that caused us to form the core libraries committee in the first place the Foldable/Traversable definitions replace the Prelude ones. There is no new conflict against Prelude. Sent from my iPhone > On Sep 19, 2014, at 5:05 PM, Henning Thielemann wrote: > > >> On Fri, 19 Sep 2014, David Feuer wrote: >> >> Joachim, you may be right about sum and product; I really don't know. Henning: this doesn't change the Data.Foldable API at all. Data.Foldable already exports all of these functions, and the class would give each of them a valid default implementation. > > For consumers of the functions it would not change much. However, user instances with custom implementations of the new methods cannot be used with older Prelude versions anymore. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries From sjoerd at w3future.com Sun Sep 21 15:21:10 2014 From: sjoerd at w3future.com (Sjoerd Visscher) Date: Sun, 21 Sep 2014 17:21:10 +0200 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: > foldMap is used to provide a 'natural' fold regardless of associativity. > > foldMap and foldr are are mutually definable, by using Endo to get foldr from foldMap, or just accepting a right associated monoidal reduction. > > This is why foldr or foldMap are the minimal definitions. > > However, you can't build foldr in terms of foldl with the right behavior on infinite containers, so foldl is _not_ a viable minimal definition for Foldable in a world where you can have infinitely big things to fold! Wouldn?t it be the other way around for infinite snoc-lists? Sjoerd -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Sun Sep 21 15:37:12 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 21 Sep 2014 11:37:12 -0400 Subject: Proposal: Add a few extra members to Foldable and Traversable classes In-Reply-To: References: Message-ID: Yes. I really do consider foldMap to be the canonical form, and both foldr and foldl to be definable things in terms of it, but for historical reasons foldMap has a default definition in terms of foldr. -Edward On Sun, Sep 21, 2014 at 11:21 AM, Sjoerd Visscher wrote: > > foldMap is used to provide a 'natural' fold regardless of associativity. > > foldMap and foldr are are mutually definable, by using Endo to get foldr > from foldMap, or just accepting a right associated monoidal reduction. > > This is why foldr or foldMap are the minimal definitions. > > However, you can't build foldr in terms of foldl with the right behavior > on infinite containers, so foldl is _not_ a viable minimal definition for > Foldable in a world where you can have infinitely big things to fold! > > > Wouldn?t it be the other way around for infinite snoc-lists? > > Sjoerd > -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at jspha.com Sun Sep 21 17:05:42 2014 From: me at jspha.com (Joseph Abrahamson) Date: Sun, 21 Sep 2014 10:05:42 -0700 (PDT) Subject: Pre-Proposal: Add Validation somewhere easily accessible Message-ID: <1411319141902.8a556dff@Nodemailer> The ?purely applicative Either? is Either with a new Applicative interface which can no longer take a corresponding Monad interface. I have personally reinvented it over and over although it is perhaps commonly known as Validation: ? ? data Validation e a = Invalid e | Valid a deriving ( Show, Functor, ? ) ? ? instance Monoid e => Applicative (Validation e) where ? ? ? pure = Valid ? ? ? Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) ? ? ? Invalid e1 <*> _? ? ? ? ? = Invalid e1 ?? ? ? ? ? ? ? ? <*> Invalid e2 = Invalid e2 ? ? ? Valid ? f? <*> Valid ? a? = Valid (f a) ? ? -- No corresponding Monad It could be perhaps better implemented as a newtype wrapper over Either to facilitate rapid conversion to the more common type. Validation appears in its own package developed by Tony Morris and Nick Partridge. It also exists in Jonathan Sterling?s Vinyl package under the name Data.Vinyl.Idiom.Validation.Result. Gabriel Gonzalez has also told me that he?d be happy to add it to his `errors` package if a PR was made. The common use for Validation is to traverse over a structure and accumulate errors throughout it. In other words, failures should not halt the process and we can think of each operation as occurring in parallel. Not only is Validation a good example of an ?Applicative without a Monad? its also a very useful practical type. I would like to build a proposal to include Validation in some form in a common package. Despite the misalignment with the name, `transformers` seems like a plausible target, though I fear changes to that package are rarely worth the pain. Suggestions on implementation and target package are welcome. Pending informative feedback, I will try to write a true proposal within 2 weeks. Thanks everyone, Joseph Joseph -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Sun Sep 21 17:14:44 2014 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Sun, 21 Sep 2014 19:14:44 +0200 (CEST) Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <1411319141902.8a556dff@Nodemailer> References: <1411319141902.8a556dff@Nodemailer> Message-ID: On Sun, 21 Sep 2014, Joseph Abrahamson wrote: > The ?purely applicative Either? is Either with a new Applicative interface which can no longer take a > corresponding Monad interface. I have personally reinvented it over and over although it is perhaps commonly > known as Validation: > > ? ? data Validation e a = Invalid e | Valid a deriving ( Show, Functor, ? ) > > ? ? instance Monoid e => Applicative (Validation e) where > ? ? ? pure = Valid > ? ? ? Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) > ? ? ? Invalid e1 <*> _? ? ? ? ? = Invalid e1 > ?? ? ? ? ? ? ? ? <*> Invalid e2 = Invalid e2 > ? ? ? Valid ? f? <*> Valid ? a? = Valid (f a) > > ? ? -- No corresponding Monad > > It could be perhaps better implemented as a newtype wrapper over Either to facilitate rapid conversion to the > more common type. I would define it as you did above. Left and Right constructors of Either are not very descriptive. > I would like to build a proposal to include Validation in some form in a common package. Despite the > misalignment with the name, `transformers` seems like a plausible target, though I fear changes to that > package are rarely worth the pain. Suggestions on implementation and target package are welcome. Pending > informative feedback, I will try to write a true proposal within 2 weeks. My first choice would be 'transformers' because I already import this extensively. Second choice would be any other package that is plain Haskell 98 for portability reasons. From ekmett at gmail.com Sun Sep 21 17:17:20 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 21 Sep 2014 13:17:20 -0400 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <1411319141902.8a556dff@Nodemailer> References: <1411319141902.8a556dff@Nodemailer> Message-ID: <5F658E46-1C0E-4EBC-AF94-0CEC2BD763EE@gmail.com> I suppose ultimately the question I'd have is what is gained from standardization here per se? I can see the merit of the authors of those libraries coming together to agree on a common API and type if they can, but I think I'd rather see that sort of consolidation out in package space than in a package that falls under the purview of the libraries@ process -- and if they can't come together that too says something. Tying it to transformers in particular would tie changes to a couple year long dev cycle. It is a ghc build package, and hence not easily upgraded for users. That point in the design space strikes me as even worse than the status quo. Once such a package exists and it sees wide adoption, then the discussion of whether it belongs in the platform seems to make sense. -Edward > On Sep 21, 2014, at 1:05 PM, "Joseph Abrahamson" wrote: > > The ?purely applicative Either? is Either with a new Applicative interface which can no longer take a corresponding Monad interface. I have personally reinvented it over and over although it is perhaps commonly known as Validation: > > data Validation e a = Invalid e | Valid a deriving ( Show, Functor, ? ) > > instance Monoid e => Applicative (Validation e) where > pure = Valid > Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) > Invalid e1 <*> _ = Invalid e1 > <*> Invalid e2 = Invalid e2 > Valid f <*> Valid a = Valid (f a) > > -- No corresponding Monad > > It could be perhaps better implemented as a newtype wrapper over Either to facilitate rapid conversion to the more common type. > > Validation appears in its own package developed by Tony Morris and Nick Partridge. It also exists in Jonathan Sterling?s Vinyl package under the name Data.Vinyl.Idiom.Validation.Result. Gabriel Gonzalez has also told me that he?d be happy to add it to his `errors` package if a PR was made. > > The common use for Validation is to traverse over a structure and accumulate errors throughout it. In other words, failures should not halt the process and we can think of each operation as occurring in parallel. > > Not only is Validation a good example of an ?Applicative without a Monad? its also a very useful practical type. > > I would like to build a proposal to include Validation in some form in a common package. Despite the misalignment with the name, `transformers` seems like a plausible target, though I fear changes to that package are rarely worth the pain. Suggestions on implementation and target package are welcome. Pending informative feedback, I will try to write a true proposal within 2 weeks. > > Thanks everyone, > > Joseph > > Joseph > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries From me at jspha.com Sun Sep 21 17:51:03 2014 From: me at jspha.com (Joseph Abrahamson) Date: Sun, 21 Sep 2014 10:51:03 -0700 (PDT) Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <5F658E46-1C0E-4EBC-AF94-0CEC2BD763EE@gmail.com> References: <5F658E46-1C0E-4EBC-AF94-0CEC2BD763EE@gmail.com> Message-ID: <1411321862734.9acd990a@Nodemailer> I think that's my feeling about the risk of placing it in such a prominent place as transformers as well. I feel that such a core location is not necessarily needed, but the functionality provided would not be difficult to standardize relatively quickly. The benefit is to make the technique more widely known and more easily included. Typically its use tosh involves the addition of either an extra one-off package which provides little extra and more deps (this is the case today with `validation` especially given the lens/profunctors dep but even without) or nestled deep inside another package with a different focus. So I feel the proper place for such a simple type is somewhere inside a toolkit of other commonly used types of its brand. If there were a good `applicatives` package that would be ideal. I mentioned transformers as nothing more or less than the nearest approximation to that which I know of. Joseph On Sun, Sep 21, 2014 at 1:17 PM, Edward Kmett wrote: > I suppose ultimately the question I'd have is what is gained from standardization here per se? > I can see the merit of the authors of those libraries coming together to agree on a common API and type if they can, but I think I'd rather see that sort of consolidation out in package space than in a package that falls under the purview of the libraries@ process -- and if they can't come together that too says something. > Tying it to transformers in particular would tie changes to a couple year long dev cycle. It is a ghc build package, and hence not easily upgraded for users. That point in the design space strikes me as even worse than the status quo. > Once such a package exists and it sees wide adoption, then the discussion of whether it belongs in the platform seems to make sense. > -Edward >> On Sep 21, 2014, at 1:05 PM, "Joseph Abrahamson" wrote: >> >> The ?purely applicative Either? is Either with a new Applicative interface which can no longer take a corresponding Monad interface. I have personally reinvented it over and over although it is perhaps commonly known as Validation: >> >> data Validation e a = Invalid e | Valid a deriving ( Show, Functor, ? ) >> >> instance Monoid e => Applicative (Validation e) where >> pure = Valid >> Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) >> Invalid e1 <*> _ = Invalid e1 >> <*> Invalid e2 = Invalid e2 >> Valid f <*> Valid a = Valid (f a) >> >> -- No corresponding Monad >> >> It could be perhaps better implemented as a newtype wrapper over Either to facilitate rapid conversion to the more common type. >> >> Validation appears in its own package developed by Tony Morris and Nick Partridge. It also exists in Jonathan Sterling?s Vinyl package under the name Data.Vinyl.Idiom.Validation.Result. Gabriel Gonzalez has also told me that he?d be happy to add it to his `errors` package if a PR was made. >> >> The common use for Validation is to traverse over a structure and accumulate errors throughout it. In other words, failures should not halt the process and we can think of each operation as occurring in parallel. >> >> Not only is Validation a good example of an ?Applicative without a Monad? its also a very useful practical type. >> >> I would like to build a proposal to include Validation in some form in a common package. Despite the misalignment with the name, `transformers` seems like a plausible target, though I fear changes to that package are rarely worth the pain. Suggestions on implementation and target package are welcome. Pending informative feedback, I will try to write a true proposal within 2 weeks. >> >> Thanks everyone, >> >> Joseph >> >> Joseph >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From greg at gregweber.info Sun Sep 21 18:05:32 2014 From: greg at gregweber.info (Greg Weber) Date: Sun, 21 Sep 2014 11:05:32 -0700 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <1411321862734.9acd990a@Nodemailer> References: <5F658E46-1C0E-4EBC-AF94-0CEC2BD763EE@gmail.com> <1411321862734.9acd990a@Nodemailer> Message-ID: The errors package seems like a good location for it. On Sun, Sep 21, 2014 at 10:51 AM, Joseph Abrahamson wrote: > I think that's my feeling about the risk of placing it in such a prominent > place as transformers as well. I feel that such a core location is not > necessarily needed, but the functionality provided would not be difficult > to standardize relatively quickly. > > The benefit is to make the technique more widely known and more easily > included. Typically its use tosh involves the addition of either an extra > one-off package which provides little extra and more deps (this is the case > today with `validation` especially given the lens/profunctors dep but even > without) or nestled deep inside another package with a different focus. > > So I feel the proper place for such a simple type is somewhere inside a > toolkit of other commonly used types of its brand. If there were a good > `applicatives` package that would be ideal. I mentioned transformers as > nothing more or less than the nearest approximation to that which I know of. > > Joseph > > > On Sun, Sep 21, 2014 at 1:17 PM, Edward Kmett wrote: > >> I suppose ultimately the question I'd have is what is gained from >> standardization here per se? >> >> I can see the merit of the authors of those libraries coming together to >> agree on a common API and type if they can, but I think I'd rather see that >> sort of consolidation out in package space than in a package that falls >> under the purview of the libraries@ process -- and if they can't come >> together that too says something. >> >> Tying it to transformers in particular would tie changes to a couple year >> long dev cycle. It is a ghc build package, and hence not easily upgraded >> for users. That point in the design space strikes me as even worse than the >> status quo. >> >> Once such a package exists and it sees wide adoption, then the discussion >> of whether it belongs in the platform seems to make sense. >> >> -Edward >> >> > On Sep 21, 2014, at 1:05 PM, "Joseph Abrahamson" wrote: >> > >> > The ?purely applicative Either? is Either with a new Applicative >> interface which can no longer take a corresponding Monad interface. I have >> personally reinvented it over and over although it is perhaps commonly >> known as Validation: >> > >> > data Validation e a = Invalid e | Valid a deriving ( Show, Functor, ? ) >> > >> > instance Monoid e => Applicative (Validation e) where >> > pure = Valid >> > Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) >> > Invalid e1 <*> _ = Invalid e1 >> > <*> Invalid e2 = Invalid e2 >> > Valid f <*> Valid a = Valid (f a) >> > >> > -- No corresponding Monad >> > >> > It could be perhaps better implemented as a newtype wrapper over Either >> to facilitate rapid conversion to the more common type. >> > >> > Validation appears in its own package developed by Tony Morris and Nick >> Partridge. It also exists in Jonathan Sterling?s Vinyl package under the >> name Data.Vinyl.Idiom.Validation.Result. Gabriel Gonzalez has also told me >> that he?d be happy to add it to his `errors` package if a PR was made. >> > >> > The common use for Validation is to traverse over a structure and >> accumulate errors throughout it. In other words, failures should not halt >> the process and we can think of each operation as occurring in parallel. >> > >> > Not only is Validation a good example of an ?Applicative without a >> Monad? its also a very useful practical type. >> > >> > I would like to build a proposal to include Validation in some form in >> a common package. Despite the misalignment with the name, `transformers` >> seems like a plausible target, though I fear changes to that package are >> rarely worth the pain. Suggestions on implementation and target package are >> welcome. Pending informative feedback, I will try to write a true proposal >> within 2 weeks. >> > >> > Thanks everyone, >> > >> > Joseph >> > >> > Joseph >> > _______________________________________________ >> > Libraries mailing list >> > Libraries at haskell.org >> > http://www.haskell.org/mailman/listinfo/libraries >> > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at jspha.com Sun Sep 21 20:56:18 2014 From: me at jspha.com (Joseph Abrahamson) Date: Sun, 21 Sep 2014 13:56:18 -0700 (PDT) Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: References: Message-ID: <1411332977735.6956c807@Nodemailer> I think errors is a good place to begin a process like what Ed suggests. I do think that, ultimately, it?s a more pervasively useful type than that?just to leave that on the record. Joseph On Sun, Sep 21, 2014 at 2:05 PM, Greg Weber wrote: > The errors package seems like a good location for it. > On Sun, Sep 21, 2014 at 10:51 AM, Joseph Abrahamson wrote: >> I think that's my feeling about the risk of placing it in such a prominent >> place as transformers as well. I feel that such a core location is not >> necessarily needed, but the functionality provided would not be difficult >> to standardize relatively quickly. >> >> The benefit is to make the technique more widely known and more easily >> included. Typically its use tosh involves the addition of either an extra >> one-off package which provides little extra and more deps (this is the case >> today with `validation` especially given the lens/profunctors dep but even >> without) or nestled deep inside another package with a different focus. >> >> So I feel the proper place for such a simple type is somewhere inside a >> toolkit of other commonly used types of its brand. If there were a good >> `applicatives` package that would be ideal. I mentioned transformers as >> nothing more or less than the nearest approximation to that which I know of. >> >> Joseph >> >> >> On Sun, Sep 21, 2014 at 1:17 PM, Edward Kmett wrote: >> >>> I suppose ultimately the question I'd have is what is gained from >>> standardization here per se? >>> >>> I can see the merit of the authors of those libraries coming together to >>> agree on a common API and type if they can, but I think I'd rather see that >>> sort of consolidation out in package space than in a package that falls >>> under the purview of the libraries@ process -- and if they can't come >>> together that too says something. >>> >>> Tying it to transformers in particular would tie changes to a couple year >>> long dev cycle. It is a ghc build package, and hence not easily upgraded >>> for users. That point in the design space strikes me as even worse than the >>> status quo. >>> >>> Once such a package exists and it sees wide adoption, then the discussion >>> of whether it belongs in the platform seems to make sense. >>> >>> -Edward >>> >>> > On Sep 21, 2014, at 1:05 PM, "Joseph Abrahamson" wrote: >>> > >>> > The ?purely applicative Either? is Either with a new Applicative >>> interface which can no longer take a corresponding Monad interface. I have >>> personally reinvented it over and over although it is perhaps commonly >>> known as Validation: >>> > >>> > data Validation e a = Invalid e | Valid a deriving ( Show, Functor, ? ) >>> > >>> > instance Monoid e => Applicative (Validation e) where >>> > pure = Valid >>> > Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) >>> > Invalid e1 <*> _ = Invalid e1 >>> > <*> Invalid e2 = Invalid e2 >>> > Valid f <*> Valid a = Valid (f a) >>> > >>> > -- No corresponding Monad >>> > >>> > It could be perhaps better implemented as a newtype wrapper over Either >>> to facilitate rapid conversion to the more common type. >>> > >>> > Validation appears in its own package developed by Tony Morris and Nick >>> Partridge. It also exists in Jonathan Sterling?s Vinyl package under the >>> name Data.Vinyl.Idiom.Validation.Result. Gabriel Gonzalez has also told me >>> that he?d be happy to add it to his `errors` package if a PR was made. >>> > >>> > The common use for Validation is to traverse over a structure and >>> accumulate errors throughout it. In other words, failures should not halt >>> the process and we can think of each operation as occurring in parallel. >>> > >>> > Not only is Validation a good example of an ?Applicative without a >>> Monad? its also a very useful practical type. >>> > >>> > I would like to build a proposal to include Validation in some form in >>> a common package. Despite the misalignment with the name, `transformers` >>> seems like a plausible target, though I fear changes to that package are >>> rarely worth the pain. Suggestions on implementation and target package are >>> welcome. Pending informative feedback, I will try to write a true proposal >>> within 2 weeks. >>> > >>> > Thanks everyone, >>> > >>> > Joseph >>> > >>> > Joseph >>> > _______________________________________________ >>> > Libraries mailing list >>> > Libraries at haskell.org >>> > http://www.haskell.org/mailman/listinfo/libraries >>> >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Mon Sep 22 14:38:07 2014 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 22 Sep 2014 10:38:07 -0400 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <1411332977735.6956c807@Nodemailer> References: <1411332977735.6956c807@Nodemailer> Message-ID: Another option is to consider sliding it up into the 'either' package which is a dependency of errors. I'd be willing to help out there. -Edward On Sun, Sep 21, 2014 at 4:56 PM, Joseph Abrahamson wrote: > I think errors is a good place to begin a process like what Ed suggests. I > do think that, ultimately, it?s a more pervasively useful type than > that?just to leave that on the record. > > Joseph > > > On Sun, Sep 21, 2014 at 2:05 PM, Greg Weber wrote: > >> The errors package seems like a good location for it. >> >> On Sun, Sep 21, 2014 at 10:51 AM, Joseph Abrahamson wrote: >> >>> I think that's my feeling about the risk of placing it in such a >>> prominent place as transformers as well. I feel that such a core location >>> is not necessarily needed, but the functionality provided would not be >>> difficult to standardize relatively quickly. >>> >>> The benefit is to make the technique more widely known and more easily >>> included. Typically its use tosh involves the addition of either an extra >>> one-off package which provides little extra and more deps (this is the case >>> today with `validation` especially given the lens/profunctors dep but even >>> without) or nestled deep inside another package with a different focus. >>> >>> So I feel the proper place for such a simple type is somewhere inside a >>> toolkit of other commonly used types of its brand. If there were a good >>> `applicatives` package that would be ideal. I mentioned transformers as >>> nothing more or less than the nearest approximation to that which I know of. >>> >>> Joseph >>> >>> >>> On Sun, Sep 21, 2014 at 1:17 PM, Edward Kmett wrote: >>> >>>> I suppose ultimately the question I'd have is what is gained from >>>> standardization here per se? >>>> >>>> I can see the merit of the authors of those libraries coming together >>>> to agree on a common API and type if they can, but I think I'd rather see >>>> that sort of consolidation out in package space than in a package that >>>> falls under the purview of the libraries@ process -- and if they can't >>>> come together that too says something. >>>> >>>> Tying it to transformers in particular would tie changes to a couple >>>> year long dev cycle. It is a ghc build package, and hence not easily >>>> upgraded for users. That point in the design space strikes me as even worse >>>> than the status quo. >>>> >>>> Once such a package exists and it sees wide adoption, then the >>>> discussion of whether it belongs in the platform seems to make sense. >>>> >>>> -Edward >>>> >>>> > On Sep 21, 2014, at 1:05 PM, "Joseph Abrahamson" >>>> wrote: >>>> > >>>> > The ?purely applicative Either? is Either with a new Applicative >>>> interface which can no longer take a corresponding Monad interface. I have >>>> personally reinvented it over and over although it is perhaps commonly >>>> known as Validation: >>>> > >>>> > data Validation e a = Invalid e | Valid a deriving ( Show, Functor, ? >>>> ) >>>> > >>>> > instance Monoid e => Applicative (Validation e) where >>>> > pure = Valid >>>> > Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) >>>> > Invalid e1 <*> _ = Invalid e1 >>>> > <*> Invalid e2 = Invalid e2 >>>> > Valid f <*> Valid a = Valid (f a) >>>> > >>>> > -- No corresponding Monad >>>> > >>>> > It could be perhaps better implemented as a newtype wrapper over >>>> Either to facilitate rapid conversion to the more common type. >>>> > >>>> > Validation appears in its own package developed by Tony Morris and >>>> Nick Partridge. It also exists in Jonathan Sterling?s Vinyl package under >>>> the name Data.Vinyl.Idiom.Validation.Result. Gabriel Gonzalez has also told >>>> me that he?d be happy to add it to his `errors` package if a PR was made. >>>> > >>>> > The common use for Validation is to traverse over a structure and >>>> accumulate errors throughout it. In other words, failures should not halt >>>> the process and we can think of each operation as occurring in parallel. >>>> > >>>> > Not only is Validation a good example of an ?Applicative without a >>>> Monad? its also a very useful practical type. >>>> > >>>> > I would like to build a proposal to include Validation in some form >>>> in a common package. Despite the misalignment with the name, `transformers` >>>> seems like a plausible target, though I fear changes to that package are >>>> rarely worth the pain. Suggestions on implementation and target package are >>>> welcome. Pending informative feedback, I will try to write a true proposal >>>> within 2 weeks. >>>> > >>>> > Thanks everyone, >>>> > >>>> > Joseph >>>> > >>>> > Joseph >>>> > _______________________________________________ >>>> > Libraries mailing list >>>> > Libraries at haskell.org >>>> > http://www.haskell.org/mailman/listinfo/libraries >>>> >>> >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael at snoyman.com Mon Sep 22 14:41:19 2014 From: michael at snoyman.com (Michael Snoyman) Date: Mon, 22 Sep 2014 17:41:19 +0300 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: References: <1411332977735.6956c807@Nodemailer> Message-ID: FWIW, my neither package[1] (deprecated in favor of your either package) does in fact define this Applicative Either datatype (though under a different name). IMO, either is the right place for this. One minor bikeshedding question: it seems like the Applicative instance doesn't require a Monoid constraint, but rather only a Semigroup constraint. Since semigroup is already a dependency of either, would it make sense to define the instance as such? [1] http://hackage.haskell.org/package/neither-0.3.1.1/docs/Data-Neither.html On Mon, Sep 22, 2014 at 5:38 PM, Edward Kmett wrote: > Another option is to consider sliding it up into the 'either' package > which is a dependency of errors. I'd be willing to help out there. > > -Edward > > On Sun, Sep 21, 2014 at 4:56 PM, Joseph Abrahamson wrote: > >> I think errors is a good place to begin a process like what Ed suggests. >> I do think that, ultimately, it?s a more pervasively useful type than >> that?just to leave that on the record. >> >> Joseph >> >> >> On Sun, Sep 21, 2014 at 2:05 PM, Greg Weber wrote: >> >>> The errors package seems like a good location for it. >>> >>> On Sun, Sep 21, 2014 at 10:51 AM, Joseph Abrahamson >>> wrote: >>> >>>> I think that's my feeling about the risk of placing it in such a >>>> prominent place as transformers as well. I feel that such a core location >>>> is not necessarily needed, but the functionality provided would not be >>>> difficult to standardize relatively quickly. >>>> >>>> The benefit is to make the technique more widely known and more easily >>>> included. Typically its use tosh involves the addition of either an extra >>>> one-off package which provides little extra and more deps (this is the case >>>> today with `validation` especially given the lens/profunctors dep but even >>>> without) or nestled deep inside another package with a different focus. >>>> >>>> So I feel the proper place for such a simple type is somewhere inside a >>>> toolkit of other commonly used types of its brand. If there were a good >>>> `applicatives` package that would be ideal. I mentioned transformers as >>>> nothing more or less than the nearest approximation to that which I know of. >>>> >>>> Joseph >>>> >>>> >>>> On Sun, Sep 21, 2014 at 1:17 PM, Edward Kmett wrote: >>>> >>>>> I suppose ultimately the question I'd have is what is gained from >>>>> standardization here per se? >>>>> >>>>> I can see the merit of the authors of those libraries coming together >>>>> to agree on a common API and type if they can, but I think I'd rather see >>>>> that sort of consolidation out in package space than in a package that >>>>> falls under the purview of the libraries@ process -- and if they >>>>> can't come together that too says something. >>>>> >>>>> Tying it to transformers in particular would tie changes to a couple >>>>> year long dev cycle. It is a ghc build package, and hence not easily >>>>> upgraded for users. That point in the design space strikes me as even worse >>>>> than the status quo. >>>>> >>>>> Once such a package exists and it sees wide adoption, then the >>>>> discussion of whether it belongs in the platform seems to make sense. >>>>> >>>>> -Edward >>>>> >>>>> > On Sep 21, 2014, at 1:05 PM, "Joseph Abrahamson" >>>>> wrote: >>>>> > >>>>> > The ?purely applicative Either? is Either with a new Applicative >>>>> interface which can no longer take a corresponding Monad interface. I have >>>>> personally reinvented it over and over although it is perhaps commonly >>>>> known as Validation: >>>>> > >>>>> > data Validation e a = Invalid e | Valid a deriving ( Show, Functor, >>>>> ? ) >>>>> > >>>>> > instance Monoid e => Applicative (Validation e) where >>>>> > pure = Valid >>>>> > Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) >>>>> > Invalid e1 <*> _ = Invalid e1 >>>>> > <*> Invalid e2 = Invalid e2 >>>>> > Valid f <*> Valid a = Valid (f a) >>>>> > >>>>> > -- No corresponding Monad >>>>> > >>>>> > It could be perhaps better implemented as a newtype wrapper over >>>>> Either to facilitate rapid conversion to the more common type. >>>>> > >>>>> > Validation appears in its own package developed by Tony Morris and >>>>> Nick Partridge. It also exists in Jonathan Sterling?s Vinyl package under >>>>> the name Data.Vinyl.Idiom.Validation.Result. Gabriel Gonzalez has also told >>>>> me that he?d be happy to add it to his `errors` package if a PR was made. >>>>> > >>>>> > The common use for Validation is to traverse over a structure and >>>>> accumulate errors throughout it. In other words, failures should not halt >>>>> the process and we can think of each operation as occurring in parallel. >>>>> > >>>>> > Not only is Validation a good example of an ?Applicative without a >>>>> Monad? its also a very useful practical type. >>>>> > >>>>> > I would like to build a proposal to include Validation in some form >>>>> in a common package. Despite the misalignment with the name, `transformers` >>>>> seems like a plausible target, though I fear changes to that package are >>>>> rarely worth the pain. Suggestions on implementation and target package are >>>>> welcome. Pending informative feedback, I will try to write a true proposal >>>>> within 2 weeks. >>>>> > >>>>> > Thanks everyone, >>>>> > >>>>> > Joseph >>>>> > >>>>> > Joseph >>>>> > _______________________________________________ >>>>> > Libraries mailing list >>>>> > Libraries at haskell.org >>>>> > http://www.haskell.org/mailman/listinfo/libraries >>>>> >>>> >>>> >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://www.haskell.org/mailman/listinfo/libraries >>>> >>>> >>> >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at jspha.com Mon Sep 22 14:49:25 2014 From: me at jspha.com (Joseph Abrahamson) Date: Mon, 22 Sep 2014 07:49:25 -0700 (PDT) Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: References: Message-ID: <1411397364544.24ad4a78@Nodemailer> I was just thinking about this opportunity last night. I think it is a fairly appropriate place for Validation and lets `errors` include the type naturally. Further, Michael is right in that so long as the package dependency is above `semigroups` then it?d be more accurate to state the instance using Semigroup e. I?d personally be in favor of that as well. I?d be interested in entertaining a small amount of bikeshedding over the name as well. I wrote this up using Validation to mime the `validation` package, but have personally used a number of names in the past. Other potential options include: Result, Collect, and Combine. I propose sticking with Validation (and the implementation in the head of this thread, potentially modulo [Monoid\Semigroup]) by default but would like to hear if anyone has strong justification for another name. Joseph On Mon, Sep 22, 2014 at 10:41 AM, Michael Snoyman wrote: > FWIW, my neither package[1] (deprecated in favor of your either package) > does in fact define this Applicative Either datatype (though under a > different name). IMO, either is the right place for this. > One minor bikeshedding question: it seems like the Applicative instance > doesn't require a Monoid constraint, but rather only a Semigroup > constraint. Since semigroup is already a dependency of either, would it > make sense to define the instance as such? > [1] > http://hackage.haskell.org/package/neither-0.3.1.1/docs/Data-Neither.html > On Mon, Sep 22, 2014 at 5:38 PM, Edward Kmett wrote: >> Another option is to consider sliding it up into the 'either' package >> which is a dependency of errors. I'd be willing to help out there. >> >> -Edward >> >> On Sun, Sep 21, 2014 at 4:56 PM, Joseph Abrahamson wrote: >> >>> I think errors is a good place to begin a process like what Ed suggests. >>> I do think that, ultimately, it?s a more pervasively useful type than >>> that?just to leave that on the record. >>> >>> Joseph >>> >>> >>> On Sun, Sep 21, 2014 at 2:05 PM, Greg Weber wrote: >>> >>>> The errors package seems like a good location for it. >>>> >>>> On Sun, Sep 21, 2014 at 10:51 AM, Joseph Abrahamson >>>> wrote: >>>> >>>>> I think that's my feeling about the risk of placing it in such a >>>>> prominent place as transformers as well. I feel that such a core location >>>>> is not necessarily needed, but the functionality provided would not be >>>>> difficult to standardize relatively quickly. >>>>> >>>>> The benefit is to make the technique more widely known and more easily >>>>> included. Typically its use tosh involves the addition of either an extra >>>>> one-off package which provides little extra and more deps (this is the case >>>>> today with `validation` especially given the lens/profunctors dep but even >>>>> without) or nestled deep inside another package with a different focus. >>>>> >>>>> So I feel the proper place for such a simple type is somewhere inside a >>>>> toolkit of other commonly used types of its brand. If there were a good >>>>> `applicatives` package that would be ideal. I mentioned transformers as >>>>> nothing more or less than the nearest approximation to that which I know of. >>>>> >>>>> Joseph >>>>> >>>>> >>>>> On Sun, Sep 21, 2014 at 1:17 PM, Edward Kmett wrote: >>>>> >>>>>> I suppose ultimately the question I'd have is what is gained from >>>>>> standardization here per se? >>>>>> >>>>>> I can see the merit of the authors of those libraries coming together >>>>>> to agree on a common API and type if they can, but I think I'd rather see >>>>>> that sort of consolidation out in package space than in a package that >>>>>> falls under the purview of the libraries@ process -- and if they >>>>>> can't come together that too says something. >>>>>> >>>>>> Tying it to transformers in particular would tie changes to a couple >>>>>> year long dev cycle. It is a ghc build package, and hence not easily >>>>>> upgraded for users. That point in the design space strikes me as even worse >>>>>> than the status quo. >>>>>> >>>>>> Once such a package exists and it sees wide adoption, then the >>>>>> discussion of whether it belongs in the platform seems to make sense. >>>>>> >>>>>> -Edward >>>>>> >>>>>> > On Sep 21, 2014, at 1:05 PM, "Joseph Abrahamson" >>>>>> wrote: >>>>>> > >>>>>> > The ?purely applicative Either? is Either with a new Applicative >>>>>> interface which can no longer take a corresponding Monad interface. I have >>>>>> personally reinvented it over and over although it is perhaps commonly >>>>>> known as Validation: >>>>>> > >>>>>> > data Validation e a = Invalid e | Valid a deriving ( Show, Functor, >>>>>> ? ) >>>>>> > >>>>>> > instance Monoid e => Applicative (Validation e) where >>>>>> > pure = Valid >>>>>> > Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) >>>>>> > Invalid e1 <*> _ = Invalid e1 >>>>>> > <*> Invalid e2 = Invalid e2 >>>>>> > Valid f <*> Valid a = Valid (f a) >>>>>> > >>>>>> > -- No corresponding Monad >>>>>> > >>>>>> > It could be perhaps better implemented as a newtype wrapper over >>>>>> Either to facilitate rapid conversion to the more common type. >>>>>> > >>>>>> > Validation appears in its own package developed by Tony Morris and >>>>>> Nick Partridge. It also exists in Jonathan Sterling?s Vinyl package under >>>>>> the name Data.Vinyl.Idiom.Validation.Result. Gabriel Gonzalez has also told >>>>>> me that he?d be happy to add it to his `errors` package if a PR was made. >>>>>> > >>>>>> > The common use for Validation is to traverse over a structure and >>>>>> accumulate errors throughout it. In other words, failures should not halt >>>>>> the process and we can think of each operation as occurring in parallel. >>>>>> > >>>>>> > Not only is Validation a good example of an ?Applicative without a >>>>>> Monad? its also a very useful practical type. >>>>>> > >>>>>> > I would like to build a proposal to include Validation in some form >>>>>> in a common package. Despite the misalignment with the name, `transformers` >>>>>> seems like a plausible target, though I fear changes to that package are >>>>>> rarely worth the pain. Suggestions on implementation and target package are >>>>>> welcome. Pending informative feedback, I will try to write a true proposal >>>>>> within 2 weeks. >>>>>> > >>>>>> > Thanks everyone, >>>>>> > >>>>>> > Joseph >>>>>> > >>>>>> > Joseph >>>>>> > _______________________________________________ >>>>>> > Libraries mailing list >>>>>> > Libraries at haskell.org >>>>>> > http://www.haskell.org/mailman/listinfo/libraries >>>>>> >>>>> >>>>> >>>>> _______________________________________________ >>>>> Libraries mailing list >>>>> Libraries at haskell.org >>>>> http://www.haskell.org/mailman/listinfo/libraries >>>>> >>>>> >>>> >>> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From cma at bitemyapp.com Mon Sep 22 15:11:55 2014 From: cma at bitemyapp.com (Chris Allen) Date: Mon, 22 Sep 2014 10:11:55 -0500 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <1411397364544.24ad4a78@Nodemailer> References: <1411397364544.24ad4a78@Nodemailer> Message-ID: I was already working on adding it to errors because of EitherT - should it go into either instead? Sent from my iPhone > On Sep 22, 2014, at 9:49 AM, Joseph Abrahamson wrote: > > I was just thinking about this opportunity last night. I think it is a fairly appropriate place for Validation and lets `errors` include the type naturally. Further, Michael is right in that so long as the package dependency is above `semigroups` then it?d be more accurate to state the instance using Semigroup e. I?d personally be in favor of that as well. > > I?d be interested in entertaining a small amount of bikeshedding over the name as well. I wrote this up using Validation to mime the `validation` package, but have personally used a number of names in the past. Other potential options include: Result, Collect, and Combine. > > I propose sticking with Validation (and the implementation in the head of this thread, potentially modulo [Monoid\Semigroup]) by default but would like to hear if anyone has strong justification for another name. > > Joseph > > >> On Mon, Sep 22, 2014 at 10:41 AM, Michael Snoyman wrote: >> FWIW, my neither package[1] (deprecated in favor of your either package) does in fact define this Applicative Either datatype (though under a different name). IMO, either is the right place for this. >> >> One minor bikeshedding question: it seems like the Applicative instance doesn't require a Monoid constraint, but rather only a Semigroup constraint. Since semigroup is already a dependency of either, would it make sense to define the instance as such? >> >> [1] http://hackage.haskell.org/package/neither-0.3.1.1/docs/Data-Neither.html >> >>> On Mon, Sep 22, 2014 at 5:38 PM, Edward Kmett wrote: >>> Another option is to consider sliding it up into the 'either' package which is a dependency of errors. I'd be willing to help out there. >>> >>> -Edward >>> >>>> On Sun, Sep 21, 2014 at 4:56 PM, Joseph Abrahamson wrote: >>>> I think errors is a good place to begin a process like what Ed suggests. I do think that, ultimately, it?s a more pervasively useful type than that?just to leave that on the record. >>>> >>>> Joseph >>>> >>>> >>>>> On Sun, Sep 21, 2014 at 2:05 PM, Greg Weber wrote: >>>>> The errors package seems like a good location for it. >>>>> >>>>>> On Sun, Sep 21, 2014 at 10:51 AM, Joseph Abrahamson wrote: >>>>>> I think that's my feeling about the risk of placing it in such a prominent place as transformers as well. I feel that such a core location is not necessarily needed, but the functionality provided would not be difficult to standardize relatively quickly. >>>>>> >>>>>> The benefit is to make the technique more widely known and more easily included. Typically its use tosh involves the addition of either an extra one-off package which provides little extra and more deps (this is the case today with `validation` especially given the lens/profunctors dep but even without) or nestled deep inside another package with a different focus. >>>>>> >>>>>> So I feel the proper place for such a simple type is somewhere inside a toolkit of other commonly used types of its brand. If there were a good `applicatives` package that would be ideal. I mentioned transformers as nothing more or less than the nearest approximation to that which I know of. >>>>>> >>>>>> Joseph >>>>>> >>>>>> >>>>>>> On Sun, Sep 21, 2014 at 1:17 PM, Edward Kmett wrote: >>>>>>> I suppose ultimately the question I'd have is what is gained from standardization here per se? >>>>>>> >>>>>>> I can see the merit of the authors of those libraries coming together to agree on a common API and type if they can, but I think I'd rather see that sort of consolidation out in package space than in a package that falls under the purview of the libraries@ process -- and if they can't come together that too says something. >>>>>>> >>>>>>> Tying it to transformers in particular would tie changes to a couple year long dev cycle. It is a ghc build package, and hence not easily upgraded for users. That point in the design space strikes me as even worse than the status quo. >>>>>>> >>>>>>> Once such a package exists and it sees wide adoption, then the discussion of whether it belongs in the platform seems to make sense. >>>>>>> >>>>>>> -Edward >>>>>>> >>>>>>> > On Sep 21, 2014, at 1:05 PM, "Joseph Abrahamson" wrote: >>>>>>> > >>>>>>> > The ?purely applicative Either? is Either with a new Applicative interface which can no longer take a corresponding Monad interface. I have personally reinvented it over and over although it is perhaps commonly known as Validation: >>>>>>> > >>>>>>> > data Validation e a = Invalid e | Valid a deriving ( Show, Functor, ? ) >>>>>>> > >>>>>>> > instance Monoid e => Applicative (Validation e) where >>>>>>> > pure = Valid >>>>>>> > Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) >>>>>>> > Invalid e1 <*> _ = Invalid e1 >>>>>>> > <*> Invalid e2 = Invalid e2 >>>>>>> > Valid f <*> Valid a = Valid (f a) >>>>>>> > >>>>>>> > -- No corresponding Monad >>>>>>> > >>>>>>> > It could be perhaps better implemented as a newtype wrapper over Either to facilitate rapid conversion to the more common type. >>>>>>> > >>>>>>> > Validation appears in its own package developed by Tony Morris and Nick Partridge. It also exists in Jonathan Sterling?s Vinyl package under the name Data.Vinyl.Idiom.Validation.Result. Gabriel Gonzalez has also told me that he?d be happy to add it to his `errors` package if a PR was made. >>>>>>> > >>>>>>> > The common use for Validation is to traverse over a structure and accumulate errors throughout it. In other words, failures should not halt the process and we can think of each operation as occurring in parallel. >>>>>>> > >>>>>>> > Not only is Validation a good example of an ?Applicative without a Monad? its also a very useful practical type. >>>>>>> > >>>>>>> > I would like to build a proposal to include Validation in some form in a common package. Despite the misalignment with the name, `transformers` seems like a plausible target, though I fear changes to that package are rarely worth the pain. Suggestions on implementation and target package are welcome. Pending informative feedback, I will try to write a true proposal within 2 weeks. >>>>>>> > >>>>>>> > Thanks everyone, >>>>>>> > >>>>>>> > Joseph >>>>>>> > >>>>>>> > Joseph >>>>>>> > _______________________________________________ >>>>>>> > Libraries mailing list >>>>>>> > Libraries at haskell.org >>>>>>> > http://www.haskell.org/mailman/listinfo/libraries >>>>>> >>>>>> >>>>>> _______________________________________________ >>>>>> Libraries mailing list >>>>>> Libraries at haskell.org >>>>>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From abela at chalmers.se Mon Sep 22 15:43:05 2014 From: abela at chalmers.se (Andreas Abel) Date: Mon, 22 Sep 2014 17:43:05 +0200 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: References: <1411397364544.24ad4a78@Nodemailer> Message-ID: <54204389.9090401@chalmers.se> Joseph, your idiom seems indeed fundamental to some extend and seems to be rediscovered time and again. (My PhD student showed a version of it to me very recently.) I also found that it generalizes the existing "Failing a" in Control.Applicative.Error http://hackage.haskell.org/package/applicative-extras-0.1.3/docs/Control-Applicative-Error.html Control.Applicative.Error is the place where it should go, whether you generalize the existing package or roll your own... Bikeshedding: "Failing" sounds more fundamental and generic than "Validation", so I'd prefer the former. However, "Failing" is too negative, as if the computation must fail, "CanFail" is less definite. UPDATE: I found that "Errors e" on https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html seems to be doing the job of "Validation" already (no nice names of the operations, though). Cheers, Andreas On 22.09.2014 17:11, Chris Allen wrote: > I was already working on adding it to errors because of EitherT - should > it go into either instead? > > Sent from my iPhone > > On Sep 22, 2014, at 9:49 AM, Joseph Abrahamson > wrote: > >> I was just thinking about this opportunity last night. I think it is a >> fairly appropriate place for Validation and lets `errors` include the >> type naturally. Further, Michael is right in that so long as the >> package dependency is above `semigroups` then it?d be more accurate to >> state the instance using Semigroup e. I?d personally be in favor of >> that as well. >> >> I?d be interested in entertaining a small amount of bikeshedding over >> the name as well. I wrote this up using Validation to mime the >> `validation` package, but have personally used a number of names in >> the past. Other potential options include: Result, Collect, and Combine. >> >> I propose sticking with Validation (and the implementation in the head >> of this thread, potentially modulo [Monoid\Semigroup]) by default but >> would like to hear if anyone has strong justification for another name. >> >> Joseph >> >> >> On Mon, Sep 22, 2014 at 10:41 AM, Michael Snoyman > > wrote: >> >> FWIW, my neither package[1] (deprecated in favor of your either >> package) does in fact define this Applicative Either datatype >> (though under a different name). IMO, either is the right place >> for this. >> >> One minor bikeshedding question: it seems like the Applicative >> instance doesn't require a Monoid constraint, but rather only a >> Semigroup constraint. Since semigroup is already a dependency of >> either, would it make sense to define the instance as such? >> >> [1] >> http://hackage.haskell.org/package/neither-0.3.1.1/docs/Data-Neither.html >> >> On Mon, Sep 22, 2014 at 5:38 PM, Edward Kmett > > wrote: >> >> Another option is to consider sliding it up into the 'either' >> package which is a dependency of errors. I'd be willing to >> help out there. >> >> -Edward >> >> On Sun, Sep 21, 2014 at 4:56 PM, Joseph Abrahamson >> > wrote: >> >> I think errors is a good place to begin a process like >> what Ed suggests. I do think that, ultimately, it?s a more >> pervasively useful type than that?just to leave that on >> the record. >> >> Joseph >> >> >> On Sun, Sep 21, 2014 at 2:05 PM, Greg Weber >> > wrote: >> >> The errors package seems like a good location for it. >> >> On Sun, Sep 21, 2014 at 10:51 AM, Joseph Abrahamson >> > wrote: >> >> I think that's my feeling about the risk of >> placing it in such a prominent place as >> transformers as well. I feel that such a core >> location is not necessarily needed, but the >> functionality provided would not be difficult to >> standardize relatively quickly. >> >> The benefit is to make the technique more widely >> known and more easily included. Typically its use >> tosh involves the addition of either an extra >> one-off package which provides little extra and >> more deps (this is the case today with >> `validation` especially given the lens/profunctors >> dep but even without) or nestled deep inside >> another package with a different focus. >> >> So I feel the proper place for such a simple type >> is somewhere inside a toolkit of other commonly >> used types of its brand. If there were a good >> `applicatives` package that would be ideal. I >> mentioned transformers as nothing more or less >> than the nearest approximation to that which I >> know of. >> >> Joseph >> >> >> On Sun, Sep 21, 2014 at 1:17 PM, Edward Kmett >> > wrote: >> >> I suppose ultimately the question I'd have is >> what is gained from standardization here per se? >> >> I can see the merit of the authors of those >> libraries coming together to agree on a common >> API and type if they can, but I think I'd >> rather see that sort of consolidation out in >> package space than in a package that falls >> under the purview of the libraries@ process -- >> and if they can't come together that too says >> something. >> >> Tying it to transformers in particular would >> tie changes to a couple year long dev cycle. >> It is a ghc build package, and hence not >> easily upgraded for users. That point in the >> design space strikes me as even worse than the >> status quo. >> >> Once such a package exists and it sees wide >> adoption, then the discussion of whether it >> belongs in the platform seems to make sense. >> >> -Edward >> >> > On Sep 21, 2014, at 1:05 PM, "Joseph >> Abrahamson" > > wrote: >> > >> > The ?purely applicative Either? is Either >> with a new Applicative interface which can no >> longer take a corresponding Monad interface. I >> have personally reinvented it over and over >> although it is perhaps commonly known as >> Validation: >> > >> > data Validation e a = Invalid e | Valid a >> deriving ( Show, Functor, ? ) >> > >> > instance Monoid e => Applicative (Validation >> e) where >> > pure = Valid >> > Invalid e1 <*> Invalid e2 = Invalid (e1 <> e2) >> > Invalid e1 <*> _ = Invalid e1 >> > <*> Invalid e2 = Invalid e2 >> > Valid f <*> Valid a = Valid (f a) >> > >> > -- No corresponding Monad >> > >> > It could be perhaps better implemented as a >> newtype wrapper over Either to facilitate >> rapid conversion to the more common type. >> > >> > Validation appears in its own package >> developed by Tony Morris and Nick Partridge. >> It also exists in Jonathan Sterling?s Vinyl >> package under the name >> Data.Vinyl.Idiom.Validation.Result. Gabriel >> Gonzalez has also told me that he?d be happy >> to add it to his `errors` package if a PR was >> made. >> > >> > The common use for Validation is to traverse >> over a structure and accumulate errors >> throughout it. In other words, failures should >> not halt the process and we can think of each >> operation as occurring in parallel. >> > >> > Not only is Validation a good example of an >> ?Applicative without a Monad? its also a very >> useful practical type. >> > >> > I would like to build a proposal to include >> Validation in some form in a common package. >> Despite the misalignment with the name, >> `transformers` seems like a plausible target, >> though I fear changes to that package are >> rarely worth the pain. Suggestions on >> implementation and target package are welcome. >> Pending informative feedback, I will try to >> write a true proposal within 2 weeks. >> > >> > Thanks everyone, >> > >> > Joseph >> > >> > Joseph >> > _______________________________________________ >> > Libraries mailing list >> > Libraries at haskell.org >> >> > >> http://www.haskell.org/mailman/listinfo/libraries >> >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> >> >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel at gu.se http://www2.tcs.ifi.lmu.de/~abel/ From roma at ro-che.info Mon Sep 22 19:13:54 2014 From: roma at ro-che.info (Roman Cheplyaka) Date: Mon, 22 Sep 2014 22:13:54 +0300 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <54204389.9090401@chalmers.se> References: <1411397364544.24ad4a78@Nodemailer> <54204389.9090401@chalmers.se> Message-ID: <542074F2.4020600@ro-che.info> On 22/09/14 18:43, Andreas Abel wrote: > UPDATE: I found that "Errors e" on > > > https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html Brilliant, thanks a lot! For me, having it in transformers outweighs all the benefits that a separate package may provide (especially a package as heavy as 'errors'). Roman -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From lemming at henning-thielemann.de Mon Sep 22 20:05:46 2014 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Mon, 22 Sep 2014 22:05:46 +0200 (CEST) Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <54204389.9090401@chalmers.se> References: <1411397364544.24ad4a78@Nodemailer> <54204389.9090401@chalmers.se> Message-ID: On Mon, 22 Sep 2014, Andreas Abel wrote: > UPDATE: I found that "Errors e" on > > > https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html > > seems to be doing the job of "Validation" already (no nice names of the > operations, though). Well spotted! For me this is enough of a solution. From me at jspha.com Mon Sep 22 20:08:22 2014 From: me at jspha.com (Joseph Abrahamson) Date: Mon, 22 Sep 2014 13:08:22 -0700 (PDT) Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: References: Message-ID: <1411416502045.6c3b564e@Nodemailer> Andreas, that?s perfect! I had never realized the solution was sitting under my nose the whole time. Indeed, for my purposes?basically any time I?ve used this type?this is by far the best solution. It?s more than enough for me to just withdrawal any desire to make a concrete proposal. Thanks for the discussion everyone. Joseph On Mon, Sep 22, 2014 at 4:05 PM, Henning Thielemann wrote: > On Mon, 22 Sep 2014, Andreas Abel wrote: >> UPDATE: I found that "Errors e" on >> >> >> https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html >> >> seems to be doing the job of "Validation" already (no nice names of the >> operations, though). > Well spotted! For me this is enough of a solution. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Mon Sep 22 23:12:49 2014 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 22 Sep 2014 19:12:49 -0400 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <542074F2.4020600@ro-che.info> References: <1411397364544.24ad4a78@Nodemailer> <54204389.9090401@chalmers.se> <542074F2.4020600@ro-che.info> Message-ID: Lift is rather different than Validation. On Mon, Sep 22, 2014 at 3:13 PM, Roman Cheplyaka wrote: > On 22/09/14 18:43, Andreas Abel wrote: > > UPDATE: I found that "Errors e" on > > > > > > > https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html > > Brilliant, thanks a lot! For me, having it in transformers outweighs all > the benefits that a separate package may provide (especially a package > as heavy as 'errors'). > > Roman > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From me at jspha.com Mon Sep 22 23:27:14 2014 From: me at jspha.com (Joseph Abrahamson) Date: Mon, 22 Sep 2014 16:27:14 -0700 (PDT) Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: References: Message-ID: <1411428434026.76ccd097@Nodemailer> `Lift` is, but `Errors` should be identical, correct? It appears to work exactly as I would hope in my testing, anyway. The only difference is one further step unwrapping the Constant. Am I missing something major? Tangentially, I don?t understand why transformers defines its own Constant type, though, given Const in Applicative. At least in transformers 4.0 they use the built-in Eq1 classes and the like. Joseph On Mon, Sep 22, 2014 at 7:12 PM, Edward Kmett wrote: > Lift is rather different than Validation. > On Mon, Sep 22, 2014 at 3:13 PM, Roman Cheplyaka wrote: >> On 22/09/14 18:43, Andreas Abel wrote: >> > UPDATE: I found that "Errors e" on >> > >> > >> > >> https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html >> >> Brilliant, thanks a lot! For me, having it in transformers outweighs all >> the benefits that a separate package may provide (especially a package >> as heavy as 'errors'). >> >> Roman >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Tue Sep 23 00:17:35 2014 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 22 Sep 2014 20:17:35 -0400 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <1411428434026.76ccd097@Nodemailer> References: <1411428434026.76ccd097@Nodemailer> Message-ID: There was some discussion of retiring Constant, as it is mostly unused, and Const has supplanted it in common usage. It didn't happen with this last release of transformers. -Edward On Mon, Sep 22, 2014 at 7:27 PM, Joseph Abrahamson wrote: > `Lift` is, but `Errors` should be identical, correct? It appears to work > exactly as I would hope in my testing, anyway. The only difference is one > further step unwrapping the Constant. Am I missing something major? > > Tangentially, I don?t understand why transformers defines its own Constant > type, though, given Const in Applicative. At least in transformers 4.0 they > use the built-in Eq1 classes and the like. > > Joseph > > > On Mon, Sep 22, 2014 at 7:12 PM, Edward Kmett wrote: > >> Lift is rather different than Validation. >> >> On Mon, Sep 22, 2014 at 3:13 PM, Roman Cheplyaka >> wrote: >> >>> On 22/09/14 18:43, Andreas Abel wrote: >>> > UPDATE: I found that "Errors e" on >>> > >>> > >>> > >>> https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html >>> >>> Brilliant, thanks a lot! For me, having it in transformers outweighs all >>> the benefits that a separate package may provide (especially a package >>> as heavy as 'errors'). >>> >>> Roman >>> >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gershomb at gmail.com Tue Sep 23 02:29:17 2014 From: gershomb at gmail.com (Gershom B) Date: Mon, 22 Sep 2014 22:29:17 -0400 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: References: <1411428434026.76ccd097@Nodemailer> Message-ID: I wrote some about Lift, etc. back in this comonad reader post: http://comonad.com/reader/2012/abstracting-with-applicatives/ Note that I give a more general construction than Lift, in that it produces an applicative for any Sum with an appropriate natural transformation. Note that Lift Const arises both from the initial homomorphism that sends identity to anything, and the terminal homomorphism that sends everything to const. I?m not advocating moving any of the things described in that post into transformers or the like (certainly not at the moment), but for those interested in how we build these things up, and where they come from, the post may be of some interest. Cheers, Gershom On September 22, 2014 at 8:17:44 PM, Edward Kmett (ekmett at gmail.com) wrote: > There was some discussion of retiring Constant, as it is mostly unused, and > Const has supplanted it in common usage. It didn't happen with this last > release of transformers. > > -Edward > > On Mon, Sep 22, 2014 at 7:27 PM, Joseph Abrahamson wrote: > > > `Lift` is, but `Errors` should be identical, correct? It appears to work > > exactly as I would hope in my testing, anyway. The only difference is one > > further step unwrapping the Constant. Am I missing something major? > > > > Tangentially, I don?t understand why transformers defines its own Constant > > type, though, given Const in Applicative. At least in transformers 4.0 they > > use the built-in Eq1 classes and the like. > > > > Joseph > > > > > > On Mon, Sep 22, 2014 at 7:12 PM, Edward Kmett wrote: > > > >> Lift is rather different than Validation. > >> > >> On Mon, Sep 22, 2014 at 3:13 PM, Roman Cheplyaka > >> wrote: > >> > >>> On 22/09/14 18:43, Andreas Abel wrote: > >>> > UPDATE: I found that "Errors e" on > >>> > > >>> > > >>> > > >>> https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html > >>> > >>> Brilliant, thanks a lot! For me, having it in transformers outweighs all > >>> the benefits that a separate package may provide (especially a package > >>> as heavy as 'errors'). > >>> > >>> Roman > >>> > >>> > >>> _______________________________________________ > >>> Libraries mailing list > >>> Libraries at haskell.org > >>> http://www.haskell.org/mailman/listinfo/libraries > >>> > >>> > >> > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > From michael at snoyman.com Tue Sep 23 03:52:40 2014 From: michael at snoyman.com (Michael Snoyman) Date: Tue, 23 Sep 2014 06:52:40 +0300 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: References: <1411397364544.24ad4a78@Nodemailer> <54204389.9090401@chalmers.se> <542074F2.4020600@ro-che.info> Message-ID: I may have misread, but it seems like Errors is isomorphic to Validation. Nonetheless, I'd still support having something like Validation in the either package, as I'm certain the error messages that would result from using Errors would be atrocious, making it a non-starter for many use cases. On Tue, Sep 23, 2014 at 2:12 AM, Edward Kmett wrote: > Lift is rather different than Validation. > > On Mon, Sep 22, 2014 at 3:13 PM, Roman Cheplyaka wrote: > >> On 22/09/14 18:43, Andreas Abel wrote: >> > UPDATE: I found that "Errors e" on >> > >> > >> > >> https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html >> >> Brilliant, thanks a lot! For me, having it in transformers outweighs all >> the benefits that a separate package may provide (especially a package >> as heavy as 'errors'). >> >> Roman >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From thomasmiedema at gmail.com Tue Sep 23 21:45:00 2014 From: thomasmiedema at gmail.com (Thomas Miedema) Date: Tue, 23 Sep 2014 23:45:00 +0200 Subject: Proposal: make nubBy obey the 98 report semantics Message-ID: The implementation of nubBy in Data.List is as follows, where USE_REPORT_PRELUDE refers to [1]: #ifdef USE_REPORT_PRELUDE nubBy eq [] = [] nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs) #else nubBy eq l = nubBy' l [] where nubBy' [] _ = [] nubBy' (y:ys) xs | elem_by eq y xs = nubBy' ys xs | otherwise = y : nubBy' ys (y:xs) -- Not exported: -- Note that we keep the call to `eq` with arguments in the -- same order as in the reference implementation -- 'xs' is the list of things we've seen so far, -- 'y' is the potential new element elem_by :: (a -> a -> Bool) -> a -> [a] -> Bool elem_by _ _ [] = False elem_by eq y (x:xs) = y `eq` x || elem_by eq y xs #endif That comment is actually not correct [2], and the report version and the base version don't have the same semantics when used on asymmetric relations: MyReportPrelude> nubBy (<) [1] [1] Data.List> nubBy (<) [1,2] [1,2] ## Proposal Make nubBy and nub obey the report semantics by swapping the arguments to `eq` in elem_by, and defining nub as nubBy (==). This is the 'still easy' variant from [3]. ## Motivation The Report's order is more sensible, since the parameters to the relation stay in the left-to-right order in which they occurred in the list. See [4,5] for user bug reports. Discussion period: 2 weeks Code review: https://phabricator.haskell.org/D238 [1] https://www.haskell.org/onlinereport/list.html#sect17.6 [2] https://ghc.haskell.org/trac/ghc/ticket/2528 [3] https://ghc.haskell.org/trac/ghc/ticket/7913#comment:3 [4] https://ghc.haskell.org/trac/ghc/ticket/3280 [5] https://ghc.haskell.org/trac/ghc/ticket/7913 -------------- next part -------------- An HTML attachment was scrubbed... URL: From thomasmiedema at gmail.com Tue Sep 23 21:57:47 2014 From: thomasmiedema at gmail.com (Thomas Miedema) Date: Tue, 23 Sep 2014 23:57:47 +0200 Subject: Proposal: remove versionTags from Data.Version Message-ID: Version in Data.Version from base is defined as: data Version = Version { versionBranch :: [Int], versionTags :: [String] } instance Eq Version where v1 == v2 = versionBranch v1 == versionBranch v2 && sort (versionTags v1) == sort (versionTags v2) -- tags may be in any order instance Ord Version where v1 `compare` v2 = versionBranch v1 `compare` versionBranch v2 ## Proposal Remove the `versionTags` field from this type. ## Motivation * The Eq and Ord instances of Version don't agree whether two versions with different versionTags are equal or not [1]: > a = Version [1] ["a"] > b = Version [1] ["b"] > compare a b EQ > a == b False * The Package versioning policy does not include version tags [2]. * Cabal no longer supports package version tags [3,4]. Discussion period: 2 weeks. Note: this is not a proposal to ignore trailing zeros when comparing versions. Neither is this is a proposal to change the Eq instance for Version to only consider the versionBranch field. This is a proposal to remove versionTags altogether. [1] https://ghc.haskell.org/trac/ghc/ticket/2496 [2] http://www.haskell.org/haskellwiki/Package_versioning_policy [3] https://github.com/haskell/cabal/issues/890 [4] http://www.haskell.org/cabal/users-guide/developing-packages.html#package-names-and-versions -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Tue Sep 23 22:01:55 2014 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Wed, 24 Sep 2014 00:01:55 +0200 (CEST) Subject: Proposal: remove versionTags from Data.Version In-Reply-To: References: Message-ID: On Tue, 23 Sep 2014, Thomas Miedema wrote: > ## Motivation > * The Eq and Ord instances of Version don't agree whether two versions with?different versionTags are equal > or not [1]: > > ? ? > a = Version [1] ["a"] > ? ? > b = Version [1] ["b"] > ? ? > compare a b > ? ? EQ > ? ? > a == b > ? ? False > > * The Package versioning policy does not include version tags [2]. > * Cabal no longer supports package version tags [3,4]. How are versions of pkg-config handled? pkg-config does not always return numeric versions. From dan.doel at gmail.com Tue Sep 23 23:45:54 2014 From: dan.doel at gmail.com (Dan Doel) Date: Tue, 23 Sep 2014 19:45:54 -0400 Subject: Proposal: make nubBy obey the 98 report semantics In-Reply-To: References: Message-ID: nub and nubBy already obey the semantics of the Haskell 2010 report, which only specifies the behavior when you pass it an "equality test," presumably an equivalence relation. The Haskell 98 report similarly specified nubBy as assuming the function passed in defined an equivalence. So the current definition is not actually in violation of that spec, either. Rather, 'nubBy (<)' is calling the function with an invalid argument. I'm ambivalent about whether this gets 'fixed', but it is technically not a bug (or, the only definitive error is that the comment doesn't match the implementation). -- Dan On Tue, Sep 23, 2014 at 5:45 PM, Thomas Miedema wrote: > The implementation of nubBy in Data.List is as follows, where > USE_REPORT_PRELUDE refers to [1]: > > #ifdef USE_REPORT_PRELUDE > nubBy eq [] = [] > nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) > xs) > #else > nubBy eq l = nubBy' l [] > where > nubBy' [] _ = [] > nubBy' (y:ys) xs > | elem_by eq y xs = nubBy' ys xs > | otherwise = y : nubBy' ys (y:xs) > > -- Not exported: > -- Note that we keep the call to `eq` with arguments in the > -- same order as in the reference implementation > -- 'xs' is the list of things we've seen so far, > -- 'y' is the potential new element > elem_by :: (a -> a -> Bool) -> a -> [a] -> Bool > elem_by _ _ [] = False > elem_by eq y (x:xs) = y `eq` x || elem_by eq y xs > #endif > > That comment is actually not correct [2], and the report version and the > base > version don't have the same semantics when used on asymmetric relations: > > MyReportPrelude> nubBy (<) [1] > [1] > > Data.List> nubBy (<) [1,2] > [1,2] > > ## Proposal > Make nubBy and nub obey the report semantics by swapping the arguments to > `eq` in elem_by, and defining nub as nubBy (==). This is the 'still easy' > variant from [3]. > > ## Motivation > The Report's order is more sensible, since the parameters to the relation > stay > in the left-to-right order in which they occurred in the list. See [4,5] > for > user bug reports. > > Discussion period: 2 weeks > Code review: https://phabricator.haskell.org/D238 > > [1] https://www.haskell.org/onlinereport/list.html#sect17.6 > [2] https://ghc.haskell.org/trac/ghc/ticket/2528 > [3] https://ghc.haskell.org/trac/ghc/ticket/7913#comment:3 > [4] https://ghc.haskell.org/trac/ghc/ticket/3280 > [5] https://ghc.haskell.org/trac/ghc/ticket/7913 > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From duncan.coutts at googlemail.com Wed Sep 24 08:15:47 2014 From: duncan.coutts at googlemail.com (Duncan Coutts) Date: Wed, 24 Sep 2014 09:15:47 +0100 Subject: Proposal: remove versionTags from Data.Version In-Reply-To: References: Message-ID: <1411546547.20616.305.camel@dunky.localdomain> On Tue, 2014-09-23 at 23:57 +0200, Thomas Miedema wrote: > Version in Data.Version from base is defined as: > > data Version = Version { versionBranch :: [Int], versionTags :: > [String] } > > instance Eq Version where > v1 == v2 = versionBranch v1 == versionBranch v2 > && sort (versionTags v1) == sort (versionTags v2) > -- tags may be in any order > > instance Ord Version where > v1 `compare` v2 = versionBranch v1 `compare` versionBranch v2 > > > ## Proposal > Remove the `versionTags` field from this type. > > > ## Motivation > * The Eq and Ord instances of Version don't agree whether two versions > with different > versionTags are equal or not [1]: > > > a = Version [1] ["a"] > > b = Version [1] ["b"] > > compare a b > EQ > > a == b > False > > * The Package versioning policy does not include version tags [2]. > * Cabal no longer supports package version tags [3,4]. > > Discussion period: 2 weeks. > > Note: this is not a proposal to ignore trailing zeros when comparing > versions. Neither is this is a proposal to change the Eq instance for > Version to only consider the versionBranch field. This is a proposal to > remove versionTags altogether. Cabal is probably the primary user of this type. With my Cabal maintainer's hat on I support this change. Cabal has for a long time deprecated the version tags feature. It accepts but ignores tags in most places, and never emits tags (Cabal uses its own parser and printer). Packages using tags in their version are not allowed on hackage for example. The tags idea turned out not to really work. The fact that it's not part of the Ord instance causes all sorts of problems (think package indexes), but then it's not clear what an Ord instance including an unordered set of tags should be. It does not map onto other package system's versions (which have strings like "beta" but they're part of the version number, not an additional unordered set). In short, Cabal tried to make sense of the tags but it just causes too many problems and so Cabal has for years now pretended that the tags feature does not exist. Duncan From duncan.coutts at googlemail.com Wed Sep 24 08:21:20 2014 From: duncan.coutts at googlemail.com (Duncan Coutts) Date: Wed, 24 Sep 2014 09:21:20 +0100 Subject: Proposal: remove versionTags from Data.Version In-Reply-To: References: Message-ID: <1411546880.20616.311.camel@dunky.localdomain> On Wed, 2014-09-24 at 00:01 +0200, Henning Thielemann wrote: > On Tue, 23 Sep 2014, Thomas Miedema wrote: > > > ## Motivation > > * The Eq and Ord instances of Version don't agree whether two versions with different versionTags are equal > > or not [1]: > > > > > a = Version [1] ["a"] > > > b = Version [1] ["b"] > > > compare a b > > EQ > > > a == b > > False > > > > * The Package versioning policy does not include version tags [2]. > > * Cabal no longer supports package version tags [3,4]. > > > How are versions of pkg-config handled? pkg-config does not always return > numeric versions. The pkg-config versions with string (e.g. 0.9.8b) do not map cleanly onto the Version type, neither with tags nor without. The strings in pkg-config versions are part of the version and are included in the (complicated) ordering rules, where as Data.Version version tags are explicitly an unordered set, so the pkg-config alphanumeric versions do not map onto those tags. Basically pkg-config style versions need handling specially if you want to cover the full alphanumeric versions. In practice Cabal has always done this wrong, by only handling the common numeric subset. It's never been a high enough priority to handle in full. Except for old versions of OpenSSL this has not been too much of problem in practice. Duncan From abela at chalmers.se Wed Sep 24 09:05:17 2014 From: abela at chalmers.se (Andreas Abel) Date: Wed, 24 Sep 2014 11:05:17 +0200 Subject: Proposal: make nubBy obey the 98 report semantics In-Reply-To: References: Message-ID: <5422894D.2000101@chalmers.se> Same indifference here, what does "remove duplicates according to relation R" mean intuitively if R is not an equivalence relation? (nub and nubBy with their quadratic complexity are anyway a wart. These names should ideally be used for versions that only work for lists over ordered type, so that one can give an implementation with a sensible complexity.) But do if you must. On 24.09.2014 01:45, Dan Doel wrote: > nub and nubBy already obey the semantics of the Haskell 2010 report, > which only specifies the behavior when you pass it an "equality test," > presumably an equivalence relation. > > The Haskell 98 report similarly specified nubBy as assuming the function > passed in defined an equivalence. So the current definition is not > actually in violation of that spec, either. Rather, 'nubBy (<)' is > calling the function with an invalid argument. > > I'm ambivalent about whether this gets 'fixed', but it is technically > not a bug (or, the only definitive error is that the comment doesn't > match the implementation). > > -- Dan > > On Tue, Sep 23, 2014 at 5:45 PM, Thomas Miedema > wrote: > > The implementation of nubBy in Data.List is as follows, where > USE_REPORT_PRELUDE refers to [1]: > > #ifdef USE_REPORT_PRELUDE > nubBy eq [] = [] > nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq > x y)) xs) > #else > nubBy eq l = nubBy' l [] > where > nubBy' [] _ = [] > nubBy' (y:ys) xs > | elem_by eq y xs = nubBy' ys xs > | otherwise = y : nubBy' ys (y:xs) > > -- Not exported: > -- Note that we keep the call to `eq` with arguments in the > -- same order as in the reference implementation > -- 'xs' is the list of things we've seen so far, > -- 'y' is the potential new element > elem_by :: (a -> a -> Bool) -> a -> [a] -> Bool > elem_by _ _ [] = False > elem_by eq y (x:xs) = y `eq` x || elem_by eq y xs > #endif > > That comment is actually not correct [2], and the report version and > the base > version don't have the same semantics when used on asymmetric relations: > > MyReportPrelude> nubBy (<) [1] > [1] > > Data.List> nubBy (<) [1,2] > [1,2] > > ## Proposal > Make nubBy and nub obey the report semantics by swapping the > arguments to > `eq` in elem_by, and defining nub as nubBy (==). This is the 'still > easy' > variant from [3]. > > ## Motivation > The Report's order is more sensible, since the parameters to the > relation stay > in the left-to-right order in which they occurred in the list. See > [4,5] for > user bug reports. > > Discussion period: 2 weeks > Code review: https://phabricator.haskell.org/D238 > > [1] https://www.haskell.org/onlinereport/list.html#sect17.6 > [2] https://ghc.haskell.org/trac/ghc/ticket/2528 > [3] https://ghc.haskell.org/trac/ghc/ticket/7913#comment:3 > [4] https://ghc.haskell.org/trac/ghc/ticket/3280 > [5] https://ghc.haskell.org/trac/ghc/ticket/7913 > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel at gu.se http://www2.tcs.ifi.lmu.de/~abel/ From hvr at gnu.org Wed Sep 24 09:27:50 2014 From: hvr at gnu.org (Herbert Valerio Riedel) Date: Wed, 24 Sep 2014 11:27:50 +0200 Subject: Proposal: remove versionTags from Data.Version In-Reply-To: (Thomas Miedema's message of "Tue, 23 Sep 2014 23:57:47 +0200") References: Message-ID: <87egv1nzah.fsf@gnu.org> On 2014-09-23 at 23:57:47 +0200, Thomas Miedema wrote: > Version in Data.Version from base is defined as: > > data Version = Version { versionBranch :: [Int], versionTags :: > [String] } [...] > ## Proposal > Remove the `versionTags` field from this type. +1 (possibly with a DEPRECATE-cycle during GHC 7.10, and actual removal with GHC 7.12) From marlowsd at gmail.com Wed Sep 24 12:51:46 2014 From: marlowsd at gmail.com (Simon Marlow) Date: Wed, 24 Sep 2014 13:51:46 +0100 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: References: <20140904144629.GA21972@sniper> <5409D931.1030503@gmail.com> Message-ID: <5422BE62.7010205@gmail.com> Ok, sorry for the delay, we still need a resolution on this one. So thanks to your persuasive comments I think I'm convinced. What finally tipped me over the edge was this: https://phabricator.haskell.org/diffusion/GHC/browse/master/libraries/base/Control/Concurrent/QSem.hs;165072b334ebb2ccbef38a963ac4d126f1e08c96$103-112 It turns out I've been a victim of this "bug" myself :-) So let's fix it. But what is the cost? Adding an uninterruptibleMask won't be free. In the case of `catch`, since the mask is already built in to the primitive, we can just change it to be an uninterruptibleMask, and that applies to handle and onException too. For `finally` we can replace the mask with an uninterruptibleMask, but for `bracket` we have to add a new layer of uninterruptibleMask. Lots of documentation probably needs to be updated. Any chance you could make a patch and upload it to Phabricator? Cheers, Simon On 05/09/2014 18:34, Eyal Lotem wrote: > Hey Simon, thanks for the reply! > > > On Fri, Sep 5, 2014 at 6:39 PM, Simon Marlow > wrote: > > Eyal, thanks for bringing up this issue. It's been at the back of > my mind for a while, but I've never really thought through the > issues and consequences of changes. So this is a good opportunity > to do that. You point out (in another email in the thread) that: > > A) Cases that were not interruptible will remain the same. > B) Cases that were interruptible were bugs and will be fixed. > > However, > > C) Some bugs will turn into deadlocks (unkillable threads) > > Being able to recover from bugs is an important property in large > long-running systems. So this is a serious problem. Hence why I > always treat uninterruptibleMask with the deepest suspicion. > > > Recovering from various kinds of failures makes a lot of sense. But how > can you recover from arbitrary invariants of the program being broken? > > For example, if you use a bracket on some semaphore monitoring a global > resource. How do you recover from a bug of leaking semaphore tokens? > > Recovering from crashes of whole processes whose internal state can be > recovered to a fresh, usable state, is a great feature. > Recovering from thread crashes that share arbitrary mutable state with > other threads is not practical, I believe. > > Let's consider the case where we have an interruptible operation in > the handler, and divide it into two (er three): > > 1. it blocks for a short bounded amount of time. > 2. It blocks for a long time > 3. It blocks indefinitely > > These are all buggy, but in different ways. Only (1) is fixed by > adding uninterruptibleMask. (2) is "fixed", but in exchange for an > unresponsive thread - also undesirable. (3) was a bug in the > application code, and turns into a deadlock with > uninterruptibleMask, which is undesirable. > > > I think that (1) is by far the most common and is very prevalent. I > think 0-time interruptible (that can block but almost never do) > operations are the most common cleanup handlers. > > For (2) and (3), we need to choose the lesser evil: > > A) Deadlocks and/or unresponsiveness > B) Arbitrary invariants being broken and leaks > > In my experience, A tends to manifest exactly where the bug is, and is > therefore easy to debug and mostly a "performance bug" . > B tends to manifest as difficult to explain behavior elsewhere from > where the bug actually is, and is usually a "correctness bug", which is > almost always worse. > > Therefore, I think A is a far far lesser evil than B, when (2) and (3) > are involved. > > I'd like to reemphasize that this change will almost always fix the > problem completely since the most common case is (1), and in rare cases, > it will convert B to A, which is also, IMO, very desirable. > > > This is as far as I've got thinking through the issues so far. I > wonder to what extent the programmer can and should mitigate these > cases, and how much we can help them. I don't want unkillable > threads, even when caused by buggy code. > > > Cheers, > Simon > > > On 04/09/2014 16:46, Roman Cheplyaka wrote: > > I find your arguments quite convincing. Count that as +1 from me. > > Roman > > > > _________________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/__mailman/listinfo/libraries > > > > > > -- > Eyal From merijn at inconsistent.nl Wed Sep 24 16:58:03 2014 From: merijn at inconsistent.nl (Merijn Verstraaten) Date: Wed, 24 Sep 2014 09:58:03 -0700 Subject: Proposal: Use uninterruptibleMask for cleanup actions in Control.Exception In-Reply-To: <5422BE62.7010205@gmail.com> References: <20140904144629.GA21972@sniper> <5409D931.1030503@gmail.com> <5422BE62.7010205@gmail.com> Message-ID: Hi Simon, Well, another issue that was raised (I forget by whom!) was the fact that stackoverflows are currently thrown externally from the executing thread and that this should really be changed into being thrown to the thread by itself, thereby avoiding the mask. Cheers, Merijn On 24 Sep 2014, at 05:51 , Simon Marlow wrote: > Ok, sorry for the delay, we still need a resolution on this one. > > So thanks to your persuasive comments I think I'm convinced. What finally tipped me over the edge was this: > > https://phabricator.haskell.org/diffusion/GHC/browse/master/libraries/base/Control/Concurrent/QSem.hs;165072b334ebb2ccbef38a963ac4d126f1e08c96$103-112 > > It turns out I've been a victim of this "bug" myself :-) So let's fix it. > > But what is the cost? Adding an uninterruptibleMask won't be free. > > In the case of `catch`, since the mask is already built in to the primitive, we can just change it to be an uninterruptibleMask, and that applies to handle and onException too. For `finally` we can replace the mask with an uninterruptibleMask, but for `bracket` we have to add a new layer of uninterruptibleMask. > > Lots of documentation probably needs to be updated. Any chance you could make a patch and upload it to Phabricator? > > Cheers, > Simon > > On 05/09/2014 18:34, Eyal Lotem wrote: >> Hey Simon, thanks for the reply! >> >> >> On Fri, Sep 5, 2014 at 6:39 PM, Simon Marlow > > wrote: >> >> Eyal, thanks for bringing up this issue. It's been at the back of >> my mind for a while, but I've never really thought through the >> issues and consequences of changes. So this is a good opportunity >> to do that. You point out (in another email in the thread) that: >> >> A) Cases that were not interruptible will remain the same. >> B) Cases that were interruptible were bugs and will be fixed. >> >> However, >> >> C) Some bugs will turn into deadlocks (unkillable threads) >> >> Being able to recover from bugs is an important property in large >> long-running systems. So this is a serious problem. Hence why I >> always treat uninterruptibleMask with the deepest suspicion. >> >> >> Recovering from various kinds of failures makes a lot of sense. But how >> can you recover from arbitrary invariants of the program being broken? >> >> For example, if you use a bracket on some semaphore monitoring a global >> resource. How do you recover from a bug of leaking semaphore tokens? >> >> Recovering from crashes of whole processes whose internal state can be >> recovered to a fresh, usable state, is a great feature. >> Recovering from thread crashes that share arbitrary mutable state with >> other threads is not practical, I believe. >> >> Let's consider the case where we have an interruptible operation in >> the handler, and divide it into two (er three): >> >> 1. it blocks for a short bounded amount of time. >> 2. It blocks for a long time >> 3. It blocks indefinitely >> >> These are all buggy, but in different ways. Only (1) is fixed by >> adding uninterruptibleMask. (2) is "fixed", but in exchange for an >> unresponsive thread - also undesirable. (3) was a bug in the >> application code, and turns into a deadlock with >> uninterruptibleMask, which is undesirable. >> >> >> I think that (1) is by far the most common and is very prevalent. I >> think 0-time interruptible (that can block but almost never do) >> operations are the most common cleanup handlers. >> >> For (2) and (3), we need to choose the lesser evil: >> >> A) Deadlocks and/or unresponsiveness >> B) Arbitrary invariants being broken and leaks >> >> In my experience, A tends to manifest exactly where the bug is, and is >> therefore easy to debug and mostly a "performance bug" . >> B tends to manifest as difficult to explain behavior elsewhere from >> where the bug actually is, and is usually a "correctness bug", which is >> almost always worse. >> >> Therefore, I think A is a far far lesser evil than B, when (2) and (3) >> are involved. >> >> I'd like to reemphasize that this change will almost always fix the >> problem completely since the most common case is (1), and in rare cases, >> it will convert B to A, which is also, IMO, very desirable. >> >> >> This is as far as I've got thinking through the issues so far. I >> wonder to what extent the programmer can and should mitigate these >> cases, and how much we can help them. I don't want unkillable >> threads, even when caused by buggy code. >> >> >> Cheers, >> Simon >> >> >> On 04/09/2014 16:46, Roman Cheplyaka wrote: >> >> I find your arguments quite convincing. Count that as +1 from me. >> >> Roman >> >> >> >> _________________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/__mailman/listinfo/libraries >> >> >> >> >> >> -- >> Eyal > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 801 bytes Desc: Message signed with OpenPGP using GPGMail URL: From R.Paterson at city.ac.uk Wed Sep 24 19:06:17 2014 From: R.Paterson at city.ac.uk (Ross Paterson) Date: Wed, 24 Sep 2014 20:06:17 +0100 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <54204389.9090401@chalmers.se> References: <1411397364544.24ad4a78@Nodemailer> <54204389.9090401@chalmers.se> Message-ID: <20140924190617.GA6019@city.ac.uk> On Mon, Sep 22, 2014 at 05:43:05PM +0200, Andreas Abel wrote: > UPDATE: I found that "Errors e" on > > https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html > > seems to be doing the job of "Validation" already (no nice names of the > operations, though). Which operations and names would you like? From david.feuer at gmail.com Thu Sep 25 03:25:02 2014 From: david.feuer at gmail.com (David Feuer) Date: Wed, 24 Sep 2014 23:25:02 -0400 Subject: Proposal (long term): Remove (/=) from Eq; change the semantics of (==) for floating point Message-ID: As Edward Kmett explained to me, (/=) is currently needed in Eq to support IEEE floating point semantics for (==) and (/=). As I see it, those semantics are badly broken from the perspective of what Eq is supposed to mean, and really should be supported using special functions (eqIEEE and neqIEEE or whatever), whereas the most appropriate Eq instance for floating point would be something more like instance Eq Double where x == y = decodeFloat x == decodeFloat y If this is (eventually) done, that would allow us to remove (/=) from Eq, reducing its dictionary to a single member, (==), improving efficiency when the type is not statically known. David -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwlato at gmail.com Thu Sep 25 03:43:20 2014 From: jwlato at gmail.com (John Lato) Date: Thu, 25 Sep 2014 11:43:20 +0800 Subject: Proposal (long term): Remove (/=) from Eq; change the semantics of (==) for floating point In-Reply-To: References: Message-ID: This strikes me as a halfway measure between those who want arithmatic operations on Float/Double to be fast (i.e. IEEE754 semantics/machine ops) and those who want more exacting laws associated with arithmatic classes. As such, I think it's a bad idea. I think it's better that all operations follow the same philosophy. On Thu, Sep 25, 2014 at 11:25 AM, David Feuer wrote: > As Edward Kmett explained to me, (/=) is currently needed in Eq to support > IEEE floating point semantics for (==) and (/=). As I see it, those > semantics are badly broken from the perspective of what Eq is supposed to > mean, and really should be supported using special functions (eqIEEE and > neqIEEE or whatever), whereas the most appropriate Eq instance for floating > point would be something more like > > instance Eq Double where > x == y = decodeFloat x == decodeFloat y > > If this is (eventually) done, that would allow us to remove (/=) from Eq, > reducing its dictionary to a single member, (==), improving efficiency when > the type is not statically known. > > David > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Thu Sep 25 03:51:27 2014 From: david.feuer at gmail.com (David Feuer) Date: Wed, 24 Sep 2014 23:51:27 -0400 Subject: Proposal (long term): Remove (/=) from Eq; change the semantics of (==) for floating point In-Reply-To: References: Message-ID: I'm not sure what you're saying. What I'm saying is that we can make Eq faster for some things *other* than Float/Double in some contexts if we take away the ability of Eq to deal with the messiness of IEEE requirements, which also happens to have the advantage of making sure that (a==b) /= _|_ -> (a==b) == not (a /= b). I have my own opinions about the numerical typeclass hierarchy (Num et al), but I think this issue is pretty much orthogonal. On Wed, Sep 24, 2014 at 11:43 PM, John Lato wrote: > This strikes me as a halfway measure between those who want arithmatic > operations on Float/Double to be fast (i.e. IEEE754 semantics/machine ops) > and those who want more exacting laws associated with arithmatic classes. > As such, I think it's a bad idea. I think it's better that all operations > follow the same philosophy. > > On Thu, Sep 25, 2014 at 11:25 AM, David Feuer > wrote: > >> As Edward Kmett explained to me, (/=) is currently needed in Eq to >> support IEEE floating point semantics for (==) and (/=). As I see it, those >> semantics are badly broken from the perspective of what Eq is supposed to >> mean, and really should be supported using special functions (eqIEEE and >> neqIEEE or whatever), whereas the most appropriate Eq instance for floating >> point would be something more like >> >> instance Eq Double where >> x == y = decodeFloat x == decodeFloat y >> >> If this is (eventually) done, that would allow us to remove (/=) from Eq, >> reducing its dictionary to a single member, (==), improving efficiency when >> the type is not statically known. >> >> David >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ky3 at atamo.com Thu Sep 25 04:09:14 2014 From: ky3 at atamo.com (Kim-Ee Yeoh) Date: Thu, 25 Sep 2014 11:09:14 +0700 Subject: Proposal (long term): Remove (/=) from Eq; change the semantics of (==) for floating point In-Reply-To: References: Message-ID: On Thu, Sep 25, 2014 at 10:25 AM, David Feuer wrote: > As Edward Kmett explained to me, (/=) is currently needed in Eq to support > IEEE floating point semantics for (==) and (/=). As I see it, those > semantics are badly broken from the perspective of what Eq is supposed to > mean, and really should be supported using special functions (eqIEEE and > neqIEEE or whatever), whereas the most appropriate Eq instance for floating > point would be something more like A short-term improvement you could make is to move this discussion to haskell-cafe. By reaching a larger audience with lots more stakeholders, you'll garner support and assistance putting your proposal in the best light possible. -- Kim-Ee -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwlato at gmail.com Thu Sep 25 04:14:59 2014 From: jwlato at gmail.com (John Lato) Date: Thu, 25 Sep 2014 12:14:59 +0800 Subject: Proposal (long term): Remove (/=) from Eq; change the semantics of (==) for floating point In-Reply-To: References: Message-ID: My primary objection is that currently all operators have ieee semantics on Float/Double. This change would mean that basic arithmatic operators would have ieee semantics but comparisons would not. I consider this a significant added burden on users who are used to thinking in the current semantics (it makes Eq more uniform at the cost of making Float/Double less so). Of course I do concede that it's probably much simpler for people using Eq to assume reflexivity. On Thu, Sep 25, 2014 at 11:51 AM, David Feuer wrote: > I'm not sure what you're saying. What I'm saying is that we can make Eq > faster for some things *other* than Float/Double in some contexts if we > take away the ability of Eq to deal with the messiness of IEEE > requirements, which also happens to have the advantage of making sure that > (a==b) /= _|_ -> (a==b) == not (a /= b). I have my own opinions about the > numerical typeclass hierarchy (Num et al), but I think this issue is pretty > much orthogonal. > > On Wed, Sep 24, 2014 at 11:43 PM, John Lato wrote: > >> This strikes me as a halfway measure between those who want arithmatic >> operations on Float/Double to be fast (i.e. IEEE754 semantics/machine ops) >> and those who want more exacting laws associated with arithmatic classes. >> As such, I think it's a bad idea. I think it's better that all operations >> follow the same philosophy. >> >> On Thu, Sep 25, 2014 at 11:25 AM, David Feuer >> wrote: >> >>> As Edward Kmett explained to me, (/=) is currently needed in Eq to >>> support IEEE floating point semantics for (==) and (/=). As I see it, those >>> semantics are badly broken from the perspective of what Eq is supposed to >>> mean, and really should be supported using special functions (eqIEEE and >>> neqIEEE or whatever), whereas the most appropriate Eq instance for floating >>> point would be something more like >>> >>> instance Eq Double where >>> x == y = decodeFloat x == decodeFloat y >>> >>> If this is (eventually) done, that would allow us to remove (/=) from >>> Eq, reducing its dictionary to a single member, (==), improving efficiency >>> when the type is not statically known. >>> >>> David >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From johan.tibell at gmail.com Thu Sep 25 05:05:01 2014 From: johan.tibell at gmail.com (Johan Tibell) Date: Thu, 25 Sep 2014 07:05:01 +0200 Subject: Proposal (long term): Remove (/=) from Eq; change the semantics of (==) for floating point In-Reply-To: References: Message-ID: -1 This would make floating point values a pain to work with for seemingly little gain. -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Thu Sep 25 05:19:47 2014 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Thu, 25 Sep 2014 01:19:47 -0400 Subject: Proposal (long term): Remove (/=) from Eq; change the semantics of (==) for floating point In-Reply-To: References: Message-ID: i'm strongly -1 on doing ANYTHING resembling instance Eq Double where x == y = decodeFloat x == decodeFloat y floating point is odd because it kinda has to be, and changes to the defaults for that need a lot of discussion about the implications (even before they got to the libraries list). On Thu, Sep 25, 2014 at 1:05 AM, Johan Tibell wrote: > -1 > > This would make floating point values a pain to work with for seemingly > little gain. > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Thu Sep 25 05:21:39 2014 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Thu, 25 Sep 2014 01:21:39 -0400 Subject: Proposal (long term): Remove (/=) from Eq; change the semantics of (==) for floating point In-Reply-To: References: Message-ID: point being, Floating point is weird, but it *does* obey an approximate (bounded relative error) version of the standard algebraic laws, but most folks are unaccustomed to that (admittedly WEIRD/Different) style of thinking On Thu, Sep 25, 2014 at 1:19 AM, Carter Schonwald < carter.schonwald at gmail.com> wrote: > i'm strongly -1 on doing ANYTHING resembling > instance Eq Double where > x == y = decodeFloat x == decodeFloat y > > floating point is odd because it kinda has to be, and changes to the > defaults for that > need a lot of discussion about the implications (even before they got to > the libraries list). > > > > > > On Thu, Sep 25, 2014 at 1:05 AM, Johan Tibell > wrote: > >> -1 >> >> This would make floating point values a pain to work with for seemingly >> little gain. >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From abela at chalmers.se Thu Sep 25 07:52:15 2014 From: abela at chalmers.se (Andreas Abel) Date: Thu, 25 Sep 2014 09:52:15 +0200 Subject: Pre-Proposal: Add Validation somewhere easily accessible In-Reply-To: <20140924190617.GA6019@city.ac.uk> References: <1411397364544.24ad4a78@Nodemailer> <54204389.9090401@chalmers.se> <20140924190617.GA6019@city.ac.uk> Message-ID: <5423C9AF.9070806@chalmers.se> To use the Errors type in a nice way: * I'd like to import it from a module named Control.Applicative.Error(s) * be able to work it without reference to Lift, Constant, Pure, Other. The second point would amout to, I guess, * newtype Errors instead of type Errors * having 'runErrors' that give me the result or the errors. Just some initial thoughts, Andreas On 24.09.2014 21:06, Ross Paterson wrote: > On Mon, Sep 22, 2014 at 05:43:05PM +0200, Andreas Abel wrote: >> UPDATE: I found that "Errors e" on >> >> https://hackage.haskell.org/package/transformers-0.4.1.0/docs/Control-Applicative-Lift.html >> >> seems to be doing the job of "Validation" already (no nice names of the >> operations, though). > > Which operations and names would you like? -- Andreas Abel <>< Du bist der geliebte Mensch. Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden andreas.abel at gu.se http://www2.tcs.ifi.lmu.de/~abel/ From hvr at gnu.org Thu Sep 25 09:38:37 2014 From: hvr at gnu.org (Herbert Valerio Riedel) Date: Thu, 25 Sep 2014 11:38:37 +0200 Subject: Proposal (long term): Remove (/=) from Eq; change the semantics of (==) for floating point In-Reply-To: (David Feuer's message of "Wed, 24 Sep 2014 23:25:02 -0400") References: Message-ID: <87h9zw9h0i.fsf@gnu.org> On 2014-09-25 at 05:25:02 +0200, David Feuer wrote: > As Edward Kmett explained to me, (/=) is currently needed in Eq to support > IEEE floating point semantics for (==) and (/=). As I see it, those > semantics are badly broken from the perspective of what Eq is supposed to > mean, and really should be supported using special functions (eqIEEE and > neqIEEE or whatever), whereas the most appropriate Eq instance for floating > point would be something more like If the Eq instance for Double is changed, what about its Ord instance then? Right now, (0/0::Double) is handled poorly for both Eq and Ord, resulting in Data.Map and other operations relying on Eq/Ord to behave weirdly when (0/0::Double) happens to be used as key. From ekmett at gmail.com Thu Sep 25 15:30:51 2014 From: ekmett at gmail.com (Edward Kmett) Date: Thu, 25 Sep 2014 11:30:51 -0400 Subject: Proposal (long term): Remove (/=) from Eq; change the semantics of (==) for floating point In-Reply-To: <87h9zw9h0i.fsf@gnu.org> References: <87h9zw9h0i.fsf@gnu.org> Message-ID: On Thu, Sep 25, 2014 at 5:38 AM, Herbert Valerio Riedel wrote: > On 2014-09-25 at 05:25:02 +0200, David Feuer wrote: > > As Edward Kmett explained to me, (/=) is currently needed in Eq to > support > > IEEE floating point semantics for (==) and (/=). As I see it, those > > semantics are badly broken from the perspective of what Eq is supposed to > > mean, and really should be supported using special functions (eqIEEE and > > neqIEEE or whatever), whereas the most appropriate Eq instance for > floating > > point would be something more like > > If the Eq instance for Double is changed, what about its Ord instance > then? Right now, (0/0::Double) is handled poorly for both Eq and Ord, > resulting in Data.Map and other operations relying on Eq/Ord to behave > weirdly when (0/0::Double) happens to be used as key. > If you go to use Doubles for keys in a Data.Map you'd have a whole host of other problems. Even if you had the instance proposed here, which makes it harder to work nicely with underflow/overflow conditions on doubles, which are a far more common going concern and motivate the IEEE design, you have an issue. Notably, that if you compute the same number twice in different parts of your program or even the same part at different times you can get different answers due to intermediate value promotion in the FPU, etc. That pretty much damns any attempt to use doubles for exact value-match key lookup to unreliability or failure. FWIW- I'm -1 on this proposal. -Edward > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From thomasmiedema at gmail.com Fri Sep 26 16:23:11 2014 From: thomasmiedema at gmail.com (Thomas Miedema) Date: Fri, 26 Sep 2014 18:23:11 +0200 Subject: Proposal unix. Change to `IO (Maybe String)`: getLoginName, getUserEntry* and getGroupEntry* Message-ID: In the unix package, in System.Posix.User, we have the following functions [1]: * getLoginName (getlogin) * getUserEntryForID (getpwuid_r) * getGroupEntryForID (getgrgid_r) * getUserEntryForName (getpwnam_r) * getGroupEntryForName (getgrnam_r) They have signature `IO String`, and use `throwErrnoIfNull` to call the c functions listed in parenthesis. ## Proposal Change the signature of the functions listed above to `IO (Maybe String)`. The new semantics would be: * If the c function returns a NULL pointer with errno set to ENOENT, meaning the given user or group could not be found, the result is Nothing. * If another error occured, an error is thrown (no change). * Otherwise the result is Just "result". ## Motivation At least `getlogin` and `getgrgid` are unreliable on Linux. It is possible for them to return NULL pointers [2] even when the user is logged in and has an associated user entry in /etc/passwd and group entry in /etc/group. Examples: * when `getLoginName` is called using a terminal emulator that doesn't write login records to /var/run/utmp, or inside screen/tmux, `getlogin` tends to return NULL pointers [3]. * `getGroupEntryForID` can throw a NULL pointer exception inside chroots or other environments where the information in /etc/groups is not to be considered reliable [4]. Since we can, let's give the above Haskell functions a type safe(r) api. If the proposal gets rejected, I will just add a warning message to the docstrings of the functions in question and permanently disable their tests from the unix testsuite, since this is currently causing problems [5,6]. Discussion period: 2 weeks. ## Links [1] https://github.com/haskell/unix/blob/master/System/Posix/User.hsc [2] http://linux.die.net/man/3/getlogin [3] https://github.com/haskell/unix/blob/cad1ef27bb0a51bc68ebadb1297de1ae05bee9db/tests/all.T#L14-L18 [4] https://ghc.haskell.org/trac/ghc/ticket/8293 [5] http://www.haskell.org/pipermail/ghc-devs/2014-September/006420.html [6] https://ghc.haskell.org/trac/ghc/ticket/1487#comment:23 ## Details * Another function in the same module that needs to change is `getEffectiveUserName`, because it calls the function `getUserEntryForID` mentioned before. * The following functions don't need to change, since they return the empty list if no entries are found: - getGroups (getgroups) - getAllGroupEntries (getgrent) - getAllUserEntries (getpwent) * The rest of the functions in the module don't need to change either, since they are not expected to return NULL pointers, according to their respective man pages: - getRealUserID (getuid) - getRealGroupID (getgid) - getEffectiveUserID (geteuid) - getEffectiveGroupID (getegid) -------------- next part -------------- An HTML attachment was scrubbed... URL: From johan.tibell at gmail.com Fri Sep 26 16:47:07 2014 From: johan.tibell at gmail.com (Johan Tibell) Date: Fri, 26 Sep 2014 18:47:07 +0200 Subject: Proposal unix. Change to `IO (Maybe String)`: getLoginName, getUserEntry* and getGroupEntry* In-Reply-To: References: Message-ID: I think we should add the saner versions (that return Maybe) under new names to avoid unnecessarily breaking backwards compatibility. On Fri, Sep 26, 2014 at 6:23 PM, Thomas Miedema wrote: > In the unix package, in System.Posix.User, we have the following functions > [1]: > > * getLoginName (getlogin) > * getUserEntryForID (getpwuid_r) > * getGroupEntryForID (getgrgid_r) > * getUserEntryForName (getpwnam_r) > * getGroupEntryForName (getgrnam_r) > > They have signature `IO String`, and use `throwErrnoIfNull` to call the c > functions listed in parenthesis. > > > ## Proposal > Change the signature of the functions listed above to `IO (Maybe String)`. > > The new semantics would be: > * If the c function returns a NULL pointer with errno set to ENOENT, > meaning the given user or group could not be found, the result is Nothing. > * If another error occured, an error is thrown (no change). > * Otherwise the result is Just "result". > > > ## Motivation > At least `getlogin` and `getgrgid` are unreliable on Linux. It is possible > for them to return NULL pointers [2] even when the user is logged in and > has an associated user entry in /etc/passwd and group entry in /etc/group. > > Examples: > * when `getLoginName` is called using a terminal emulator that doesn't > write login records to /var/run/utmp, or inside screen/tmux, `getlogin` > tends to return NULL pointers [3]. > * `getGroupEntryForID` can throw a NULL pointer exception inside chroots > or other environments where the information in /etc/groups is not to be > considered reliable [4]. > > Since we can, let's give the above Haskell functions a type safe(r) api. > > If the proposal gets rejected, I will just add a warning message to the > docstrings of the functions in question and permanently disable their tests > from the unix testsuite, since this is currently causing problems [5,6]. > > Discussion period: 2 weeks. > > > ## Links > [1] https://github.com/haskell/unix/blob/master/System/Posix/User.hsc > [2] http://linux.die.net/man/3/getlogin > [3] > https://github.com/haskell/unix/blob/cad1ef27bb0a51bc68ebadb1297de1ae05bee9db/tests/all.T#L14-L18 > [4] https://ghc.haskell.org/trac/ghc/ticket/8293 > [5] http://www.haskell.org/pipermail/ghc-devs/2014-September/006420.html > [6] https://ghc.haskell.org/trac/ghc/ticket/1487#comment:23 > > > ## Details > * Another function in the same module that needs to change is > `getEffectiveUserName`, because it calls the function `getUserEntryForID` > mentioned before. > > * The following functions don't need to change, since they return the > empty list if no entries are found: > - getGroups (getgroups) > - getAllGroupEntries (getgrent) > - getAllUserEntries (getpwent) > > * The rest of the functions in the module don't need to change either, > since they are not expected to return NULL pointers, according to their > respective man pages: > - getRealUserID (getuid) > - getRealGroupID (getgid) > - getEffectiveUserID (geteuid) > - getEffectiveGroupID (getegid) > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From greg at gregweber.info Fri Sep 26 17:33:18 2014 From: greg at gregweber.info (Greg Weber) Date: Fri, 26 Sep 2014 10:33:18 -0700 Subject: Proposal unix. Change to `IO (Maybe String)`: getLoginName, getUserEntry* and getGroupEntry* In-Reply-To: References: Message-ID: Agreed with Johan. If there are meaningful error messages that get produced, Either is better than Maybe. On Fri, Sep 26, 2014 at 9:47 AM, Johan Tibell wrote: > I think we should add the saner versions (that return Maybe) under new > names to avoid unnecessarily breaking backwards compatibility. > > On Fri, Sep 26, 2014 at 6:23 PM, Thomas Miedema > wrote: > >> In the unix package, in System.Posix.User, we have the following >> functions [1]: >> >> * getLoginName (getlogin) >> * getUserEntryForID (getpwuid_r) >> * getGroupEntryForID (getgrgid_r) >> * getUserEntryForName (getpwnam_r) >> * getGroupEntryForName (getgrnam_r) >> >> They have signature `IO String`, and use `throwErrnoIfNull` to call the c >> functions listed in parenthesis. >> >> >> ## Proposal >> Change the signature of the functions listed above to `IO (Maybe String)`. >> >> The new semantics would be: >> * If the c function returns a NULL pointer with errno set to ENOENT, >> meaning the given user or group could not be found, the result is Nothing. >> * If another error occured, an error is thrown (no change). >> * Otherwise the result is Just "result". >> >> >> ## Motivation >> At least `getlogin` and `getgrgid` are unreliable on Linux. It is >> possible for them to return NULL pointers [2] even when the user is logged >> in and has an associated user entry in /etc/passwd and group entry in >> /etc/group. >> >> Examples: >> * when `getLoginName` is called using a terminal emulator that doesn't >> write login records to /var/run/utmp, or inside screen/tmux, `getlogin` >> tends to return NULL pointers [3]. >> * `getGroupEntryForID` can throw a NULL pointer exception inside chroots >> or other environments where the information in /etc/groups is not to be >> considered reliable [4]. >> >> Since we can, let's give the above Haskell functions a type safe(r) api. >> >> If the proposal gets rejected, I will just add a warning message to the >> docstrings of the functions in question and permanently disable their tests >> from the unix testsuite, since this is currently causing problems [5,6]. >> >> Discussion period: 2 weeks. >> >> >> ## Links >> [1] https://github.com/haskell/unix/blob/master/System/Posix/User.hsc >> [2] http://linux.die.net/man/3/getlogin >> [3] >> https://github.com/haskell/unix/blob/cad1ef27bb0a51bc68ebadb1297de1ae05bee9db/tests/all.T#L14-L18 >> [4] https://ghc.haskell.org/trac/ghc/ticket/8293 >> [5] http://www.haskell.org/pipermail/ghc-devs/2014-September/006420.html >> [6] https://ghc.haskell.org/trac/ghc/ticket/1487#comment:23 >> >> >> ## Details >> * Another function in the same module that needs to change is >> `getEffectiveUserName`, because it calls the function `getUserEntryForID` >> mentioned before. >> >> * The following functions don't need to change, since they return the >> empty list if no entries are found: >> - getGroups (getgroups) >> - getAllGroupEntries (getgrent) >> - getAllUserEntries (getpwent) >> >> * The rest of the functions in the module don't need to change either, >> since they are not expected to return NULL pointers, according to their >> respective man pages: >> - getRealUserID (getuid) >> - getRealGroupID (getgid) >> - getEffectiveUserID (geteuid) >> - getEffectiveGroupID (getegid) >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Fri Sep 26 17:52:48 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Fri, 26 Sep 2014 13:52:48 -0400 Subject: Proposal unix. Change to `IO (Maybe String)`: getLoginName, getUserEntry* and getGroupEntry* In-Reply-To: References: Message-ID: On Fri, Sep 26, 2014 at 1:33 PM, Greg Weber wrote: > Agreed with Johan. If there are meaningful error messages that get > produced, Either is better than Maybe. "Meaningful" is open to question; what you get back is a NULL pointer amd an errno, both of which can be annoyingly non-specific. -- 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 thomasmiedema at gmail.com Sat Sep 27 17:13:15 2014 From: thomasmiedema at gmail.com (Thomas Miedema) Date: Sat, 27 Sep 2014 19:13:15 +0200 Subject: List of core libraries Message-ID: Hello core libraries committee, on the library submissions page on the Haskell wiki it says: "The core libraries ... define basic APIs that are expected to be available in any Haskell implementation." Is this list of those core libraries and their maintainers up-to-date: http://www.haskell.org/haskellwiki/Library_submissions#The_Core_Libraries I am asking, since GHC 7.8.3 also includes: * binary * bytestring * filepath * haskeline * hoopl * integer-gmp * terminfo * transformers But they are not core libraries. Is that correct? And GHC 7.8.3 doesn't include: * mtl * parallel * primitive * random * vector But they are core libraries. Is that correct? Cheers, Thomas -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Sat Sep 27 17:40:15 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Sat, 27 Sep 2014 13:40:15 -0400 Subject: List of core libraries In-Reply-To: References: Message-ID: On Sat, Sep 27, 2014 at 1:13 PM, Thomas Miedema wrote: > on the library submissions page on the Haskell wiki it says: "The core > libraries ... define basic APIs that are expected to be available in any > Haskell implementation." > > Is this list of those core libraries and their maintainers up-to-date: > http://www.haskell.org/haskellwiki/Library_submissions#The_Core_Libraries > > I am asking, since GHC 7.8.3 also includes: > * binary > * bytestring > * filepath > * haskeline > * hoopl > * integer-gmp > * terminfo > * transformers > But they are not core libraries. Is that correct? > There is a difference between the libraries needed to provide a core usable Haskell installation, and the libraries required for a particular Haskell implementation (in this case ghc) to provide basic functionality. For example, integer-gmp is an artifact of how GHC implements bigints, and haskeline and terminfo are required for ghci's line editing. We generally distinguish between "core libraries" and "GHC bootstrap libraries" ("bootlibs"). -- 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 david.feuer at gmail.com Sat Sep 27 17:59:04 2014 From: david.feuer at gmail.com (David Feuer) Date: Sat, 27 Sep 2014 13:59:04 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: Currently, the (.&.) and (.|.) methods for Bool are short-circuiting, defined like this: instance Bits Bool where (.&.) = (&&) (.|.) = (||) Unlike the instances for Int, Word, etc., this gives short-circuiting behavior (conditionally lazy in the second operand). Unfortunately, this requires a conditional branch to implement, which can sometimes be bad. Since (&&) and (||) are readily available to anyone who wants short-circuiting, I propose that we use the following instead. Note that the Bits class does not specify anything about this aspect of instance behavior. x .&. y = tagToEnum# (dataToTag# x `andI#` dataToTag# y) x .|. y = tagToEnum# (dataToTag# x `orI#` dataToTag# y) The rest of the operations look like this: x `xor` y = tagToEnum# (dataToTag# x `xorI#` dataToTag# y) complement x = tagToEnum# (dataToTag# x `xorI#` 1#) shift x s = testBit x s rotate x _ = x -- I don't think we gain anything changing this one. bit 0 = True bit _ = False testBit x b = tagToEnum# (dataToTag# x `andI#` (dataToTag# b ==# 0#)) bitSizeMaybe _ = Just 1 bitSize _ = 1 isSigned _ = False popCount x = I# (dataToTag# x) instance FiniteBits Bool where finiteBitSize _ = 1 countTrailingZeros x = I# (dataToTag# x `xorI#` 1#) countLeadingZeros x = I# (dataToTag# x `xorI#` 1#) -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Sat Sep 27 18:06:47 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sat, 27 Sep 2014 14:06:47 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: Do we have a benchmark of the relative performance of the short-circuiting vs. non-short-circuiting versions? There *is* a consistency argument in that we don't currently try to short-circuit any of the other instances, but increasing strictness means reduced termination, so we should look before we leap. On the other hand there is also a cultural bias towards being as lazy as possible, and we derive a lot of benefit in terms of reasoning across the entire ecosystem from the uniformity of that bias. If we are going to consider trading asymptotics for constant factors, we should at least take a look at if we're getting anything for our trade. -Edward On Sat, Sep 27, 2014 at 1:59 PM, David Feuer wrote: > Currently, the (.&.) and (.|.) methods for Bool are short-circuiting, > defined like this: > > instance Bits Bool where > (.&.) = (&&) > > (.|.) = (||) > > Unlike the instances for Int, Word, etc., this gives short-circuiting > behavior (conditionally lazy in the second operand). Unfortunately, this > requires a conditional branch to implement, which can sometimes be bad. > Since (&&) and (||) are readily available to anyone who wants > short-circuiting, I propose that we use the following instead. Note that > the Bits class does not specify anything about this aspect of instance > behavior. > > x .&. y = tagToEnum# (dataToTag# x `andI#` dataToTag# y) > > x .|. y = tagToEnum# (dataToTag# x `orI#` dataToTag# y) > > The rest of the operations look like this: > > x `xor` y = tagToEnum# (dataToTag# x `xorI#` dataToTag# y) > > complement x = tagToEnum# (dataToTag# x `xorI#` 1#) > > shift x s = testBit x s > > rotate x _ = x > > -- I don't think we gain anything changing this one. > bit 0 = True > bit _ = False > > testBit x b = tagToEnum# (dataToTag# x `andI#` (dataToTag# b ==# 0#)) > > bitSizeMaybe _ = Just 1 > > bitSize _ = 1 > > isSigned _ = False > > popCount x = I# (dataToTag# x) > > instance FiniteBits Bool where > finiteBitSize _ = 1 > countTrailingZeros x = I# (dataToTag# x `xorI#` 1#) > countLeadingZeros x = I# (dataToTag# x `xorI#` 1#) > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Sat Sep 27 18:26:23 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sat, 27 Sep 2014 14:26:23 -0400 Subject: [core libraries] List of core libraries In-Reply-To: References: Message-ID: We have the Haskell Platform, which is basically a bunch of our "best of breed" packages we believe everyone should have installed by default. These packages are all maintained by individuals. Mark Lentczner takes care of herding the cats to get that out the door. GHC itself has a smaller collection of boot libraries it needs to build. Some of these are very GHC specific and fall under the purview of GHC HQ itself. Some of these actually have dedicated maintainers, even though GHC needs them. e.g. Ross Paterson still owns transformers, he wrote it, its his to do with as he pleases. We do have to work with him fairly closely, however, as, being a boot package, it can only really effectively be upgraded every year or so, and we often have to maintain patched versions of it to keep developing on GHC in the meantime. But, there is a fair bit ligaments and gristle between the bone of GHC itself and the body of the platform it, i.e. stuff that has to be there to hold the whole ecosystem together, but on which GHC HQ itself doesn't have a particularly strong opinion. That is the stuff that falls under the purview of the core libraries committee, which acts as a collective maintainer under the libraries submission process. That rounds out the idiosyncrasies of having a single maintainer, but lets us have some entity that can collectively reach a decision and allow progress. Prior to the formation of the committee there were a number of issues on these middle-ground packages that would deadlock without universal consent. The packages random, vector and primitive recently came under the purview of the committee because they were in the platform and seeing broad use but not being actively maintained. By way of contrast, mtl isn't currently under the core-libraries-committee, but it is in the platform. I took over maintainership of it personally a year or two before we formed the committee and haven't yet found it to be a sufficient burden to pawn off on the collective. -Edward On Sat, Sep 27, 2014 at 1:13 PM, Thomas Miedema wrote: > Hello core libraries committee, > > on the library submissions page on the Haskell wiki it says: "The core > libraries ... define basic APIs that are expected to be available in any > Haskell implementation." > > Is this list of those core libraries and their maintainers up-to-date: > http://www.haskell.org/haskellwiki/Library_submissions#The_Core_Libraries > > I am asking, since GHC 7.8.3 also includes: > * binary > * bytestring > * filepath > * haskeline > * hoopl > * integer-gmp > * terminfo > * transformers > But they are not core libraries. Is that correct? > > And GHC 7.8.3 doesn't include: > * mtl > * parallel > * primitive > * random > * vector > But they are core libraries. Is that correct? > > Cheers, > Thomas > > -- > You received this message because you are subscribed to the Google Groups > "haskell-core-libraries" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to haskell-core-libraries+unsubscribe at googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sat Sep 27 18:29:12 2014 From: david.feuer at gmail.com (David Feuer) Date: Sat, 27 Sep 2014 14:29:12 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: I don't have benchmarks, but I will. My intuition on this is that Data.Bits is about *arithmetic*, not control flow. I *usually* expect arithmetic to be strict. I also *usually* expect to do arithmetic in contexts where branch prediction is likely to be crummy. I further *usually* expect a compiler to optimize arithmetic on little things very aggressively, without regard for the sorts of ordering constraints that short-circuiting imposes. Do we have a benchmark of the relative performance of the short-circuiting vs. non-short-circuiting versions? There *is* a consistency argument in that we don't currently try to short-circuit any of the other instances, but increasing strictness means reduced termination, so we should look before we leap. On the other hand there is also a cultural bias towards being as lazy as possible, and we derive a lot of benefit in terms of reasoning across the entire ecosystem from the uniformity of that bias. If we are going to consider trading asymptotics for constant factors, we should at least take a look at if we're getting anything for our trade. -Edward On Sat, Sep 27, 2014 at 1:59 PM, David Feuer wrote: > Currently, the (.&.) and (.|.) methods for Bool are short-circuiting, > defined like this: > > instance Bits Bool where > (.&.) = (&&) > > (.|.) = (||) > > Unlike the instances for Int, Word, etc., this gives short-circuiting > behavior (conditionally lazy in the second operand). Unfortunately, this > requires a conditional branch to implement, which can sometimes be bad. > Since (&&) and (||) are readily available to anyone who wants > short-circuiting, I propose that we use the following instead. Note that > the Bits class does not specify anything about this aspect of instance > behavior. > > x .&. y = tagToEnum# (dataToTag# x `andI#` dataToTag# y) > > x .|. y = tagToEnum# (dataToTag# x `orI#` dataToTag# y) > > The rest of the operations look like this: > > x `xor` y = tagToEnum# (dataToTag# x `xorI#` dataToTag# y) > > complement x = tagToEnum# (dataToTag# x `xorI#` 1#) > > shift x s = testBit x s > > rotate x _ = x > > -- I don't think we gain anything changing this one. > bit 0 = True > bit _ = False > > testBit x b = tagToEnum# (dataToTag# x `andI#` (dataToTag# b ==# 0#)) > > bitSizeMaybe _ = Just 1 > > bitSize _ = 1 > > isSigned _ = False > > popCount x = I# (dataToTag# x) > > instance FiniteBits Bool where > finiteBitSize _ = 1 > countTrailingZeros x = I# (dataToTag# x `xorI#` 1#) > countLeadingZeros x = I# (dataToTag# x `xorI#` 1#) > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From fox at ucw.cz Sun Sep 28 10:06:43 2014 From: fox at ucw.cz (Milan Straka) Date: Sun, 28 Sep 2014 12:06:43 +0200 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: <20140928100643.GA4876@auryn.cz> Hi all, I am not really convinced that the proposed implementation will be faster -- if the short-circuiting kicks in, I believe it will perform better, even if it uses conditional branching. So unless being convinced by benchmark results, I would prefer the lazier version of these operators. Cheers, Milan > -----Original message----- > From: David Feuer > Sent: 27 Sep 2014, 13:59 > > ... > Currently, the (.&.) and (.|.) methods for Bool are short-circuiting, > defined like this: > > instance Bits Bool where > (.&.) = (&&) > > (.|.) = (||) > > Unlike the instances for Int, Word, etc., this gives short-circuiting > behavior (conditionally lazy in the second operand). Unfortunately, this > requires a conditional branch to implement, which can sometimes be bad. > Since (&&) and (||) are readily available to anyone who wants > short-circuiting, I propose that we use the following instead. Note that > the Bits class does not specify anything about this aspect of instance > behavior. > > x .&. y = tagToEnum# (dataToTag# x `andI#` dataToTag# y) > > x .|. y = tagToEnum# (dataToTag# x `orI#` dataToTag# y) > > The rest of the operations look like this: > > x `xor` y = tagToEnum# (dataToTag# x `xorI#` dataToTag# y) > > complement x = tagToEnum# (dataToTag# x `xorI#` 1#) > > shift x s = testBit x s > > rotate x _ = x > > -- I don't think we gain anything changing this one. > bit 0 = True > bit _ = False > > testBit x b = tagToEnum# (dataToTag# x `andI#` (dataToTag# b ==# 0#)) > > bitSizeMaybe _ = Just 1 > > bitSize _ = 1 > > isSigned _ = False > > popCount x = I# (dataToTag# x) > > instance FiniteBits Bool where > finiteBitSize _ = 1 > countTrailingZeros x = I# (dataToTag# x `xorI#` 1#) > countLeadingZeros x = I# (dataToTag# x `xorI#` 1#) > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries From thomasmiedema at gmail.com Sun Sep 28 10:57:58 2014 From: thomasmiedema at gmail.com (Thomas Miedema) Date: Sun, 28 Sep 2014 12:57:58 +0200 Subject: [core libraries] List of core libraries In-Reply-To: References: Message-ID: Hi Edward, Thank you for your explanation. I would still like to make sure [1] is up-to-date, since those are the packages for which third party contributions need to go through the library submissions process. Do you have a complete list of the packages maintained by the Core Libraries Committee? Thanks, Thomas [1] http://www.haskell.org/haskellwiki/Library_submissions#The_Core_Libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From voldermort at hotmail.com Sun Sep 28 11:53:49 2014 From: voldermort at hotmail.com (harry) Date: Sun, 28 Sep 2014 04:53:49 -0700 (PDT) Subject: [core libraries] List of core libraries In-Reply-To: References: Message-ID: <1411905229596-5757146.post@n5.nabble.com> Edward Kmett wrote > We have the Haskell Platform, which is basically a bunch of our "best of > breed" packages we believe everyone should have installed by default How does html fit that description? -- View this message in context: http://haskell.1045720.n5.nabble.com/List-of-core-libraries-tp5757100p5757146.html Sent from the Haskell - Libraries mailing list archive at Nabble.com. From ekmett at gmail.com Sun Sep 28 17:00:04 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 28 Sep 2014 13:00:04 -0400 Subject: [core libraries] List of core libraries In-Reply-To: References: Message-ID: The list that we maintain is the list you referenced. =) If there is a package we're supposed to maintain as part of the platform, we add it to that list and put our name next to it. -Edward On Sun, Sep 28, 2014 at 6:57 AM, Thomas Miedema wrote: > Hi Edward, > > Thank you for your explanation. I would still like to make sure [1] is > up-to-date, since those are the packages for which third party > contributions need to go through the library submissions process. > > Do you have a complete list of the packages maintained by the Core > Libraries Committee? > > Thanks, > Thomas > > [1] > http://www.haskell.org/haskellwiki/Library_submissions#The_Core_Libraries > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Sun Sep 28 17:02:58 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 28 Sep 2014 13:02:58 -0400 Subject: [core libraries] List of core libraries In-Reply-To: <1411905229596-5757146.post@n5.nabble.com> References: <1411905229596-5757146.post@n5.nabble.com> Message-ID: There is some allowance for historical accident.. er precedent. ;) -Edward On Sun, Sep 28, 2014 at 7:53 AM, harry wrote: > Edward Kmett wrote > > We have the Haskell Platform, which is basically a bunch of our "best of > > breed" packages we believe everyone should have installed by default > > How does html fit that description? > > > > -- > View this message in context: > http://haskell.1045720.n5.nabble.com/List-of-core-libraries-tp5757100p5757146.html > Sent from the Haskell - Libraries mailing list archive at Nabble.com. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Sun Sep 28 17:06:13 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 28 Sep 2014 13:06:13 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: <20140928100643.GA4876@auryn.cz> References: <20140928100643.GA4876@auryn.cz> Message-ID: In my quick tests, the branchless form only looked to be about 10% faster. If others have better benchmarks, I'm happy to defer as my methodology was rather sloppy. Considering the alternative is an asymptotic hit, I'm having a hard time favoring the branchless form as well. -Edward On Sun, Sep 28, 2014 at 6:06 AM, Milan Straka wrote: > Hi all, > > I am not really convinced that the proposed implementation will be > faster -- if the short-circuiting kicks in, I believe it will perform > better, even if it uses conditional branching. > > So unless being convinced by benchmark results, I would prefer the > lazier version of these operators. > > Cheers, > Milan > > > -----Original message----- > > From: David Feuer > > Sent: 27 Sep 2014, 13:59 > > > > ... > > Currently, the (.&.) and (.|.) methods for Bool are short-circuiting, > > defined like this: > > > > instance Bits Bool where > > (.&.) = (&&) > > > > (.|.) = (||) > > > > Unlike the instances for Int, Word, etc., this gives short-circuiting > > behavior (conditionally lazy in the second operand). Unfortunately, this > > requires a conditional branch to implement, which can sometimes be bad. > > Since (&&) and (||) are readily available to anyone who wants > > short-circuiting, I propose that we use the following instead. Note that > > the Bits class does not specify anything about this aspect of instance > > behavior. > > > > x .&. y = tagToEnum# (dataToTag# x `andI#` dataToTag# y) > > > > x .|. y = tagToEnum# (dataToTag# x `orI#` dataToTag# y) > > > > The rest of the operations look like this: > > > > x `xor` y = tagToEnum# (dataToTag# x `xorI#` dataToTag# y) > > > > complement x = tagToEnum# (dataToTag# x `xorI#` 1#) > > > > shift x s = testBit x s > > > > rotate x _ = x > > > > -- I don't think we gain anything changing this one. > > bit 0 = True > > bit _ = False > > > > testBit x b = tagToEnum# (dataToTag# x `andI#` (dataToTag# b ==# 0#)) > > > > bitSizeMaybe _ = Just 1 > > > > bitSize _ = 1 > > > > isSigned _ = False > > > > popCount x = I# (dataToTag# x) > > > > instance FiniteBits Bool where > > finiteBitSize _ = 1 > > countTrailingZeros x = I# (dataToTag# x `xorI#` 1#) > > countLeadingZeros x = I# (dataToTag# x `xorI#` 1#) > > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://www.haskell.org/mailman/listinfo/libraries > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sun Sep 28 17:15:53 2014 From: david.feuer at gmail.com (David Feuer) Date: Sun, 28 Sep 2014 13:15:53 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: 10% sounds pretty big to me when you're trying to really squeeze out a bit more performance (which is what tends to lead people to even look at Data.Bits). The asymptotic hit, as you call it, will only hit you if you use what I consider to be the wrong operator. Why would you use .&. and .|. if what you want are && and ||? From the perspective of the Bits concept, Bool is a bitvector that happens to hold only one bit. Why would you expect that to short-circuit? Why would you use it for control flow? -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Sun Sep 28 17:34:18 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 28 Sep 2014 13:34:18 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: Let's factor your proposal into two pieces, creating branchless boolean operations and using them in Data.Bits. I'm 100% on board with adding a combinator for fast non-short-circuiting boolean and' and or' to Data.Bool. I'm not yet convinced that the thing in Data.Bits should be that operation rather than the safer choice. That turn your argument around on you to some extent. You'd have the fast branchless version as and' and or' and when you are working monomorphically with booleans and want short-circuiting behavior you can reach for them. ;) Why am I being a pain in the ass about this? I can envision a point in Haskell's future where we might want to let the combinators in Data.Bits be the ones we use for Bool, where &&/||/and/or/any/all/not/ just smash things together with Bits and we generalize more of base. That would be an incredibly dumb thing to do with non-short-circuiting versions of the operators. I for one don't want to cut off that possible future for a 10% gain for a limited usecase. I'm not willing to say we should do make that generalization, but I'm also not willing to cut off that possible future. -Edward On Sun, Sep 28, 2014 at 1:15 PM, David Feuer wrote: > 10% sounds pretty big to me when you're trying to really squeeze out a bit > more performance (which is what tends to lead people to even look at > Data.Bits). The asymptotic hit, as you call it, will only hit you if you > use what I consider to be the wrong operator. Why would you use .&. and .|. > if what you want are && and ||? From the perspective of the Bits concept, > Bool is a bitvector that happens to hold only one bit. Why would you expect > that to short-circuit? Why would you use it for control flow? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From acowley at seas.upenn.edu Sun Sep 28 17:35:18 2014 From: acowley at seas.upenn.edu (Anthony Cowley) Date: Sun, 28 Sep 2014 13:35:18 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: > On Sep 28, 2014, at 1:15 PM, David Feuer wrote: > > 10% sounds pretty big to me when you're trying to really squeeze out a bit more performance (which is what tends to lead people to even look at Data.Bits). The asymptotic hit, as you call it, will only hit you if you use what I consider to be the wrong operator. Why would you use .&. and .|. if what you want are && and ||? From the perspective of the Bits concept, Bool is a bitvector that happens to hold only one bit. Why would you expect that to short-circuit? Why would you use it for control flow? This is exactly my thinking, too. I'm +1 for consistency, potential speed in ostensibly straight-line code, and offering the opportunity specifically for this distinct behavior. Anthony From thomasmiedema at gmail.com Sun Sep 28 17:40:25 2014 From: thomasmiedema at gmail.com (Thomas Miedema) Date: Sun, 28 Sep 2014 19:40:25 +0200 Subject: [core libraries] List of core libraries In-Reply-To: References: Message-ID: > > The list that we maintain is the list you referenced. =) > > If there is a package we're supposed to maintain as part of the platform, > we add it to that list and put our name next to it. > Ok, final question: What about filepath and hpc? Their .cabal files list libraries at haskell.org as maintainer, which usually means the Core Libraries Committee. Should filepath be added to that list, and the maintainer for both filepath and hpc be set to the Core Libraries Committee? If not, who maintains filepath? Thanks, Thomas -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Sun Sep 28 17:51:16 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 28 Sep 2014 13:51:16 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sun, Sep 28, 2014 at 1:34 PM, Edward Kmett wrote: > I can envision a point in Haskell's future where we might want to let the > combinators in Data.Bits be the ones we use for Bool, where > &&/||/and/or/any/all/not/ just smash things together with Bits and we > generalize more of base. > > That would be an incredibly dumb thing to do with non-short-circuiting > versions of the operators. > > I for one don't want to cut off that possible future for a 10% gain for a > limited usecase. > My counter-question is: is it even worth considering this generalization if it only makes sense for the Bool case? Because none of the other instances short-circuit. -- 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 felipe.lessa at gmail.com Sun Sep 28 18:12:21 2014 From: felipe.lessa at gmail.com (Felipe Almeida Lessa) Date: Sun, 28 Sep 2014 15:12:21 -0300 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: +1 for the same reason, too. -- Felipe. Em 28/09/2014 14:35, "Anthony Cowley" escreveu: > > > On Sep 28, 2014, at 1:15 PM, David Feuer wrote: > > > > 10% sounds pretty big to me when you're trying to really squeeze out a > bit more performance (which is what tends to lead people to even look at > Data.Bits). The asymptotic hit, as you call it, will only hit you if you > use what I consider to be the wrong operator. Why would you use .&. and .|. > if what you want are && and ||? From the perspective of the Bits concept, > Bool is a bitvector that happens to hold only one bit. Why would you expect > that to short-circuit? Why would you use it for control flow? > > This is exactly my thinking, too. I'm +1 for consistency, potential speed > in ostensibly straight-line code, and offering the opportunity specifically > for this distinct behavior. > > Anthony > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Sun Sep 28 18:39:20 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 28 Sep 2014 14:39:20 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: That said, you *could* make them short-circuit as well when they are all 0s or all 1s. I'm not saying we should, as I'm disinclined to introduce even a cold branch for the check, but it is a possibility. My main concern is that if (*sigh* probably when) we adopt this proposal we collapse the whole waveform of possibilities in this space, perhaps needlessly cutting off future growth directions. I'm willing to lose the argument here, but I think we should eventually *have the argument* rather than blindly take the 10%. I also realize that if we have the argument today, it is probably a sealed deal, and I'll lose. Since this proposal is acting as a forcing function, and I don't think I can stem the tide of opinion on this one I accept the fact that it will probably go through. I don't have the time right now to flesh out a full proposal, and I don't even think it would be a good idea to adopt in the current state of the Haskell. If we're talking about a counter-proposal that makes sense in the 7.10 or likely even 7.12 timeframe, I'm out. As a fairly weak example: Many of the other usecases that would be opened up by the alternative to this proposal are also currently blocked or rendered ugly by the shape of Bits and are complicated. e.g. The alternative permits you to use (.&.) and (.|.) in EDSLs when you need to capture the shape of your conditionals. (As long as you ignore testBit) An example of something lost if this proposal is adopted: Folks can't use (.&.) and (.|.) for freely overridden logical connectives in finally tagless EDSLs and have Bool just be the default interpreted case. I can see the appeal of the proposal, it is simple. I'm personally a weak -1 on the grounds that I think it prematurely forces us to evaluate the possibilities in this space and takes us in a direction that cuts us off from paths that could lead to greater generality in the future. On a more immediate front, I think the small constant factor performance gain is counter-balanced by the asymptotic hit, and saying 'don't do that then' is sweeping an asymptotic issue under the rug. I also expect that these arguments aren't going to be strong enough to beat the immediate obviousness of the proposal. -Edward On Sun, Sep 28, 2014 at 1:51 PM, Brandon Allbery wrote: > On Sun, Sep 28, 2014 at 1:34 PM, Edward Kmett wrote: > >> I can envision a point in Haskell's future where we might want to let the >> combinators in Data.Bits be the ones we use for Bool, where >> &&/||/and/or/any/all/not/ just smash things together with Bits and we >> generalize more of base. >> >> That would be an incredibly dumb thing to do with non-short-circuiting >> versions of the operators. >> >> I for one don't want to cut off that possible future for a 10% gain for a >> limited usecase. >> > > My counter-question is: is it even worth considering this generalization > if it only makes sense for the Bool case? Because none of the other > instances short-circuit. > > -- > 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 ekmett at gmail.com Sun Sep 28 18:45:07 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 28 Sep 2014 14:45:07 -0400 Subject: [core libraries] List of core libraries In-Reply-To: <878ul3ehoc.fsf@gmail.com> References: <878ul3ehoc.fsf@gmail.com> Message-ID: Herbert: Heretofore I'd been treating filepath as owned by Neil Mitchell, but that statement does sound like he's handed it off to the libraries process, which would make it a core-libraries issue if he doesn't want to deal with it. I'm copying him on this thread to get his opinion. I've also copied Andy Gill, to see if he has any opinions on the state of who owns update responsibility for hpc itself. Andy, Neil: Thoughts? Thomas: Thanks for forcing this issue to attention. -Edward On Sun, Sep 28, 2014 at 2:14 PM, Herbert Valerio Riedel wrote: > On 2014-09-28 at 19:40:25 +0200, Thomas Miedema wrote: > > [...] > > > Ok, final question: What about filepath and hpc? Their .cabal files list > > libraries at haskell.org as maintainer, which usually means the Core > Libraries > > Committee. Should filepath be added to that list, and the maintainer for > > both filepath and hpc be set to the Core Libraries Committee? If not, who > > maintains filepath? > > This is supposed to be an answer, but rather additional data-points: > > As far as filepath is concerned: > > http://community.haskell.org/~ndm/filepath/ > > states > > | The library is now part of the core Haskell libraries, and since GHC > | 6.6.1 has been shipped with all major compilers. While I am the > | original author, changes are now made through the library submissions > | process. > > as for Hpc, if you look at its changelog over at > > http://git.haskell.org/packages/hpc.git/shortlog > > it's been effectively maintained by GHC HQ for the last couple of > years... > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sun Sep 28 18:45:45 2014 From: david.feuer at gmail.com (David Feuer) Date: Sun, 28 Sep 2014 14:45:45 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: I would think what you're trying to do would likely be better with a different class, by another name, supporting things like .&&., .||., etc., or maybe even moving && and || into a class. Another direction is to look at structures representing other sorts of logics. I just don't see that Data.Bits is the right place to try to do these things. On Sep 28, 2014 2:39 PM, "Edward Kmett" wrote: > That said, you *could* make them short-circuit as well when they are all > 0s or all 1s. I'm not saying we should, as I'm disinclined to introduce > even a cold branch for the check, but it is a possibility. > > My main concern is that if (*sigh* probably when) we adopt this proposal > we collapse the whole waveform of possibilities in this space, perhaps > needlessly cutting off future growth directions. > > I'm willing to lose the argument here, but I think we should eventually *have > the argument* rather than blindly take the 10%. > > I also realize that if we have the argument today, it is probably a sealed > deal, and I'll lose. > > Since this proposal is acting as a forcing function, and I don't think I > can stem the tide of opinion on this one I accept the fact that it will > probably go through. > > I don't have the time right now to flesh out a full proposal, and I don't > even think it would be a good idea to adopt in the current state of the > Haskell. > > If we're talking about a counter-proposal that makes sense in the 7.10 or > likely even 7.12 timeframe, I'm out. > > As a fairly weak example: > > Many of the other usecases that would be opened up by the alternative to > this proposal are also currently blocked or rendered ugly by the shape of > Bits and are complicated. > > e.g. The alternative permits you to use (.&.) and (.|.) in EDSLs when you > need to capture the shape of your conditionals. (As long as you ignore > testBit) > > An example of something lost if this proposal is adopted: Folks can't use > (.&.) and (.|.) for freely overridden logical connectives in finally > tagless EDSLs and have Bool just be the default interpreted case. > > I can see the appeal of the proposal, it is simple. > > I'm personally a weak -1 on the grounds that I think it prematurely forces > us to evaluate the possibilities in this space and takes us in a direction > that cuts us off from paths that could lead to greater generality in the > future. > > On a more immediate front, I think the small constant factor performance > gain is counter-balanced by the asymptotic hit, and saying 'don't do that > then' is sweeping an asymptotic issue under the rug. > > I also expect that these arguments aren't going to be strong enough to > beat the immediate obviousness of the proposal. > > -Edward > > On Sun, Sep 28, 2014 at 1:51 PM, Brandon Allbery > wrote: > >> On Sun, Sep 28, 2014 at 1:34 PM, Edward Kmett wrote: >> >>> I can envision a point in Haskell's future where we might want to let >>> the combinators in Data.Bits be the ones we use for Bool, where >>> &&/||/and/or/any/all/not/ just smash things together with Bits and we >>> generalize more of base. >>> >>> That would be an incredibly dumb thing to do with non-short-circuiting >>> versions of the operators. >>> >>> I for one don't want to cut off that possible future for a 10% gain for >>> a limited usecase. >>> >> >> My counter-question is: is it even worth considering this generalization >> if it only makes sense for the Bool case? Because none of the other >> instances short-circuit. >> >> -- >> 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 allbery.b at gmail.com Sun Sep 28 18:49:27 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 28 Sep 2014 14:49:27 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sun, Sep 28, 2014 at 2:45 PM, David Feuer wrote: > I would think what you're trying to do would likely be better with a > different class, by another name, supporting things like .&&., .||., etc., > or maybe even moving && and || into a class. Another direction is to look > at structures representing other sorts of logics. I just don't see that > Data.Bits is the right place to try to do these things. Yes. This is what I was trying to get at with my question; Data.Bits already has a specific usage, and that usage just doesn't seem to fit the proposed one; that proposal belongs in a related yet different (and, I suspect, significantly different once fleshed out) class. Otherwise, we might well be reinventing the current Enum/Bounded mess or something similar --- trying to wedge something that looks superficially similar into an inappropriate structure. -- 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 ekmett at gmail.com Sun Sep 28 18:54:34 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 28 Sep 2014 14:54:34 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: That is the approach people are forced to take now. I currently do so in Ersatz, though I'd intended ever since Bits shed Num to switch to Bits once we obtained the Bool instance, Lennart does also uses a custom Boolean class in at least one edsl he has online. I'm okay if we collectively agree that this is a price we want to pay, I just want to acknowledge that it there is a price. You've made it clear you have a very tight vision for the role of Bits. I personally haven't yet committed to your viewpoint, but I can see the merit of it. Like I said, I suspect that I've lost this debate. I feel much better about making a decision if I can see both the upside and the downside, rather than just listen to the sales pitch, and wanted folks who were giving it +1s to do so after considering the cost, not just after considering the small performance benefit. -Edward On Sun, Sep 28, 2014 at 2:45 PM, David Feuer wrote: > I would think what you're trying to do would likely be better with a > different class, by another name, supporting things like .&&., .||., etc., > or maybe even moving && and || into a class. Another direction is to look > at structures representing other sorts of logics. I just don't see that > Data.Bits is the right place to try to do these things. > On Sep 28, 2014 2:39 PM, "Edward Kmett" wrote: > >> That said, you *could* make them short-circuit as well when they are all >> 0s or all 1s. I'm not saying we should, as I'm disinclined to introduce >> even a cold branch for the check, but it is a possibility. >> >> My main concern is that if (*sigh* probably when) we adopt this proposal >> we collapse the whole waveform of possibilities in this space, perhaps >> needlessly cutting off future growth directions. >> >> I'm willing to lose the argument here, but I think we should eventually *have >> the argument* rather than blindly take the 10%. >> >> I also realize that if we have the argument today, it is probably a >> sealed deal, and I'll lose. >> >> Since this proposal is acting as a forcing function, and I don't think I >> can stem the tide of opinion on this one I accept the fact that it will >> probably go through. >> >> I don't have the time right now to flesh out a full proposal, and I don't >> even think it would be a good idea to adopt in the current state of the >> Haskell. >> >> If we're talking about a counter-proposal that makes sense in the 7.10 or >> likely even 7.12 timeframe, I'm out. >> >> As a fairly weak example: >> >> Many of the other usecases that would be opened up by the alternative to >> this proposal are also currently blocked or rendered ugly by the shape of >> Bits and are complicated. >> >> e.g. The alternative permits you to use (.&.) and (.|.) in EDSLs when you >> need to capture the shape of your conditionals. (As long as you ignore >> testBit) >> >> An example of something lost if this proposal is adopted: Folks can't use >> (.&.) and (.|.) for freely overridden logical connectives in finally >> tagless EDSLs and have Bool just be the default interpreted case. >> >> I can see the appeal of the proposal, it is simple. >> >> I'm personally a weak -1 on the grounds that I think it prematurely >> forces us to evaluate the possibilities in this space and takes us in a >> direction that cuts us off from paths that could lead to greater generality >> in the future. >> >> On a more immediate front, I think the small constant factor performance >> gain is counter-balanced by the asymptotic hit, and saying 'don't do that >> then' is sweeping an asymptotic issue under the rug. >> >> I also expect that these arguments aren't going to be strong enough to >> beat the immediate obviousness of the proposal. >> >> -Edward >> >> On Sun, Sep 28, 2014 at 1:51 PM, Brandon Allbery >> wrote: >> >>> On Sun, Sep 28, 2014 at 1:34 PM, Edward Kmett wrote: >>> >>>> I can envision a point in Haskell's future where we might want to let >>>> the combinators in Data.Bits be the ones we use for Bool, where >>>> &&/||/and/or/any/all/not/ just smash things together with Bits and we >>>> generalize more of base. >>>> >>>> That would be an incredibly dumb thing to do with non-short-circuiting >>>> versions of the operators. >>>> >>>> I for one don't want to cut off that possible future for a 10% gain for >>>> a limited usecase. >>>> >>> >>> My counter-question is: is it even worth considering this generalization >>> if it only makes sense for the Bool case? Because none of the other >>> instances short-circuit. >>> >>> -- >>> 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 allbery.b at gmail.com Sun Sep 28 18:56:43 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 28 Sep 2014 14:56:43 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sun, Sep 28, 2014 at 2:54 PM, Edward Kmett wrote: > You've made it clear you have a very tight vision for the role of Bits. I > personally haven't yet committed to your viewpoint, but I can see the merit > of it. Like I said, I suspect that I've lost this debate. It might help if (a) we could see some examples of this alternative, and (b) how it interacts with the existing one. And I'm still left wondering how it relates to the non-Bool instances of Bits. -- 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 thomasmiedema at gmail.com Sun Sep 28 19:00:05 2014 From: thomasmiedema at gmail.com (Thomas Miedema) Date: Sun, 28 Sep 2014 21:00:05 +0200 Subject: List of core libraries In-Reply-To: References: Message-ID: On Sat, Sep 27, 2014 at 7:40 PM, Brandon Allbery wrote: > > There is a difference between the libraries needed to provide a core > usable Haskell installation, and the libraries required for a particular > Haskell implementation (in this case ghc) to provide basic functionality. > For example, integer-gmp is an artifact of how GHC implements bigints, and > haskeline and terminfo are required for ghci's line editing. We generally > distinguish between "core libraries" and "GHC bootstrap libraries" > ("bootlibs"). > Thanks Brandon, that cleared up part of my initial confusion. I added the following section to the haskellwiki: http://www.haskell.org/haskellwiki/Applications_and_libraries#GHC_bootstrap_libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sun Sep 28 19:01:02 2014 From: david.feuer at gmail.com (David Feuer) Date: Sun, 28 Sep 2014 15:01:02 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sep 28, 2014 2:39 PM, "Edward Kmett" wrote: > On a more immediate front, I think the small constant factor performance gain is counter-balanced by the asymptotic hit, and saying 'don't do that then' is sweeping an asymptotic issue under the rug. It's not sweeping it under the rug; it's forcing it into the open. Code that is fast purely by accident, because the programmer happened, without consideration, to put the arguments in the right order, is code that can very easily be made slow by accident, when someone changes something they had no idea was important. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Sun Sep 28 19:14:47 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 28 Sep 2014 15:14:47 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: Like I mentioned earlier. I don't think a fully fleshed out version of the alternative makes sense today. Too many small changes would have to go in, and you'd need at least one factoring of the Bits class to make it compelling. But since you insist on trying to force me to provide a fully concrete realization of a counter-proposal, here: A fully consistent version of it would be to adopt short-circuiting across all Bits instances (ugh), factor out testBit somehow, then consider converting (&&) = (.&.) (||) = (.|.) and = getAll . foldMap All or = Any . foldMap Any any f = getAny . foldMap (Any . f) all f = getAll . foldMap (All . f) not = complement for a suitably generalized Any and All. If testBit didn't exist in the class, then you could support (&&) and (||) for function spaces. e.g. isAlnum = isDigit || isAlpha with no new classes being constructed. In a world where the current proposal does come to fruition, such a class would be a separate ad hoc construction, and well, frankly that just would probably never happen. Like I said repeatedly above, I believe such a proposal doesn't have a chance in hell of succeeding today, but the existence of possibilities in that design space are why I'm hesitant to rush forward here. -Edward On Sun, Sep 28, 2014 at 2:56 PM, Brandon Allbery wrote: > On Sun, Sep 28, 2014 at 2:54 PM, Edward Kmett wrote: > >> You've made it clear you have a very tight vision for the role of Bits. I >> personally haven't yet committed to your viewpoint, but I can see the merit >> of it. Like I said, I suspect that I've lost this debate. > > > It might help if (a) we could see some examples of this alternative, and > (b) how it interacts with the existing one. And I'm still left wondering > how it relates to the non-Bool instances of Bits. > > -- > 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 allbery.b at gmail.com Sun Sep 28 19:20:13 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 28 Sep 2014 15:20:13 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sun, Sep 28, 2014 at 3:14 PM, Edward Kmett wrote: > But since you insist on trying to force me to provide a fully concrete > realization of a counter-proposal Well, no. I, and apparently dfeuer, are missing something; I'm trying to figure out what it is. So I don't want a fleshed-out counter-proposal, just pointers to whatever it is that's not at all obvious to us. -- 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 allbery.b at gmail.com Sun Sep 28 19:38:26 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 28 Sep 2014 15:38:26 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sun, Sep 28, 2014 at 3:20 PM, Brandon Allbery wrote: > On Sun, Sep 28, 2014 at 3:14 PM, Edward Kmett wrote: > >> But since you insist on trying to force me to provide a fully concrete >> realization of a counter-proposal > > > Well, no. I, and apparently dfeuer, are missing something; I'm trying to > figure out what it is. So I don't want a fleshed-out counter-proposal, just > pointers to whatever it is that's not at all obvious to us. > Unpacking this a bit more: I fully admit to not being in my element when it comes to things like this. I also have this feeling (which may well be a heuristic that is inappropriate in this case) that, when someone proposes something that sounds like it's specific to a particular instance of a typeclass as belonging in the typeclass itself, something's wrong somewhere. In particular, I'm not quite seeing where this fits within Data.Bits. Now, it may well be that there is some algebra somewhere that makes what I'm seeing a good generalization to all of Data.Bits (and the fact that you're proposing it makes it seem more likely; sadly, it also makes it more likely that it'll soar well over my head...). Flip side, it may be that the use case is compelling enough to justify making the Bool instance "different" from the other Data.Bits instances. Or some other possibility I'm completely missing. Under normal circumstances I'd probably just accept that this is something over my pay grade --- but it seems dfeuer is tripping over the same confusion? So I'm trying to figure out how to get at the part that's not coming together in all of this, that would make it look less like abuse-of-typeclass and more an expression of a mathematical consonance on some level. -- 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 allbery.b at gmail.com Sun Sep 28 19:45:49 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 28 Sep 2014 15:45:49 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sun, Sep 28, 2014 at 3:38 PM, Brandon Allbery wrote: > In particular, I'm not quite seeing where this fits within Data.Bits It just occurred to me that I may have answered part of this myself on IRC yesterday, in a different context: the strictness of the other instances may not indicate a fundamental difference between Bool and the other instances beyond the fact that the other instances are effectively spine-strict bit arrays, whereas Bool is free to *express* laziness. -- 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 allbery.b at gmail.com Sun Sep 28 20:03:10 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 28 Sep 2014 16:03:10 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sun, Sep 28, 2014 at 2:45 PM, David Feuer wrote: > I would think what you're trying to do would likely be better with a > different class, by another name, supporting things like .&&., .||., etc., > or maybe even moving && and || into a class. So, if I look at this from the angle that the strictness of other Bits instances is an artifact of their being spine-strict bit vectors, I get that the correct answer to this is not a new class but a "strict" newtype on Bool. The standard lazy Bool is by far the more common one, so it's the strict variant that gets the newtype. (Compare the Sum and Product monoid newtype-s.) -- 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 david.feuer at gmail.com Sun Sep 28 20:07:44 2014 From: david.feuer at gmail.com (David Feuer) Date: Sun, 28 Sep 2014 16:07:44 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sep 28, 2014 3:14 PM, "Edward Kmett" wrote: > Too many small changes would have to go in, and you'd need at least one factoring of the Bits class to make it compelling. ... > A fully consistent version of it would be to adopt short-circuiting across all Bits instances (ugh), factor out testBit somehow, then consider converting > If testBit didn't exist in the class ... > In a world where the current proposal does come to fruition, such a class would be a separate ad hoc construction, and well, frankly that just would probably never happen. Yes, it would be a separate construction. It would not be any more "ad hoc" than anything else, and could well be cleaner than some. If you formulated it and proposed it as an addition to base, I bet you'd win a lot of agreement. It seems a lot harder *and uglier* to hack Bits to do that too. You already have &&, ||, and not available to push into it. That said, isn't some of what you're talking about already possible (and less confusing) if you just do a little explicit lifting? -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Sun Sep 28 20:15:01 2014 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sun, 28 Sep 2014 16:15:01 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: Brandon, I think you're articulating a very good point here, in noting that the current set of instances for Bits that *are* *strict* are precisely so because their underlying representations are *spine strict*! >From that perspective, it is definitely valid to argue that the shortcircuiting behavior of bool is in fact correct. Its also important to keep in mind that theres many examples where the branchless version of bool is not a win, and we've not yet articulated an example where someone will be writing code that is both generic AND branchless (indeed, I'm not certain if there is actually a meaningful performance win in the fully polymorphic case when its the desired semantics). Additionally, one entire space left unaddressed here is this: "why cant we formulate an optimization algorithm to add to ghc that tries to estimate when transformation into a (relatively) branchless formulation of the same code"? a style i've grown to favor is the following: make it easy to write generic code thats always correct (wrt complexity), and make it sane to do specialization/optimization by hand later (and/or teach the compiler.) I guess my point here is this: while i've many examples of code i've written that has benefited from being rewritten in a branch free form, that is because of *bad branch prediction* rather than branching itself. Branchless code is immune to that problem, but if you dont have bad branch prediction, the *branching* code will be *faster* */ simpler* than the *branch free * code. On Sun, Sep 28, 2014 at 4:03 PM, Brandon Allbery wrote: > On Sun, Sep 28, 2014 at 2:45 PM, David Feuer > wrote: > >> I would think what you're trying to do would likely be better with a >> different class, by another name, supporting things like .&&., .||., etc., >> or maybe even moving && and || into a class. > > > So, if I look at this from the angle that the strictness of other Bits > instances is an artifact of their being spine-strict bit vectors, I get > that the correct answer to this is not a new class but a "strict" newtype > on Bool. The standard lazy Bool is by far the more common one, so it's the > strict variant that gets the newtype. (Compare the Sum and Product monoid > newtype-s.) > > -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sun Sep 28 20:39:40 2014 From: david.feuer at gmail.com (David Feuer) Date: Sun, 28 Sep 2014 16:39:40 -0400 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List Message-ID: BACKGROUND: A somewhat common idiom I discovered digging around the GHC tree is the use of reverse . dropWhile p . reverse to remove some unwanted things from the end of a list. The lists involved tend to be short (e.g., file names, package names, lines of user input, etc.) and the amount removed from the end of the list tends to be short (a trailing newline, the last part of a filename, extra spaces, etc.). I initially intended to replace all of these with Data.List.dropWhileEnd p. Unfortunately, my benchmarking showed that this had a substantial negative impact on performance. Data.List.dropWhileEnd is defined like this: dropWhileEnd p = foldr (\x r -> if p x && null r then [] else x:r) [] This is lazy in the *spine* of the list--it can "flush its buffer" and produce list elements any time p x is found to be false. This is the best you can do if you need to process a very large list and don't want to have to load the whole thing into memory, and/or your predicate is *very* cheap. Unfortunately, it pays a steep price: for non-trivial p, it's strict in the *elements* of the list. This makes it unsuitable, from a performance standpoint, for most of the purposes for which I've seen reverse . dropWhile p . reverse used. CONCEPT: Add (by some name) a function that is lazy in the elements while strict in the spine: dropWhileEndLE :: (a -> Bool) -> [a] -> [a] -- specification: dropWhileEndLE p = reverse . dropWhile p . reverse dropWhileEndLE p = foldr (\x r -> if null r && p x then [] else x:r) [] This is a good bit faster than the double-reversing version, presumably because it presumably allocates its buffer stack on the GHC stack rather than spraying junk across the heap. If I were a Time Lord, I'd go back in time and add to the library, instead of dropWhileEnd as it is, a function with a name like takeUntilLastSatisfying p = dropWhileEnd (not . p) which has a name that explains better what it does, and I'd define dropWhileEnd to be dropWhileEndLE. But I'm not a Time Lord, so I'd like to hear what name or naming approach other people would recommend. -------------- next part -------------- An HTML attachment was scrubbed... URL: From fox at ucw.cz Sun Sep 28 21:08:53 2014 From: fox at ucw.cz (Milan Straka) Date: Sun, 28 Sep 2014 23:08:53 +0200 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: <20140928210853.GA8993@auryn.cz> Hi all, > -----Original message----- > From: Edward Kmett > Sent: 28 Sep 2014, 13:06 > > In my quick tests, the branchless form only looked to be about 10% faster. Maybe we should have a real benchmark. I tried to measure these numbers myself and got very varied results, from no change at all, to 80% faster (that was actually lazy version of && versus strict .&. because of the unboxing). It would be really helpful if someone could create and publish benchmark comparing the implementations (I could not come up with a good one). If we agree on the 10%, I would be -1 on the whole proposal. The reason from the performance view would be that in half of the cases, the shortcutting kicks in and we may get faster execution (and in the worst case 10% slowdown on the ands themselves, not on the rest of the computation). The reason from the language point of view is that I would expect a .&. b to be shortcutting on Bools. Cheers, Milan From ekmett at gmail.com Sun Sep 28 21:13:48 2014 From: ekmett at gmail.com (Edward Kmett) Date: Sun, 28 Sep 2014 17:13:48 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: <094B2429-FE1D-4449-B2D8-47428EBC9F0A@gmail.com> You was intended as a collective noun, not an attempt to pick on you in particular. :) Sent from my iPad > On Sep 28, 2014, at 3:20 PM, Brandon Allbery wrote: > >> On Sun, Sep 28, 2014 at 3:14 PM, Edward Kmett wrote: >> But since you insist on trying to force me to provide a fully concrete realization of a counter-proposal > > Well, no. I, and apparently dfeuer, are missing something; I'm trying to figure out what it is. So I don't want a fleshed-out counter-proposal, just pointers to whatever it is that's not at all obvious to us. > > -- > 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 david.feuer at gmail.com Sun Sep 28 21:25:07 2014 From: david.feuer at gmail.com (David Feuer) Date: Sun, 28 Sep 2014 17:25:07 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sep 28, 2014 4:15 PM, "Carter Schonwald" wrote: > > Brandon, I think you're articulating a very good point here, in noting that the current set of instances for Bits that *are* strict are precisely so because their underlying representations are spine strict! > > From that perspective, it is definitely valid to argue that the shortcircuiting behavior of bool is in fact correct. Maybe, but maybe not so much. For example, it would make sense (to me, at least) to write instance Bits x => Bits [x] where xs .&. ys = zipWith (.&.) xs ys xs .|. ya = zipWith (.|.) xs ys .... This is, I guess you'd say, partially spine-lazy, but it's not short-circuiting. > Its also important to keep in mind that theres many examples where the branchless version of bool is not a win Yes, of course. As Edward Kmett indicated, there seems to be clear value in offering both short-circuiting and branchless Bool operators in *some* fashion, whether the branchless ones do or don't end up in Bits. > We've not yet articulated an example where someone will be writing code that is both generic AND branchless (indeed, I'm not certain if there is actually a meaningful performance win in the fully polymorphic case when its the desired semantics). If you're arguing that Bool shouldn't be in Bits at all, I could understand that viewpoint. There are a number of Bits members that reduce to useless trivialities for Bool. But I would turn your argument around?where's the code that's both generic and short-circuiting? What makes it valuable to put Bool in Bits at all? The most valuable thing *I* see is to give it branchless operators that match a common interface. Edward Kmett sees a different benefit?but a different benefit requiring the whole class to be refactored to become something else. > Additionally, one entire space left unaddressed here is this: "why cant we formulate an optimization algorithm to add to ghc that tries to estimate when transformation into a (relatively) branchless formulation of the same code"? This is a *very* good question. I don't know enough about compilation to really say, and there are surely some challenges, but I think it's an important question. If y is already forced, or it's certain to be forced later, then case x of True -> case y of True -> e1 False -> e2 False -> e2 Is the same as if (x & y) then e1 else e2. The next question is whether e1 and e2 are such that the case selection can become a conditional move or something. I have no idea what's involved in general. It also seems more awkward to write if y `seq` x && y then blah else bloop than to write if x .&. y then blah else bloop or even if x `bland` y then blah else bloop --Yucky name, but whatever. But to catch cases programmers might not recognize, I think your idea sounds interesting. > a style i've grown to favor is the following: make it easy to write generic code thats always correct (wrt complexity), and make it sane to do specialization/optimization by hand later (and/or teach the compiler.) "Correct wrt complexity" is clearly something we disagree on here. > Branchless code is immune to that problem, but if you dont have bad branch prediction, the branching code will be faster / simpler than the branch free code. Sometimes. The branchless code is sometimes still slightly faster, depending on the situation, and of course it's also *smaller* in many cases. -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sun Sep 28 22:53:35 2014 From: david.feuer at gmail.com (David Feuer) Date: Sun, 28 Sep 2014 18:53:35 -0400 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: Message-ID: One good option might be dropWhileR, to match Data.Sequence, but I'd only want to use that if the dropWhileEnd name were deprecated in favor of takeUntilLastSatisfying or whatever?otherwise it's just too confusing. On Sep 28, 2014 4:39 PM, "David Feuer" wrote: > BACKGROUND: > > A somewhat common idiom I discovered digging around the GHC tree is the > use of > > reverse . dropWhile p . reverse > > to remove some unwanted things from the end of a list. The lists involved > tend to be short (e.g., file names, package names, lines of user input, > etc.) and the amount removed from the end of the list tends to be short (a > trailing newline, the last part of a filename, extra spaces, etc.). I > initially intended to replace all of these with Data.List.dropWhileEnd p. > Unfortunately, my benchmarking showed that this had a substantial negative > impact on performance. Data.List.dropWhileEnd is defined like this: > > dropWhileEnd p = foldr (\x r -> if p x && null r then [] else x:r) [] > > This is lazy in the *spine* of the list--it can "flush its buffer" and > produce list elements any time p x is found to be false. This is the best > you can do if you need to process a very large list and don't want to have > to load the whole thing into memory, and/or your predicate is *very* cheap. > Unfortunately, it pays a steep price: for non-trivial p, it's strict in the > *elements* of the list. This makes it unsuitable, from a performance > standpoint, for most of the purposes for which I've seen reverse . > dropWhile p . reverse used. > > CONCEPT: > > Add (by some name) a function that is lazy in the elements while strict in > the spine: > > dropWhileEndLE :: (a -> Bool) -> [a] -> [a] > -- specification: dropWhileEndLE p = reverse . dropWhile p . reverse > dropWhileEndLE p = foldr (\x r -> if null r && p x then [] else x:r) [] > > This is a good bit faster than the double-reversing version, presumably > because it presumably allocates its buffer stack on the GHC stack rather > than spraying junk across the heap. > > If I were a Time Lord, I'd go back in time and add to the library, instead > of dropWhileEnd as it is, a function with a name like > > takeUntilLastSatisfying p = dropWhileEnd (not . p) > > which has a name that explains better what it does, and I'd define > dropWhileEnd to be dropWhileEndLE. But I'm not a Time Lord, so I'd like to > hear what name or naming approach other people would recommend. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From greg at gregweber.info Sun Sep 28 22:59:58 2014 From: greg at gregweber.info (Greg Weber) Date: Sun, 28 Sep 2014 15:59:58 -0700 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: Message-ID: Should the code be using Seq instead of a List? On Sun, Sep 28, 2014 at 3:53 PM, David Feuer wrote: > One good option might be dropWhileR, to match Data.Sequence, but I'd only > want to use that if the dropWhileEnd name were deprecated in favor of > takeUntilLastSatisfying or whatever?otherwise it's just too confusing. > On Sep 28, 2014 4:39 PM, "David Feuer" wrote: > >> BACKGROUND: >> >> A somewhat common idiom I discovered digging around the GHC tree is the >> use of >> >> reverse . dropWhile p . reverse >> >> to remove some unwanted things from the end of a list. The lists involved >> tend to be short (e.g., file names, package names, lines of user input, >> etc.) and the amount removed from the end of the list tends to be short (a >> trailing newline, the last part of a filename, extra spaces, etc.). I >> initially intended to replace all of these with Data.List.dropWhileEnd p. >> Unfortunately, my benchmarking showed that this had a substantial negative >> impact on performance. Data.List.dropWhileEnd is defined like this: >> >> dropWhileEnd p = foldr (\x r -> if p x && null r then [] else x:r) [] >> >> This is lazy in the *spine* of the list--it can "flush its buffer" and >> produce list elements any time p x is found to be false. This is the best >> you can do if you need to process a very large list and don't want to have >> to load the whole thing into memory, and/or your predicate is *very* cheap. >> Unfortunately, it pays a steep price: for non-trivial p, it's strict in the >> *elements* of the list. This makes it unsuitable, from a performance >> standpoint, for most of the purposes for which I've seen reverse . >> dropWhile p . reverse used. >> >> CONCEPT: >> >> Add (by some name) a function that is lazy in the elements while strict >> in the spine: >> >> dropWhileEndLE :: (a -> Bool) -> [a] -> [a] >> -- specification: dropWhileEndLE p = reverse . dropWhile p . reverse >> dropWhileEndLE p = foldr (\x r -> if null r && p x then [] else x:r) [] >> >> This is a good bit faster than the double-reversing version, presumably >> because it presumably allocates its buffer stack on the GHC stack rather >> than spraying junk across the heap. >> >> If I were a Time Lord, I'd go back in time and add to the library, >> instead of dropWhileEnd as it is, a function with a name like >> >> takeUntilLastSatisfying p = dropWhileEnd (not . p) >> >> which has a name that explains better what it does, and I'd define >> dropWhileEnd to be dropWhileEndLE. But I'm not a Time Lord, so I'd like to >> hear what name or naming approach other people would recommend. >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Mon Sep 29 00:13:39 2014 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sun, 28 Sep 2014 20:13:39 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: I'd actually consider that "spine lazy" definition instance Bits x => Bits [x] where xs .&. ys = zipWith (.&.) xs ys xs .|. ya = zipWith (.|.) xs ys to be the proper "short circuiting" definition, because it has the minimal work complexity and just a nice lifted version of the pointwise boolean / bitwise operation. the "is this all True/1s" lifted version doesnt seem to provide a good work complexity bound (seems all or nothing). Otoh, my stance might be a bit heretical or subtley wrong :), NB that I do undersand that unlike the "batch" short circuit, this one would fail if the right hand side was "undefined / error", but thats ok :) -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Mon Sep 29 00:34:45 2014 From: david.feuer at gmail.com (David Feuer) Date: Sun, 28 Sep 2014 20:34:45 -0400 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: Message-ID: That decision is up to the user. Data.List provides a number of sequence functions that aren't efficient for lists, including take, drop, splitAt, init, last, reverse, zip, unzip, and (!!). dropWhileEnd and dropWhileLE aren't any worse, I don't think. On Sun, Sep 28, 2014 at 6:59 PM, Greg Weber wrote: > Should the code be using Seq instead of a List? > > On Sun, Sep 28, 2014 at 3:53 PM, David Feuer > wrote: > >> One good option might be dropWhileR, to match Data.Sequence, but I'd only >> want to use that if the dropWhileEnd name were deprecated in favor of >> takeUntilLastSatisfying or whatever?otherwise it's just too confusing. >> On Sep 28, 2014 4:39 PM, "David Feuer" wrote: >> >>> BACKGROUND: >>> >>> A somewhat common idiom I discovered digging around the GHC tree is the >>> use of >>> >>> reverse . dropWhile p . reverse >>> >>> to remove some unwanted things from the end of a list. The lists >>> involved tend to be short (e.g., file names, package names, lines of user >>> input, etc.) and the amount removed from the end of the list tends to be >>> short (a trailing newline, the last part of a filename, extra spaces, >>> etc.). I initially intended to replace all of these with >>> Data.List.dropWhileEnd p. Unfortunately, my benchmarking showed that this >>> had a substantial negative impact on performance. Data.List.dropWhileEnd is >>> defined like this: >>> >>> dropWhileEnd p = foldr (\x r -> if p x && null r then [] else x:r) [] >>> >>> This is lazy in the *spine* of the list--it can "flush its buffer" and >>> produce list elements any time p x is found to be false. This is the best >>> you can do if you need to process a very large list and don't want to have >>> to load the whole thing into memory, and/or your predicate is *very* cheap. >>> Unfortunately, it pays a steep price: for non-trivial p, it's strict in the >>> *elements* of the list. This makes it unsuitable, from a performance >>> standpoint, for most of the purposes for which I've seen reverse . >>> dropWhile p . reverse used. >>> >>> CONCEPT: >>> >>> Add (by some name) a function that is lazy in the elements while strict >>> in the spine: >>> >>> dropWhileEndLE :: (a -> Bool) -> [a] -> [a] >>> -- specification: dropWhileEndLE p = reverse . dropWhile p . reverse >>> dropWhileEndLE p = foldr (\x r -> if null r && p x then [] else x:r) [] >>> >>> This is a good bit faster than the double-reversing version, presumably >>> because it presumably allocates its buffer stack on the GHC stack rather >>> than spraying junk across the heap. >>> >>> If I were a Time Lord, I'd go back in time and add to the library, >>> instead of dropWhileEnd as it is, a function with a name like >>> >>> takeUntilLastSatisfying p = dropWhileEnd (not . p) >>> >>> which has a name that explains better what it does, and I'd define >>> dropWhileEnd to be dropWhileEndLE. But I'm not a Time Lord, so I'd like to >>> hear what name or naming approach other people would recommend. >>> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Mon Sep 29 01:11:42 2014 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sun, 28 Sep 2014 21:11:42 -0400 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: Message-ID: on the flip side, how can we encourage more usage of Data.Sequence ? :) On Sun, Sep 28, 2014 at 8:34 PM, David Feuer wrote: > That decision is up to the user. Data.List provides a number of sequence > functions that aren't efficient for lists, including take, drop, splitAt, > init, last, reverse, zip, unzip, and (!!). dropWhileEnd and dropWhileLE > aren't any worse, I don't think. > > On Sun, Sep 28, 2014 at 6:59 PM, Greg Weber wrote: > >> Should the code be using Seq instead of a List? >> >> On Sun, Sep 28, 2014 at 3:53 PM, David Feuer >> wrote: >> >>> One good option might be dropWhileR, to match Data.Sequence, but I'd >>> only want to use that if the dropWhileEnd name were deprecated in favor of >>> takeUntilLastSatisfying or whatever?otherwise it's just too confusing. >>> On Sep 28, 2014 4:39 PM, "David Feuer" wrote: >>> >>>> BACKGROUND: >>>> >>>> A somewhat common idiom I discovered digging around the GHC tree is the >>>> use of >>>> >>>> reverse . dropWhile p . reverse >>>> >>>> to remove some unwanted things from the end of a list. The lists >>>> involved tend to be short (e.g., file names, package names, lines of user >>>> input, etc.) and the amount removed from the end of the list tends to be >>>> short (a trailing newline, the last part of a filename, extra spaces, >>>> etc.). I initially intended to replace all of these with >>>> Data.List.dropWhileEnd p. Unfortunately, my benchmarking showed that this >>>> had a substantial negative impact on performance. Data.List.dropWhileEnd is >>>> defined like this: >>>> >>>> dropWhileEnd p = foldr (\x r -> if p x && null r then [] else x:r) >>>> [] >>>> >>>> This is lazy in the *spine* of the list--it can "flush its buffer" and >>>> produce list elements any time p x is found to be false. This is the best >>>> you can do if you need to process a very large list and don't want to have >>>> to load the whole thing into memory, and/or your predicate is *very* cheap. >>>> Unfortunately, it pays a steep price: for non-trivial p, it's strict in the >>>> *elements* of the list. This makes it unsuitable, from a performance >>>> standpoint, for most of the purposes for which I've seen reverse . >>>> dropWhile p . reverse used. >>>> >>>> CONCEPT: >>>> >>>> Add (by some name) a function that is lazy in the elements while strict >>>> in the spine: >>>> >>>> dropWhileEndLE :: (a -> Bool) -> [a] -> [a] >>>> -- specification: dropWhileEndLE p = reverse . dropWhile p . reverse >>>> dropWhileEndLE p = foldr (\x r -> if null r && p x then [] else x:r) [] >>>> >>>> This is a good bit faster than the double-reversing version, presumably >>>> because it presumably allocates its buffer stack on the GHC stack rather >>>> than spraying junk across the heap. >>>> >>>> If I were a Time Lord, I'd go back in time and add to the library, >>>> instead of dropWhileEnd as it is, a function with a name like >>>> >>>> takeUntilLastSatisfying p = dropWhileEnd (not . p) >>>> >>>> which has a name that explains better what it does, and I'd define >>>> dropWhileEnd to be dropWhileEndLE. But I'm not a Time Lord, so I'd like to >>>> hear what name or naming approach other people would recommend. >>>> >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://www.haskell.org/mailman/listinfo/libraries >>> >>> >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Mon Sep 29 01:26:30 2014 From: david.feuer at gmail.com (David Feuer) Date: Sun, 28 Sep 2014 21:26:30 -0400 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: Message-ID: I think the Foldable/Traversable work for 7.10 will help with a lot of these issues. Beyond that: make it faster if possible, make less-capable versions that are faster, and make it easier to find the right version for the job. A complicated way might be to use the "bundle" approach that the vector fusion folks have pioneered, but there are surely other ways. But I don't think any of that discussion takes away from the need to have really great list support. On Sun, Sep 28, 2014 at 9:11 PM, Carter Schonwald < carter.schonwald at gmail.com> wrote: > on the flip side, how can we encourage more usage of Data.Sequence ? :) > > On Sun, Sep 28, 2014 at 8:34 PM, David Feuer > wrote: > >> That decision is up to the user. Data.List provides a number of sequence >> functions that aren't efficient for lists, including take, drop, splitAt, >> init, last, reverse, zip, unzip, and (!!). dropWhileEnd and dropWhileLE >> aren't any worse, I don't think. >> >> On Sun, Sep 28, 2014 at 6:59 PM, Greg Weber wrote: >> >>> Should the code be using Seq instead of a List? >>> >>> On Sun, Sep 28, 2014 at 3:53 PM, David Feuer >>> wrote: >>> >>>> One good option might be dropWhileR, to match Data.Sequence, but I'd >>>> only want to use that if the dropWhileEnd name were deprecated in favor of >>>> takeUntilLastSatisfying or whatever?otherwise it's just too confusing. >>>> On Sep 28, 2014 4:39 PM, "David Feuer" wrote: >>>> >>>>> BACKGROUND: >>>>> >>>>> A somewhat common idiom I discovered digging around the GHC tree is >>>>> the use of >>>>> >>>>> reverse . dropWhile p . reverse >>>>> >>>>> to remove some unwanted things from the end of a list. The lists >>>>> involved tend to be short (e.g., file names, package names, lines of user >>>>> input, etc.) and the amount removed from the end of the list tends to be >>>>> short (a trailing newline, the last part of a filename, extra spaces, >>>>> etc.). I initially intended to replace all of these with >>>>> Data.List.dropWhileEnd p. Unfortunately, my benchmarking showed that this >>>>> had a substantial negative impact on performance. Data.List.dropWhileEnd is >>>>> defined like this: >>>>> >>>>> dropWhileEnd p = foldr (\x r -> if p x && null r then [] else x:r) >>>>> [] >>>>> >>>>> This is lazy in the *spine* of the list--it can "flush its buffer" and >>>>> produce list elements any time p x is found to be false. This is the best >>>>> you can do if you need to process a very large list and don't want to have >>>>> to load the whole thing into memory, and/or your predicate is *very* cheap. >>>>> Unfortunately, it pays a steep price: for non-trivial p, it's strict in the >>>>> *elements* of the list. This makes it unsuitable, from a performance >>>>> standpoint, for most of the purposes for which I've seen reverse . >>>>> dropWhile p . reverse used. >>>>> >>>>> CONCEPT: >>>>> >>>>> Add (by some name) a function that is lazy in the elements while >>>>> strict in the spine: >>>>> >>>>> dropWhileEndLE :: (a -> Bool) -> [a] -> [a] >>>>> -- specification: dropWhileEndLE p = reverse . dropWhile p . reverse >>>>> dropWhileEndLE p = foldr (\x r -> if null r && p x then [] else x:r) [] >>>>> >>>>> This is a good bit faster than the double-reversing version, >>>>> presumably because it presumably allocates its buffer stack on the GHC >>>>> stack rather than spraying junk across the heap. >>>>> >>>>> If I were a Time Lord, I'd go back in time and add to the library, >>>>> instead of dropWhileEnd as it is, a function with a name like >>>>> >>>>> takeUntilLastSatisfying p = dropWhileEnd (not . p) >>>>> >>>>> which has a name that explains better what it does, and I'd define >>>>> dropWhileEnd to be dropWhileEndLE. But I'm not a Time Lord, so I'd like to >>>>> hear what name or naming approach other people would recommend. >>>>> >>>> >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://www.haskell.org/mailman/listinfo/libraries >>>> >>>> >>> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwlato at gmail.com Mon Sep 29 01:38:02 2014 From: jwlato at gmail.com (John Lato) Date: Mon, 29 Sep 2014 09:38:02 +0800 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: Message-ID: I don't think we should be encouraging the use of Data.Sequence for file paths. An opaque OS-specific structure seems like the natural choice IMHO. (Incidentally I'd like to develop this as a userland library, if anyone would step forward to help with the Windows-specific stuff) On Mon, Sep 29, 2014 at 9:11 AM, Carter Schonwald < carter.schonwald at gmail.com> wrote: > on the flip side, how can we encourage more usage of Data.Sequence ? :) > > On Sun, Sep 28, 2014 at 8:34 PM, David Feuer > wrote: > >> That decision is up to the user. Data.List provides a number of sequence >> functions that aren't efficient for lists, including take, drop, splitAt, >> init, last, reverse, zip, unzip, and (!!). dropWhileEnd and dropWhileLE >> aren't any worse, I don't think. >> >> On Sun, Sep 28, 2014 at 6:59 PM, Greg Weber wrote: >> >>> Should the code be using Seq instead of a List? >>> >>> On Sun, Sep 28, 2014 at 3:53 PM, David Feuer >>> wrote: >>> >>>> One good option might be dropWhileR, to match Data.Sequence, but I'd >>>> only want to use that if the dropWhileEnd name were deprecated in favor of >>>> takeUntilLastSatisfying or whatever?otherwise it's just too confusing. >>>> On Sep 28, 2014 4:39 PM, "David Feuer" wrote: >>>> >>>>> BACKGROUND: >>>>> >>>>> A somewhat common idiom I discovered digging around the GHC tree is >>>>> the use of >>>>> >>>>> reverse . dropWhile p . reverse >>>>> >>>>> to remove some unwanted things from the end of a list. The lists >>>>> involved tend to be short (e.g., file names, package names, lines of user >>>>> input, etc.) and the amount removed from the end of the list tends to be >>>>> short (a trailing newline, the last part of a filename, extra spaces, >>>>> etc.). I initially intended to replace all of these with >>>>> Data.List.dropWhileEnd p. Unfortunately, my benchmarking showed that this >>>>> had a substantial negative impact on performance. Data.List.dropWhileEnd is >>>>> defined like this: >>>>> >>>>> dropWhileEnd p = foldr (\x r -> if p x && null r then [] else x:r) >>>>> [] >>>>> >>>>> This is lazy in the *spine* of the list--it can "flush its buffer" and >>>>> produce list elements any time p x is found to be false. This is the best >>>>> you can do if you need to process a very large list and don't want to have >>>>> to load the whole thing into memory, and/or your predicate is *very* cheap. >>>>> Unfortunately, it pays a steep price: for non-trivial p, it's strict in the >>>>> *elements* of the list. This makes it unsuitable, from a performance >>>>> standpoint, for most of the purposes for which I've seen reverse . >>>>> dropWhile p . reverse used. >>>>> >>>>> CONCEPT: >>>>> >>>>> Add (by some name) a function that is lazy in the elements while >>>>> strict in the spine: >>>>> >>>>> dropWhileEndLE :: (a -> Bool) -> [a] -> [a] >>>>> -- specification: dropWhileEndLE p = reverse . dropWhile p . reverse >>>>> dropWhileEndLE p = foldr (\x r -> if null r && p x then [] else x:r) [] >>>>> >>>>> This is a good bit faster than the double-reversing version, >>>>> presumably because it presumably allocates its buffer stack on the GHC >>>>> stack rather than spraying junk across the heap. >>>>> >>>>> If I were a Time Lord, I'd go back in time and add to the library, >>>>> instead of dropWhileEnd as it is, a function with a name like >>>>> >>>>> takeUntilLastSatisfying p = dropWhileEnd (not . p) >>>>> >>>>> which has a name that explains better what it does, and I'd define >>>>> dropWhileEnd to be dropWhileEndLE. But I'm not a Time Lord, so I'd like to >>>>> hear what name or naming approach other people would recommend. >>>>> >>>> >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://www.haskell.org/mailman/listinfo/libraries >>>> >>>> >>> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From gershomb at gmail.com Mon Sep 29 03:06:52 2014 From: gershomb at gmail.com (Gershom B) Date: Sun, 28 Sep 2014 23:06:52 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: Did I miss in this thread an actual use-case for strict and/or for Bool such that it might occur in a tight inner loop? Absent such a use case, I?m -1 on this proposal. If I wanted to use something that I felt had strict bitwise behaviour, I?d never reach for a bool, no matter what operator set I was working with. My instinct would be to reach for a Word8 or the like, since on any real implementation it would take up the same space regardless? Essentially, to my laziness-infected brain, the current instance obeys the principle of least surprise, and the proposed instance violates the sort of wall of ?abstraction intuitions? I?ve built up regarding when I should and shouldn?t expect lazy behaviour. -g On September 27, 2014 at 1:59:43 PM, David Feuer (david.feuer at gmail.com) wrote: > Currently, the (.&.) and (.|.) methods for Bool are short-circuiting, > defined like this: > > instance Bits Bool where > (.&.) = (&&) > > (.|.) = (||) > > Unlike the instances for Int, Word, etc., this gives short-circuiting > behavior (conditionally lazy in the second operand). Unfortunately, this > requires a conditional branch to implement, which can sometimes be bad. > Since (&&) and (||) are readily available to anyone who wants > short-circuiting, I propose that we use the following instead. Note that > the Bits class does not specify anything about this aspect of instance > behavior. > > x .&. y = tagToEnum# (dataToTag# x `andI#` dataToTag# y) > > x .|. y = tagToEnum# (dataToTag# x `orI#` dataToTag# y) > > The rest of the operations look like this: > > x `xor` y = tagToEnum# (dataToTag# x `xorI#` dataToTag# y) > > complement x = tagToEnum# (dataToTag# x `xorI#` 1#) > > shift x s = testBit x s > > rotate x _ = x > > -- I don't think we gain anything changing this one. > bit 0 = True > bit _ = False > > testBit x b = tagToEnum# (dataToTag# x `andI#` (dataToTag# b ==# 0#)) > > bitSizeMaybe _ = Just 1 > > bitSize _ = 1 > > isSigned _ = False > > popCount x = I# (dataToTag# x) > > instance FiniteBits Bool where > finiteBitSize _ = 1 > countTrailingZeros x = I# (dataToTag# x `xorI#` 1#) > countLeadingZeros x = I# (dataToTag# x `xorI#` 1#) > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > From gershomb at gmail.com Mon Sep 29 03:35:43 2014 From: gershomb at gmail.com (Gershom B) Date: Sun, 28 Sep 2014 23:35:43 -0400 Subject: List of core libraries In-Reply-To: References: Message-ID: This is a good discussion on clearing things up. The following, from the core libraries wiki page, is clearly not entirely correct: "The core libraries are a subset of the packages in the Haskell Platform, and define basic APIs that are expected to be available in any Haskell implementation.? Some libraries, like xhtml, are clearly there for historical reasons at this point. Other libraries, such as hpc and ghc-prim, are clearly not expected to be available in ?any Haskell implementation?. Furthermore, does this imply that the core libraries committee, which can choose to adopt packages, can therefore choose what is ?expected to be available in any Haskell implementation?? I suppose it can, but will ?any Haskell implementation? listen? :-P Better perhaps to do something like the following: "The core libraries are a subset of the packages in the Haskell Platform. Many core libraries define basic APIs that are expected to be available in any Haskell implementation. A second set of core libraries are coupled tightly to the Glasgow Haskell Compiler but nonetheless managed through the core libraries process, as they are considered core functionality in the GHC Haskell ecosystem.? Additionally, the libraries committee may want to more explicitly seperate the two lists? If we do ever have a new libraries section of a Haskell report, I imagine, e.g. it may well mention directory and process, but not ?ghc-prim?. Finally, I think this is premature, but I do suspect that there will come a time soon in which we want to move xhtml to the "maintained only for backward compatibility? slot. My understanding is that modern Haskell web frameworks nearly unanimously avoid it in favor of more performant alternatives (at a minimum, not based on ?String?). Furthermore, the xhtml package seems like it has recieved nearly no patches in the past four years outside of changes to maintain compatibility with new versions of GHC. In a few years time, I suspect that most code that continues to use this library rather than more modern alternatives will be hoplessly bitrotted in other ways as well. Even further down the road, I suspect many of the same considerations may apply to ?pretty? as well. Also note that having xhtml and pretty as core libraries discourages adding more modern alternatives to the platform down the line (such as, say, blaze-html and wl-pprint-text). Cheers, Gershom On September 28, 2014 at 3:00:14 PM, Thomas Miedema (thomasmiedema at gmail.com) wrote: > On Sat, Sep 27, 2014 at 7:40 PM, Brandon Allbery > wrote: > > > > There is a difference between the libraries needed to provide a core > > usable Haskell installation, and the libraries required for a particular > > Haskell implementation (in this case ghc) to provide basic functionality. > > For example, integer-gmp is an artifact of how GHC implements bigints, and > > haskeline and terminfo are required for ghci's line editing. We generally > > distinguish between "core libraries" and "GHC bootstrap libraries" > > ("bootlibs"). > > > > Thanks Brandon, that cleared up part of my initial confusion. I added the > following section to the haskellwiki: > http://www.haskell.org/haskellwiki/Applications_and_libraries#GHC_bootstrap_libraries > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > From allbery.b at gmail.com Mon Sep 29 03:43:52 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 28 Sep 2014 23:43:52 -0400 Subject: List of core libraries In-Reply-To: References: Message-ID: On Sun, Sep 28, 2014 at 11:35 PM, Gershom B wrote: > Better perhaps to do something like the following: > > "The core libraries are a subset of the packages in the Haskell Platform. > Many core libraries define basic APIs that are expected to be available in > any Haskell implementation. A second set of core libraries are coupled > tightly to the Glasgow Haskell Compiler but nonetheless managed through the > core libraries process, as they are considered core functionality in the > GHC Haskell ecosystem.? > > Additionally, the libraries committee may want to more explicitly seperate > the two lists? If we do ever have a new libraries section of a Haskell > report, I imagine, e.g. it may well mention directory and process, but not > ?ghc-prim?. > I would argue that implementation specific libraries do not belong in the core libraries list. Instead, perhaps the libraries committee should state two functions: maintaining the core libraries list, and acting as the community interface/liaison for libraries specific to implementations. The implementations themselves should (and indeed must) maintain their implementation libraries lists; but to the extent that the community affects and is affected by these lists, the libraries committee is empowered to act on behalf of the community. -- 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 allbery.b at gmail.com Mon Sep 29 03:47:56 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 28 Sep 2014 23:47:56 -0400 Subject: List of core libraries In-Reply-To: References: Message-ID: On Sun, Sep 28, 2014 at 11:43 PM, Brandon Allbery wrote: > the libraries committee is empowered to act on behalf of the community On second thought, this sounds a bit stronger than I intended --- especially in the absence of a well-defined notion of the community's interest. -- 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 david.feuer at gmail.com Mon Sep 29 04:20:55 2014 From: david.feuer at gmail.com (David Feuer) Date: Mon, 29 Sep 2014 00:20:55 -0400 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: Message-ID: Since so many people like to see benchmarks, I figured I'd give you some. I tested nf (unlines . dropWhile__ isSpace . lines) li__ li1 is a lorem ipsum produced by an online lorem ipsum generator. li4 is the same thing, but with each space replaced by a bunch of spaces. dwr is dropWhileEndLE isSpace rdr is reverse . dropWhile isSpace . reverse dwe is dropWhileEnd isSpace The poor performance of dwe compared to rdr in li1 seems most likely to be caused by excessive use of isSpace, which takes quite a few tests to determine that a character is *not* a space. The prevalence of ' ' characters in li4 makes this less substantial. The difference between dwr and rdr is relatively small in li1, but it jumps way up in li4. I'm guessing this is because rdr sprays the entire string onto the heap before filtering out most of it, whereas dwr pushes everything onto the stack and only puts what it actually produces onto the heap. In any case, I think these demonstrate the practical utility of dropWhileEndLE for code that chooses to use lists for such purposes. benchmarking li1/dwr time 4.436 ms (4.405 ms .. 4.465 ms) 1.000 R? (0.999 R? .. 1.000 R?) mean 4.483 ms (4.481 ms .. 4.487 ms) std dev 9.562 ?s (6.414 ?s .. 14.38 ?s) benchmarking li1/rdr time 5.061 ms (5.053 ms .. 5.071 ms) 1.000 R? (1.000 R? .. 1.000 R?) mean 5.062 ms (5.059 ms .. 5.069 ms) std dev 15.05 ?s (7.515 ?s .. 24.65 ?s) benchmarking li1/dwe time 8.448 ms (8.441 ms .. 8.460 ms) 1.000 R? (1.000 R? .. 1.000 R?) mean 8.450 ms (8.444 ms .. 8.464 ms) std dev 24.61 ?s (10.83 ?s .. 46.48 ?s) benchmarking li4/dwr time 19.52 ms (17.23 ms .. 21.93 ms) 0.919 R? (0.861 R? .. 0.983 R?) mean 18.11 ms (17.16 ms .. 19.46 ms) std dev 2.683 ms (1.772 ms .. 3.495 ms) variance introduced by outliers: 67% (severely inflated) benchmarking li4/rdr time 29.63 ms (27.63 ms .. 31.69 ms) 0.980 R? (0.955 R? .. 0.993 R?) mean 30.03 ms (28.31 ms .. 32.27 ms) std dev 4.152 ms (2.719 ms .. 5.921 ms) variance introduced by outliers: 57% (severely inflated) benchmarking li4/dwe time 28.52 ms (27.40 ms .. 29.72 ms) 0.994 R? (0.990 R? .. 0.997 R?) mean 27.99 ms (26.08 ms .. 28.94 ms) std dev 2.961 ms (1.437 ms .. 5.016 ms) variance introduced by outliers: 43% (moderately inflated) From ekmett at gmail.com Mon Sep 29 04:32:11 2014 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 29 Sep 2014 00:32:11 -0400 Subject: [core libraries] Re: List of core libraries In-Reply-To: References: Message-ID: On Sun, Sep 28, 2014 at 11:43 PM, Brandon Allbery wrote: > On Sun, Sep 28, 2014 at 11:35 PM, Gershom B wrote: > >> Better perhaps to do something like the following: >> >> "The core libraries are a subset of the packages in the Haskell Platform. >> Many core libraries define basic APIs that are expected to be available in >> any Haskell implementation. >> > Sadly this isn't true. The core libraries are simply basic APIs that are parts of the Haskell Platform that aren't maintained by another individual. The Haskell Platform consists more or less of stuff we need to ship to be useful and/or is too hard to expect an end user to figure out how to build but which deserves broad distribution. > A second set of core libraries are coupled tightly to the Glasgow Haskell >> Compiler but nonetheless managed through the core libraries process, as >> they are considered core functionality in the GHC Haskell ecosystem.? >> >> Additionally, the libraries committee may want to more explicitly >> seperate the two lists? If we do ever have a new libraries section of a >> Haskell report, I imagine, e.g. it may well mention directory and process, >> but not ?ghc-prim?. >> > > I would argue that implementation specific libraries do not belong in the > core libraries list. Instead, perhaps the libraries committee should state > two functions: maintaining the core libraries list, and acting as the > community interface/liaison for libraries specific to implementations. > > The implementations themselves should (and indeed must) maintain their > implementation libraries lists; > The main thing the core libraries committee does right now is deal with that uncomfortable buffer zone between what GHC HQ wants to deal with (making GHC fast and nice to use) and what the rest of the ecosystem wants to maintain (many of the individual maintainer packages in the platform). There were a whole lot of packages left to this grey area, needed by the rest of the platform, but where it was basically assumed that GHC HQ was maintaining them but really nobody felt ownership. > but to the extent that the community affects and is affected by these > lists, the libraries committee is empowered to act on behalf of the > community. > If there are other teams working on compilers that want to engage with the core libraries committee to get better interoperability, we'd be happy to engage, but thus far, GHC is the only party at the table actively talking to us. -Edward -- > brandon s allbery kf8nh sine nomine > associates > allbery.b at gmail.com > ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad > http://sinenomine.net > > -- > You received this message because you are subscribed to the Google Groups > "haskell-core-libraries" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to haskell-core-libraries+unsubscribe at googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Mon Sep 29 04:44:54 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Mon, 29 Sep 2014 00:44:54 -0400 Subject: [core libraries] Re: List of core libraries In-Reply-To: References: Message-ID: On Mon, Sep 29, 2014 at 12:32 AM, Edward Kmett wrote: > > >> but to the extent that the community affects and is affected by these >> lists, the libraries committee is empowered to act on behalf of the >> community. >> > > If there are other teams working on compilers that want to engage with the > core libraries committee to get better interoperability, we'd be happy to > engage, but thus far, GHC is the only party at the table actively talking > to us. > Yes, de facto this only means GHC at present. But it also captures, or intends to capture, your statement: The main thing the core libraries committee does right now is deal with > that uncomfortable buffer zone between what GHC HQ wants to deal with > (making GHC fast and nice to use) and what the rest of the ecosystem wants > to maintain (many of the individual maintainer packages in the platform). > -- 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 ekmett at gmail.com Mon Sep 29 04:54:31 2014 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 29 Sep 2014 00:54:31 -0400 Subject: [core libraries] Re: List of core libraries In-Reply-To: References: Message-ID: I've updated the verbiage on the Library_Submissions process to capture a bit more about the effective role of the core libraries. It was rather messy before. I do agree we do probably want to do more to break out what portions of the core-libraries are intended for portable implementation and which ones are just things we simply have to maintain for glue, but for that we'd probably need more feedback from other compiler implementors to get a sense of what it is they have been able / willing to implement. -Edward On Mon, Sep 29, 2014 at 12:44 AM, Brandon Allbery wrote: > On Mon, Sep 29, 2014 at 12:32 AM, Edward Kmett wrote: > >> >> >>> but to the extent that the community affects and is affected by these >>> lists, the libraries committee is empowered to act on behalf of the >>> community. >>> >> >> If there are other teams working on compilers that want to engage with >> the core libraries committee to get better interoperability, we'd be happy >> to engage, but thus far, GHC is the only party at the table actively >> talking to us. >> > > Yes, de facto this only means GHC at present. But it also captures, or > intends to capture, your statement: > > The main thing the core libraries committee does right now is deal with >> that uncomfortable buffer zone between what GHC HQ wants to deal with >> (making GHC fast and nice to use) and what the rest of the ecosystem wants >> to maintain (many of the individual maintainer packages in the platform). >> > > -- > 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 felipe.lessa at gmail.com Mon Sep 29 13:19:34 2014 From: felipe.lessa at gmail.com (Felipe Lessa) Date: Mon, 29 Sep 2014 10:19:34 -0300 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: Message-ID: <54295C66.6080508@gmail.com> On 28-09-2014 22:38, John Lato wrote: > I don't think we should be encouraging the use of Data.Sequence for file > paths. An opaque OS-specific structure seems like the natural choice IMHO. > > (Incidentally I'd like to develop this as a userland library, if anyone > would step forward to help with the Windows-specific stuff) Do you mean system-filepath [1]? Cheers, [1] http://hackage.haskell.org/package/system-filepath -- Felipe. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: OpenPGP digital signature URL: From acowley at seas.upenn.edu Mon Sep 29 14:14:03 2014 From: acowley at seas.upenn.edu (Anthony Cowley) Date: Mon, 29 Sep 2014 10:14:03 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: On Sun, Sep 28, 2014 at 11:06 PM, Gershom B wrote: > Did I miss in this thread an actual use-case for strict and/or for Bool such that it might occur in a tight inner loop? Absent such a use case, I?m -1 on this proposal. If I wanted to use something that I felt had strict bitwise behaviour, I?d never reach for a bool, no matter what operator set I was working with. My instinct would be to reach for a Word8 or the like, since on any real implementation it would take up the same space regardless? > > Essentially, to my laziness-infected brain, the current instance obeys the principle of least surprise, and the proposed instance violates the sort of wall of ?abstraction intuitions? I?ve built up regarding when I should and shouldn?t expect lazy behaviour. > > -g The problem is that Bool is the odd duck with respect to the Data.Bits operations, so the only way your intuition would serve you is if you were sure you would only be working with Bool, in which case the question is why you were reaching for Data.Bits. Anthony > > > On September 27, 2014 at 1:59:43 PM, David Feuer (david.feuer at gmail.com) wrote: >> Currently, the (.&.) and (.|.) methods for Bool are short-circuiting, >> defined like this: >> >> instance Bits Bool where >> (.&.) = (&&) >> >> (.|.) = (||) >> >> Unlike the instances for Int, Word, etc., this gives short-circuiting >> behavior (conditionally lazy in the second operand). Unfortunately, this >> requires a conditional branch to implement, which can sometimes be bad. >> Since (&&) and (||) are readily available to anyone who wants >> short-circuiting, I propose that we use the following instead. Note that >> the Bits class does not specify anything about this aspect of instance >> behavior. >> >> x .&. y = tagToEnum# (dataToTag# x `andI#` dataToTag# y) >> >> x .|. y = tagToEnum# (dataToTag# x `orI#` dataToTag# y) >> >> The rest of the operations look like this: >> >> x `xor` y = tagToEnum# (dataToTag# x `xorI#` dataToTag# y) >> >> complement x = tagToEnum# (dataToTag# x `xorI#` 1#) >> >> shift x s = testBit x s >> >> rotate x _ = x >> >> -- I don't think we gain anything changing this one. >> bit 0 = True >> bit _ = False >> >> testBit x b = tagToEnum# (dataToTag# x `andI#` (dataToTag# b ==# 0#)) >> >> bitSizeMaybe _ = Just 1 >> >> bitSize _ = 1 >> >> isSigned _ = False >> >> popCount x = I# (dataToTag# x) >> >> instance FiniteBits Bool where >> finiteBitSize _ = 1 >> countTrailingZeros x = I# (dataToTag# x `xorI#` 1#) >> countLeadingZeros x = I# (dataToTag# x `xorI#` 1#) >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries From ekmett at gmail.com Mon Sep 29 14:46:49 2014 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 29 Sep 2014 10:46:49 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: We currently as a culture tolerate wildly varying strictness in Num's (+), Applicative's (<*>), Monoid's mappend, etc. Keep in mind the strictness analyzer isn't going to see through those (or this) when you are working polymorphically. Should we require every Monoid's mappend to be strict in both to maybe get a few percentage points improvement on fold when you have a strict container? After all only finitary containers exist, right? But you *can* foldMap over an infinite list with the subset of Monoids that are lazy in their right argument. Folks don't seem to have a problem employing Foldable/Monoid in this scenario in practice, or using foldr to build a lazy natural when they want to do a lazy list length comparison for a list that might be infinite. What distinguishes Bits in this regard? -Edward On Mon, Sep 29, 2014 at 10:14 AM, Anthony Cowley wrote: > On Sun, Sep 28, 2014 at 11:06 PM, Gershom B wrote: > > Did I miss in this thread an actual use-case for strict and/or for Bool > such that it might occur in a tight inner loop? Absent such a use case, I?m > -1 on this proposal. If I wanted to use something that I felt had strict > bitwise behaviour, I?d never reach for a bool, no matter what operator set > I was working with. My instinct would be to reach for a Word8 or the like, > since on any real implementation it would take up the same space regardless? > > > > Essentially, to my laziness-infected brain, the current instance obeys > the principle of least surprise, and the proposed instance violates the > sort of wall of ?abstraction intuitions? I?ve built up regarding when I > should and shouldn?t expect lazy behaviour. > > > > -g > > The problem is that Bool is the odd duck with respect to the Data.Bits > operations, so the only way your intuition would serve you is if you > were sure you would only be working with Bool, in which case the > question is why you were reaching for Data.Bits. > > Anthony > > > > > > > > On September 27, 2014 at 1:59:43 PM, David Feuer (david.feuer at gmail.com) > wrote: > >> Currently, the (.&.) and (.|.) methods for Bool are short-circuiting, > >> defined like this: > >> > >> instance Bits Bool where > >> (.&.) = (&&) > >> > >> (.|.) = (||) > >> > >> Unlike the instances for Int, Word, etc., this gives short-circuiting > >> behavior (conditionally lazy in the second operand). Unfortunately, this > >> requires a conditional branch to implement, which can sometimes be bad. > >> Since (&&) and (||) are readily available to anyone who wants > >> short-circuiting, I propose that we use the following instead. Note that > >> the Bits class does not specify anything about this aspect of instance > >> behavior. > >> > >> x .&. y = tagToEnum# (dataToTag# x `andI#` dataToTag# y) > >> > >> x .|. y = tagToEnum# (dataToTag# x `orI#` dataToTag# y) > >> > >> The rest of the operations look like this: > >> > >> x `xor` y = tagToEnum# (dataToTag# x `xorI#` dataToTag# y) > >> > >> complement x = tagToEnum# (dataToTag# x `xorI#` 1#) > >> > >> shift x s = testBit x s > >> > >> rotate x _ = x > >> > >> -- I don't think we gain anything changing this one. > >> bit 0 = True > >> bit _ = False > >> > >> testBit x b = tagToEnum# (dataToTag# x `andI#` (dataToTag# b ==# 0#)) > >> > >> bitSizeMaybe _ = Just 1 > >> > >> bitSize _ = 1 > >> > >> isSigned _ = False > >> > >> popCount x = I# (dataToTag# x) > >> > >> instance FiniteBits Bool where > >> finiteBitSize _ = 1 > >> countTrailingZeros x = I# (dataToTag# x `xorI#` 1#) > >> countLeadingZeros x = I# (dataToTag# x `xorI#` 1#) > >> _______________________________________________ > >> Libraries mailing list > >> Libraries at haskell.org > >> http://www.haskell.org/mailman/listinfo/libraries > >> > > > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://www.haskell.org/mailman/listinfo/libraries > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Mon Sep 29 15:19:38 2014 From: david.feuer at gmail.com (David Feuer) Date: Mon, 29 Sep 2014 11:19:38 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: On Sep 29, 2014 10:46 AM, "Edward Kmett" wrote: > > We currently as a culture tolerate wildly varying strictness in Num's (+), Applicative's (<*>), Monoid's mappend, etc. > > Keep in mind the strictness analyzer isn't going to see through those (or this) when you are working polymorphically. Do we currently have a convincing case for using *anything* in Bits polymorphically? As far as I can tell, the primary purpose of Bits is to provide a uniform interface to fast bitwise operations on short bitvectors (e.g., Int, Word, etc.) with enough flexibility thrown in to handle things like multi-word bitvectors, and a few other things with varying degrees of grace. Your intuition (which seems generally to be very good) obviously suggests otherwise. I'd be perfectly happy to put this proposal on hold for at least a year to let you figure out what it is that *you* think Bits should be, under two conditions: 1. We add non-short-circuiting and, or, and xor, by some names, somewhere. 2. We explicitly document that the short-circuiting behavior of Bits operations for Bool is as yet completely unspecified and subject to change without notice. > Should we require every Monoid's mappend to be strict in both to maybe get a few percentage points improvement on fold when you have a strict container? ... slippery slope fallacy ... > What distinguishes Bits in this regard? Its purpose. As it was designed, Bits is *not* for the sort of higher-order generalized fun that you love but rather performance hacks with varying levels of ugliness. I'm 100% in favor of higher-order generalized fun classes being available; I just don't thing Bits is supposed to be one of them. David -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Mon Sep 29 15:33:54 2014 From: david.feuer at gmail.com (David Feuer) Date: Mon, 29 Sep 2014 11:33:54 -0400 Subject: Discussion: Change the specification of rotateL for non-finite Bits, or move rotations to FiniteBits In-Reply-To: References: Message-ID: Problem: The documentation currently specifies that for non-finite Bits instances, rotate is the same as shift. This seems reasonable for Integer rotateR, but very strange for Integer rotateL. In particular: rotateL 5 (-1 :: Int) = -1 rotateL 5 (-1 :: Integer) = 16 Based on the concept that Integers represent two's complement out to infinity, rotating a negative integer left should fill with 1s, but it fills with 0s instead. Solutions: As stated in the subject, I think one reasonable solution is just to make rotateL fill with 1s for negative non-finite instances, and the other is to move rotations to FiniteBits, as was done with bitSize. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Mon Sep 29 15:36:57 2014 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 29 Sep 2014 11:36:57 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: On Mon, Sep 29, 2014 at 11:19 AM, David Feuer wrote: > > On Sep 29, 2014 10:46 AM, "Edward Kmett" wrote: > > > > We currently as a culture tolerate wildly varying strictness in Num's > (+), Applicative's (<*>), Monoid's mappend, etc. > > > > Keep in mind the strictness analyzer isn't going to see through those > (or this) when you are working polymorphically. > > Do we currently have a convincing case for using *anything* in Bits > polymorphically? As far as I can tell, the primary purpose of Bits is to > provide a uniform interface to fast bitwise operations on short bitvectors > (e.g., Int, Word, etc.) with enough flexibility thrown in to handle things > like multi-word bitvectors, and a few other things with varying degrees of > grace. Your intuition (which seems generally to be very good) obviously > suggests otherwise. I'd be perfectly happy to put this proposal on hold for > at least a year to let you figure out what it is that *you* think Bits > should be, under two conditions: > > 1. We add non-short-circuiting and, or, and xor, by some names, somewhere. > 2. We explicitly document that the short-circuiting behavior of Bits > operations for Bool is as yet completely unspecified and subject to change > without notice. > I'd go for that. > > Should we require every Monoid's mappend to be strict in both to maybe > get a few percentage points improvement on fold when you have a strict > container? > > ... slippery slope fallacy ... > Touch?. > > What distinguishes Bits in this regard? > > Its purpose. As it was designed, Bits is *not* for the sort of > higher-order generalized fun that you love but rather performance hacks > with varying levels of ugliness. I'm 100% in favor of higher-order > generalized fun classes being available; I just don't thing Bits is > supposed to be one of them. > But if it is only intended for ad hoc overloading at known concrete instances then the uniformity argument doesn't hold. It is really for the higher order "generalized fun" use case that your argument is strongest. ;) -Edward -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Mon Sep 29 15:41:49 2014 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 29 Sep 2014 11:41:49 -0400 Subject: Discussion: Change the specification of rotateL for non-finite Bits, or move rotations to FiniteBits In-Reply-To: References: Message-ID: It does seem like it should rotate in 1s, but if it does so, what happens when it rotates out something that isn't all 1s into a negative number or all 0s into a positive number? We'd expect `rotateL n . rotateR n = id = rotateR n . rotateL n` for the finite cases. but you can't rotate out the digits "up at infinity". So even this is messy. =/ Ideally we *would* move rotate/rotateL/rotateR to FiniteBits, but there is a huge upgrade/migration cost associated with that. All user specified instances break in a way that requires CPP and it diverges from the standard further. On Mon, Sep 29, 2014 at 11:33 AM, David Feuer wrote: > Problem: > > The documentation currently specifies that for non-finite Bits instances, > rotate is the same as shift. This seems reasonable for Integer rotateR, but > very strange for Integer rotateL. In particular: > > rotateL 5 (-1 :: Int) = -1 > rotateL 5 (-1 :: Integer) = 16 > > Based on the concept that Integers represent two's complement out to > infinity, rotating a negative integer left should fill with 1s, but it > fills with 0s instead. > > Solutions: > > As stated in the subject, I think one reasonable solution is just to make > rotateL fill with 1s for negative non-finite instances, and the other is to > move rotations to FiniteBits, as was done with bitSize. > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Mon Sep 29 15:55:25 2014 From: david.feuer at gmail.com (David Feuer) Date: Mon, 29 Sep 2014 11:55:25 -0400 Subject: Discussion: Change the specification of rotateL for non-finite Bits, or move rotations to FiniteBits In-Reply-To: References: Message-ID: On Sep 29, 2014 11:41 AM, "Edward Kmett" wrote: > > It does seem like it should rotate in 1s, but if it does so, what happens when it rotates out something that isn't all 1s into a negative number or all 0s into a positive number? > > We'd expect `rotateL n . rotateR n = id = rotateR n . rotateL n` for the finite cases. > > but you can't rotate out the digits "up at infinity". > > So even this is messy. =/ You're absolutely right. Integer couldn't support that. You could, however, have a Bits instance newtype RotInteger = RotInteger {number::Integer, atInfinity::Integer} That would be able to support rotations into and out of the bits "at infinity". > Ideally we would move rotate/rotateL/rotateR to FiniteBits, but there is a huge upgrade/migration cost associated with that. All user specified instances break in a way that requires CPP and it diverges from the standard further. Well, the approach taken for bitSize would work here too. Deprecate the three names, leaving them in place. Add three new ones to FiniteBits, using correct but somewhat slow defaults (implementing rotations using shifting and masking). The FiniteBits dictionary is already growing from one member to three, so adding another few should be okay, right? -------------- next part -------------- An HTML attachment was scrubbed... URL: From fox at ucw.cz Mon Sep 29 15:58:36 2014 From: fox at ucw.cz (Milan Straka) Date: Mon, 29 Sep 2014 17:58:36 +0200 Subject: Discussion: Change the specification of rotateL for non-finite Bits, or move rotations to FiniteBits In-Reply-To: References: Message-ID: <20140929155836.GA12041@auryn.cz> Hi all, I agree with Edward that although rotate{,L,R} should really live in FiniteBits, it is probably too costly to move them there. When staying in Bits, I find the "rotate is shift for infinite" semantics the most appealing -- rotations do not make really sense for infinite sequences, so I would not pretend they are rotating the sequence. Cheers, Milan > -----Original message----- > From: Edward Kmett > Sent: 29 Sep 2014, 11:41 > > It does seem like it should rotate in 1s, but if it does so, what happens > when it rotates out something that isn't all 1s into a negative number or > all 0s into a positive number? > > We'd expect `rotateL n . rotateR n = id = rotateR n . rotateL n` for the > finite cases. > > but you can't rotate out the digits "up at infinity". > > So even this is messy. =/ > > Ideally we *would* move rotate/rotateL/rotateR to FiniteBits, but there is > a huge upgrade/migration cost associated with that. All user specified > instances break in a way that requires CPP and it diverges from the > standard further. > > > On Mon, Sep 29, 2014 at 11:33 AM, David Feuer wrote: > > > Problem: > > > > The documentation currently specifies that for non-finite Bits instances, > > rotate is the same as shift. This seems reasonable for Integer rotateR, but > > very strange for Integer rotateL. In particular: > > > > rotateL 5 (-1 :: Int) = -1 > > rotateL 5 (-1 :: Integer) = 16 > > > > Based on the concept that Integers represent two's complement out to > > infinity, rotating a negative integer left should fill with 1s, but it > > fills with 0s instead. > > > > Solutions: > > > > As stated in the subject, I think one reasonable solution is just to make > > rotateL fill with 1s for negative non-finite instances, and the other is to > > move rotations to FiniteBits, as was done with bitSize. > > > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://www.haskell.org/mailman/listinfo/libraries > > > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries From gershomb at gmail.com Mon Sep 29 16:21:33 2014 From: gershomb at gmail.com (Gershom B) Date: Mon, 29 Sep 2014 12:21:33 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: On Mon, Sep 29, 2014 at 11:19 AM, David Feuer wrote: > > Do we currently have a convincing case for using *anything* in Bits > polymorphically? As far as I can tell, the primary purpose of Bits is to > provide a uniform interface to fast bitwise operations on short bitvectors > (e.g., Int, Word, etc.) with enough flexibility thrown in to handle things > like multi-word bitvectors, and a few other things with varying degrees of > grace. Your intuition (which seems generally to be very good) obviously > suggests otherwise. I'd be perfectly happy to put this proposal on hold for > at least a year to let you figure out what it is that *you* think Bits > should be, under two conditions: > > 1. We add non-short-circuiting and, or, and xor, by some names, somewhere. > 2. We explicitly document that the short-circuiting behavior of Bits > operations for Bool is as yet completely unspecified and subject to change > without notice. I don't think that bits is designed to "provide a uniform interface to fast bitwise operations on short bitvectors". It is designed to provide uniform operations over datatypes that can be treated as a sequence of bits. In general, it seems to do this just fine. All operations we define in our core libraries, should, by default, have two properties: 1) They are efficient, 2) They are maximally defined; i.e. they produce bottom as infrequently as possible. The latter property, in general, should constrain the former. This proposal is to make a default implementation violate my expectations by asking, in the name of _sometimes_ efficiency, that it be less general than it can be, and produce nonterminating results when _otherwise_ it might terminate. I don't think either condition is necessary. If somebody wants "extra strict" operations on bool, they can define those in an external package. I don't feel it is a common enough use case to go into base. Furthermore, I don't see explicitly documenting that something is subject to change when it may well be that its fine and there's no reason to change it. I can think of three uses for the Bool instance for bits. First, because `xor` may be a more clear name than (/=) for a use of Bool. Second, to test a generic operation on Bits in a minimal context as a "sanity check". Third, because I may wish to write _logical operations_ in a manner polymorphic over my "bool-like" type. In the first two cases, the existing behaviour is fine. In the last case, it is a net positive. In the continued absence of any good arguments for why we _should_ make this change, at this point I'm a firm -1. -g From acowley at seas.upenn.edu Mon Sep 29 16:32:10 2014 From: acowley at seas.upenn.edu (Anthony Cowley) Date: Mon, 29 Sep 2014 12:32:10 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: <59203F5E-2707-4C00-B185-182C5127EBA9@seas.upenn.edu> Part of what distinguishes Bits here is specifically what we're discussing. There is some level of agreement that there should be a non-short-circuiting operation on Bool somewhere, and the proposal points out that such a thing fits into Bits quite well because it is consistent with other Bits instances. It happens that this also suits my intuition about the use of bitwise operations, and that turning to Bits suggests that the programmer is digging a bit deeper into a representation than is perhaps usual. Since different folks have different intuitions, however, I think a vote is the only useful way forward. To be clear, I very much like the idea of having generalized and- (and or-)like operations that are short-circuiting, and appreciate that the dearth of operator symbols is a nuisance (my EDSLs are indeed littered with various and'-ish corruptions). But it is not apparent to me that the right solution should involve a redesign of Bits as you've sketched. This is hard, though: while I sympathize with you not wanting to moot your future proposal yet, this veers rather close to a kind of individual veto power that I'm not sure is fair. I don't think there is any specific rush for the original proposal, so would it be possible to try to tackle both of these issues in the near future so that we might aim for a better holistic solution? Anthony > On Sep 29, 2014, at 10:46 AM, Edward Kmett wrote: > > We currently as a culture tolerate wildly varying strictness in Num's (+), Applicative's (<*>), Monoid's mappend, etc. > > Keep in mind the strictness analyzer isn't going to see through those (or this) when you are working polymorphically. > > Should we require every Monoid's mappend to be strict in both to maybe get a few percentage points improvement on fold when you have a strict container? > > After all only finitary containers exist, right? > > But you can foldMap over an infinite list with the subset of Monoids that are lazy in their right argument. Folks don't seem to have a problem employing Foldable/Monoid in this scenario in practice, or using foldr to build a lazy natural when they want to do a lazy list length comparison for a list that might be infinite. > > What distinguishes Bits in this regard? > > -Edward > >> On Mon, Sep 29, 2014 at 10:14 AM, Anthony Cowley wrote: >> On Sun, Sep 28, 2014 at 11:06 PM, Gershom B wrote: >> > Did I miss in this thread an actual use-case for strict and/or for Bool such that it might occur in a tight inner loop? Absent such a use case, I?m -1 on this proposal. If I wanted to use something that I felt had strict bitwise behaviour, I?d never reach for a bool, no matter what operator set I was working with. My instinct would be to reach for a Word8 or the like, since on any real implementation it would take up the same space regardless? >> > >> > Essentially, to my laziness-infected brain, the current instance obeys the principle of least surprise, and the proposed instance violates the sort of wall of ?abstraction intuitions? I?ve built up regarding when I should and shouldn?t expect lazy behaviour. >> > >> > -g >> >> The problem is that Bool is the odd duck with respect to the Data.Bits >> operations, so the only way your intuition would serve you is if you >> were sure you would only be working with Bool, in which case the >> question is why you were reaching for Data.Bits. >> >> Anthony >> >> >> > >> > >> > On September 27, 2014 at 1:59:43 PM, David Feuer (david.feuer at gmail.com) wrote: >> >> Currently, the (.&.) and (.|.) methods for Bool are short-circuiting, >> >> defined like this: >> >> >> >> instance Bits Bool where >> >> (.&.) = (&&) >> >> >> >> (.|.) = (||) >> >> >> >> Unlike the instances for Int, Word, etc., this gives short-circuiting >> >> behavior (conditionally lazy in the second operand). Unfortunately, this >> >> requires a conditional branch to implement, which can sometimes be bad. >> >> Since (&&) and (||) are readily available to anyone who wants >> >> short-circuiting, I propose that we use the following instead. Note that >> >> the Bits class does not specify anything about this aspect of instance >> >> behavior. >> >> >> >> x .&. y = tagToEnum# (dataToTag# x `andI#` dataToTag# y) >> >> >> >> x .|. y = tagToEnum# (dataToTag# x `orI#` dataToTag# y) >> >> >> >> The rest of the operations look like this: >> >> >> >> x `xor` y = tagToEnum# (dataToTag# x `xorI#` dataToTag# y) >> >> >> >> complement x = tagToEnum# (dataToTag# x `xorI#` 1#) >> >> >> >> shift x s = testBit x s >> >> >> >> rotate x _ = x >> >> >> >> -- I don't think we gain anything changing this one. >> >> bit 0 = True >> >> bit _ = False >> >> >> >> testBit x b = tagToEnum# (dataToTag# x `andI#` (dataToTag# b ==# 0#)) >> >> >> >> bitSizeMaybe _ = Just 1 >> >> >> >> bitSize _ = 1 >> >> >> >> isSigned _ = False >> >> >> >> popCount x = I# (dataToTag# x) >> >> >> >> instance FiniteBits Bool where >> >> finiteBitSize _ = 1 >> >> countTrailingZeros x = I# (dataToTag# x `xorI#` 1#) >> >> countLeadingZeros x = I# (dataToTag# x `xorI#` 1#) >> >> _______________________________________________ >> >> Libraries mailing list >> >> Libraries at haskell.org >> >> http://www.haskell.org/mailman/listinfo/libraries >> >> >> > >> > _______________________________________________ >> > Libraries mailing list >> > Libraries at haskell.org >> > http://www.haskell.org/mailman/listinfo/libraries >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Mon Sep 29 16:39:59 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Mon, 29 Sep 2014 12:39:59 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: <59203F5E-2707-4C00-B185-182C5127EBA9@seas.upenn.edu> References: <59203F5E-2707-4C00-B185-182C5127EBA9@seas.upenn.edu> Message-ID: On Mon, Sep 29, 2014 at 12:32 PM, Anthony Cowley wrote: > Part of what distinguishes Bits here is specifically what we're > discussing. There is some level of agreement that there should be a > non-short-circuiting operation on Bool somewhere, and the proposal points > out that such a thing fits into Bits quite well because it is consistent > with other Bits instances. It happens that this also suits my intuition > about the use of bitwise operations, and that turning to Bits suggests that > the programmer is digging a bit deeper into a representation than is > perhaps usual. Since different folks have different intuitions, however, I > think a vote is the only useful way forward. Maybe I should just formally propose newtype Bit = Bit { unBit :: Bool } with the appropriate derived instances, and a strict Bits instance. The distinction between Bit and Bool also seems to fit my intuitions. -- 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 acowley at seas.upenn.edu Mon Sep 29 16:40:44 2014 From: acowley at seas.upenn.edu (Anthony Cowley) Date: Mon, 29 Sep 2014 12:40:44 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: <0F045C0C-54BD-449E-89A1-A42F163BFFAB@seas.upenn.edu> > On Sep 29, 2014, at 12:21 PM, Gershom B wrote: > >> On Mon, Sep 29, 2014 at 11:19 AM, David Feuer wrote: >> >> Do we currently have a convincing case for using *anything* in Bits >> polymorphically? As far as I can tell, the primary purpose of Bits is to >> provide a uniform interface to fast bitwise operations on short bitvectors >> (e.g., Int, Word, etc.) with enough flexibility thrown in to handle things >> like multi-word bitvectors, and a few other things with varying degrees of >> grace. Your intuition (which seems generally to be very good) obviously >> suggests otherwise. I'd be perfectly happy to put this proposal on hold for >> at least a year to let you figure out what it is that *you* think Bits >> should be, under two conditions: >> >> 1. We add non-short-circuiting and, or, and xor, by some names, somewhere. >> 2. We explicitly document that the short-circuiting behavior of Bits >> operations for Bool is as yet completely unspecified and subject to change >> without notice. > > I don't think that bits is designed to "provide a uniform interface to > fast bitwise operations on short bitvectors". It is designed to > provide uniform operations over datatypes that can be treated as a > sequence of bits. In general, it seems to do this just fine. All > operations we define in our core libraries, should, by default, have > two properties: 1) They are efficient, 2) They are maximally defined; > i.e. they produce bottom as infrequently as possible. The latter > property, in general, should constrain the former. This proposal is to > make a default implementation violate my expectations by asking, in > the name of _sometimes_ efficiency, that it be less general than it > can be, and produce nonterminating results when _otherwise_ it might > terminate. Are you then proposing that we make the other Bits instances lazier? Your argument is well-stated, and this discussion is quite interesting, so I really don't mean that question rhetorically. We clearly could test an individual CInt before applying a binary operation, and I support the notion of adding such an operation somewhere. But I wouldn't support removing the current behavior, which is why I then come down on Bool differently than you. Anthony > > I don't think either condition is necessary. If somebody wants "extra > strict" operations on bool, they can define those in an external > package. I don't feel it is a common enough use case to go into base. > Furthermore, I don't see explicitly documenting that something is > subject to change when it may well be that its fine and there's no > reason to change it. > > I can think of three uses for the Bool instance for bits. First, > because `xor` may be a more clear name than (/=) for a use of Bool. > Second, to test a generic operation on Bits in a minimal context as a > "sanity check". Third, because I may wish to write _logical > operations_ in a manner polymorphic over my "bool-like" type. In the > first two cases, the existing behaviour is fine. In the last case, it > is a net positive. > > In the continued absence of any good arguments for why we _should_ > make this change, at this point I'm a firm -1. > > -g From acowley at seas.upenn.edu Mon Sep 29 16:50:33 2014 From: acowley at seas.upenn.edu (Anthony Cowley) Date: Mon, 29 Sep 2014 12:50:33 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <59203F5E-2707-4C00-B185-182C5127EBA9@seas.upenn.edu> Message-ID: > On Sep 29, 2014, at 12:39 PM, Brandon Allbery wrote: > >> On Mon, Sep 29, 2014 at 12:32 PM, Anthony Cowley wrote: >> Part of what distinguishes Bits here is specifically what we're discussing. There is some level of agreement that there should be a non-short-circuiting operation on Bool somewhere, and the proposal points out that such a thing fits into Bits quite well because it is consistent with other Bits instances. It happens that this also suits my intuition about the use of bitwise operations, and that turning to Bits suggests that the programmer is digging a bit deeper into a representation than is perhaps usual. Since different folks have different intuitions, however, I think a vote is the only useful way forward. > > Maybe I should just formally propose > > newtype Bit = Bit { unBit :: Bool } > > with the appropriate derived instances, and a strict Bits instance. The distinction between Bit and Bool also seems to fit my intuitions. > Yes, the differing opinions make the newtype introduction appealing, but if Bits is eventually made lazier to support generalized short-circuiting, will this then be a wart there? I've really liked a lot of the points I've seen from both sides of this debate, so it'd be great to navigate the branchy vs branchless crossroads with a bit of style. Anthony > -- > 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 allbery.b at gmail.com Mon Sep 29 16:54:32 2014 From: allbery.b at gmail.com (Brandon Allbery) Date: Mon, 29 Sep 2014 12:54:32 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <59203F5E-2707-4C00-B185-182C5127EBA9@seas.upenn.edu> Message-ID: On Mon, Sep 29, 2014 at 12:50 PM, Anthony Cowley wrote: > Yes, the differing opinions make the newtype introduction appealing, but > if Bits is eventually made lazier to support generalized short-circuiting, > will this then be a wart there? I've really liked a lot of the points I've > seen from both sides of this debate, so it'd be great to navigate the > branchy vs branchless crossroads with a bit of style. I think the point is that this exactly addresses that: people who want the spine strictness of the existing Bits instances get it for Bool via the newtype and corresponding strict Bits instance (and maybe other instances), people who want laziness get it via Bool --- and this also advances the cause of generalizing existing Bool-related things, since the next obvious thing to do is make it possible to use && and || on a typeclass instead of hardcoded for Bool, so they can be extended to Bit. -- 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 david.feuer at gmail.com Mon Sep 29 18:01:45 2014 From: david.feuer at gmail.com (David Feuer) Date: Mon, 29 Sep 2014 14:01:45 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <59203F5E-2707-4C00-B185-182C5127EBA9@seas.upenn.edu> Message-ID: I don't think this newtype idea is likely to work out so beautifully. The main problem is that real code is likely to do a lot of mixing and matching of short-circuit and non-short-circuit code. The newtype concept requires a lot of wrapping and unwrapping to express that, and trying out different approaches to find the fastest leads to a lot of complicated wrapper rearrangement. On Mon, Sep 29, 2014 at 12:54 PM, Brandon Allbery wrote: > On Mon, Sep 29, 2014 at 12:50 PM, Anthony Cowley > wrote: >> >> Yes, the differing opinions make the newtype introduction appealing, but >> if Bits is eventually made lazier to support generalized short-circuiting, >> will this then be a wart there? I've really liked a lot of the points I've >> seen from both sides of this debate, so it'd be great to navigate the >> branchy vs branchless crossroads with a bit of style. > > > I think the point is that this exactly addresses that: people who want the > spine strictness of the existing Bits instances get it for Bool via the > newtype and corresponding strict Bits instance (and maybe other instances), > people who want laziness get it via Bool --- and this also advances the > cause of generalizing existing Bool-related things, since the next obvious > thing to do is make it possible to use && and || on a typeclass instead of > hardcoded for Bool, so they can be extended to Bit. > > -- > brandon s allbery kf8nh sine nomine associates > allbery.b at gmail.com ballbery at sinenomine.net > unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > From david.feuer at gmail.com Mon Sep 29 18:28:23 2014 From: david.feuer at gmail.com (David Feuer) Date: Mon, 29 Sep 2014 14:28:23 -0400 Subject: Discussion: Change the specification of rotateL for non-finite Bits, or move rotations to FiniteBits In-Reply-To: <20140929155836.GA12041@auryn.cz> References: <20140929155836.GA12041@auryn.cz> Message-ID: Thinking about this some more, I ran into something else to chew on. It would seem to make a certain amount of sense to have instance (Bits b) => Bits (Seq b) with .&., .|., and xor defined using a zero-prepending zipWith variant. but there are a few challenges relating to size. Specifically: 1. The specification indicates that finiteBitSize and bitSizeMaybe are supposed to return a result based only on the type of their argument. Clearly, that will not work for this. 2. There is no obviously correct size to use for zeroBits and bit. One approach, of course, is to define something wonky like newtype SeqN (n::Nat) a = SeqN (Seq a) and then use instance (Bits b) => Bits (SeqN n b) but that gives a different, more limited type than one might expect. From jwlato at gmail.com Mon Sep 29 19:10:50 2014 From: jwlato at gmail.com (John Lato) Date: Mon, 29 Sep 2014 12:10:50 -0700 Subject: Discussion: Change the specification of rotateL for non-finite Bits, or move rotations to FiniteBits In-Reply-To: References: <20140929155836.GA12041@auryn.cz> Message-ID: Do you have a use case for this instance? I don't think I would ever want it. Also I think the behavior is too unspecified, and trying to specify it more precisely will inevitably lead to a much less useful instance. In this instance I might prefer we focus on problems we have already rather make new ones. Also +1 for rotate acting like shift for infinite types, for the reasons Milan gave. John L. On Sep 29, 2014 11:28 AM, "David Feuer" wrote: > Thinking about this some more, I ran into something else to chew on. > It would seem to make a certain amount of sense to have > > instance (Bits b) => Bits (Seq b) > > with .&., .|., and xor defined using a zero-prepending zipWith variant. > > but there are a few challenges relating to size. Specifically: > > 1. The specification indicates that finiteBitSize and bitSizeMaybe are > supposed to return a result based only on the type of their argument. > Clearly, that will not work for this. > 2. There is no obviously correct size to use for zeroBits and bit. > > One approach, of course, is to define something wonky like > > newtype SeqN (n::Nat) a = SeqN (Seq a) > > and then use > > instance (Bits b) => Bits (SeqN n b) > > but that gives a different, more limited type than one might expect. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Mon Sep 29 19:54:50 2014 From: david.feuer at gmail.com (David Feuer) Date: Mon, 29 Sep 2014 15:54:50 -0400 Subject: Discussion: Change the specification of rotateL for non-finite Bits, or move rotations to FiniteBits In-Reply-To: References: <20140929155836.GA12041@auryn.cz> Message-ID: No particular use case. Just trying to look at where the boundaries lie. I think rejecting such things is an argument for putting rotations in `FiniteBits`, though. On Mon, Sep 29, 2014 at 3:10 PM, John Lato wrote: > Do you have a use case for this instance? I don't think I would ever want > it. Also I think the behavior is too unspecified, and trying to specify it > more precisely will inevitably lead to a much less useful instance. In this > instance I might prefer we focus on problems we have already rather make new > ones. > > Also +1 for rotate acting like shift for infinite types, for the reasons > Milan gave. > > John L. > > On Sep 29, 2014 11:28 AM, "David Feuer" wrote: >> >> Thinking about this some more, I ran into something else to chew on. >> It would seem to make a certain amount of sense to have >> >> instance (Bits b) => Bits (Seq b) >> >> with .&., .|., and xor defined using a zero-prepending zipWith variant. >> >> but there are a few challenges relating to size. Specifically: >> >> 1. The specification indicates that finiteBitSize and bitSizeMaybe are >> supposed to return a result based only on the type of their argument. >> Clearly, that will not work for this. >> 2. There is no obviously correct size to use for zeroBits and bit. >> >> One approach, of course, is to define something wonky like >> >> newtype SeqN (n::Nat) a = SeqN (Seq a) >> >> and then use >> >> instance (Bits b) => Bits (SeqN n b) >> >> but that gives a different, more limited type than one might expect. >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries From ekmett at gmail.com Mon Sep 29 20:47:05 2014 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 29 Sep 2014 16:47:05 -0400 Subject: Discussion: Change the specification of rotateL for non-finite Bits, or move rotations to FiniteBits In-Reply-To: References: <20140929155836.GA12041@auryn.cz> Message-ID: Seq Bool and [Bool] aren't really correct Bits instances, let alone Bits a => Bits (Seq a) (the latter really only even starts to make sense for FiniteBits a => Bits (Seq a), because you have to enumerate bits. I also think defining such SeqN types (which _are_ legal) should really be left up to the end user if they want them. There are lots of points in the design space (Do you trim excess 0-bit only entries from on the right? Leave them? etc.) it involves messy types, and there is little to be gained by standardizing on one of them. We don't have to include everything someone may someday want in base. -Edward On Mon, Sep 29, 2014 at 2:28 PM, David Feuer wrote: > Thinking about this some more, I ran into something else to chew on. > It would seem to make a certain amount of sense to have > > instance (Bits b) => Bits (Seq b) > > with .&., .|., and xor defined using a zero-prepending zipWith variant. > > but there are a few challenges relating to size. Specifically: > > 1. The specification indicates that finiteBitSize and bitSizeMaybe are > supposed to return a result based only on the type of their argument. > Clearly, that will not work for this. > 2. There is no obviously correct size to use for zeroBits and bit. > > One approach, of course, is to define something wonky like > > newtype SeqN (n::Nat) a = SeqN (Seq a) > > and then use > > instance (Bits b) => Bits (SeqN n b) > > but that gives a different, more limited type than one might expect. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwlato at gmail.com Mon Sep 29 20:47:49 2014 From: jwlato at gmail.com (John Lato) Date: Mon, 29 Sep 2014 13:47:49 -0700 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: <54295C66.6080508@gmail.com> References: <54295C66.6080508@gmail.com> Message-ID: On Sep 29, 2014 6:19 AM, "Felipe Lessa" wrote: > > On 28-09-2014 22:38, John Lato wrote: > > I don't think we should be encouraging the use of Data.Sequence for file > > paths. An opaque OS-specific structure seems like the natural choice IMHO. > > > > (Incidentally I'd like to develop this as a userland library, if anyone > > would step forward to help with the Windows-specific stuff) > > Do you mean system-filepath [1]? No. The api is ok, but performance is terrible because everything is a String. Traversing large directories in Haskell is orders of magnitude slower than it should be (unless you use posix-paths, which obviously isn't portable). I mean something that internally uses a RawFilePath on posix systems and some windows-specific thing on Windows. -------------- next part -------------- An HTML attachment was scrubbed... URL: From greg at gregweber.info Mon Sep 29 21:31:56 2014 From: greg at gregweber.info (Greg Weber) Date: Mon, 29 Sep 2014 14:31:56 -0700 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: <54295C66.6080508@gmail.com> Message-ID: > > > > Do you mean system-filepath [1]? > > No. The api is ok, but performance is terrible because everything is a > String. Traversing large directories in Haskell is orders of magnitude > slower than it should be (unless you use posix-paths, which obviously isn't > portable). I mean something that internally uses a RawFilePath on posix > systems and some windows-specific thing on Windows. > > I don't know how to reconcile this statement with how find-conduit was benchmarked to operate about as fast as GNU grep since it uses system-filepath. I am probably missing something important. http://hackage.haskell.org/package/find-conduit-0.4.1/docs/Data-Conduit-Find.html#t:FileEntry > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From spam at scientician.net Mon Sep 29 21:50:35 2014 From: spam at scientician.net (Bardur Arantsson) Date: Mon, 29 Sep 2014 23:50:35 +0200 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: <54295C66.6080508@gmail.com> Message-ID: On 2014-09-29 23:31, Greg Weber wrote: >> >> >>> Do you mean system-filepath [1]? >> >> No. The api is ok, but performance is terrible because everything is a >> String. Traversing large directories in Haskell is orders of magnitude >> slower than it should be (unless you use posix-paths, which obviously isn't >> portable). I mean something that internally uses a RawFilePath on posix >> systems and some windows-specific thing on Windows. >> >> > I don't know how to reconcile this statement with how find-conduit was > benchmarked to operate about as fast as GNU grep since it uses > system-filepath. I am probably missing something important. > http://hackage.haskell.org/package/find-conduit-0.4.1/docs/Data-Conduit-Find.html#t:FileEntry > I'm not seeing exactly what "grep" has to do with "find"...? Did you mean to compare GNU find with "find-conduit"? Regards, From greg at gregweber.info Mon Sep 29 22:11:04 2014 From: greg at gregweber.info (Greg Weber) Date: Mon, 29 Sep 2014 15:11:04 -0700 (PDT) Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: References: Message-ID: <1412028664463.59b67857@Nodemailer> Yep, I didn't understand what was going on. The fast version of find-conduit was using a raw file path ? Sent from Mailbox On Mon, Sep 29, 2014 at 2:50 PM, Bardur Arantsson wrote: > On 2014-09-29 23:31, Greg Weber wrote: >>> >>> >>>> Do you mean system-filepath [1]? >>> >>> No. The api is ok, but performance is terrible because everything is a >>> String. Traversing large directories in Haskell is orders of magnitude >>> slower than it should be (unless you use posix-paths, which obviously isn't >>> portable). I mean something that internally uses a RawFilePath on posix >>> systems and some windows-specific thing on Windows. >>> >>> >> I don't know how to reconcile this statement with how find-conduit was >> benchmarked to operate about as fast as GNU grep since it uses >> system-filepath. I am probably missing something important. >> http://hackage.haskell.org/package/find-conduit-0.4.1/docs/Data-Conduit-Find.html#t:FileEntry >> > I'm not seeing exactly what "grep" has to do with "find"...? > Did you mean to compare GNU find with "find-conduit"? > Regards, > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From jwlato at gmail.com Mon Sep 29 22:18:24 2014 From: jwlato at gmail.com (John Lato) Date: Mon, 29 Sep 2014 15:18:24 -0700 Subject: Pre-proposal discussion: add a version of dropWhileEnd with different laziness properties to Data.List In-Reply-To: <1412028664463.59b67857@Nodemailer> References: <1412028664463.59b67857@Nodemailer> Message-ID: So I'm understanding this properly, there is a fast version of find-conduit that uses RawFilePath, and the regular find-conduit that uses system-filepath? Are there benchmarks published that compare the two? On Sep 29, 2014 3:11 PM, "Greg Weber" wrote: > Yep, I didn't understand what was going on. The fast version of > find-conduit was using a raw file path > ? > Sent from Mailbox > > > On Mon, Sep 29, 2014 at 2:50 PM, Bardur Arantsson > wrote: > >> On 2014-09-29 23:31, Greg Weber wrote: >> >> >> >> >> >>> Do you mean system-filepath [1]? >> >> >> >> No. The api is ok, but performance is terrible because everything is a >> >> String. Traversing large directories in Haskell is orders of magnitude >> >> slower than it should be (unless you use posix-paths, which obviously >> isn't >> >> portable). I mean something that internally uses a RawFilePath on >> posix >> >> systems and some windows-specific thing on Windows. >> >> >> >> >> > I don't know how to reconcile this statement with how find-conduit was >> > benchmarked to operate about as fast as GNU grep since it uses >> > system-filepath. I am probably missing something important. >> > >> http://hackage.haskell.org/package/find-conduit-0.4.1/docs/Data-Conduit-Find.html#t:FileEntry >> > >> >> I'm not seeing exactly what "grep" has to do with "find"...? >> >> Did you mean to compare GNU find with "find-conduit"? >> >> Regards, >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://www.haskell.org/mailman/listinfo/libraries >> > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://www.haskell.org/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From winterkoninkje at gmail.com Tue Sep 30 22:59:14 2014 From: winterkoninkje at gmail.com (wren romano) Date: Tue, 30 Sep 2014 18:59:14 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: <20140928100643.GA4876@auryn.cz> Message-ID: On Sun, Sep 28, 2014 at 2:45 PM, David Feuer wrote: > I would think what you're trying to do would likely be better with a > different class, by another name, supporting things like .&&., .||., etc., > or maybe even moving && and || into a class. Another direction is to look at > structures representing other sorts of logics. I just don't see that > Data.Bits is the right place to try to do these things. I agree. The *current* use of (.&.) and (.|.) is for capturing strict bitops and doing so as quickly as possible by trying to map them onto CPU instructions. IMO it makes sense to codify this behavior as part of the intention/goal of the Bits class. I'll gladly take the 10% if I can get it, because that's what bit twiddling is all about. The shortcircuiting behavior of (&&) and (||) is also nice to have on hand, but it's currently restricted to Bool. If we want to generalize this behavior to other types, then it makes sense to introduce a separate class for generalizing these boolean operators. Doing so would (a) allow greater consistency of the Bit instances, and (b) allow other logical operators of a similar shortcircuitable nature without assuming that the shortcircuiting logic ops are at all related to the strict bitvector ops. -- Live well, ~wren From winterkoninkje at gmail.com Tue Sep 30 23:24:03 2014 From: winterkoninkje at gmail.com (wren romano) Date: Tue, 30 Sep 2014 19:24:03 -0400 Subject: Proposal: change the Bits instance for Bool to align with other basic types and support branchless calculations In-Reply-To: References: Message-ID: On Mon, Sep 29, 2014 at 12:21 PM, Gershom B wrote: > I can think of three uses for the Bool instance for bits. First, > because `xor` may be a more clear name than (/=) for a use of Bool. > Second, to test a generic operation on Bits in a minimal context as a > "sanity check". Third, because I may wish to write _logical > operations_ in a manner polymorphic over my "bool-like" type. In the > first two cases, the existing behaviour is fine. In the last case, it > is a net positive. I agree about the desire to abstract over lattices so we can write logic programs over generalized truth values. However, this is not what the Bits class gives us. Most of the operations explicitly assume we're working with bitvectors. Some of these operations (bit, setBit, clearBit,...) can be argued to make sense for any complete Boolean algebra, but doing so requires an arbitrary mapping between atoms and Int. Other operations (shift, rotate,...) don't make sense with arbitrary Int--atom mappings because they rely on an ordering of atoms (as given by the ordering of Int). Moreover, being intuitionists, if we were to codify lattices as a type class then we'd surely want to have a class for Heyting algebras, and then have Boolean algebras as a subclass. -- Live well, ~wren