From eacameron at gmail.com Sat Jun 1 13:31:02 2019 From: eacameron at gmail.com (Elliot Cameron) Date: Sat, 1 Jun 2019 09:31:02 -0400 Subject: Memory Barriers with STM and MVar In-Reply-To: References: Message-ID: For my education, can you describe your use case a bit more? Using MVar as you did in your example seems like a strange use case. Normally you'd just put the pointer to the structure in the MVar itself. -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew.thaddeus at gmail.com Sat Jun 1 14:11:20 2019 From: andrew.thaddeus at gmail.com (Andrew Martin) Date: Sat, 1 Jun 2019 10:11:20 -0400 Subject: Memory Barriers with STM and MVar In-Reply-To: References: Message-ID: What I'm doing is using STM (but it could be done with MVar instead) to guard access to a rotating queue that is a large mmapped region of memory (in my situation, it also happens to be backed by a file on disk). There can only be one writer at a time. There can be many readers, but the readers cannot read from the head of the queue if the writer is still working on it. They must wait until the writer is finished. So, every thread has the same base address and then they are all working at different offsets into the queue. But when the writer tries to tell the readers "I'm done writing to this area", how can I be sure that the readers will actually see the writes to memory? That's the difficulty I'm having. On Sat, Jun 1, 2019 at 9:31 AM Elliot Cameron wrote: > For my education, can you describe your use case a bit more? Using MVar as > you did in your example seems like a strange use case. Normally you'd just > put the pointer to the structure in the MVar itself. > -- -Andrew Thaddeus Martin -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew.thaddeus at gmail.com Mon Jun 3 15:34:12 2019 From: andrew.thaddeus at gmail.com (Andrew Martin) Date: Mon, 3 Jun 2019 11:34:12 -0400 Subject: Memory Barriers with STM and MVar In-Reply-To: References: Message-ID: After thinking about this more, it appears that a store-store barrier (not a store-load barrier) is actually sufficient for this. I just need to be sure that other threads see the writes to memory before the writes to the MVar (or before whatever STM writes to when atomically completes). However, I don't see any calls to write_barrier in the STM code or in the MVar code, so GHC may not currently provide the behavior I am looking for. On Sat, Jun 1, 2019 at 10:11 AM Andrew Martin wrote: > What I'm doing is using STM (but it could be done with MVar instead) to > guard access to a rotating queue that is a large mmapped region of memory > (in my situation, it also happens to be backed by a file on disk). There > can only be one writer at a time. There can be many readers, but the > readers cannot read from the head of the queue if the writer is still > working on it. They must wait until the writer is finished. So, every > thread has the same base address and then they are all working at different > offsets into the queue. But when the writer tries to tell the readers "I'm > done writing to this area", how can I be sure that the readers will > actually see the writes to memory? That's the difficulty I'm having. > > On Sat, Jun 1, 2019 at 9:31 AM Elliot Cameron wrote: > >> For my education, can you describe your use case a bit more? Using MVar >> as you did in your example seems like a strange use case. Normally you'd >> just put the pointer to the structure in the MVar itself. >> > > > -- > -Andrew Thaddeus Martin > -- -Andrew Thaddeus Martin -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Tue Jun 4 00:57:55 2019 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Mon, 3 Jun 2019 20:57:55 -0400 Subject: Memory Barriers with STM and MVar In-Reply-To: References: Message-ID: you could use the STM based sleep where the try to read an STMvar and then retry to sleep until the write was done if you only care about AMD64, https://en.wikipedia.org/wiki/Memory_ordering#In_symmetric_multiprocessing_(SMP)_microprocessor_systems , you're probably not going to have the issues I think you're worrying about other platforms, ehhhhh On Mon, Jun 3, 2019 at 11:34 AM Andrew Martin wrote: > After thinking about this more, it appears that a store-store barrier (not > a store-load barrier) is actually sufficient for this. I just need to be > sure that other threads see the writes to memory before the writes to the > MVar (or before whatever STM writes to when atomically completes). However, > I don't see any calls to write_barrier in the STM code or in the MVar code, > so GHC may not currently provide the behavior I am looking for. > > On Sat, Jun 1, 2019 at 10:11 AM Andrew Martin > wrote: > >> What I'm doing is using STM (but it could be done with MVar instead) to >> guard access to a rotating queue that is a large mmapped region of memory >> (in my situation, it also happens to be backed by a file on disk). There >> can only be one writer at a time. There can be many readers, but the >> readers cannot read from the head of the queue if the writer is still >> working on it. They must wait until the writer is finished. So, every >> thread has the same base address and then they are all working at different >> offsets into the queue. But when the writer tries to tell the readers "I'm >> done writing to this area", how can I be sure that the readers will >> actually see the writes to memory? That's the difficulty I'm having. >> >> On Sat, Jun 1, 2019 at 9:31 AM Elliot Cameron >> wrote: >> >>> For my education, can you describe your use case a bit more? Using MVar >>> as you did in your example seems like a strange use case. Normally you'd >>> just put the pointer to the structure in the MVar itself. >>> >> >> >> -- >> -Andrew Thaddeus Martin >> > > > -- > -Andrew Thaddeus Martin > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ndospark320 at gmail.com Tue Jun 4 03:11:19 2019 From: ndospark320 at gmail.com (Dannyu NDos) Date: Tue, 4 Jun 2019 12:11:19 +0900 Subject: add instance Monad (Arg a) Message-ID: I think it's reasonable to make Arg as a writer monad with alternate ordering. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ndospark320 at gmail.com Wed Jun 5 07:45:17 2019 From: ndospark320 at gmail.com (Dannyu NDos) Date: Wed, 5 Jun 2019 16:45:17 +0900 Subject: Laws for Show and Read? Message-ID: Shouldn't it be laws that "show" must be injective and "read" must be surjective? Without such laws, one could define: data Foo = Foo instance Show Foo where show _ _ = id instance Read Foo where readPrec = pfail which should be prevented. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ndospark320 at gmail.com Wed Jun 5 07:47:05 2019 From: ndospark320 at gmail.com (Dannyu NDos) Date: Wed, 5 Jun 2019 16:47:05 +0900 Subject: Laws for Show and Read? In-Reply-To: References: Message-ID: In the instance Show Foo, I mean "showsPrec" rather than "show". 2019년 6월 5일 (수) 16:45, Dannyu NDos 님이 작성: > Shouldn't it be laws that "show" must be injective and "read" must be > surjective? Without such laws, one could define: > > data Foo = Foo > instance Show Foo where > show _ _ = id > instance Read Foo where > readPrec = pfail > > which should be prevented. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at nh2.me Wed Jun 5 14:18:17 2019 From: mail at nh2.me (=?UTF-8?Q?Niklas_Hamb=c3=bcchen?=) Date: Wed, 5 Jun 2019 16:18:17 +0200 Subject: Laws for Show and Read? In-Reply-To: References: Message-ID: > Shouldn't it be laws that "show" must be injective and "read" must be surjective? My opinion (and that of many others) is that * Show and Read should be used only for debugging purposes or things that directly relate to Haskell data types when written as literals * whenever possible, use only the GHC-derived instances for those * for all other use cases, different explicit parsers or pretty-printers should be used. The GHC-derived instances also automatically make your desired laws mostly hold. Injectivity seems a bit off, given that e.g. (read "3" :: Int) == (read " 3 " :: Int) so whitespace stripping, parentheses etc. allow different inputs to map to same outputs. Niklas From lysxia at gmail.com Wed Jun 5 14:32:52 2019 From: lysxia at gmail.com (Li-yao Xia) Date: Wed, 5 Jun 2019 10:32:52 -0400 Subject: Laws for Show and Read? In-Reply-To: References: Message-ID: Hi Dannyu, On 6/5/19 3:45 AM, Dannyu NDos wrote: > Shouldn't it be laws that "show" must be injective and "read" must be > surjective? Without such laws, one could define: > > data Foo = Foo > instance Show Foo where > show _ _ = id > instance Read Foo where > readPrec = pfail > > which should be prevented. This doesn't look like something anyone would ever want to do, even out of ignorance. So that example is not really compelling. What is your general motivation to add "laws" to Show and Read? Li-yao From david.feuer at gmail.com Wed Jun 5 15:02:03 2019 From: david.feuer at gmail.com (David Feuer) Date: Wed, 5 Jun 2019 11:02:03 -0400 Subject: Laws for Show and Read? In-Reply-To: References: Message-ID: We already have the law read . show = id which implies the injectivity and surjectivity conditions you specify. On Wed, Jun 5, 2019, 3:45 AM Dannyu NDos wrote: > Shouldn't it be laws that "show" must be injective and "read" must be > surjective? Without such laws, one could define: > > data Foo = Foo > instance Show Foo where > show _ _ = id > instance Read Foo where > readPrec = pfail > > which should be prevented. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From svenpanne at gmail.com Wed Jun 5 18:55:58 2019 From: svenpanne at gmail.com (Sven Panne) Date: Wed, 5 Jun 2019 20:55:58 +0200 Subject: Laws for Show and Read? In-Reply-To: References: Message-ID: Am Mi., 5. Juni 2019 um 17:02 Uhr schrieb David Feuer : > We already have the law > > read . show = id > > which implies the injectivity and surjectivity conditions you specify. > I think this doesn't hold for the standard Read/Show instances for Double/Float: IEEE-754 NaNs have a sign bit and a payload, and both parts are probably lost by the "read . show"-combination. The 2 infinities are probably OK, but what about -0 vs. +0? -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Wed Jun 5 19:15:00 2019 From: david.feuer at gmail.com (David Feuer) Date: Wed, 5 Jun 2019 15:15:00 -0400 Subject: Laws for Show and Read? In-Reply-To: References: Message-ID: Double and Float instances are terminally broken in general. What's new? On Wed, Jun 5, 2019, 2:56 PM Sven Panne wrote: > Am Mi., 5. Juni 2019 um 17:02 Uhr schrieb David Feuer < > david.feuer at gmail.com>: > >> We already have the law >> >> read . show = id >> >> which implies the injectivity and surjectivity conditions you specify. >> > > I think this doesn't hold for the standard Read/Show instances for > Double/Float: IEEE-754 NaNs have a sign bit and a payload, and both parts > are probably lost by the "read . show"-combination. The 2 infinities are > probably OK, but what about -0 vs. +0? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From bertram.felgenhauer at googlemail.com Wed Jun 5 20:37:18 2019 From: bertram.felgenhauer at googlemail.com (Bertram Felgenhauer) Date: Wed, 5 Jun 2019 22:37:18 +0200 Subject: Laws for Show and Read? In-Reply-To: References: Message-ID: <20190605203718.GB16528@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> Sven Panne wrote: > We already have the law > read . show = id > which implies the injectivity and surjectivity conditions you specify. > > I think this doesn't hold for the standard Read/Show instances for > Double/Float: IEEE-754 NaNs have a sign bit and a payload, and both > parts are probably lost by the "read . show"-combination. The 2 > infinities are probably OK, but what about -0 vs. +0? ghci> show (-0 :: Double) "-0.0" ghci> read (show (-0 :: Double)) :: Double -0.0 It's true that extra information in NaNs is lost, but they all behave the same anyway... Cheers, Bertram From svenpanne at gmail.com Wed Jun 5 21:14:51 2019 From: svenpanne at gmail.com (Sven Panne) Date: Wed, 5 Jun 2019 23:14:51 +0200 Subject: Laws for Show and Read? In-Reply-To: <20190605203718.GB16528@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> References: <20190605203718.GB16528@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> Message-ID: Am Mi., 5. Juni 2019 um 22:57 Uhr schrieb Bertram Felgenhauer via Libraries : > [...] It's true that extra information in NaNs is lost, but they all behave > the same anyway... > That's true for normal arithmetic with them, but wrong if you use e.g. an external library which encodes things into the sign bit/paylod of NaNs (see e.g. NaN tagging). In the latter case, "read . show" actively destroys necessary information. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jp at jamesparker.me Thu Jun 6 00:48:59 2019 From: jp at jamesparker.me (James Parker) Date: Wed, 5 Jun 2019 20:48:59 -0400 Subject: Proposal: Expose reverse topological ordering in Data.Graph Message-ID: <5753BB69-F314-4C82-85B1-3406C7BA0A2F@jamesparker.me> Hi, I’d like to expose reverse topological ordering in Data.Graph. I’ve created a pull request that implements this. I named it `revTopSort` for now, but am fine with alternatives. Thanks, James Parker -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Thu Jun 6 00:50:37 2019 From: david.feuer at gmail.com (David Feuer) Date: Wed, 5 Jun 2019 20:50:37 -0400 Subject: Proposal: Expose reverse topological ordering in Data.Graph In-Reply-To: <5753BB69-F314-4C82-85B1-3406C7BA0A2F@jamesparker.me> References: <5753BB69-F314-4C82-85B1-3406C7BA0A2F@jamesparker.me> Message-ID: If there's an application, I firmly believe we should add it. The name is up for grabs. On Wed, Jun 5, 2019, 8:49 PM James Parker wrote: > Hi, > > I’d like to expose reverse topological ordering in Data.Graph. I’ve > created a pull request that > implements this. I named it `revTopSort` for now, but am fine with > alternatives. > > Thanks, > > James Parker > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jp at jamesparker.me Thu Jun 6 15:43:57 2019 From: jp at jamesparker.me (James Parker) Date: Thu, 6 Jun 2019 11:43:57 -0400 Subject: Proposal: Expose reverse topological ordering in Data.Graph In-Reply-To: References: <5753BB69-F314-4C82-85B1-3406C7BA0A2F@jamesparker.me> Message-ID: <6BDF33EF-A382-4036-B386-D41926EF0B83@jamesparker.me> My application is I have a dependency graph (DAG) where `a` depends on `b` (a -> b). I need to process all dependencies of a node before processing that node. Currently I’m doing `reverse . topSort` which is `reverse . reverse . postOrd`. > On Jun 5, 2019, at 8:50 PM, David Feuer wrote: > > If there's an application, I firmly believe we should add it. The name is up for grabs. > > On Wed, Jun 5, 2019, 8:49 PM James Parker > wrote: > Hi, > > I’d like to expose reverse topological ordering in Data.Graph. I’ve created a pull request that implements this. I named it `revTopSort` for now, but am fine with alternatives. > > Thanks, > > James Parker > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Fri Jun 7 03:51:48 2019 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Thu, 6 Jun 2019 23:51:48 -0400 Subject: Laws for Show and Read? In-Reply-To: References: <20190605203718.GB16528@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> Message-ID: @Sven Panne you are correct, and its definitely true that 1) we dont have informative literals for +/- infity OR the bits in the nan. and those are truely informative in debugging, as IEEE float and show/read intend! so i support and would like to improve that state of affairs myself! (eg my slow motion ghc float ieee improvement stuff, most recently removing x87 support to make rounding deterministic for a change on x86 32 platform!) On Wed, Jun 5, 2019 at 5:15 PM Sven Panne wrote: > Am Mi., 5. Juni 2019 um 22:57 Uhr schrieb Bertram Felgenhauer via > Libraries : > >> [...] It's true that extra information in NaNs is lost, but they all >> behave >> the same anyway... >> > > That's true for normal arithmetic with them, but wrong if you use e.g. an > external library which encodes things into the sign bit/paylod of NaNs (see > e.g. NaN tagging). In the latter case, "read . show" actively destroys > necessary information. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From andrew.thaddeus at gmail.com Fri Jun 14 14:57:06 2019 From: andrew.thaddeus at gmail.com (Andrew Martin) Date: Fri, 14 Jun 2019 10:57:06 -0400 Subject: Strictness in Kinds Message-ID: TLDR: I wrote up an idea: https://gist.github.com/andrewthad/90a4b23051870d14afb4ba064699bc5b. Last night, the phrase "strictness in kinds" just stuck in my head. I could have sworn I'd heard it or read it before. But after some googling, I couldn't find anything on it. So, I started think about what it would look like for GHC to track strictness in the kind of an expression. It's kind of like proposals B2 and B3 from https://gitlab.haskell.org/ghc/ghc/wikis/unlifted-data-types, but I thought I'd share it here. -- -Andrew Thaddeus Martin -------------- next part -------------- An HTML attachment was scrubbed... URL: From ndospark320 at gmail.com Fri Jun 14 23:44:38 2019 From: ndospark320 at gmail.com (Dannyu NDos) Date: Sat, 15 Jun 2019 08:44:38 +0900 Subject: Add instance Bounded (Ratio a) Message-ID: instance (Integral a, Bounded a) => Bounded (Ratio a) where minBound = minBound % 1 maxBound = maxBound % 1 -------------- next part -------------- An HTML attachment was scrubbed... URL: From luochen1990 at gmail.com Sun Jun 16 12:30:20 2019 From: luochen1990 at gmail.com (LuoChen) Date: Sun, 16 Jun 2019 20:30:20 +0800 Subject: Proposal: add HasCallStack for all partial functions in base Message-ID: Motivation Partial functions in base (especially Prelude) often cause runtime errors and is hard to locate. (here is a document about the concept of totality and partial function, ignore this if you are familiar with them) For example, consider the following piece of code: import GHC.Stack foo :: HasCallStack => [Int] -> Int foo xs = last xs + 1 xs :: [Int] xs = [] main :: IO () main = do print $ foo xs In this case, the error message will tell nothing about foo, and the HasCallStack constraint is totally helpless, because the call stack is cut off by the call to last which without HasCallStack constraint. My current workaround is define my own wrapper functions with HasCallStack constraint for some mostly used partial functions to make them traceable, and use the wrapper (the traceable version) whenever I need them. e.g. last' :: HasCallStack => [a] -> a last' xs = case xs of [] -> error "abuse last"; _ -> last xs So, IMHO, if our goal is to make errors in haskell traceable, then *only providing HasCallStack mechanism is not enough, we have to provide traceable base package and prelude at the same time*. Further more, all untraceable partial functions are considered to be harmful, and should not be exported by any package. Because an improper call to an untraceable partial function will cut off the call stack, and here is a demonstration about that . On the other hand, is it ever necessary for us to add HasCallStack for a total function? Or we can ask, is it possible that a call to a total function cause runtime error? Maybe it’s a NO, since a total function will also crash when the machine is Out Of Memory, but that is also the only situation I can find out. So I suggest that we add HasCallStack constraint only for partial functions, and IMHO this could be a good balance for better debugging experience and less runtime overhead. Proposal 1. add HasCallStack constraint for all partial functions in base package 2. suggest all programmers to add HasCallStack constraint for their exported partial functions when they release a package 3. provide a compiler option -fignore-hascallstack to toggle off the effect of HasCallStack constraint in case somebody need best performance Other Considerations How to get a full list of partial functions provided by the base package? I wanted to provide a full list of partial functions exported by the base package in this post, but I find it is hard, since Haskell have no totality checking mechanism like Idris have, and there are no consistent keyword like “total” or “partial” in document, so it takes a lot of work to list all the partial functions of a package by check every item manually. Maybe we can work on this list later — when it’s turned out to be worth after some discussion. Here is part of the list that I have tidied for several modules of the base package. How to encourage all package contributors to obey the rule (see proposal #2)? I don’t know, but I think there may be some other rules to obey when contributing packages. Maybe we can just add this into the list. Obviously, the final perfect solution should be let the compiler to check the totality of functions, and automatically add HasCallStack for the ones which the compiler cannot confirm it’s totality. But this seems too far away from us, since we still doesn’t have dependent type haskell yet. How to deal with recursive partial functions? Since the HasCallStack constraint affects the performance (not only because of the runtime overhead, but also it’s influence on optimization strategy), It is best not to add HasCallStack on recursive functions. In most of the cases, we can just check the input shallowly before everything start, just like how we deal with the non-recursive ones. But in some other cases, we need to go deep to recognize the invalidity of the input. A trivial solution is just perform a deep check before everything start, but the checking phase seems expensive. The best solution, IMHO, is to make the recursive part a total function, wrap the return value into Maybe or some similar things, and the partial version is just the total version combined fromJust. In this way, we avoid the single input checking phase and left the error awareing logic where it was before this translation. -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Sun Jun 16 14:49:26 2019 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Sun, 16 Jun 2019 16:49:26 +0200 (CEST) Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: On Sun, 16 Jun 2019, LuoChen wrote: > On the other hand, is it ever necessary for us to add HasCallStack for a > total function? Or we can ask, is it possible that a call to a total > function cause runtime error? Maybe it’s a NO, since a total function > will also crash when the machine is Out Of Memory, but that is also the > only situation I can find out. A non-IO function 'f' cannot crash because of memory exhaustion. The IO function calling 'f' is the one that crashes. A call stack would not help because it is not a programming error in 'f'. From ben.franksen at online.de Sun Jun 16 15:32:27 2019 From: ben.franksen at online.de (Ben Franksen) Date: Sun, 16 Jun 2019 17:32:27 +0200 Subject: Laws for Show and Read? In-Reply-To: References: <20190605203718.GB16528@24f89f8c-e6a1-4e75-85ee-bb8a3743bb9f> Message-ID: Am 07.06.19 um 05:51 schrieb Carter Schonwald: > @Sven Panne you are correct, and its definitely true > that > 1) we dont have informative literals for +/- infity OR the bits in the nan. > and those are truely informative in debugging, as IEEE float and show/read > intend! FWIW, my take is that the prefix (-) should be eliminated from Haskell as an operator (we have negate method for that). Instead, prefix + and - (no space allow in between) should be part of the syntax of numeric literals. This would solve a lot of problems, including the one mentioned. From simon.jakobi at googlemail.com Sun Jun 16 16:20:27 2019 From: simon.jakobi at googlemail.com (Simon Jakobi) Date: Sun, 16 Jun 2019 18:20:27 +0200 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: I like the idea of marking partial functions with HasCallStack. But I'd like to point out that we also have class methods where some but not all implementations are partial, such as foldr1 in Foldable. Should methods like these also get a HasCallStack constraint? Am So., 16. Juni 2019 um 14:30 Uhr schrieb LuoChen : > Motivation > > Partial functions in base (especially Prelude) often cause runtime errors > and is hard to locate. > > (here > is > a document about the concept of totality and partial function, ignore this > if you are familiar with them) > > For example, consider the following piece of code: > > import GHC.Stack > > foo :: HasCallStack => [Int] -> Int > foo xs = last xs + 1 > > xs :: [Int] > xs = [] > > main :: IO () > main = do > print $ foo xs > > In this case, the error message will tell nothing about foo, and the > HasCallStack constraint is totally helpless, because the call stack is > cut off by the call to last which without HasCallStack constraint. > > My current workaround is define my own wrapper functions with HasCallStack > constraint for some mostly used partial functions to make them traceable, > and use the wrapper (the traceable version) whenever I need them. > > e.g. > > last' :: HasCallStack => [a] -> a > last' xs = case xs of [] -> error "abuse last"; _ -> last xs > > So, IMHO, if our goal is to make errors in haskell traceable, then *only > providing HasCallStack mechanism is not enough, we have to provide > traceable base package and prelude at the same time*. > > Further more, all untraceable partial functions are considered to be > harmful, and should not be exported by any package. Because an improper > call to an untraceable partial function will cut off the call stack, and here > is a demonstration about that > . > > On the other hand, is it ever necessary for us to add HasCallStack for a > total function? Or we can ask, is it possible that a call to a total > function cause runtime error? Maybe it’s a NO, since a total function will > also crash when the machine is Out Of Memory, but that is also the only > situation I can find out. So I suggest that we add HasCallStack > constraint only for partial functions, and IMHO this could be a good > balance for better debugging experience and less runtime overhead. > Proposal > > 1. add HasCallStack constraint for all partial functions in base > package > 2. suggest all programmers to add HasCallStack constraint for their > exported partial functions when they release a package > 3. provide a compiler option -fignore-hascallstack to toggle off the > effect of HasCallStack constraint in case somebody need best > performance > > Other Considerations How to get a full list of partial functions provided > by the base package? > > I wanted to provide a full list of partial functions exported by the base > package in this post, but I find it is hard, since Haskell have no totality > checking mechanism like Idris have, and there are no consistent keyword > like “total” or “partial” in document, so it takes a lot of work to list > all the partial functions of a package by check every item manually. Maybe > we can work on this list later — when it’s turned out to be worth after > some discussion. > > Here > is > part of the list that I have tidied for several modules of the base package. > How to encourage all package contributors to obey the rule (see proposal > #2)? > > I don’t know, but I think there may be some other rules to obey when > contributing packages. Maybe we can just add this into the list. > > Obviously, the final perfect solution should be let the compiler to check > the totality of functions, and automatically add HasCallStack for the > ones which the compiler cannot confirm it’s totality. But this seems too > far away from us, since we still doesn’t have dependent type haskell yet. > How to deal with recursive partial functions? > > Since the HasCallStack constraint affects the performance (not only > because of the runtime overhead, but also it’s influence on optimization > strategy), It is best not to add HasCallStack on recursive functions. > > In most of the cases, we can just check the input shallowly before > everything start, just like how we deal with the non-recursive ones. > > But in some other cases, we need to go deep to recognize the invalidity of > the input. A trivial solution is just perform a deep check before > everything start, but the checking phase seems expensive. > > The best solution, IMHO, is to make the recursive part a total function, > wrap the return value into Maybe or some similar things, and the partial > version is just the total version combined fromJust. In this way, we > avoid the single input checking phase and left the error awareing logic > where it was before this translation. > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Sun Jun 16 16:26:03 2019 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Sun, 16 Jun 2019 18:26:03 +0200 (CEST) Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: On Sun, 16 Jun 2019, Simon Jakobi via Libraries wrote: > I like the idea of marking partial functions with HasCallStack. > But I'd like to point out that we also have class methods where some but not all implementations are partial, > such as foldr1 in Foldable. > > Should methods like these also get a HasCallStack constraint? I think only the partial implementations should get that constraint. From vanessa.mchale at iohk.io Sun Jun 16 17:14:04 2019 From: vanessa.mchale at iohk.io (Vanessa McHale) Date: Sun, 16 Jun 2019 12:14:04 -0500 Subject: Add instance Bounded (Ratio a) In-Reply-To: References: Message-ID: <4b9c0101-870f-738a-d550-ac06715fcdba@iohk.io> Seems sensible. Out of curiosity, what would this help with? On 6/14/19 6:44 PM, Dannyu NDos wrote: > instance (Integral a, Bounded a) => Bounded (Ratio a) where >     minBound = minBound % 1 >     maxBound = maxBound % 1 > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: OpenPGP digital signature URL: From simon.jakobi at googlemail.com Sun Jun 16 18:16:49 2019 From: simon.jakobi at googlemail.com (Simon Jakobi) Date: Sun, 16 Jun 2019 20:16:49 +0200 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: > I think only the partial implementations should get that constraint. Oops, I had the misconception that one couldn't add a HasCallStack constraint to method implementations. I agree though! Am So., 16. Juni 2019 um 18:26 Uhr schrieb Henning Thielemann < lemming at henning-thielemann.de>: > > On Sun, 16 Jun 2019, Simon Jakobi via Libraries wrote: > > > I like the idea of marking partial functions with HasCallStack. > > But I'd like to point out that we also have class methods where some but > not all implementations are partial, > > such as foldr1 in Foldable. > > > > Should methods like these also get a HasCallStack constraint? > > I think only the partial implementations should get that constraint. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Sun Jun 16 18:26:52 2019 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Sun, 16 Jun 2019 20:26:52 +0200 (CEST) Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: On Sun, 16 Jun 2019, Simon Jakobi wrote: > >  I think only the partial implementations should get that constraint. > Oops, I had the misconception that one couldn't add a HasCallStack > constraint to method implementations. I think you have to declare: instance Foldable [] where foldl1 = foldl1List foldl1List :: HasCallStack => (a->a->a) -> [a] -> a foldl1List = ... Would this work? From emertens at gmail.com Sun Jun 16 18:29:54 2019 From: emertens at gmail.com (Eric Mertens) Date: Sun, 16 Jun 2019 11:29:54 -0700 Subject: Add instance Bounded (Ratio a) In-Reply-To: <4b9c0101-870f-738a-d550-ac06715fcdba@iohk.io> References: <4b9c0101-870f-738a-d550-ac06715fcdba@iohk.io> Message-ID: Ratio only only generally be used with Integer, which isn’t itself an instance of Bounded. This probably wouldn’t be a very useful instance. It has overflow issues with Bounded types like Int for various operations including comparisons. > On Jun 16, 2019, at 10:14 AM, Vanessa McHale wrote: > > Signed PGP part > Seems sensible. Out of curiosity, what would this help with? > > On 6/14/19 6:44 PM, Dannyu NDos wrote: >> instance (Integral a, Bounded a) => Bounded (Ratio a) where >> minBound = minBound % 1 >> maxBound = maxBound % 1 >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: Message signed with OpenPGP URL: From david.feuer at gmail.com Sun Jun 16 18:49:14 2019 From: david.feuer at gmail.com (David Feuer) Date: Sun, 16 Jun 2019 14:49:14 -0400 Subject: Add instance Bounded (Ratio a) In-Reply-To: References: <4b9c0101-870f-738a-d550-ac06715fcdba@iohk.io> Message-ID: Agreed. Moreover, even if we had some magical way to avoid overflow issues, there's no guarantee that maxBound % 1 >= minBound % (-1) or that minBound % 1 <= maxBound % (-1) So I think this is fundamentally doomed. On Sun, Jun 16, 2019, 2:30 PM Eric Mertens wrote: > Ratio only only generally be used with Integer, which isn’t itself an > instance of Bounded. This probably wouldn’t be a very useful instance. It > has overflow issues with Bounded types like Int for various operations > including comparisons. > > On Jun 16, 2019, at 10:14 AM, Vanessa McHale > wrote: > > Signed PGP part > > Seems sensible. Out of curiosity, what would this help with? > On 6/14/19 6:44 PM, Dannyu NDos wrote: > > instance (Integral a, Bounded a) => Bounded (Ratio a) where > minBound = minBound % 1 > maxBound = maxBound % 1 > > _______________________________________________ > Libraries mailing listLibraries at haskell.orghttp://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sun Jun 16 18:50:41 2019 From: david.feuer at gmail.com (David Feuer) Date: Sun, 16 Jun 2019 14:50:41 -0400 Subject: Add instance Bounded (Ratio a) In-Reply-To: References: <4b9c0101-870f-738a-d550-ac06715fcdba@iohk.io> Message-ID: Sorry, agreed with one caveat. Ratio Natural is also perfectly sensible. On Sun, Jun 16, 2019, 2:49 PM David Feuer wrote: > Agreed. Moreover, even if we had some magical way to avoid overflow > issues, there's no guarantee that > > maxBound % 1 >= minBound % (-1) > > or that > > minBound % 1 <= maxBound % (-1) > > So I think this is fundamentally doomed. > > On Sun, Jun 16, 2019, 2:30 PM Eric Mertens wrote: > >> Ratio only only generally be used with Integer, which isn’t itself an >> instance of Bounded. This probably wouldn’t be a very useful instance. It >> has overflow issues with Bounded types like Int for various operations >> including comparisons. >> >> On Jun 16, 2019, at 10:14 AM, Vanessa McHale >> wrote: >> >> Signed PGP part >> >> Seems sensible. Out of curiosity, what would this help with? >> On 6/14/19 6:44 PM, Dannyu NDos wrote: >> >> instance (Integral a, Bounded a) => Bounded (Ratio a) where >> minBound = minBound % 1 >> maxBound = maxBound % 1 >> >> _______________________________________________ >> Libraries mailing listLibraries at haskell.orghttp://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ollie at ocharles.org.uk Sun Jun 16 19:03:11 2019 From: ollie at ocharles.org.uk (Oliver Charles) Date: Sun, 16 Jun 2019 20:03:11 +0100 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: Surely then the call stack is only foldr1, and not foldr1's callsite? On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, < lemming at henning-thielemann.de> wrote: > > On Sun, 16 Jun 2019, Simon Jakobi wrote: > > > > I think only the partial implementations should get that constraint. > > > Oops, I had the misconception that one couldn't add a HasCallStack > > constraint to method implementations. > > I think you have to declare: > > instance Foldable [] where > foldl1 = foldl1List > > foldl1List :: HasCallStack => (a->a->a) -> [a] -> a > foldl1List = ... > > Would this work?_______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From luochen1990 at gmail.com Mon Jun 17 14:06:00 2019 From: luochen1990 at gmail.com (LuoChen) Date: Mon, 17 Jun 2019 22:06:00 +0800 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: I have just confirmed that we can specify HasCallStack separately for different instance of same typeclass, and here is the test code. Oliver Charles 于2019年6月17日周一 上午3:02写道: > Surely then the call stack is only foldr1, and not foldr1's callsite? > > On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, < > lemming at henning-thielemann.de> wrote: > >> >> On Sun, 16 Jun 2019, Simon Jakobi wrote: >> >> > > I think only the partial implementations should get that constraint. >> >> > Oops, I had the misconception that one couldn't add a HasCallStack >> > constraint to method implementations. >> >> I think you have to declare: >> >> instance Foldable [] where >> foldl1 = foldl1List >> >> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a >> foldl1List = ... >> >> Would this work?_______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ekmett at gmail.com Mon Jun 17 17:09:15 2019 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 17 Jun 2019 19:09:15 +0200 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: Re: your code. This is passing the callStack to each instance and dropping it on the floor for the cases where you ignore the constraint. I’m starting to warm to the idea of putting HasCallStack constraints on the obviously partial combinators in base if we can demonstrate that the performance impact isn't bad in practice, and even really, to some extent if there is a somewhat middling impact on the performance of code that leans on these hard to debug combinators, so long as the performance of their more total siblings remains unaffected. The impact on the perceived debuggability of Haskell seems _likely_ to significantly outweigh the performance concerns. Heck, off of the HEAD of cabal, which we’re encouraging folks to build to play with the ghc 8.8.1 alpha, just today we ran into an issue where the very build system we are using spat out an oh so informative “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that didnt include any explicit bounds. It seems worth implementing and measuring quite how bad the impact would be before pulling the trigger for good. The impact should be reasonable if the constraints only really live right at the outside of base though, then users can choose to propagate the constraint further outwards, just like they get to do with “error” today. Slightly more controversially, MonadFail’s fail could be similarly modified with near zero user facing impact other than a bit of additional static info flowing to explicit callstacks to make it take a HasCallStack constraint. The code in existing instances would all still work. This one I think would need more benchmarking though, as recovering from a fail is a far “lighter” affair than catching an exception, but I’d be happy to raise it to the CLC as a question, especially if we can get benchmarks in hand. —Edward > On Jun 17, 2019, at 4:06 PM, LuoChen wrote: > > I have just confirmed that we can specify HasCallStack separately for different instance of same typeclass, and here is the test code. > > > Oliver Charles 于2019年6月17日周一 上午3:02写道: >> Surely then the call stack is only foldr1, and not foldr1's callsite? >> >>> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, wrote: >>> >>> On Sun, 16 Jun 2019, Simon Jakobi wrote: >>> >>> > > I think only the partial implementations should get that constraint. >>> >>> > Oops, I had the misconception that one couldn't add a HasCallStack >>> > constraint to method implementations. >>> >>> I think you have to declare: >>> >>> instance Foldable [] where >>> foldl1 = foldl1List >>> >>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a >>> foldl1List = ... >>> >>> Would this work?_______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Mon Jun 17 19:57:20 2019 From: david.feuer at gmail.com (David Feuer) Date: Mon, 17 Jun 2019 15:57:20 -0400 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: As I recall, the main things to watch out for, performance-wise, are recursive definitions. When we throw an error from a library function, we *typically* mean that the caller made a mistake. We don't want to build up the call stacks we'd need to debug the library function itself, unless we're actually doing so (in which case we can edit it in, of course). On Mon, Jun 17, 2019, 1:09 PM Edward Kmett wrote: > Re: your code. This is passing the callStack to each instance and dropping > it on the floor for the cases where you ignore the constraint. > > I’m starting to warm to the idea of putting HasCallStack constraints on > the obviously partial combinators in base if we can demonstrate that the > performance impact isn't bad in practice, and even really, to some extent > if there is a somewhat middling impact on the performance of code that > leans on these hard to debug combinators, so long as the performance of > their more total siblings remains unaffected. The impact on the perceived > debuggability of Haskell seems _likely_ to significantly outweigh the > performance concerns. > > Heck, off of the HEAD of cabal, which we’re encouraging folks to build to > play with the ghc 8.8.1 alpha, just today we ran into an issue where the > very build system we are using spat out an oh so informative > “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that > didnt include any explicit bounds. > > It seems worth implementing and measuring quite how bad the impact would > be before pulling the trigger for good. The impact should be reasonable if > the constraints only really live right at the outside of base though, then > users can choose to propagate the constraint further outwards, just like > they get to do with “error” today. > > Slightly more controversially, MonadFail’s fail could be similarly > modified with near zero user facing impact other than a bit of additional > static info flowing to explicit callstacks to make it take a HasCallStack > constraint. The code in existing instances would all still work. This one I > think would need more benchmarking though, as recovering from a fail is a > far “lighter” affair than catching an exception, but I’d be happy to raise > it to the CLC as a question, especially if we can get benchmarks in hand. > > —Edward > > > On Jun 17, 2019, at 4:06 PM, LuoChen wrote: > > I have just confirmed that we can specify HasCallStack separately for > different instance of same typeclass, and here > is > the test code. > > Oliver Charles 于2019年6月17日周一 上午3:02写道: > >> Surely then the call stack is only foldr1, and not foldr1's callsite? >> >> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, < >> lemming at henning-thielemann.de> wrote: >> >>> >>> On Sun, 16 Jun 2019, Simon Jakobi wrote: >>> >>> > > I think only the partial implementations should get that constraint. >>> >>> > Oops, I had the misconception that one couldn't add a HasCallStack >>> > constraint to method implementations. >>> >>> I think you have to declare: >>> >>> instance Foldable [] where >>> foldl1 = foldl1List >>> >>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a >>> foldl1List = ... >>> >>> Would this work?_______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> >> _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From eric at seidel.io Mon Jun 17 20:02:27 2019 From: eric at seidel.io (Eric Seidel) Date: Mon, 17 Jun 2019 16:02:27 -0400 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: <5055536a-3a24-4ab1-87fa-cf511427fd78@www.fastmail.com> I did some very basic benchmarks back when I implemented HasCallStack. What I remember finding back then was that there was a small overhead for non-recursive functions like `head` but a substantial overhead for recursive functions. (My benchmarks are available at https://github.com/gridaphobe/located-base/tree/master/bench.) So if we want to add HasCallStack to partial `base` functions, I'd suggest extra care around recursive functions ((!!) comes to mind). Perhaps rewrite them to use an inner recursive loop that does not extend the CallStack (this might produce nicer stacktraces anyway). Eric On Mon, Jun 17, 2019, at 13:09, Edward Kmett wrote: > Re: your code. This is passing the callStack to each instance and > dropping it on the floor for the cases where you ignore the constraint. > > I’m starting to warm to the idea of putting HasCallStack constraints on > the obviously partial combinators in base if we can demonstrate that > the performance impact isn't bad in practice, and even really, to some > extent if there is a somewhat middling impact on the performance of > code that leans on these hard to debug combinators, so long as the > performance of their more total siblings remains unaffected. The impact > on the perceived debuggability of Haskell seems _likely_ to > significantly outweigh the performance concerns. > > Heck, off of the HEAD of cabal, which we’re encouraging folks to build > to play with the ghc 8.8.1 alpha, just today we ran into an issue where > the very build system we are using spat out an oh so informative > “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that > didnt include any explicit bounds. > > It seems worth implementing and measuring quite how bad the impact > would be before pulling the trigger for good. The impact should be > reasonable if the constraints only really live right at the outside of > base though, then users can choose to propagate the constraint further > outwards, just like they get to do with “error” today. > > Slightly more controversially, MonadFail’s fail could be similarly > modified with near zero user facing impact other than a bit of > additional static info flowing to explicit callstacks to make it take a > HasCallStack constraint. The code in existing instances would all still > work. This one I think would need more benchmarking though, as > recovering from a fail is a far “lighter” affair than catching an > exception, but I’d be happy to raise it to the CLC as a question, > especially if we can get benchmarks in hand. > > —Edward > > > On Jun 17, 2019, at 4:06 PM, LuoChen wrote: > > > I have just confirmed that we can specify `HasCallStack` separately for different instance of same typeclass, and here is the test code. > > > > > Oliver Charles 于2019年6月17日周一 上午3:02写道: > >> Surely then the call stack is only foldr1, and not foldr1's callsite? > >> > >> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, wrote: > >>> > >>> On Sun, 16 Jun 2019, Simon Jakobi wrote: > >>> > >>> > > I think only the partial implementations should get that constraint. > >>> > >>> > Oops, I had the misconception that one couldn't add a HasCallStack > >>> > constraint to method implementations. > >>> > >>> I think you have to declare: > >>> > >>> instance Foldable [] where > >>> foldl1 = foldl1List > >>> > >>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a > >>> foldl1List = ... > >>> > >>> Would this work?_______________________________________________ > >>> Libraries mailing list > >>> Libraries at haskell.org > >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > From ekmett at gmail.com Mon Jun 17 20:18:20 2019 From: ekmett at gmail.com (Edward Kmett) Date: Mon, 17 Jun 2019 22:18:20 +0200 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: <5055536a-3a24-4ab1-87fa-cf511427fd78@www.fastmail.com> References: <5055536a-3a24-4ab1-87fa-cf511427fd78@www.fastmail.com> Message-ID: <875B0FF3-8326-47E6-9662-FCD00402E43F@gmail.com> I definitely do not want to push them through recursive functions! But e.g. foldr1 builds its error just once despite being recursive. We’d need to be somewhat careful there, but otherwise the cost should basically be comparable to a cons. -Edward > On Jun 17, 2019, at 10:02 PM, Eric Seidel wrote: > > I did some very basic benchmarks back when I implemented HasCallStack. What I remember finding back then was that there was a small overhead for non-recursive functions like `head` but a substantial overhead for recursive functions. (My benchmarks are available at https://github.com/gridaphobe/located-base/tree/master/bench.) > > So if we want to add HasCallStack to partial `base` functions, I'd suggest extra care around recursive functions ((!!) comes to mind). Perhaps rewrite them to use an inner recursive loop that does not extend the CallStack (this might produce nicer stacktraces anyway). > > Eric > >> On Mon, Jun 17, 2019, at 13:09, Edward Kmett wrote: >> Re: your code. This is passing the callStack to each instance and >> dropping it on the floor for the cases where you ignore the constraint. >> >> I’m starting to warm to the idea of putting HasCallStack constraints on >> the obviously partial combinators in base if we can demonstrate that >> the performance impact isn't bad in practice, and even really, to some >> extent if there is a somewhat middling impact on the performance of >> code that leans on these hard to debug combinators, so long as the >> performance of their more total siblings remains unaffected. The impact >> on the perceived debuggability of Haskell seems _likely_ to >> significantly outweigh the performance concerns. >> >> Heck, off of the HEAD of cabal, which we’re encouraging folks to build >> to play with the ghc 8.8.1 alpha, just today we ran into an issue where >> the very build system we are using spat out an oh so informative >> “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that >> didnt include any explicit bounds. >> >> It seems worth implementing and measuring quite how bad the impact >> would be before pulling the trigger for good. The impact should be >> reasonable if the constraints only really live right at the outside of >> base though, then users can choose to propagate the constraint further >> outwards, just like they get to do with “error” today. >> >> Slightly more controversially, MonadFail’s fail could be similarly >> modified with near zero user facing impact other than a bit of >> additional static info flowing to explicit callstacks to make it take a >> HasCallStack constraint. The code in existing instances would all still >> work. This one I think would need more benchmarking though, as >> recovering from a fail is a far “lighter” affair than catching an >> exception, but I’d be happy to raise it to the CLC as a question, >> especially if we can get benchmarks in hand. >> >> —Edward >> >> >>> On Jun 17, 2019, at 4:06 PM, LuoChen wrote: >>> >>> I have just confirmed that we can specify `HasCallStack` separately for different instance of same typeclass, and here is the test code. >> >>> >>> Oliver Charles 于2019年6月17日周一 上午3:02写道: >>>> Surely then the call stack is only foldr1, and not foldr1's callsite? >>>> >>>>> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, wrote: >>>>> >>>>> On Sun, 16 Jun 2019, Simon Jakobi wrote: >>>>> >>>>>>> I think only the partial implementations should get that constraint. >>>>> >>>>>> Oops, I had the misconception that one couldn't add a HasCallStack >>>>>> constraint to method implementations. >>>>> >>>>> I think you have to declare: >>>>> >>>>> instance Foldable [] where >>>>> foldl1 = foldl1List >>>>> >>>>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a >>>>> foldl1List = ... >>>>> >>>>> Would this work?_______________________________________________ >>>>> Libraries mailing list >>>>> Libraries at haskell.org >>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries From luochen1990 at gmail.com Wed Jun 19 04:41:26 2019 From: luochen1990 at gmail.com (LuoChen) Date: Wed, 19 Jun 2019 12:41:26 +0800 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: @david It seem that we doesn't have such a mechanism yet. AFAIK with `HasCallStack` we can only build a call stack from the deepest bottom. Is it possible to build a call stack from middle of the call chain to the top, without containing the deepest parts? e.g. f1 -> f2 -> f3 -> error (f -> g means f call g) , is it possible to build a call stack only contains f1 and f2, without f3 and error? David Feuer 于2019年6月18日周二 上午3:57写道: > As I recall, the main things to watch out for, performance-wise, are > recursive definitions. When we throw an error from a library function, we > *typically* mean that the caller made a mistake. We don't want to build up > the call stacks we'd need to debug the library function itself, unless > we're actually doing so (in which case we can edit it in, of course). > > On Mon, Jun 17, 2019, 1:09 PM Edward Kmett wrote: > >> Re: your code. This is passing the callStack to each instance and >> dropping it on the floor for the cases where you ignore the constraint. >> >> I’m starting to warm to the idea of putting HasCallStack constraints on >> the obviously partial combinators in base if we can demonstrate that the >> performance impact isn't bad in practice, and even really, to some extent >> if there is a somewhat middling impact on the performance of code that >> leans on these hard to debug combinators, so long as the performance of >> their more total siblings remains unaffected. The impact on the perceived >> debuggability of Haskell seems _likely_ to significantly outweigh the >> performance concerns. >> >> Heck, off of the HEAD of cabal, which we’re encouraging folks to build to >> play with the ghc 8.8.1 alpha, just today we ran into an issue where the >> very build system we are using spat out an oh so informative >> “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that >> didnt include any explicit bounds. >> >> It seems worth implementing and measuring quite how bad the impact would >> be before pulling the trigger for good. The impact should be reasonable if >> the constraints only really live right at the outside of base though, then >> users can choose to propagate the constraint further outwards, just like >> they get to do with “error” today. >> >> Slightly more controversially, MonadFail’s fail could be similarly >> modified with near zero user facing impact other than a bit of additional >> static info flowing to explicit callstacks to make it take a HasCallStack >> constraint. The code in existing instances would all still work. This one I >> think would need more benchmarking though, as recovering from a fail is a >> far “lighter” affair than catching an exception, but I’d be happy to raise >> it to the CLC as a question, especially if we can get benchmarks in hand. >> >> —Edward >> >> >> On Jun 17, 2019, at 4:06 PM, LuoChen wrote: >> >> I have just confirmed that we can specify HasCallStack separately for >> different instance of same typeclass, and here >> >> is the test code. >> >> Oliver Charles 于2019年6月17日周一 上午3:02写道: >> >>> Surely then the call stack is only foldr1, and not foldr1's callsite? >>> >>> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, < >>> lemming at henning-thielemann.de> wrote: >>> >>>> >>>> On Sun, 16 Jun 2019, Simon Jakobi wrote: >>>> >>>> > > I think only the partial implementations should get that >>>> constraint. >>>> >>>> > Oops, I had the misconception that one couldn't add a HasCallStack >>>> > constraint to method implementations. >>>> >>>> I think you have to declare: >>>> >>>> instance Foldable [] where >>>> foldl1 = foldl1List >>>> >>>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a >>>> foldl1List = ... >>>> >>>> Would this work?_______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>>> >>> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From eric at seidel.io Wed Jun 19 11:25:08 2019 From: eric at seidel.io (Eric Seidel) Date: Wed, 19 Jun 2019 07:25:08 -0400 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: Message-ID: <6A3E215A-266A-4A9E-B896-039F7458B98D@seidel.io> You can use withFrozenCallstack to avoid adding new entries to the stacktrace (but you still need HasCallstack constraints all the way down to error, of course). http://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Stack.html#v:withFrozenCallStack Sent from my iPhone > On Jun 19, 2019, at 00:41, LuoChen wrote: > > @david It seem that we doesn't have such a mechanism yet. AFAIK with `HasCallStack` we can only build a call stack from the deepest bottom. > > Is it possible to build a call stack from middle of the call chain to the top, without containing the deepest parts? > e.g. f1 -> f2 -> f3 -> error (f -> g means f call g) , is it possible to build a call stack only contains f1 and f2, without f3 and error? > > David Feuer 于2019年6月18日周二 上午3:57写道: >> As I recall, the main things to watch out for, performance-wise, are recursive definitions. When we throw an error from a library function, we *typically* mean that the caller made a mistake. We don't want to build up the call stacks we'd need to debug the library function itself, unless we're actually doing so (in which case we can edit it in, of course). >> >>> On Mon, Jun 17, 2019, 1:09 PM Edward Kmett wrote: >>> Re: your code. This is passing the callStack to each instance and dropping it on the floor for the cases where you ignore the constraint. >>> >>> I’m starting to warm to the idea of putting HasCallStack constraints on the obviously partial combinators in base if we can demonstrate that the performance impact isn't bad in practice, and even really, to some extent if there is a somewhat middling impact on the performance of code that leans on these hard to debug combinators, so long as the performance of their more total siblings remains unaffected. The impact on the perceived debuggability of Haskell seems _likely_ to significantly outweigh the performance concerns. >>> >>> Heck, off of the HEAD of cabal, which we’re encouraging folks to build to play with the ghc 8.8.1 alpha, just today we ran into an issue where the very build system we are using spat out an oh so informative “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that didnt include any explicit bounds. >>> >>> It seems worth implementing and measuring quite how bad the impact would be before pulling the trigger for good. The impact should be reasonable if the constraints only really live right at the outside of base though, then users can choose to propagate the constraint further outwards, just like they get to do with “error” today. >>> >>> Slightly more controversially, MonadFail’s fail could be similarly modified with near zero user facing impact other than a bit of additional static info flowing to explicit callstacks to make it take a HasCallStack constraint. The code in existing instances would all still work. This one I think would need more benchmarking though, as recovering from a fail is a far “lighter” affair than catching an exception, but I’d be happy to raise it to the CLC as a question, especially if we can get benchmarks in hand. >>> >>> —Edward >>> >>> >>>> On Jun 17, 2019, at 4:06 PM, LuoChen wrote: >>>> >>>> I have just confirmed that we can specify HasCallStack separately for different instance of same typeclass, and here is the test code. >>>> >>>> >>>> Oliver Charles 于2019年6月17日周一 上午3:02写道: >>>>> Surely then the call stack is only foldr1, and not foldr1's callsite? >>>>> >>>>>> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, wrote: >>>>>> >>>>>> On Sun, 16 Jun 2019, Simon Jakobi wrote: >>>>>> >>>>>> > > I think only the partial implementations should get that constraint. >>>>>> >>>>>> > Oops, I had the misconception that one couldn't add a HasCallStack >>>>>> > constraint to method implementations. >>>>>> >>>>>> I think you have to declare: >>>>>> >>>>>> instance Foldable [] where >>>>>> foldl1 = foldl1List >>>>>> >>>>>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a >>>>>> foldl1List = ... >>>>>> >>>>>> Would this work?_______________________________________________ >>>>>> Libraries mailing list >>>>>> Libraries at haskell.org >>>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From luochen1990 at gmail.com Wed Jun 19 14:47:49 2019 From: luochen1990 at gmail.com (LuoChen) Date: Wed, 19 Jun 2019 22:47:49 +0800 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: <6A3E215A-266A-4A9E-B896-039F7458B98D@seidel.io> References: <6A3E215A-266A-4A9E-B896-039F7458B98D@seidel.io> Message-ID: @eric Thanks, this withFrozenCallstack works as expected! Maybe we can provide a compiler option to automatically insert `withFrozenCallstack` somewhere when importing other packages, so that we can focus on current working package's call stack, just like david said. Eric Seidel 于2019年6月19日周三 下午7:25写道: > You can use withFrozenCallstack to avoid adding new entries to the > stacktrace (but you still need HasCallstack constraints all the way down to > error, of course). > > > http://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Stack.html#v:withFrozenCallStack > > Sent from my iPhone > > On Jun 19, 2019, at 00:41, LuoChen wrote: > > @david It seem that we doesn't have such a mechanism yet. AFAIK with > `HasCallStack` we can only build a call stack from the deepest bottom. > > Is it possible to build a call stack from middle of the call chain to the > top, without containing the deepest parts? > e.g. f1 -> f2 -> f3 -> error (f -> g means f call g) , is it possible to > build a call stack only contains f1 and f2, without f3 and error? > > David Feuer 于2019年6月18日周二 上午3:57写道: > >> As I recall, the main things to watch out for, performance-wise, are >> recursive definitions. When we throw an error from a library function, we >> *typically* mean that the caller made a mistake. We don't want to build up >> the call stacks we'd need to debug the library function itself, unless >> we're actually doing so (in which case we can edit it in, of course). >> >> On Mon, Jun 17, 2019, 1:09 PM Edward Kmett wrote: >> >>> Re: your code. This is passing the callStack to each instance and >>> dropping it on the floor for the cases where you ignore the constraint. >>> >>> I’m starting to warm to the idea of putting HasCallStack constraints on >>> the obviously partial combinators in base if we can demonstrate that the >>> performance impact isn't bad in practice, and even really, to some extent >>> if there is a somewhat middling impact on the performance of code that >>> leans on these hard to debug combinators, so long as the performance of >>> their more total siblings remains unaffected. The impact on the perceived >>> debuggability of Haskell seems _likely_ to significantly outweigh the >>> performance concerns. >>> >>> Heck, off of the HEAD of cabal, which we’re encouraging folks to build >>> to play with the ghc 8.8.1 alpha, just today we ran into an issue where the >>> very build system we are using spat out an oh so informative >>> “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that >>> didnt include any explicit bounds. >>> >>> It seems worth implementing and measuring quite how bad the impact would >>> be before pulling the trigger for good. The impact should be reasonable if >>> the constraints only really live right at the outside of base though, then >>> users can choose to propagate the constraint further outwards, just like >>> they get to do with “error” today. >>> >>> Slightly more controversially, MonadFail’s fail could be similarly >>> modified with near zero user facing impact other than a bit of additional >>> static info flowing to explicit callstacks to make it take a HasCallStack >>> constraint. The code in existing instances would all still work. This one I >>> think would need more benchmarking though, as recovering from a fail is a >>> far “lighter” affair than catching an exception, but I’d be happy to raise >>> it to the CLC as a question, especially if we can get benchmarks in hand. >>> >>> —Edward >>> >>> >>> On Jun 17, 2019, at 4:06 PM, LuoChen wrote: >>> >>> I have just confirmed that we can specify HasCallStack separately for >>> different instance of same typeclass, and here >>> >>> is the test code. >>> >>> Oliver Charles 于2019年6月17日周一 上午3:02写道: >>> >>>> Surely then the call stack is only foldr1, and not foldr1's callsite? >>>> >>>> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, < >>>> lemming at henning-thielemann.de> wrote: >>>> >>>>> >>>>> On Sun, 16 Jun 2019, Simon Jakobi wrote: >>>>> >>>>> > > I think only the partial implementations should get that >>>>> constraint. >>>>> >>>>> > Oops, I had the misconception that one couldn't add a HasCallStack >>>>> > constraint to method implementations. >>>>> >>>>> I think you have to declare: >>>>> >>>>> instance Foldable [] where >>>>> foldl1 = foldl1List >>>>> >>>>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a >>>>> foldl1List = ... >>>>> >>>>> Would this work?_______________________________________________ >>>>> Libraries mailing list >>>>> Libraries at haskell.org >>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>>>> >>>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> >> _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From matthewtpickering at gmail.com Wed Jun 19 15:11:09 2019 From: matthewtpickering at gmail.com (Matthew Pickering) Date: Wed, 19 Jun 2019 16:11:09 +0100 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: <6A3E215A-266A-4A9E-B896-039F7458B98D@seidel.io> Message-ID: I find this thread a bit concerning. In my opinion the current best way to get call stacks on exceptions is with `-xc`. Adding runtime overhead to every user program is not acceptable. `HasCallStack` is useful in libraries such as shake or hspec which use them to good effect to provide callstacks to users on exceptions controlled by the libraries. There is an argument that it would be good to disentangle `-xc` from `prof` but you would still have to compile `base` in this way which instruments these partial functions (as a user can not do it herself). I'm not too sure on the details but I don't think -xc uses any information from the profiling header so the fact it's connected with -prof seems more like convenience than necessity. Matt On Wed, Jun 19, 2019 at 3:48 PM LuoChen wrote: > > @eric Thanks, this withFrozenCallstack works as expected! Maybe we can provide a compiler option to automatically insert `withFrozenCallstack` somewhere when importing other packages, so that we can focus on current working package's call stack, just like david said. > > Eric Seidel 于2019年6月19日周三 下午7:25写道: >> >> You can use withFrozenCallstack to avoid adding new entries to the stacktrace (but you still need HasCallstack constraints all the way down to error, of course). >> >> http://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Stack.html#v:withFrozenCallStack >> >> Sent from my iPhone >> >> On Jun 19, 2019, at 00:41, LuoChen wrote: >> >> @david It seem that we doesn't have such a mechanism yet. AFAIK with `HasCallStack` we can only build a call stack from the deepest bottom. >> >> Is it possible to build a call stack from middle of the call chain to the top, without containing the deepest parts? >> e.g. f1 -> f2 -> f3 -> error (f -> g means f call g) , is it possible to build a call stack only contains f1 and f2, without f3 and error? >> >> David Feuer 于2019年6月18日周二 上午3:57写道: >>> >>> As I recall, the main things to watch out for, performance-wise, are recursive definitions. When we throw an error from a library function, we *typically* mean that the caller made a mistake. We don't want to build up the call stacks we'd need to debug the library function itself, unless we're actually doing so (in which case we can edit it in, of course). >>> >>> On Mon, Jun 17, 2019, 1:09 PM Edward Kmett wrote: >>>> >>>> Re: your code. This is passing the callStack to each instance and dropping it on the floor for the cases where you ignore the constraint. >>>> >>>> I’m starting to warm to the idea of putting HasCallStack constraints on the obviously partial combinators in base if we can demonstrate that the performance impact isn't bad in practice, and even really, to some extent if there is a somewhat middling impact on the performance of code that leans on these hard to debug combinators, so long as the performance of their more total siblings remains unaffected. The impact on the perceived debuggability of Haskell seems _likely_ to significantly outweigh the performance concerns. >>>> >>>> Heck, off of the HEAD of cabal, which we’re encouraging folks to build to play with the ghc 8.8.1 alpha, just today we ran into an issue where the very build system we are using spat out an oh so informative “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that didnt include any explicit bounds. >>>> >>>> It seems worth implementing and measuring quite how bad the impact would be before pulling the trigger for good. The impact should be reasonable if the constraints only really live right at the outside of base though, then users can choose to propagate the constraint further outwards, just like they get to do with “error” today. >>>> >>>> Slightly more controversially, MonadFail’s fail could be similarly modified with near zero user facing impact other than a bit of additional static info flowing to explicit callstacks to make it take a HasCallStack constraint. The code in existing instances would all still work. This one I think would need more benchmarking though, as recovering from a fail is a far “lighter” affair than catching an exception, but I’d be happy to raise it to the CLC as a question, especially if we can get benchmarks in hand. >>>> >>>> —Edward >>>> >>>> >>>> On Jun 17, 2019, at 4:06 PM, LuoChen wrote: >>>> >>>> I have just confirmed that we can specify HasCallStack separately for different instance of same typeclass, and here is the test code. >>>> >>>> >>>> Oliver Charles 于2019年6月17日周一 上午3:02写道: >>>>> >>>>> Surely then the call stack is only foldr1, and not foldr1's callsite? >>>>> >>>>> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, wrote: >>>>>> >>>>>> >>>>>> On Sun, 16 Jun 2019, Simon Jakobi wrote: >>>>>> >>>>>> > > I think only the partial implementations should get that constraint. >>>>>> >>>>>> > Oops, I had the misconception that one couldn't add a HasCallStack >>>>>> > constraint to method implementations. >>>>>> >>>>>> I think you have to declare: >>>>>> >>>>>> instance Foldable [] where >>>>>> foldl1 = foldl1List >>>>>> >>>>>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a >>>>>> foldl1List = ... >>>>>> >>>>>> Would this work?_______________________________________________ >>>>>> Libraries mailing list >>>>>> Libraries at haskell.org >>>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>>> >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>>> >>>> _______________________________________________ >>>> Libraries mailing list >>>> Libraries at haskell.org >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries From eric at seidel.io Wed Jun 19 16:27:39 2019 From: eric at seidel.io (Eric Seidel) Date: Wed, 19 Jun 2019 12:27:39 -0400 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: <6A3E215A-266A-4A9E-B896-039F7458B98D@seidel.io> Message-ID: I’m not sure I understand your objection. You seem to be ok with libraries adding HasCallstack constraints for partial functions they control, but the proposal here is to do precisely that for base. The performance concern I completely understand, but there seems to be something else going on too. Sent from my iPhone > On Jun 19, 2019, at 11:11, Matthew Pickering wrote: > > I find this thread a bit concerning. In my opinion the current best > way to get call stacks on exceptions is with `-xc`. Adding runtime > overhead to every user program is not acceptable. > > `HasCallStack` is useful in libraries such as shake or hspec which use > them to good effect to provide callstacks to users on exceptions > controlled by the libraries. > > There is an argument that it would be good to disentangle `-xc` from > `prof` but you would still have to compile `base` in this way which > instruments these partial functions (as a user can not do it herself). > I'm not too sure on the details but I don't think -xc uses any > information from the profiling header so the fact it's connected with > -prof seems more like convenience than necessity. > > Matt > >> On Wed, Jun 19, 2019 at 3:48 PM LuoChen wrote: >> >> @eric Thanks, this withFrozenCallstack works as expected! Maybe we can provide a compiler option to automatically insert `withFrozenCallstack` somewhere when importing other packages, so that we can focus on current working package's call stack, just like david said. >> >> Eric Seidel 于2019年6月19日周三 下午7:25写道: >>> >>> You can use withFrozenCallstack to avoid adding new entries to the stacktrace (but you still need HasCallstack constraints all the way down to error, of course). >>> >>> http://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Stack.html#v:withFrozenCallStack >>> >>> Sent from my iPhone >>> >>> On Jun 19, 2019, at 00:41, LuoChen wrote: >>> >>> @david It seem that we doesn't have such a mechanism yet. AFAIK with `HasCallStack` we can only build a call stack from the deepest bottom. >>> >>> Is it possible to build a call stack from middle of the call chain to the top, without containing the deepest parts? >>> e.g. f1 -> f2 -> f3 -> error (f -> g means f call g) , is it possible to build a call stack only contains f1 and f2, without f3 and error? >>> >>> David Feuer 于2019年6月18日周二 上午3:57写道: >>>> >>>> As I recall, the main things to watch out for, performance-wise, are recursive definitions. When we throw an error from a library function, we *typically* mean that the caller made a mistake. We don't want to build up the call stacks we'd need to debug the library function itself, unless we're actually doing so (in which case we can edit it in, of course). >>>> >>>>> On Mon, Jun 17, 2019, 1:09 PM Edward Kmett wrote: >>>>> >>>>> Re: your code. This is passing the callStack to each instance and dropping it on the floor for the cases where you ignore the constraint. >>>>> >>>>> I’m starting to warm to the idea of putting HasCallStack constraints on the obviously partial combinators in base if we can demonstrate that the performance impact isn't bad in practice, and even really, to some extent if there is a somewhat middling impact on the performance of code that leans on these hard to debug combinators, so long as the performance of their more total siblings remains unaffected. The impact on the perceived debuggability of Haskell seems _likely_ to significantly outweigh the performance concerns. >>>>> >>>>> Heck, off of the HEAD of cabal, which we’re encouraging folks to build to play with the ghc 8.8.1 alpha, just today we ran into an issue where the very build system we are using spat out an oh so informative “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that didnt include any explicit bounds. >>>>> >>>>> It seems worth implementing and measuring quite how bad the impact would be before pulling the trigger for good. The impact should be reasonable if the constraints only really live right at the outside of base though, then users can choose to propagate the constraint further outwards, just like they get to do with “error” today. >>>>> >>>>> Slightly more controversially, MonadFail’s fail could be similarly modified with near zero user facing impact other than a bit of additional static info flowing to explicit callstacks to make it take a HasCallStack constraint. The code in existing instances would all still work. This one I think would need more benchmarking though, as recovering from a fail is a far “lighter” affair than catching an exception, but I’d be happy to raise it to the CLC as a question, especially if we can get benchmarks in hand. >>>>> >>>>> —Edward >>>>> >>>>> >>>>> On Jun 17, 2019, at 4:06 PM, LuoChen wrote: >>>>> >>>>> I have just confirmed that we can specify HasCallStack separately for different instance of same typeclass, and here is the test code. >>>>> >>>>> >>>>> Oliver Charles 于2019年6月17日周一 上午3:02写道: >>>>>> >>>>>> Surely then the call stack is only foldr1, and not foldr1's callsite? >>>>>> >>>>>>> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, wrote: >>>>>>> >>>>>>> >>>>>>> On Sun, 16 Jun 2019, Simon Jakobi wrote: >>>>>>> >>>>>>>>> I think only the partial implementations should get that constraint. >>>>>>> >>>>>>>> Oops, I had the misconception that one couldn't add a HasCallStack >>>>>>>> constraint to method implementations. >>>>>>> >>>>>>> I think you have to declare: >>>>>>> >>>>>>> instance Foldable [] where >>>>>>> foldl1 = foldl1List >>>>>>> >>>>>>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a >>>>>>> foldl1List = ... >>>>>>> >>>>>>> Would this work?_______________________________________________ >>>>>>> Libraries mailing list >>>>>>> Libraries at haskell.org >>>>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>>>> >>>>> _______________________________________________ >>>>> Libraries mailing list >>>>> Libraries at haskell.org >>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>>>> >>>>> _______________________________________________ >>>>> Libraries mailing list >>>>> Libraries at haskell.org >>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >>> >>> _______________________________________________ >>> Libraries mailing list >>> Libraries at haskell.org >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries From david.feuer at gmail.com Wed Jun 19 22:19:32 2019 From: david.feuer at gmail.com (David Feuer) Date: Wed, 19 Jun 2019 18:19:32 -0400 Subject: Data.Graph transitive closure Message-ID: I just noticed that Data.Graph doesn't offer a transitive closure operation. Looking into implementing one, I discovered that doing so efficiently has been the subject of non-trivial research [*]. So if there's any demand, we should try to implement a reasonably efficient version in containers. Anybody want one? [*] http://www.cs.hut.fi/~enu/thesis.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From eacameron at gmail.com Wed Jun 19 22:38:58 2019 From: eacameron at gmail.com (Elliot Cameron) Date: Wed, 19 Jun 2019 18:38:58 -0400 Subject: Data.Graph transitive closure In-Reply-To: References: Message-ID: It's hard to imagine reaching for a graph without some thought that you'd want to compute a closure. I've wanted this in the past, but I've never thought seriously about using Data.Graph for it. Perhaps this is why? On Wed, Jun 19, 2019 at 6:20 PM David Feuer wrote: > I just noticed that Data.Graph doesn't offer a transitive closure > operation. Looking into implementing one, I discovered that doing so > efficiently has been the subject of non-trivial research [*]. So if there's > any demand, we should try to implement a reasonably efficient version in > containers. Anybody want one? > > [*] http://www.cs.hut.fi/~enu/thesis.html > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From chessai1996 at gmail.com Wed Jun 19 22:47:39 2019 From: chessai1996 at gmail.com (chessai .) Date: Wed, 19 Jun 2019 18:47:39 -0400 Subject: Data.Graph transitive closure In-Reply-To: References: Message-ID: I want one, because, why not? It might be useful to those who use that API. I'm always excited to see APIs become more complete. On Wed, Jun 19, 2019, 6:39 PM Elliot Cameron wrote: > It's hard to imagine reaching for a graph without some thought that you'd > want to compute a closure. I've wanted this in the past, but I've never > thought seriously about using Data.Graph for it. Perhaps this is why? > > On Wed, Jun 19, 2019 at 6:20 PM David Feuer wrote: > >> I just noticed that Data.Graph doesn't offer a transitive closure >> operation. Looking into implementing one, I discovered that doing so >> efficiently has been the subject of non-trivial research [*]. So if there's >> any demand, we should try to implement a reasonably efficient version in >> containers. Anybody want one? >> >> [*] http://www.cs.hut.fi/~enu/thesis.html >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From andreas.abel at ifi.lmu.de Thu Jun 20 07:12:38 2019 From: andreas.abel at ifi.lmu.de (Andreas Abel) Date: Thu, 20 Jun 2019 09:12:38 +0200 Subject: Data.Graph transitive closure In-Reply-To: References: Message-ID: <2a607f42-1c8b-601b-50e4-38afa411e4b1@ifi.lmu.de> Since there was nothing standard out there we (Agda) rolled our own. https://github.com/agda/agda/blob/f3f82fa0510335087653ba715cef06a5702deb18/src/full/Agda/Utils/Graph/AdjacencyMap/Unidirectional.hs#L719-L877 There are even two versions (complete (Abel) and gaussJordanFloydWarshallMcNaughtonYamada (Danielsson)) which behave differently wrt. runtime, so we use both, for different purposes. Algorithms might look different for different graph representations, we use a version of adjacency lists which works also well for sparse graphs. On 2019-06-20 00:38, Elliot Cameron wrote: > It's hard to imagine reaching for a graph without some thought that > you'd want to compute a closure. I've wanted this in the past, but I've > never thought seriously about using Data.Graph for it. Perhaps this is why? > > On Wed, Jun 19, 2019 at 6:20 PM David Feuer > wrote: > > I just noticed that Data.Graph doesn't offer a transitive closure > operation. Looking into implementing one, I discovered that doing so > efficiently has been the subject of non-trivial research [*]. So if > there's any demand, we should try to implement a reasonably > efficient version in containers. Anybody want one? > > [*] http://www.cs.hut.fi/~enu/thesis.html > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > From andrew.thaddeus at gmail.com Thu Jun 20 12:44:46 2019 From: andrew.thaddeus at gmail.com (Andrew Martin) Date: Thu, 20 Jun 2019 08:44:46 -0400 Subject: Cayenne Source Code Message-ID: I just read through Lennart's paper on Cayenne, which was written in Haskell. It would be informative for me to look at the source code for a simple dependently typed language like this. (The paper claims the typechecker is only around 5000 LoC.) However, I cannot find the source code anywhere. Has it been devoured by the cruel jaws of the ephemeral web, or does someone out there still have a copy of it? -- -Andrew Thaddeus Martin -------------- next part -------------- An HTML attachment was scrubbed... URL: From ollie at ocharles.org.uk Thu Jun 20 13:25:17 2019 From: ollie at ocharles.org.uk (Oliver Charles) Date: Thu, 20 Jun 2019 14:25:17 +0100 Subject: Cayenne Source Code In-Reply-To: References: Message-ID: It does not directly answer your question, but are you aware of Pie? https://github.com/david-christiansen/pie-hs On Thu, Jun 20, 2019 at 1:45 PM Andrew Martin wrote: > > I just read through Lennart's paper on Cayenne, which was written in Haskell. It would be informative for me to look at the source code for a simple dependently typed language like this. (The paper claims the typechecker is only around 5000 LoC.) However, I cannot find the source code anywhere. Has it been devoured by the cruel jaws of the ephemeral web, or does someone out there still have a copy of it? > > -- > -Andrew Thaddeus Martin > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries From andrew.thaddeus at gmail.com Thu Jun 20 13:27:34 2019 From: andrew.thaddeus at gmail.com (Andrew Martin) Date: Thu, 20 Jun 2019 09:27:34 -0400 Subject: Cayenne Source Code In-Reply-To: References: Message-ID: Thanks! Pie looks like it will be equally instructional for my purposes. On Thu, Jun 20, 2019 at 9:25 AM Oliver Charles wrote: > It does not directly answer your question, but are you aware of Pie? > > https://github.com/david-christiansen/pie-hs > > On Thu, Jun 20, 2019 at 1:45 PM Andrew Martin > wrote: > > > > I just read through Lennart's paper on Cayenne, which was written in > Haskell. It would be informative for me to look at the source code for a > simple dependently typed language like this. (The paper claims the > typechecker is only around 5000 LoC.) However, I cannot find the source > code anywhere. Has it been devoured by the cruel jaws of the ephemeral web, > or does someone out there still have a copy of it? > > > > -- > > -Andrew Thaddeus Martin > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -- -Andrew Thaddeus Martin -------------- next part -------------- An HTML attachment was scrubbed... URL: From johannes.waldmann at htwk-leipzig.de Fri Jun 21 14:01:03 2019 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Fri, 21 Jun 2019 16:01:03 +0200 Subject: Data.Graph transitive closure Message-ID: > ... reasonably efficient transitive closure for Data.Graph ... well, since we have type Graph = Array Vertex [Vertex] efficiency is already questionable? We cannot quickly check whether an edge is present, we cannot quickly get all predecessors of a vertex. But perhaps we don't need to. The underlying assumptions (cost of elementary operations) of http://www.cs.hut.fi/~enu/thesis.html are not immediately clear. The cited Agda library has newtype Graph n e = Graph (Map n (Map n e)) Another option is to store back edges as well, as in https://github.com/haskell-works/relation/blob/master/src/Data/Relation/Internal.hs FGL fuses these two maps type GraphRep a b = IntMap (Context' a b) type Context' a b = (IntMap [b], a, IntMap [b]) https://hackage.haskell.org/package/fgl-5.7.0.1/docs/src/Data.Graph.Inductive.PatriciaTree.html#Gr this saves some look-ups (if you need successors and predecessors of the very same node) but this can't be used for relations, where start and end of an edge have different types. But for transitive closure, these types would agree anyway. What to make of this? Perhaps Data.Graph should be moved out of containers. The design space is just too large to single out one specific point? If we keep it, it would be very nice to document the complexity of algorithms. Section 7 of the King/Launchbury paper (cited in the API docs) claims "DFS in O(V+E)", backed up by experiments. This seems to be the main motivation for this library (DFS, with application: SCC). It's not clear whether the underlying design should be recommended for a general graph library. - Johannes From eacameron at gmail.com Fri Jun 21 16:37:26 2019 From: eacameron at gmail.com (Elliot Cameron) Date: Fri, 21 Jun 2019 12:37:26 -0400 Subject: Data.Graph transitive closure In-Reply-To: References: Message-ID: I've actually wondered why Data.Graph existed since it is obviously not written for serious/heavy usage. So I do see an argument for deprecating it instead of polishing it. On Fri, Jun 21, 2019 at 10:10 AM Johannes Waldmann < johannes.waldmann at htwk-leipzig.de> wrote: > > ... reasonably efficient transitive closure for Data.Graph ... > > well, since we have > > type Graph = Array Vertex [Vertex] > > efficiency is already questionable? > We cannot quickly check whether an edge is present, > we cannot quickly get all predecessors of a vertex. > But perhaps we don't need to. The underlying assumptions > (cost of elementary operations) > of http://www.cs.hut.fi/~enu/thesis.html > are not immediately clear. > > > The cited Agda library has > > newtype Graph n e = Graph (Map n (Map n e)) > > > Another option is to store back edges as well, as in > > https://github.com/haskell-works/relation/blob/master/src/Data/Relation/Internal.hs > > > FGL fuses these two maps > > type GraphRep a b = IntMap (Context' a b) > type Context' a b = (IntMap [b], a, IntMap [b]) > > > https://hackage.haskell.org/package/fgl-5.7.0.1/docs/src/Data.Graph.Inductive.PatriciaTree.html#Gr > > > this saves some look-ups (if you need successors and > predecessors of the very same node) > but this can't be used for relations, > where start and end of an edge have different types. > But for transitive closure, these types would agree anyway. > > > What to make of this? > > Perhaps Data.Graph should be moved out of containers. > The design space is just too large to single out one specific point? > If we keep it, it would be very nice to document the complexity > of algorithms. Section 7 of the King/Launchbury paper > (cited in the API docs) claims "DFS in O(V+E)", backed up by > experiments. This seems to be the main motivation for this library > (DFS, with application: SCC). It's not clear whether the underlying > design should be recommended for a general graph library. > > > - Johannes > > > > > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Fri Jun 21 16:49:34 2019 From: david.feuer at gmail.com (David Feuer) Date: Fri, 21 Jun 2019 12:49:34 -0400 Subject: Data.Graph transitive closure In-Reply-To: References: Message-ID: Yes, Data.Graph is a weird, difficult-to-polish corner of containers. I'm all for removing it, but there's one sticky point: it's managed to accumulate some extremely important reverse dependencies. In particular, GHC, Cabal, and Agda all use it. So if we want to deprecate it, we need a really good plan for what happens next. On Fri, Jun 21, 2019, 12:37 PM Elliot Cameron wrote: > I've actually wondered why Data.Graph existed since it is obviously not > written for serious/heavy usage. So I do see an argument for deprecating it > instead of polishing it. > > On Fri, Jun 21, 2019 at 10:10 AM Johannes Waldmann < > johannes.waldmann at htwk-leipzig.de> wrote: > >> > ... reasonably efficient transitive closure for Data.Graph ... >> >> well, since we have >> >> type Graph = Array Vertex [Vertex] >> >> efficiency is already questionable? >> We cannot quickly check whether an edge is present, >> we cannot quickly get all predecessors of a vertex. >> But perhaps we don't need to. The underlying assumptions >> (cost of elementary operations) >> of http://www.cs.hut.fi/~enu/thesis.html >> are not immediately clear. >> >> >> The cited Agda library has >> >> newtype Graph n e = Graph (Map n (Map n e)) >> >> >> Another option is to store back edges as well, as in >> >> https://github.com/haskell-works/relation/blob/master/src/Data/Relation/Internal.hs >> >> >> FGL fuses these two maps >> >> type GraphRep a b = IntMap (Context' a b) >> type Context' a b = (IntMap [b], a, IntMap [b]) >> >> >> https://hackage.haskell.org/package/fgl-5.7.0.1/docs/src/Data.Graph.Inductive.PatriciaTree.html#Gr >> >> >> this saves some look-ups (if you need successors and >> predecessors of the very same node) >> but this can't be used for relations, >> where start and end of an edge have different types. >> But for transitive closure, these types would agree anyway. >> >> >> What to make of this? >> >> Perhaps Data.Graph should be moved out of containers. >> The design space is just too large to single out one specific point? >> If we keep it, it would be very nice to document the complexity >> of algorithms. Section 7 of the King/Launchbury paper >> (cited in the API docs) claims "DFS in O(V+E)", backed up by >> experiments. This seems to be the main motivation for this library >> (DFS, with application: SCC). It's not clear whether the underlying >> design should be recommended for a general graph library. >> >> >> - Johannes >> >> >> >> >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From johannes.waldmann at htwk-leipzig.de Fri Jun 21 18:10:39 2019 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Fri, 21 Jun 2019 20:10:39 +0200 Subject: Data.Graph transitive closure In-Reply-To: References: Message-ID: > I've actually wondered why Data.Graph existed since it is obviously not > written for serious/heavy usage. But it was! As I understand, it was originally part of GHC (ghc-0.29/ghc/compiler/utils/Digraph.lhs) for computing SCCs (in the graph of dependencies of declarations). So we can assume that it does this well. And I guess it's used for the very same purpose in Cabal and Agda. - J. From david.feuer at gmail.com Fri Jun 21 18:20:37 2019 From: david.feuer at gmail.com (David Feuer) Date: Fri, 21 Jun 2019 14:20:37 -0400 Subject: Data.Graph transitive closure In-Reply-To: References: Message-ID: The big problem is that when it was broken off into containers, there was no attempt to add appropriate abstraction barriers. So it's ... awkward. On Fri, Jun 21, 2019, 2:10 PM Johannes Waldmann < johannes.waldmann at htwk-leipzig.de> wrote: > > > I've actually wondered why Data.Graph existed since it is obviously not > > written for serious/heavy usage. > > But it was! > > As I understand, it was originally part of GHC > (ghc-0.29/ghc/compiler/utils/Digraph.lhs) > for computing SCCs (in the graph of dependencies of declarations). > > So we can assume that it does this well. > > And I guess it's used for the very same purpose in Cabal and Agda. > > - J. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Fri Jun 21 18:42:37 2019 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 21 Jun 2019 14:42:37 -0400 Subject: Proposal: add HasCallStack for all partial functions in base In-Reply-To: References: <6A3E215A-266A-4A9E-B896-039F7458B98D@seidel.io> Message-ID: agreed, the -xc flag is an underused debugging tool, and making that easier to work with / front and center is probably a high impact approach On Wed, Jun 19, 2019 at 11:11 AM Matthew Pickering < matthewtpickering at gmail.com> wrote: > I find this thread a bit concerning. In my opinion the current best > way to get call stacks on exceptions is with `-xc`. Adding runtime > overhead to every user program is not acceptable. > > `HasCallStack` is useful in libraries such as shake or hspec which use > them to good effect to provide callstacks to users on exceptions > controlled by the libraries. > > There is an argument that it would be good to disentangle `-xc` from > `prof` but you would still have to compile `base` in this way which > instruments these partial functions (as a user can not do it herself). > I'm not too sure on the details but I don't think -xc uses any > information from the profiling header so the fact it's connected with > -prof seems more like convenience than necessity. > > Matt > > On Wed, Jun 19, 2019 at 3:48 PM LuoChen wrote: > > > > @eric Thanks, this withFrozenCallstack works as expected! Maybe we can > provide a compiler option to automatically insert `withFrozenCallstack` > somewhere when importing other packages, so that we can focus on current > working package's call stack, just like david said. > > > > Eric Seidel 于2019年6月19日周三 下午7:25写道: > >> > >> You can use withFrozenCallstack to avoid adding new entries to the > stacktrace (but you still need HasCallstack constraints all the way down to > error, of course). > >> > >> > http://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Stack.html#v:withFrozenCallStack > >> > >> Sent from my iPhone > >> > >> On Jun 19, 2019, at 00:41, LuoChen wrote: > >> > >> @david It seem that we doesn't have such a mechanism yet. AFAIK with > `HasCallStack` we can only build a call stack from the deepest bottom. > >> > >> Is it possible to build a call stack from middle of the call chain to > the top, without containing the deepest parts? > >> e.g. f1 -> f2 -> f3 -> error (f -> g means f call g) , is it possible > to build a call stack only contains f1 and f2, without f3 and error? > >> > >> David Feuer 于2019年6月18日周二 上午3:57写道: > >>> > >>> As I recall, the main things to watch out for, performance-wise, are > recursive definitions. When we throw an error from a library function, we > *typically* mean that the caller made a mistake. We don't want to build up > the call stacks we'd need to debug the library function itself, unless > we're actually doing so (in which case we can edit it in, of course). > >>> > >>> On Mon, Jun 17, 2019, 1:09 PM Edward Kmett wrote: > >>>> > >>>> Re: your code. This is passing the callStack to each instance and > dropping it on the floor for the cases where you ignore the constraint. > >>>> > >>>> I’m starting to warm to the idea of putting HasCallStack constraints > on the obviously partial combinators in base if we can demonstrate that the > performance impact isn't bad in practice, and even really, to some extent > if there is a somewhat middling impact on the performance of code that > leans on these hard to debug combinators, so long as the performance of > their more total siblings remains unaffected. The impact on the perceived > debuggability of Haskell seems _likely_ to significantly outweigh the > performance concerns. > >>>> > >>>> Heck, off of the HEAD of cabal, which we’re encouraging folks to > build to play with the ghc 8.8.1 alpha, just today we ran into an issue > where the very build system we are using spat out an oh so informative > “Prelude.foldr1: Empty list” when using a pkgconfig-depends stanza that > didnt include any explicit bounds. > >>>> > >>>> It seems worth implementing and measuring quite how bad the impact > would be before pulling the trigger for good. The impact should be > reasonable if the constraints only really live right at the outside of base > though, then users can choose to propagate the constraint further outwards, > just like they get to do with “error” today. > >>>> > >>>> Slightly more controversially, MonadFail’s fail could be similarly > modified with near zero user facing impact other than a bit of additional > static info flowing to explicit callstacks to make it take a HasCallStack > constraint. The code in existing instances would all still work. This one I > think would need more benchmarking though, as recovering from a fail is a > far “lighter” affair than catching an exception, but I’d be happy to raise > it to the CLC as a question, especially if we can get benchmarks in hand. > >>>> > >>>> —Edward > >>>> > >>>> > >>>> On Jun 17, 2019, at 4:06 PM, LuoChen wrote: > >>>> > >>>> I have just confirmed that we can specify HasCallStack separately for > different instance of same typeclass, and here is the test code. > >>>> > >>>> > >>>> Oliver Charles 于2019年6月17日周一 上午3:02写道: > >>>>> > >>>>> Surely then the call stack is only foldr1, and not foldr1's callsite? > >>>>> > >>>>> On Sun, 16 Jun 2019, 8:27 pm Henning Thielemann, < > lemming at henning-thielemann.de> wrote: > >>>>>> > >>>>>> > >>>>>> On Sun, 16 Jun 2019, Simon Jakobi wrote: > >>>>>> > >>>>>> > > I think only the partial implementations should get that > constraint. > >>>>>> > >>>>>> > Oops, I had the misconception that one couldn't add a HasCallStack > >>>>>> > constraint to method implementations. > >>>>>> > >>>>>> I think you have to declare: > >>>>>> > >>>>>> instance Foldable [] where > >>>>>> foldl1 = foldl1List > >>>>>> > >>>>>> foldl1List :: HasCallStack => (a->a->a) -> [a] -> a > >>>>>> foldl1List = ... > >>>>>> > >>>>>> Would this work?_______________________________________________ > >>>>>> Libraries mailing list > >>>>>> Libraries at haskell.org > >>>>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > >>>> > >>>> _______________________________________________ > >>>> Libraries mailing list > >>>> Libraries at haskell.org > >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > >>>> > >>>> _______________________________________________ > >>>> Libraries mailing list > >>>> Libraries at haskell.org > >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > >> > >> _______________________________________________ > >> Libraries mailing list > >> Libraries at haskell.org > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > > > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Fri Jun 21 18:44:29 2019 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 21 Jun 2019 14:44:29 -0400 Subject: Data.Graph transitive closure In-Reply-To: References: Message-ID: i've definitely used the efficient SCC bits of Data.Graph in the past. graphs are just such a rich area that it seems doubtful that there'll ever be a one true library On Fri, Jun 21, 2019 at 2:21 PM David Feuer wrote: > The big problem is that when it was broken off into containers, there was > no attempt to add appropriate abstraction barriers. So it's ... awkward. > > On Fri, Jun 21, 2019, 2:10 PM Johannes Waldmann < > johannes.waldmann at htwk-leipzig.de> wrote: > >> >> > I've actually wondered why Data.Graph existed since it is obviously not >> > written for serious/heavy usage. >> >> But it was! >> >> As I understand, it was originally part of GHC >> (ghc-0.29/ghc/compiler/utils/Digraph.lhs) >> for computing SCCs (in the graph of dependencies of declarations). >> >> So we can assume that it does this well. >> >> And I guess it's used for the very same purpose in Cabal and Agda. >> >> - J. >> _______________________________________________ >> Libraries mailing list >> Libraries at haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From johannes.waldmann at htwk-leipzig.de Fri Jun 21 18:48:42 2019 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Fri, 21 Jun 2019 20:48:42 +0200 Subject: Data.Graph transitive closure In-Reply-To: References: Message-ID: <0b85bef6-eaf1-fade-29e1-99f475ba57f9@htwk-leipzig.de> On 21.06.19 20:44, Carter Schonwald wrote: > ... it seems doubtful that there'll > ever be a one true [graph] library Yes. My point was that Data.Graph isn't a "graph library" (it was never meant to be) - it's a "DFS/SCC library". - J. From alan.isaac at gmail.com Sat Jun 22 00:59:11 2019 From: alan.isaac at gmail.com (Alan Isaac) Date: Fri, 21 Jun 2019 20:59:11 -0400 Subject: Data.Graph transitive closure In-Reply-To: References: Message-ID: <979848c9-dcf7-68f3-38fa-2a513ecc1df7@gmail.com> Feedback from an occasional Haskell user: I would use it. I've noticed that computational implementations of "transitive closure" often deviate from my (user-level) understanding of the standard mathematical definition. Specifically, self loops are often discarded. I assume/hope the math def will be used in haskell. A prominent example is Mathematica's TransitiveClosureGraph command. E.g., `TransitiveClosureGraph[{a -> b, b -> c, c -> a}]` has no self loops, even though `a` is clearly reachable from `a`, and TransitiveClosureGraph[{a -> a, b -> b, c -> c}]` is empty!) In the past networkx also had this flaw (although they indicated a plan to fix this; I'd have to recheck the current status). Cheers, Alan Isaac PS My apologies if I misread your post; I understood it to request user feedback, not just developer assessment. On 6/20/2019 8:00 AM, David wrote: > I just noticed that Data.Graph doesn't offer a transitive closure > operation. Looking into implementing one, I discovered that doing so > efficiently has been the subject of non-trivial research [*]. So if there's > any demand, we should try to implement a reasonably efficient version in > containers. Anybody want one? From johannes.waldmann at htwk-leipzig.de Sat Jun 22 13:03:14 2019 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Sat, 22 Jun 2019 15:03:14 +0200 Subject: Data.Graph transitive closure Message-ID: > .. I would use it. what is your use case? Can you extract test cases that could be used to validate correctness and complexity of an implementation? Specific question: assume the implementation gives you S = transitive-closure-of(R). Then what do you do with S (in your application)? Does Data.Graph (i.e., array of lists of successors) have the right structure? E.g., it is inefficient to test for membership in these lists. But lists are fine if you need to handle all successors anyway. Evaluation of (recursive) Datalog queries is another application area of transitive closure algorithms. (e.g., https://doi.org/10.1007/BF01264013 ) - J. From johannes.waldmann at htwk-leipzig.de Mon Jun 24 11:02:29 2019 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Mon, 24 Jun 2019 13:02:29 +0200 Subject: Data.Graph transitive closure In-Reply-To: <7C14FE10-8E36-4619-AC0C-06A9691175B1@scss.tcd.ie> References: <0b85bef6-eaf1-fade-29e1-99f475ba57f9@htwk-leipzig.de> <7C14FE10-8E36-4619-AC0C-06A9691175B1@scss.tcd.ie> Message-ID: <983989f8-8ba4-1c37-e3d0-93a5ccaf7ea1@htwk-leipzig.de> Hi, > I looked at doing this in a "principled" way a long time ago. > I then got distracted by something else..... You don't say :-) Well, short-term suggestion (for containers:Data.Graph) don't change existing code, but improve documentation and do some benchmarking https://github.com/haskell/containers/issues/648 https://github.com/haskell/containers/issues/649 @David: perhaps you can label these issues as "nice to have" so it does not look like "bugs that need fixing". Benchmarking would make for a nice student project? In fact, I will pitch this to my current class. - Johannes From chessai1996 at gmail.com Mon Jun 24 14:02:51 2019 From: chessai1996 at gmail.com (chessai .) Date: Mon, 24 Jun 2019 10:02:51 -0400 Subject: transformers mirroring to GitHub Message-ID: Could we mirror transformers from darcshub to GitHub? This would make browsing the current source easier for those of us who do not frequent darcshub. It would also help with the uniformity of having core libs on GitHub. Of course this would just be a mirror, and users would be advised to not open PRs there. Not sure how easy mirroring from DarcsHub to GitHub is. Thoughts? Thanks From hvriedel at gmail.com Mon Jun 24 14:08:53 2019 From: hvriedel at gmail.com (Herbert Valerio Riedel) Date: Mon, 24 Jun 2019 16:08:53 +0200 Subject: [core libraries] transformers mirroring to GitHub In-Reply-To: References: Message-ID: On Mon, Jun 24, 2019 at 4:03 PM chessai . wrote: > Could we mirror transformers from darcshub to GitHub? > Not sure if this answers your question, but I set up such a darcs->git mirror years ago on http://git.haskell.org/darcs-mirrors/transformers.git to be used as upstream repo for GHC's actual submodule http://git.haskell.org/packages/transformers.git (which needs to be a separate repo for reasons), and which is the source of the GitHub mirror https://github.com/ghc/packages-transformers -------------- next part -------------- An HTML attachment was scrubbed... URL: From Andrew.Butterfield at scss.tcd.ie Mon Jun 24 09:53:42 2019 From: Andrew.Butterfield at scss.tcd.ie (Andrew Butterfield) Date: Mon, 24 Jun 2019 10:53:42 +0100 Subject: Data.Graph transitive closure In-Reply-To: <0b85bef6-eaf1-fade-29e1-99f475ba57f9@htwk-leipzig.de> References: <0b85bef6-eaf1-fade-29e1-99f475ba57f9@htwk-leipzig.de> Message-ID: <7C14FE10-8E36-4619-AC0C-06A9691175B1@scss.tcd.ie> Dear Johannes, Carter, David, libraries, As a formal methodist who likes and uses functional languages a lot, I looked at doing this in a "principled" way a long time ago. The idea was to formally specify an abstract graph datatype and various graph operations (create, query, modify, transitive closure, etc, etc...) and then show correctness of of simple but possibly inefficient implementations. Then the plan was to develop efficient operations, including use of appropriate graph representation types, and show formally that they were refinements of the inefficient ones. It rapidly became *very* clear that the best/only? way to do something efficiently was to decide which operations were important, and specialise for those. Woe betide you if you left out an operator that later would be important, because its efficient implementation could well force you to do complete re-design. Basically, it is not feasible to design a large/general-purpose graph library that does everything efficiently. I then got distracted by something else..... Regards, Andrew > On 21 Jun 2019, at 19:48, Johannes Waldmann wrote: > > On 21.06.19 20:44, Carter Schonwald wrote: > >> ... it seems doubtful that there'll >> ever be a one true [graph] library > > Yes. My point was that Data.Graph isn't a "graph library" > (it was never meant to be) - it's a "DFS/SCC library". > > - J. > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------------------------------------------------------------- Andrew Butterfield Tel: +353-1-896-2517 Fax: +353-1-677-2204 Lero at TCD, Head of Foundations & Methods Research Group School of Computer Science and Statistics, Room G.39, O'Reilly Institute, Trinity College, University of Dublin http://www.scss.tcd.ie/Andrew.Butterfield/ -------------------------------------------------------------------- From qdunkan at gmail.com Mon Jun 24 17:38:04 2019 From: qdunkan at gmail.com (Evan Laforge) Date: Mon, 24 Jun 2019 10:38:04 -0700 Subject: Data.Graph transitive closure In-Reply-To: <983989f8-8ba4-1c37-e3d0-93a5ccaf7ea1@htwk-leipzig.de> References: <0b85bef6-eaf1-fade-29e1-99f475ba57f9@htwk-leipzig.de> <7C14FE10-8E36-4619-AC0C-06A9691175B1@scss.tcd.ie> <983989f8-8ba4-1c37-e3d0-93a5ccaf7ea1@htwk-leipzig.de> Message-ID: I have been bit before by Data.Graph... I think it's that since it's a type synonym, it inherits Eq from Array, but it doesn't have a normalized form, so Eq is misleading in that topologically equal graphs are not Eq... something like that. And it can't be fixed because it's just a type synonym over Array. That's probably the "no attempt to add abstraction barriers" alluded to above. But the reason I used it in the first place was I wanted a graph, and behold there is Data.Graph already installed. So it's presence in containers gives it the impression of authority, but it's definitely not as well developed as the other types in containers. Since it seems like it can't be moved or made into a proper type without breaking things, we could at least have some caveats in the documentation, saying what it's appropriate for and what it's not. And maybe warning about that Eq thing. So I guess I'm seconding the "just add documentation" suggestion. Also while I'm here it's weird and confusing how it silently re-exports Data.Tree... On Mon, Jun 24, 2019 at 4:02 AM Johannes Waldmann wrote: > > Hi, > > > I looked at doing this in a "principled" way a long time ago. > > I then got distracted by something else..... > > You don't say :-) > > Well, short-term suggestion (for containers:Data.Graph) > don't change existing code, > but improve documentation and do some benchmarking > https://github.com/haskell/containers/issues/648 > https://github.com/haskell/containers/issues/649 > > @David: perhaps you can label these issues as "nice to have" > so it does not look like "bugs that need fixing". > Benchmarking would make for a nice student project? > In fact, I will pitch this to my current class. > > - Johannes > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries From david.feuer at gmail.com Mon Jun 24 18:22:30 2019 From: david.feuer at gmail.com (David Feuer) Date: Mon, 24 Jun 2019 14:22:30 -0400 Subject: Data.Graph transitive closure In-Reply-To: References: <0b85bef6-eaf1-fade-29e1-99f475ba57f9@htwk-leipzig.de> <7C14FE10-8E36-4619-AC0C-06A9691175B1@scss.tcd.ie> <983989f8-8ba4-1c37-e3d0-93a5ccaf7ea1@htwk-leipzig.de> Message-ID: If we could boot it out of containers and into its own package, that would make me happier; then I wouldn't have such a weird, special-purpose structure sitting around in an otherwise general-purpose library. On Mon, Jun 24, 2019, 1:38 PM Evan Laforge wrote: > I have been bit before by Data.Graph... I think it's that since it's a > type synonym, it inherits Eq from Array, but it doesn't have a > normalized form, so Eq is misleading in that topologically equal > graphs are not Eq... something like that. And it can't be fixed > because it's just a type synonym over Array. That's probably the "no > attempt to add abstraction barriers" alluded to above. But the reason > I used it in the first place was I wanted a graph, and behold there is > Data.Graph already installed. So it's presence in containers gives it > the impression of authority, but it's definitely not as well developed > as the other types in containers. > > Since it seems like it can't be moved or made into a proper type > without breaking things, we could at least have some caveats in the > documentation, saying what it's appropriate for and what it's not. > And maybe warning about that Eq thing. So I guess I'm seconding the > "just add documentation" suggestion. > > Also while I'm here it's weird and confusing how it silently > re-exports Data.Tree... > > On Mon, Jun 24, 2019 at 4:02 AM Johannes Waldmann > wrote: > > > > Hi, > > > > > I looked at doing this in a "principled" way a long time ago. > > > I then got distracted by something else..... > > > > You don't say :-) > > > > Well, short-term suggestion (for containers:Data.Graph) > > don't change existing code, > > but improve documentation and do some benchmarking > > https://github.com/haskell/containers/issues/648 > > https://github.com/haskell/containers/issues/649 > > > > @David: perhaps you can label these issues as "nice to have" > > so it does not look like "bugs that need fixing". > > Benchmarking would make for a nice student project? > > In fact, I will pitch this to my current class. > > > > - Johannes > > _______________________________________________ > > Libraries mailing list > > Libraries at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From johannes.waldmann at htwk-leipzig.de Mon Jun 24 18:25:21 2019 From: johannes.waldmann at htwk-leipzig.de (Johannes Waldmann) Date: Mon, 24 Jun 2019 20:25:21 +0200 Subject: Data.Graph transitive closure In-Reply-To: References: <0b85bef6-eaf1-fade-29e1-99f475ba57f9@htwk-leipzig.de> <7C14FE10-8E36-4619-AC0C-06A9691175B1@scss.tcd.ie> <983989f8-8ba4-1c37-e3d0-93a5ccaf7ea1@htwk-leipzig.de> Message-ID: <2f316f47-9230-ddce-a632-2fcf1f2ae00f@htwk-leipzig.de> On 24.06.19 20:22, David Feuer wrote: > If we could boot it out of containers and into its own package, https://hackage.haskell.org/package/GraphSCC-1.0.4/docs/Data-Graph-SCC.html ? From david.feuer at gmail.com Mon Jun 24 18:29:51 2019 From: david.feuer at gmail.com (David Feuer) Date: Mon, 24 Jun 2019 14:29:51 -0400 Subject: Data.Graph transitive closure In-Reply-To: <2f316f47-9230-ddce-a632-2fcf1f2ae00f@htwk-leipzig.de> References: <0b85bef6-eaf1-fade-29e1-99f475ba57f9@htwk-leipzig.de> <7C14FE10-8E36-4619-AC0C-06A9691175B1@scss.tcd.ie> <983989f8-8ba4-1c37-e3d0-93a5ccaf7ea1@htwk-leipzig.de> <2f316f47-9230-ddce-a632-2fcf1f2ae00f@htwk-leipzig.de> Message-ID: If Iavor wants to adopt Data.Graph into his package, I'm fine with that. I'm not exactly clear on what his package adds to the mix, but if it's not my problem it's not my problem. GHC HQ needs to sign off on adding it as a boot package, but its dependencies (base, array, containers) should make that acceptable. On Mon, Jun 24, 2019, 2:25 PM Johannes Waldmann < johannes.waldmann at htwk-leipzig.de> wrote: > On 24.06.19 20:22, David Feuer wrote: > > > If we could boot it out of containers and into its own package, > > https://hackage.haskell.org/package/GraphSCC-1.0.4/docs/Data-Graph-SCC.html > ? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From chessai1996 at gmail.com Tue Jun 25 06:05:17 2019 From: chessai1996 at gmail.com (chessai .) Date: Tue, 25 Jun 2019 02:05:17 -0400 Subject: [core libraries] transformers mirroring to GitHub In-Reply-To: References: Message-ID: Ah. This does answer my question. Thanks. On Mon, Jun 24, 2019, 10:09 AM Herbert Valerio Riedel wrote: > On Mon, Jun 24, 2019 at 4:03 PM chessai . wrote: > >> Could we mirror transformers from darcshub to GitHub? >> > > Not sure if this answers your question, but I set up such a darcs->git > mirror years ago on http://git.haskell.org/darcs-mirrors/transformers.git > to be used as upstream repo for GHC's actual submodule > http://git.haskell.org/packages/transformers.git (which needs to be a > separate repo for reasons), and which is the source of the GitHub mirror > https://github.com/ghc/packages-transformers > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tristan.wibberley at gmail.com Wed Jun 26 19:57:43 2019 From: tristan.wibberley at gmail.com (Tristan Wibberley) Date: Wed, 26 Jun 2019 20:57:43 +0100 Subject: Fwd: lazier writer monad In-Reply-To: References: Message-ID: Dear Haskell Libraries mailing list members, I've submitted a merge request for an increase in the laziness of the writer monad: https://gitlab.haskell.org/ghc/ghc/merge_requests/1262 and it requires discussion via this mailing list. The link above includes an example of the motivation for this change and I hope you can all extrapolate to see the importance of this change, sufficient to not only accept this but to be moved to add a language flag, available within the content of a module's source file, to match unique constructors lazily throughout a module that uses it, lifting _|_ to the next least-defined value. The core problem is that for the most handy and practical library interfaces, we need function results to be as well-defined as possible before a strict pattern match is required to choose between two constructors/values. There are several parts to providing that but one important part is that elements of patterns that cannot be unmatched should be lazily matched so the function's definition can be used without evaluating the function's arguments first. This avoids having to train users to always avoid patterns except after a let binding which would otherwise be necessary to establish a standard habit to lazily pattern match so the user base encourages each other to make their functions maximally useful. -- Tristan -------------- next part -------------- An HTML attachment was scrubbed... URL: From emertens at gmail.com Wed Jun 26 21:19:42 2019 From: emertens at gmail.com (Eric Mertens) Date: Wed, 26 Jun 2019 14:19:42 -0700 Subject: lazier writer monad In-Reply-To: References: Message-ID: Hi, I think we should update the Applicative and Monad instances to document their strictness behaviors instead. For code that relies on a particular strictness behavior I would recommend sticking with one of the modules in the transformers package: Control.Monad.Trans.Writer.Strict and Control.Monad.Trans.Writer.Lazy As far as I can tell the current state of the PR updates the Applicative instance but not the Monad instance. Should this PR actually advance we should address that. I agree that there are compositionally benefits to code that is as lazy as possible, however there are also space leak costs to that kind of code as well. I don’t think a simple rule like “as lazy as possible is best” is a good guiding principle. Changing the behavior now would just make the instance quite challenging to use portably and doesn’t make the instance more correct, just different. Having a magic rule that datatypes with a single constructor match differently from datatypes with multiple constructors sounds like a readability nightmare. It’s already challenging to reason about the strictness behavior of programs. Making it harder like this would be a mistake. In addition adding or removing constructors from a datatype would have significant, non-local strictness effects to an existing program. (The PR mentions something about Dependent Haskell and testing. Dependent Haskell isn’t going to replace testing and it isn’t going to make strictness easy to reason about.) Best regards, Eric Mertens glguy > On Jun 26, 2019, at 12:57 PM, Tristan Wibberley wrote: > > Dear Haskell Libraries mailing list members, > > I've submitted a merge request for an increase in the laziness of the writer monad: https://gitlab.haskell.org/ghc/ghc/merge_requests/1262 and it requires discussion via this mailing list. > > The link above includes an example of the motivation for this change and I hope you can all extrapolate to see the importance of this change, sufficient to not only accept this but to be moved to add a language flag, available within the content of a module's source file, to match unique constructors lazily throughout a module that uses it, lifting _|_ to the next least-defined value. > > The core problem is that for the most handy and practical library interfaces, we need function results to be as well-defined as possible before a strict pattern match is required to choose between two constructors/values. There are several parts to providing that but one important part is that elements of patterns that cannot be unmatched should be lazily matched so the function's definition can be used without evaluating the function's arguments first. This avoids having to train users to always avoid patterns except after a let binding which would otherwise be necessary to establish a standard habit to lazily pattern match so the user base encourages each other to make their functions maximally useful. > > -- > Tristan > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Wed Jun 26 22:06:48 2019 From: david.feuer at gmail.com (David Feuer) Date: Wed, 26 Jun 2019 18:06:48 -0400 Subject: lazier writer monad In-Reply-To: References: Message-ID: I agree with Eric. Aside from the practically important concerns he raised, your proposed instance is not strictly lawful, which I find troubling for such an essential wired-in type. pure id <*> undefined = (mempty, id) <*> undefined = (mempty <> fst undefined, id undefined) = (undefined, undefined) But according to the Applicative identity law, pure id <*> undefined = undefined That's similar, but not the same. Let me add that not only the Monad instance but also the Functor one is incompatible, because we require fmap f x = pure f <*> x On Wed, Jun 26, 2019, 3:58 PM Tristan Wibberley wrote: > Dear Haskell Libraries mailing list members, > > I've submitted a merge request for an increase in the laziness of the > writer monad: https://gitlab.haskell.org/ghc/ghc/merge_requests/1262 and > it requires discussion via this mailing list. > > The link above includes an example of the motivation for this change and I > hope you can all extrapolate to see the importance of this change, > sufficient to not only accept this but to be moved to add a language flag, > available within the content of a module's source file, to match unique > constructors lazily throughout a module that uses it, lifting _|_ to the > next least-defined value. > > The core problem is that for the most handy and practical library > interfaces, we need function results to be as well-defined as possible > before a strict pattern match is required to choose between two > constructors/values. There are several parts to providing that but one > important part is that elements of patterns that cannot be unmatched should > be lazily matched so the function's definition can be used without > evaluating the function's arguments first. This avoids having to train > users to always avoid patterns except after a let binding which would > otherwise be necessary to establish a standard habit to lazily pattern > match so the user base encourages each other to make their functions > maximally useful. > > -- > Tristan > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From 0xd34df00d at gmail.com Sat Jun 29 16:46:31 2019 From: 0xd34df00d at gmail.com (Georg Rudoy) Date: Sat, 29 Jun 2019 12:46:31 -0400 Subject: Making Int{Map,Set} polymorphic over the key type Message-ID: Hi folks, What do you think about making IntMap and IntSet polymorphic over the keys as long as the key type k is Coercible to Int? The motivation is that oftentimes one needs to have a collection of newtype wrappers around Int, and then they have to either unpack/repack it around the relevant containers (which is not nice), or just use HashMap/HashSet (which is perhaps suboptimal). If this is a direction the community might deem reasonable, I'd be happy to work on this and make a PR to the containers repo (perhaps after discussing the specific details about naming, etc). -- Georg Rudoy -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Sat Jun 29 16:57:46 2019 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sat, 29 Jun 2019 12:57:46 -0400 Subject: Making Int{Map,Set} polymorphic over the key type In-Reply-To: References: Message-ID: Off hand that seems like it’d break every single piece of code that uses those data structures today or at the very least possibly weaken type inference in some cases. Or maybe I’m over thinking things. I do think it’d be super to experiment with that as a child package so we can all try it out and see how the ux compares vs the usual approaches people do today One possible gotcha / law that would need to be true for such new types is that the Ord and Eq instanced would have to be the same as INT. AT least for some parts of the container api. On Sat, Jun 29, 2019 at 12:46 PM Georg Rudoy <0xd34df00d at gmail.com> wrote: > Hi folks, > > What do you think about making IntMap and IntSet polymorphic over the keys > as long as the key type k is Coercible to Int? > > The motivation is that oftentimes one needs to have a collection of > newtype wrappers around Int, and then they have to either unpack/repack it > around the relevant containers (which is not nice), or just use > HashMap/HashSet (which is perhaps suboptimal). > > If this is a direction the community might deem reasonable, I'd be happy > to work on this and make a PR to the containers repo (perhaps after > discussing the specific details about naming, etc). > > > -- > Georg Rudoy > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Sat Jun 29 17:01:11 2019 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Sat, 29 Jun 2019 19:01:11 +0200 (CEST) Subject: Making Int{Map,Set} polymorphic over the key type In-Reply-To: References: Message-ID: On Sat, 29 Jun 2019, Georg Rudoy wrote: > The motivation is that oftentimes one needs to have a collection of > newtype wrappers around Int, and then they have to either unpack/repack > it around the relevant containers (which is not nice), or just use > HashMap/HashSet (which is perhaps suboptimal). There is already the enummapset package. From 0xd34df00d at gmail.com Sat Jun 29 17:04:29 2019 From: 0xd34df00d at gmail.com (Georg Rudoy) Date: Sat, 29 Jun 2019 13:04:29 -0400 Subject: Making Int{Map,Set} polymorphic over the key type In-Reply-To: References: Message-ID: сб, 29 июн. 2019 г. в 12:57, Carter Schonwald : > Off hand that seems like it’d break every single piece of code that uses those data structures today or at the very least possibly weaken type inference in some cases. Even if the change would be (disregarding the specific naming) to change `IntSet` to `IntSetPoly k` and have `type IntSet = IntSetPoly Int`? I don't have much experience reasoning about this, but looks like it shouldn't really break much. > I do think it’d be super to experiment with that as a child package so we can all try it out and see how the ux compares vs the usual approaches people do today More on formalities, should it be a fork or a separate package with just intmap/intset or something else? > One possible gotcha / law that would need to be true for such new types is that the Ord and Eq instanced would have to be the same as INT. AT least for some parts of the container api. Great catch! I haven't thought about that. -- Georg Rudoy From 0xd34df00d at gmail.com Sat Jun 29 17:06:08 2019 From: 0xd34df00d at gmail.com (Georg Rudoy) Date: Sat, 29 Jun 2019 13:06:08 -0400 Subject: Making Int{Map,Set} polymorphic over the key type In-Reply-To: References: Message-ID: сб, 29 июн. 2019 г. в 13:01, Henning Thielemann : > There is already the enummapset package. Isn't it using fromEnum/toEnum under the hood, which might have bigger performance penalty than `coerce`? On the other hand, sure, the original suggestion can also be made as a separate library wrapping IntMap/IntSet and all the calls to coerce. I'm happy with that approach too. -- Georg Rudoy From lemming at henning-thielemann.de Sat Jun 29 17:20:43 2019 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Sat, 29 Jun 2019 19:20:43 +0200 (CEST) Subject: Making Int{Map,Set} polymorphic over the key type In-Reply-To: References: Message-ID: On Sat, 29 Jun 2019, Georg Rudoy wrote: > сб, 29 июн. 2019 г. в 13:01, Henning Thielemann : >> There is already the enummapset package. > > Isn't it using fromEnum/toEnum under the hood, which might have bigger > performance penalty than `coerce`? Right. However, I am using the package mostly for tasks where I do a lot of 'union' and 'intersection' where there is no need to convert individual elements. I only initialize sets with say, EnumSet.fromList, do a lot of 'union', 'intersection', 'difference', that is, simple bit field operations, and then fetch the results with EnumSet.toAscList. From david.feuer at gmail.com Sat Jun 29 18:11:01 2019 From: david.feuer at gmail.com (David Feuer) Date: Sat, 29 Jun 2019 14:11:01 -0400 Subject: Making Int{Map,Set} polymorphic over the key type In-Reply-To: References: Message-ID: toEnum and fromEnum will be coercions for the types you're talking about anyway. On Sat, Jun 29, 2019, 1:06 PM Georg Rudoy <0xd34df00d at gmail.com> wrote: > сб, 29 июн. 2019 г. в 13:01, Henning Thielemann < > lemming at henning-thielemann.de>: > > There is already the enummapset package. > > Isn't it using fromEnum/toEnum under the hood, which might have bigger > performance penalty than `coerce`? > > On the other hand, sure, the original suggestion can also be made as a > separate library wrapping IntMap/IntSet and all the calls to coerce. > I'm happy with that approach too. > > -- > Georg Rudoy > _______________________________________________ > Libraries mailing list > Libraries at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Sat Jun 29 18:13:40 2019 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sat, 29 Jun 2019 14:13:40 -0400 Subject: Making Int{Map,Set} polymorphic over the key type In-Reply-To: References: Message-ID: make it a tiny little library thats its own! :) yeah, you'd probably want there to be Eq respecting Coercions flavor and the Ord respecting flavor On Sat, Jun 29, 2019 at 1:04 PM Georg Rudoy <0xd34df00d at gmail.com> wrote: > сб, 29 июн. 2019 г. в 12:57, Carter Schonwald >: > > Off hand that seems like it’d break every single piece of code that uses > those data structures today or at the very least possibly weaken type > inference in some cases. > > Even if the change would be (disregarding the specific naming) to > change `IntSet` to `IntSetPoly k` and have `type IntSet = IntSetPoly > Int`? I don't have much experience reasoning about this, but looks > like it shouldn't really break much. > > > I do think it’d be super to experiment with that as a child package so > we can all try it out and see how the ux compares vs the usual approaches > people do today > > More on formalities, should it be a fork or a separate package with > just intmap/intset or something else? > > > One possible gotcha / law that would need to be true for such new types > is that the Ord and Eq instanced would have to be the same as INT. AT > least for some parts of the container api. > > Great catch! I haven't thought about that. > > -- > Georg Rudoy > -------------- next part -------------- An HTML attachment was scrubbed... URL: