Re: [Haskell-cafe] the problem of design by negation
On Thu, May 21, 2009 at 10:53 PM, Conal Elliott co...@conal.net wrote: advice One thing you may try is to ask the architect for evidence and/or logical proof of his claims that something cannot work. As much as you can, ask from a place of curiosity and even awe. After all, existence can often be proved by demonstrating an example, while non-existence proofs tend to be much more profound. And stick to your open-minded disbelief until you really see evidence or logical rigor. If the architect gets flustered and embarrassed, he may well go on the attack. After all, bravado signals weak ego, which can quickly become a cornered animal. So pay attention to his stress level, and help his salvage his ego, by suggesting he let you know more about the evidence and/or logic when he's worked it out. Be careful to stay in your integrity, neither going along with someone's forcefulness, nor representing yourself as having more grounds for confidence than you really do. /advice Thanks Conal for that sagely advice. I recently asked my local conversation expert how to deal with passive aggressive people/managers, and he gave similar advice. He said that when someone is dragging their feet or providing excuses, change the conversation into one about problem solving. Instead of continuing to make the request, ask what it would take for the request to be possible. I think your advice is exactly that, just in a slightly different context. Also, in the times when the speaker understands the problem better than myself, I tend to learn something new about the problem domain that, whether it is a show stopper or not, is a significant issue to address. Thanks, Jason ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Putting unit tests in cabal files (Was Re: [Haskell-cafe] HUnit)
On Fri, May 22, 2009 at 12:13 AM, Vasili I. Galchin vigalc...@gmail.com wrote: Hello, I have some code with several test cases that use HUnit. I added hunit as one of my cabal dependencies but cabal complained with: Setup: At least the following dependencies are missing: hutil -any What am I doing incorrectly? Would you mind posting your .cabal file too? The reson I'm asking is that I've so far _never_ put any information about unit tests or quickcheck tests in my .cabal file, simply because I don't want the executables to be picked up by automatic package converters such as cabal2arch. Instead I have a makefile for building my test programs. If you have some way of keeping information about building of tests in your .cabal I'd be very interested in seeing it. /M -- Magnus Therning(OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] the problem of design by negation
One flimsy argument I often hear is It wouldn't work because how ..., or because what As if a question were an argument. I call this rather popular tactic proof by ignorance or proof by lack of imagination. [...] I just remembered another popular variation on this bogus argument. If you question someone's claim of impossibility (or the only possibility), they may retort: Well, then how would you do it? The Game here is that if you don't have an answer, the other guy is right! I don't know why people perpetrate and fall for this game. One response I like is to affirm the question. Yeah, how indeed! Anyone have some creative ideas? Who wants to brainstorm? I gather that some people are terribly uncomfortable without certainty. If you take away their certainty, they demand an immediate replacement! These folks will suck the creativity out of a room if they can, because creativity requires curiosity, and curiosity requires willingness not to know. - Conal On Thu, May 21, 2009 at 10:53 PM, Conal Elliott co...@conal.net wrote: Hi Michael, I'm going to hazard a guess. Please let me know how accurate it is. When asked to justify his design, the lead software architect explains everything that *wouldn't* work. We couldn't have a unique key for every entry because blah blah blah. We couldn't use a garbage collector because blah blah. We couldn't write a sugar layer because then you have to document it separately blah blah. So the chosen design seems to be the only thing left after eliminating everything you can't do. My guess is that your software architect is making flimsy arguments. It's usually very difficult to prove that something *wouldn't* work. In my experience, people make blanket statements about what cannot work, when the truth is that they just don't know how and don't have the imagination or will even to entertain the possibility of ways that they can't yet see. Instead of using logic and evidence, these people bolster their claims (often mistakenly called arguments) by putting across confident language (obviously, clearly, without a doubt), body posture, facial expression, and voice tone. When someone is on solid ground, these bravado tactics are unnecessary. (I think of obviously, etc as words that are useful only when inaccurate. See http://conal.net/blog/posts/fostering-creativity-by-relinquishing-the-obvious/.) One flimsy argument I often hear is It wouldn't work because how ..., or because what As if a question were an argument. I call this rather popular tactic proof by ignorance or proof by lack of imagination. I don't know where people get the idea that this sort of thing is rational. If I'm ever tempted to give it any weight, I think of Arthur Hoppe's proof of the existence of God: If there's no God, then who pops up the next kleenex? Some of my favorite quotes on this dynamic: Doubt is not a pleasant condition, but certainty is absurd. - Voltaire They are ill discoverers that think there is no land, when they can see nothing but sea. - Francis Bacon To be positive: To be mistaken at the top of one's voice. Ambrose Bierce The greatest obstacle to discovering the shape of the earth, the continents, and the oceans was not ignorance but the illusion of knowledge. - Daniel J. Boorstin advice One thing you may try is to ask the architect for evidence and/or logical proof of his claims that something cannot work. As much as you can, ask from a place of curiosity and even awe. After all, existence can often be proved by demonstrating an example, while non-existence proofs tend to be much more profound. And stick to your open-minded disbelief until you really see evidence or logical rigor. If the architect gets flustered and embarrassed, he may well go on the attack. After all, bravado signals weak ego, which can quickly become a cornered animal. So pay attention to his stress level, and help his salvage his ego, by suggesting he let you know more about the evidence and/or logic when he's worked it out. Be careful to stay in your integrity, neither going along with someone's forcefulness, nor representing yourself as having more grounds for confidence than you really do. /advice Whether or not my guess is accurate or my advice relevant, good luck! I'd love to hear how this situation develops. - Conal On Wed, May 20, 2009 at 3:54 PM, Michael Mossey m...@alumni.caltech.eduwrote: This is not directly related to Haskell, but it's a thought that occurred to me after exposure to the Haskell community. I've spent most of the past 15 years doing scientific programming. The lead software architect and software managers are using good software engineering practice, though (this is *scientific* programming, not *programming by scientists*, ha ha). But, there is a particular culture in my company that has become more obvious to me by contrast to the Haskell
Re: [Haskell-cafe] the problem of design by negation
Instead of continuing to make the request, ask what it would take for the request to be possible. Thanks, Jason. I like this shift. It moves the dynamic away from a tightly confined yes/no (and often win/lose) to an expansive *how*. It welcomes collaboration in finding something better than either yes or no to the original request, in that both/all parties' needs can be addressed, not just one. - Conal On Thu, May 21, 2009 at 11:04 PM, Jason Dagit da...@codersbase.com wrote: On Thu, May 21, 2009 at 10:53 PM, Conal Elliott co...@conal.net wrote: advice One thing you may try is to ask the architect for evidence and/or logical proof of his claims that something cannot work. As much as you can, ask from a place of curiosity and even awe. After all, existence can often be proved by demonstrating an example, while non-existence proofs tend to be much more profound. And stick to your open-minded disbelief until you really see evidence or logical rigor. If the architect gets flustered and embarrassed, he may well go on the attack. After all, bravado signals weak ego, which can quickly become a cornered animal. So pay attention to his stress level, and help his salvage his ego, by suggesting he let you know more about the evidence and/or logic when he's worked it out. Be careful to stay in your integrity, neither going along with someone's forcefulness, nor representing yourself as having more grounds for confidence than you really do. /advice Thanks Conal for that sagely advice. I recently asked my local conversation expert how to deal with passive aggressive people/managers, and he gave similar advice. He said that when someone is dragging their feet or providing excuses, change the conversation into one about problem solving. Instead of continuing to make the request, ask what it would take for the request to be possible. I think your advice is exactly that, just in a slightly different context. Also, in the times when the speaker understands the problem better than myself, I tend to learn something new about the problem domain that, whether it is a show stopper or not, is a significant issue to address. Thanks, Jason ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] the problem of design by negation
Conal Elliott wrote: Hi Michael, I'm going to hazard a guess. Please let me know how accurate it is. Conal, I think you described this situation well. You must know this kind of person---I'm sure there's more than one in the world! When asked to justify his design, the lead software architect explains everything that *wouldn't* work. We couldn't have a unique key for every entry because blah blah blah. We couldn't use a garbage collector because blah blah. We couldn't write a sugar layer because then you have to document it separately blah blah. So the chosen design seems to be the only thing left after eliminating everything you can't do. My guess is that your software architect is making flimsy arguments. It's usually very difficult to prove that something *wouldn't* work. In my experience, people make blanket statements about what cannot work, when the truth is that they just don't know how and don't have the imagination or will even to entertain the possibility of ways that they can't yet see. Yes, that's the impression I get from this guy. His personality causes him to derive absolute rules or blanket statements from experience, instead of a more gentle kind of wisdom. The more experience he gets, the more he's full of constraining rules. So I really did mean to say that his design is the ONLY thing possible after eliminating everything that won't fit with his rules. Instead of using logic and evidence, these people bolster their claims (often mistakenly called arguments) by putting across confident language (obviously, clearly, without a doubt), body posture, facial expression, and voice tone. When someone is on solid ground, these bravado tactics are unnecessary. You got it---the guy is great at winning debates because he is very confident and can so quickly poke holes (what *seem* to be holes) in any other position. Moreover, his confidence is why he is lead software architect... managers are impressed by alpha males and tend to be alpha males themselves. Some of my favorite quotes on this dynamic: Doubt is not a pleasant condition, but certainty is absurd. - Voltaire They are ill discoverers that think there is no land, when they can see nothing but sea. - Francis Bacon To be positive: To be mistaken at the top of one's voice. Ambrose Bierce The greatest obstacle to discovering the shape of the earth, the continents, and the oceans was not ignorance but the illusion of knowledge. - Daniel J. Boorstin Good quotes. I was trying to get across this idea of imagination, creativity, finding solutions in unlikely places. Here's another one: The whole trouble with the world is that fools and fanatics are always so certain of themselves, and wiser people, always so full of doubts. - Bertrand Russell advice One thing you may try is to ask the architect for evidence and/or logical proof of his claims that something cannot work. As much as you can, ask from a place of curiosity and even awe. After all, existence can often be proved by demonstrating an example, while non-existence proofs tend to be much more profound. And stick to your open-minded disbelief until you really see evidence or logical rigor. If the architect gets flustered and embarrassed, he may well go on the attack. After all, bravado signals weak ego, which can quickly become a cornered animal. So pay attention to his stress level, and help his salvage his ego, by suggesting he let you know more about the evidence and/or logic when he's worked it out. Be careful to stay in your integrity, neither going along with someone's forcefulness, nor representing yourself as having more grounds for confidence than you really do. /advice That's good advice. I'm not sure how well this situation can work because I'm one of these people who is full of doubts, which I regard as ultimately a positive trait, but it makes me poor at debate. (I know you are not suggesting I debate him, but he wants to turn everything into a debate, and it takes a very level-headed outgoing person to keep up with him.) The best result from this experience is that I can improve my *own* design process. For example, I'm working on a personal project related to music, and after a few weeks of design, I realized that my thinking had turned into design by negation. I felt unhappy with every choice, and started to think of the design as the unhappy, but least unhappy, compromise. This is probably an old habit of mine. So I want to shift my thinking, by listing goals for the design, and finding ways to meet all of them. Win-win instead of lose-lose. Based on a previous reply, I think some people think this sounds like vapid cheerleading, but I think you would agree with me that life (and software) always offers more possibilities when we engage our imagination with hope and energy, not giving up too soon, being willing to sit with problems for a time without a definite conclusion. Thanks, Mike
Re: [Haskell-cafe] Introducing Instances in GHC point releases
On Thu, 2009-05-21 at 21:30 -0500, John Goerzen wrote: Duncan Coutts wrote: On Thu, 2009-05-21 at 15:22 -0700, Alexander Dunlap wrote: Since those types come out of the time library, and that library's version *has* been bumped (I assume), couldn't you use Cabal to condition on the version of the time library to determine whether or not to have CPP set a -DTYPEABLE_IN_TIME flag, and then #ifdef out your versions of the instances? I was about to suggest this: #if MIN_VERSION_time(1,1,2) ... #endif That would be slick. I'll give that a whirl. What version of Cabal does GHC 6.8 come from, 1.2.x and where can I read about the above feature? The user guide, section Creating a package, subsection Conditional compilation: http://haskell.org/cabal/release/cabal-latest/doc/users-guide/authors.html#cpp I imagine I may have to wrap the above in a __GLASGOW_HASKELL__ test for GHC 6.8 or something. Again, there's no direct relationship between the version of ghc and the version of Cabal (though there is some correlation). Though if *cabal* and not GHC generates it, isn't that a bit hurting to my portability? (Can't just ghc --make with it, or ghci on it directly anymore, etc.) True. People have been asking for a way to get cabal to invoke ghci with all the right flags, which is a reasonable idea. because Cabal 1.6+ generates these cpp macros for you. Note that relying on the value of __GLASGOW_HASKELL__ would be wrong because the version of the time library is not directly related to the version of ghc. Yeah, but when you've got nothing else to go on, it sometimes works in a pinch. Aye, it's ok for the people you don't upgrade things separately, and those people are less likely to be able to work out how to fix things. I guess my larger point is just a plea to the community: please be really careful about what you do to GHC in point releases. This is not the first issue that has screwed me in the GHC 6.10.x point releases. GHC (and the community) used to be really good about this. Is there something causing a regression here, or is it my imagination? Yes, we're loosening the connection between ghc and the non-core packages, so that package maintainers make releases rather than the ghc maintainers doing so. What we're currently missing is a PVP checker: a tool to compare APIs of package versions and check that it is following the PVP. Ideally, we will have packages opt-in to follow the PVP for those packages that do opt-in we have the PVP enforced on hackage using the checker tool. Since the HP is almost certainly going to require packages to follow the PVP then this should eliminate this class of mistakes. But it does need the tool, and nobody is working on that at the moment. Duncan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Introducing Instances in GHC point releases
Duncan Coutts wrote: What we're currently missing is a PVP checker: a tool to compare APIs of package versions and check that it is following the PVP. Ideally, we will have packages opt-in to follow the PVP for those packages that do opt-in we have the PVP enforced on hackage using the checker tool. Since the HP is almost certainly going to require packages to follow the PVP then this should eliminate this class of mistakes. But it does need the tool, and nobody is working on that at the moment. Recently, I wanted to compare two branches of one of my libraries to see what API changes I had made. My low-tech solution was to do a two-line hack on haddock so that it sorts the modules before generating Hoogle documentation, and then to compare (with diff) the two hoogle documentation files between the branches. The Hoogle format just seems to be a list of definitions with types, classes and instances -- so it seems to fit the bill. I imagine it's not foolproof, but perhaps this could be a quick fix, at least as a heuristic for a package maintainer (hoogle-diff suggests you may have altered something, please check before continuing to upload)? Thanks, Neil. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Introducing Instances in GHC point releases
John Goerzen schrieb: So this is annoying (CCing -cafe) I need NominalDiffTime and UTCTime to have Typeable instances. In 6.10.1, they didn't ship with them out of the box, so I added them. Apparently, in 6.10.3, they DO ship with those instances out of the box. Annoyingly, that means that my code breaks on 6.10.3. After having conflicting instances several times with some types in the past, I came to the conclusion that I should never define orphan instances. Can you restrict your package to 6.10.3 where an official instance is available? http://www.haskell.org/haskellwiki/Orphan_instance ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A problem with par and modules boundaries...
Am Freitag 22 Mai 2009 04:59:51 schrieb Mario Blažević: I'll cut to the chase. The short program below works perfectly: when I compile it with -O2 -threaded and run with +RTS -N2 command-line options, I get a nearly 50% real-time improvement: $ time ./primes-test +RTS -N2 5001 real 0m9.307s user 0m16.581s sys 0m0.200s However, if I move the `parallelize' definition into another module and import that module, the performance is completely lost: $ time ./primes-test +RTS -N2 5001 real 0m15.282s user 0m15.165s sys 0m0.080s I'm confused. I know that `par` must be able work across modules boundaries, because Control.Parallel.Strategies is a module and presumably it works. What am I doing wrong? You forgot {-# INLINE parallelize #-} For me, that works. module Main where import Control.Parallel import Data.List (find) import Data.Maybe (maybe) --import Parallelizable parallelize a b = a `par` (b `pseq` (a, b)) test :: Integer - Integer - Integer test n1 n2 = let (p1, p2) = parallelize (product $ factors $ product [1..n1]) (product $ factors $ product [1..n2]) in p2 `div` p1 factors n = maybe [n] (\k- (k : factors (n `div` k))) (find (\k- n `mod` k == 0) [2 .. n - 1]) main = print (test 5000 5001) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Putting unit tests in cabal files (Was Re: [Haskell-cafe] HUnit)
Magnus Therning schrieb: On Fri, May 22, 2009 at 12:13 AM, Vasili I. Galchin vigalc...@gmail.com wrote: Hello, I have some code with several test cases that use HUnit. I added hunit as one of my cabal dependencies but cabal complained with: Setup: At least the following dependencies are missing: hutil -any What am I doing incorrectly? Would you mind posting your .cabal file too? The reson I'm asking is that I've so far _never_ put any information about unit tests or quickcheck tests in my .cabal file, simply because I don't want the executables to be picked up by automatic package converters such as cabal2arch. Instead I have a makefile for building my test programs. If you have some way of keeping information about building of tests in your .cabal I'd be very interested in seeing it. I define and use Cabal flag buildTests and use Executable test If flag(buildTests) Build-Depends: HUnit Else Buildable: False ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A problem with par and modules boundaries...
Answer recorded at: http://haskell.org/haskellwiki/Performance/Parallel daniel.is.fischer: Am Freitag 22 Mai 2009 04:59:51 schrieb Mario Blažević: I'll cut to the chase. The short program below works perfectly: when I compile it with -O2 -threaded and run with +RTS -N2 command-line options, I get a nearly 50% real-time improvement: $ time ./primes-test +RTS -N2 5001 real0m9.307s user0m16.581s sys 0m0.200s However, if I move the `parallelize' definition into another module and import that module, the performance is completely lost: $ time ./primes-test +RTS -N2 5001 real0m15.282s user0m15.165s sys 0m0.080s I'm confused. I know that `par` must be able work across modules boundaries, because Control.Parallel.Strategies is a module and presumably it works. What am I doing wrong? You forgot {-# INLINE parallelize #-} For me, that works. module Main where import Control.Parallel import Data.List (find) import Data.Maybe (maybe) --import Parallelizable parallelize a b = a `par` (b `pseq` (a, b)) test :: Integer - Integer - Integer test n1 n2 = let (p1, p2) = parallelize (product $ factors $ product [1..n1]) (product $ factors $ product [1..n2]) in p2 `div` p1 factors n = maybe [n] (\k- (k : factors (n `div` k))) (find (\k- n `mod` k == 0) [2 .. n - 1]) main = print (test 5000 5001) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Introducing Instances in GHC point releases
duncan.coutts: What we're currently missing is a PVP checker: a tool to compare APIs of package versions and check that it is following the PVP. Ideally, we will have packages opt-in to follow the PVP for those packages that do opt-in we have the PVP enforced on hackage using the checker tool. Since the HP is almost certainly going to require packages to follow the PVP then this should eliminate this class of mistakes. But it does need the tool, and nobody is working on that at the moment. If I recall correct, CosmicRay wrote just such a thing (or similar to it) a while ago. John? -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Introducing Instances in GHC point releases
Don Stewart wrote: duncan.coutts: What we're currently missing is a PVP checker: a tool to compare APIs of package versions and check that it is following the PVP. Ideally, we will have packages opt-in to follow the PVP for those packages that do opt-in we have the PVP enforced on hackage using the checker tool. Since the HP is almost certainly going to require packages to follow the PVP then this should eliminate this class of mistakes. But it does need the tool, and nobody is working on that at the moment. If I recall correct, CosmicRay wrote just such a thing (or similar to it) a while ago. John? Nope, that wasn't me. Maybe the other John? -- Don ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A problem with par and modules boundaries...
Daniel Fischer wrote: Am Freitag 22 Mai 2009 04:59:51 schrieb Mario Blažević: ... I'm confused. I know that `par` must be able work across modules boundaries, because Control.Parallel.Strategies is a module and presumably it works. What am I doing wrong? You forgot {-# INLINE parallelize #-} For me, that works. That's great, thank you. I am still baffled, though. Must every exported function that uses `par' be INLINEd? Does every exported caller of such a function need the same treatment? Is `par' really a macro, rather than a function? module Main where import Control.Parallel import Data.List (find) import Data.Maybe (maybe) --import Parallelizable parallelize a b = a `par` (b `pseq` (a, b)) test :: Integer - Integer - Integer test n1 n2 = let (p1, p2) = parallelize (product $ factors $ product [1..n1]) (product $ factors $ product [1..n2]) in p2 `div` p1 factors n = maybe [n] (\k- (k : factors (n `div` k))) (find (\k- n `mod` k == 0) [2 .. n - 1]) main = print (test 5000 5001) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- Mario Blazevic mblaze...@stilo.com Stilo Corporation This message, including any attachments, is for the sole use of the intended recipient(s) and may contain confidential and privileged information. Any unauthorized review, use, disclosure, copying, or distribution is strictly prohibited. If you are not the intended recipient(s) please contact the sender by reply email and destroy all copies of the original message and any attachments. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Introducing Instances in GHC point releases
Henning Thielemann wrote: John Goerzen schrieb: So this is annoying (CCing -cafe) I need NominalDiffTime and UTCTime to have Typeable instances. In 6.10.1, they didn't ship with them out of the box, so I added them. Apparently, in 6.10.3, they DO ship with those instances out of the box. Annoyingly, that means that my code breaks on 6.10.3. After having conflicting instances several times with some types in the past, I came to the conclusion that I should never define orphan instances. Can you restrict your package to 6.10.3 where an official instance is available? http://www.haskell.org/haskellwiki/Orphan_instance I didn't care about presenting the instance to people using my library, but the instance was necessary within the library itself, and led to the compilation error. -- John ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: Putting unit tests in cabal files (Was Re: [Haskell-cafe] HUnit)
On Fri, May 22, 2009 at 1:08 PM, Henning Thielemann schlepp...@henning-thielemann.de wrote: Magnus Therning schrieb: On Fri, May 22, 2009 at 12:13 AM, Vasili I. Galchin vigalc...@gmail.com wrote: Hello, I have some code with several test cases that use HUnit. I added hunit as one of my cabal dependencies but cabal complained with: Setup: At least the following dependencies are missing: hutil -any What am I doing incorrectly? Would you mind posting your .cabal file too? The reson I'm asking is that I've so far _never_ put any information about unit tests or quickcheck tests in my .cabal file, simply because I don't want the executables to be picked up by automatic package converters such as cabal2arch. Instead I have a makefile for building my test programs. If you have some way of keeping information about building of tests in your .cabal I'd be very interested in seeing it. I define and use Cabal flag buildTests and use Executable test If flag(buildTests) Build-Depends: HUnit Else Buildable: False Ah, didn't think of that, I've only ever tried if flag(buildTests) executable but then cabal complains loudly about the if statement's location. Now I can try to take this a bit further to see if I can get rid of that ugly makefile altogether. /M -- Magnus Therning(OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.org http://therning.org/magnus identi.ca|twitter: magthe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] haskellnet
I tried contacting Jun Mukai at the email address given in the package but I haven't heard a reply. Just to get this out of the way I've put my darcs repository with the changes I've made up on my website. It should build and install with: darcs get http://www.dicta.org.uk/website/website/haskellnet cabal configure cabal build cabal install I've added some examples of using smtp, pop3 and imap to the examples directory. They seem to work against the mail servers that I have access to. I've also removed some modules from haskellnet which are now covered elswhere in hackage: eg. http, browser, json I'll put in a request to get a username on hackage so I can upload it-- unless anyone has any objections. -Rob On Thu, May 14, 2009 at 2:37 PM, Neil Mitchell ndmitch...@gmail.com wrote: Hi Email the original author, if you can. Ideally work with them to upload a working version to hackage. If they're not interested hopefully they'll make you the new maintainer. If you can't contact them, just upload a new version anyway - as long as it's done for the benefit of the community and not with malicious intent, everyone is happy. And please do make sure you upload something working, I imagine this will be very useful to lots of people! Thanks for your efforts Neil On Thu, May 14, 2009 at 12:51 PM, Robert Wills wrwi...@gmail.com wrote: Hello, Yesterday I found myself wanting to clear out a spam-ridden pop account without downloading all the messages. Rather than just using Python's poplib, I thought I might look for a haskell solution and came across Haskellnet: http://darcs.haskell.org/SoC/haskellnet/ I ended up spending much of the afternoon getting it to compile and much of last night trying to get the pop library to actually work (the 'strip' method produced exceptions). It was a good learning experience (this was helpful: http://donsbot.wordpress.com/2007/11/14/no-more-exceptions-debugging-haskell-code-with-ghci/). I'm writing here because I'm wondering whether it would be worthwhile putting it up on hackage? From searching this list, there seem to have been a few times when people have stumbled across it but got frustrated when it didn't compile. If so, what's the protocol? Is the original author, Jun Mukai, still around? Thanks, Rob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A problem with par and modules boundaries...
Am Freitag 22 Mai 2009 15:11:32 schrieb Mario Blazevic: Daniel Fischer wrote: Am Freitag 22 Mai 2009 04:59:51 schrieb Mario Blažević: ... I'm confused. I know that `par` must be able work across modules boundaries, because Control.Parallel.Strategies is a module and presumably it works. What am I doing wrong? You forgot {-# INLINE parallelize #-} For me, that works. That's great, thank you. I am still baffled, though. Must every exported function that uses `par' be INLINEd? Does every exported caller of such a function need the same treatment? Is `par' really a macro, rather than a function? I'm not an expert in either parallelism/concurrency or GHC, so my interpretation may be wrong. The functions par and pseq are defined in GHC.Conc: -- Nota Bene: 'pseq' used to be 'seq' -- but 'seq' is now defined in PrelGHC -- -- pseq is defined a bit weirdly (see below) -- -- The reason for the strange lazy call is that -- it fools the compiler into thinking that pseq and par are non-strict in -- their second argument (even if it inlines pseq at the call site). -- If it thinks pseq is strict in y, then it often evaluates -- y before x, which is totally wrong. {-# INLINE pseq #-} pseq :: a - b - b pseq x y = x `seq` lazy y {-# INLINE par #-} par :: a - b - b par x y = case (par# x) of { _ - lazy y } As far as I understand, par doesn't guarantee that both arguments are evaluated in parallel, it's just a suggestion to the compiler, and if whatever heuristics the compiler uses say it may be favourable to do it in parallel, it will produce code to calculate it in parallel (given appropriate compile- and run-time flags), otherwise it produces purely sequential code. With parallelize in a separate module, when compiling that, the compiler has no way to see whether parallelizing the computation may be beneficial, so doesn't produce (potentially) parallel code. At the use site, in the other module, it doesn't see the 'par', so has no reason to even consider producing parallel code. If parallelize is defined in the module where it's used, it will be inlined anyway since it is small, so the compiler sees the 'par' (actually par#) when compiling the use site and can employ the heuristics to decide whether to produce parallel code. If you place an INLINE pragma near the definition of parallelize, it will be inlined when compiling the importing module, so again the compiler sees the opportunity to parallelize. So, if I got it right (or nearly right), yes, every exported function that uses par should be INLINEd [1], and have a simple enough body that it will indeed be inlined. The same holds for callers of such functions, if the compiler can't see at the definition that parallelism is good, let the function be inlined so that it may be spotted at the call site. [1] Well, I suppose for function x = (expensive1 `par` expensive2) `seq` x and such, if expensive1/2 are defined in the same module, it may not be necessary. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: A problem with par and modules boundaries...
Hi Mario, It looks like the parallelize function is getting inlined when it's in the same file, but not when it's in a separate file. Adding a {-# INLINE parallelize #-} pragma to the module with parallelize recovers all the performance for me. You could probably see exactly what's happening in more detail by going through the Core output. John Lato Message: 23 Date: Thu, 21 May 2009 22:59:51 -0400 From: Mario Bla?evi? mblaze...@stilo.com Subject: [Haskell-cafe] A problem with par and modules boundaries... To: haskell-cafe@haskell.org Message-ID: .1242961...@magma.ca Content-Type: text/plain; charset=utf-8 I'll cut to the chase. The short program below works perfectly: when I compile it with -O2 -threaded and run with +RTS -N2 command-line options, I get a nearly 50% real-time improvement: $ time ./primes-test +RTS -N2 5001 real 0m9.307s user 0m16.581s sys 0m0.200s However, if I move the `parallelize' definition into another module and import that module, the performance is completely lost: $ time ./primes-test +RTS -N2 5001 real 0m15.282s user 0m15.165s sys 0m0.080s I'm confused. I know that `par` must be able work across modules boundaries, because Control.Parallel.Strategies is a module and presumably it works. What am I doing wrong? module Main where import Control.Parallel import Data.List (find) import Data.Maybe (maybe) --import Parallelizable parallelize a b = a `par` (b `pseq` (a, b)) test :: Integer - Integer - Integer test n1 n2 = let (p1, p2) = parallelize (product $ factors $ product [1..n1]) (product $ factors $ product [1..n2]) in p2 `div` p1 factors n = maybe [n] (\k- (k : factors (n `div` k))) (find (\k- n `mod` k == 0) [2 .. n - 1]) main = print (test 5000 5001) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] generic filter through MonadPlus
On May 22, 2009, at 4:13 AM, Jason Dusek wrote: I'd like to know what folks think about the use of `MonadPlus` in this case. The |guard| function is almost |filter|: import Control.Monad ( MonadPlus, guard ) filter :: MonadPlus m = (a - Bool) - m a - m a filter p m = do a - m guard (p a) return a Cheers, Sebastian -- Underestimating the novelty of the future is a time-honored tradition. (D.G.) PGP.sig Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] community.haskell.org and code.haskell.org problems
On Mon, May 18, 2009 at 11:38:09AM +0100, Neil Mitchell wrote: Is there a reason for the poor reliability of these servers? We do have a plan to move community to a beefier machine with more reliable hosting. There are a few details to sort out first, and then we just need to find the time to do it. Thanks Ian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Introducing Instances in GHC point releases
Hi John, On Thu, May 21, 2009 at 09:30:24PM -0500, John Goerzen wrote: I guess my larger point is just a plea to the community: please be really careful about what you do to GHC in point releases. We are careful about what goes into the official GHC release. However, ever since GHC 6.6 (when extralibs were first separated out), we have not made any guarantees about whether point releases come with the same, or a compatible, version; we just take what's in the darcs repo at the time of the release. Anyway, this will be a non-issue in 6.12, when there are no extralibs, and the Haskell Platform takes over the role. Thanks Ian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] haddock could be a pretty-printer?
Hi, The new version of haddock makes use of GHC parser. How much of effort would take to make haddock generate pretty-print of the source code itself, including haddock documentation (although probably loosing other comments)? Maybe even an html version that documentation could point to? Thanks, Maurício ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Data.Binary suboptimal instance
So lately I've been working on a little program to generate trippy graphics. (Indeed, some of you may remember it from a few years back...) Anyway, getting to the point, I just restructured my program. As part of the restructuring, I got rid of all the jiggery-pokery with Data.Array.Storable and so forth and decided to use Data.Binary. My first problem was quite simple. I want to write a program that reads an item from the input file, processes it, writes it to the output file, and repeats until the input file is empty. Data.Binary doesn't appear to provide any obvious way to do this. You can't be in the Get and Put monads simultaneously, and I can't figure out how to interleave them. In the end, I ended up with something like xs - decodeFile f1 encodeFile f2 (map f xs) Unfortunately, it looks like this doesn't do what I want. Serialised lists have their length prepended to them, which means that encodeFile is going to have to generate the *entire* list in memory so it can count how big it is, before it can output a single byte to disk. (!) This is particularly annoying since the output list will be exactly the same size as the input one, and the very first thing decodeFile is doing is reading in that size figure. Maybe there's a way around this glitch, and I just haven't thought of it yet. But you'd think that wanting to lazily process data from an input file and write it into an output file would be an extremely common use-case. Given that, I'm not seeing an obvious way to handle it. Anyway, that's one small problem, but I can live with it. There's another, much bigger problem though, and that's really what I wanted to talk about... As we all know, Data.Binary is *built* for speed. So imagine my shock when my newly adjusted program now based around this library turned out to be massively slower, and the files it produced were drastically larger. It didn't take me that long to dig up the problem. The problem seems to boil down to this: The Binary instance for Double (and Float, by the way) is... well I guess you could argue it's very portable, but efficient it isn't. As we all know, an IEEE-754 double-precision floating-point number occupies 64 bits; 1 sign bit, 11 exponent bits, and 52 mantissa bits (implicitly 53). I had assumed that the Binary instance for Double would simply write these bits to disk, requiring approximately 0 computational power, and exactly 64 bits of disk space. I was wrong. ...what it *actually* does is convert the 64-bit Double into a 32-bit exponent and an arbitrary-precision integer part. (!) It appears to do this by floating-point arithmetic rather than just low-level bit shuffling. Looking up how arbitrary-precision integers are serialised, I see that there's an 8-bit flag indicating whether the integer fits into 32 bits, and if it doesn't, there's an 8-bit sign value, followed by a serialised list of bytes. So, in other words, a 32-bit length value, followed by the bytes themselves. To summarise, when I ask for a 64-bit Double to be serialised, I get this: 32-bit exponent. 8-bit flag (probably always 1) 8-bit sign (either 0 or 1) 32-bit size (probably always 8) 64-bit mantissa That's 144 bits in total, i.e., 225% larger than the original Double. (Let's not even go into how much computer power it takes to construct all this data before it's written to disk...) So, that's why my files balooned in size, and why my program slowed to a crawl. But how do I fix this? Well, my solution was simple, brutal, and probably *highly* non-portable. It begins with Unsafe.Coerce (that's never a good thing!) Put simply, if you take your 64-bit Double and unsafeCoerce it into a Word64 and then ask Data.Binary to serialise that, it writes it straight to disk without screwing around with it first. The result ought to be portable to any architecture that uses IEEE-754 arithmetic natively. (Anybody know of an arch this *doesn't* apply to?) But sure, if you wanted to do this on some other architecture with a different native float format, you'd have to write some trixy code to handle it. (And then add conditional compilation for it.) Is there any danger that there might be some kind of improvement to the Double instance in the next version of Data.Binary? END. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] haddock could be a pretty-printer?
2009/5/22 Maurício briqueabra...@yahoo.com: Hi, The new version of haddock makes use of GHC parser. How much of effort would take to make haddock generate pretty-print of the source code itself, including haddock documentation (although probably loosing other comments)? Maybe even an html version that documentation could point to? You can use hscolour to output source code in HTML form and Haddock can generate links to it if you use the --source-* flags. Most documentation on Hackage seems to make use of this. Is this what you want or is there some reason why you want the code to be pretty-printed? David ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.Binary suboptimal instance
On Fri, 22 May 2009, Andrew Coppin wrote: So lately I've been working on a little program to generate trippy graphics. (Indeed, some of you may remember it from a few years back...) Anyway, getting to the point, I just restructured my program. As part of the restructuring, I got rid of all the jiggery-pokery with Data.Array.Storable and so forth and decided to use Data.Binary. My first problem was quite simple. I want to write a program that reads an item from the input file, processes it, writes it to the output file, and repeats until the input file is empty. Data.Binary doesn't appear to provide any obvious way to do this. You can't be in the Get and Put monads simultaneously, and I can't figure out how to interleave them. You can! - It's again time to point out that Put shouldn't be a monad, but a monoid. But as it is, Put is a Writer monad on top of the Builder monoid. Better use that Builder monoid directly. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.Binary suboptimal instance
Henning Thielemann wrote: On Fri, 22 May 2009, Andrew Coppin wrote: My first problem was quite simple. I want to write a program that reads an item from the input file, processes it, writes it to the output file, and repeats until the input file is empty. Data.Binary doesn't appear to provide any obvious way to do this. You can't be in the Get and Put monads simultaneously, and I can't figure out how to interleave them. You can! - It's again time to point out that Put shouldn't be a monad, but a monoid. But as it is, Put is a Writer monad on top of the Builder monoid. Better use that Builder monoid directly. Aaaahhhahaha Nice. Thanks for the tip. :-D ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: haddock could be a pretty-printer?
The new version of haddock makes use of GHC parser. How much of effort would take to make haddock generate pretty-print of the source code itself, (...) (...) Is this what you want or is there some reason why you want the code to be pretty-printed? I usually have to resort to braces or bad indenting to get code to parse, but I like to give it good presentation before publishing. I used to pretty-print my code using haskell-src-exts with great result, but that kills documentation. Best, Maurício ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.Binary suboptimal instance
On Friday 22 May 2009 23:34:50 Henning Thielemann wrote: So lately I've been working on a little program to generate trippy graphics. (Indeed, some of you may remember it from a few years back...) Anyway, getting to the point, I just restructured my program. As part of the restructuring, I got rid of all the jiggery-pokery with Data.Array.Storable and so forth and decided to use Data.Binary. My first problem was quite simple. I want to write a program that reads an item from the input file, processes it, writes it to the output file, and repeats until the input file is empty. Data.Binary doesn't appear to provide any obvious way to do this. You can't be in the Get and Put monads simultaneously, and I can't figure out how to interleave them. You can! - It's again time to point out that Put shouldn't be a monad, but a monoid. But as it is, Put is a Writer monad on top of the Builder monoid. Better use that Builder monoid directly. Could you elaborate? I didn't quite understand. Anyway I had similar problem and simply wrote few functions. They encode/decode values of same type element by element. It's lazy enough so code could be written in following style: process :: [Foo] - [Bar] foo = readFile name = writeFile out . encodeStream . process . decodeProcess There is a code. It is fast and worked for me without a problem. -- | Decode records in repetition decodeStream :: Binary a = ByteString - [a] decodeStream = runGet (getStream get) -- | Encode list of records as bytestring encodeStream :: Binary a = [a] - ByteString encodeStream = runPut . putStream put -- | Read list of values from bytestring until it ends. getStream :: Get a - Get [a] getStream getter = do empty - isEmpty if empty then return [] else do x - getter xs - getStream getter return (x:xs) -- | Write list of values. putStream :: (a - Put) - [a] - Put putStream f = mapM_ f -- Khudyakov Alexey ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Fwd: [Haskell-cafe] Data.Binary suboptimal instance
I suppose I should send my reply to the list ... -- Forwarded message -- From: Antoine Latter aslat...@gmail.com Date: Fri, May 22, 2009 at 5:54 PM Subject: Re: [Haskell-cafe] Data.Binary suboptimal instance To: Khudyakov Alexey alexey.sklad...@gmail.com On Fri, May 22, 2009 at 4:36 PM, Khudyakov Alexey alexey.sklad...@gmail.com wrote: You can! - It's again time to point out that Put shouldn't be a monad, but a monoid. But as it is, Put is a Writer monad on top of the Builder monoid. Better use that Builder monoid directly. Could you elaborate? I didn't quite understand. Anyway I had similar problem and simply wrote few functions. They encode/decode values of same type element by element. It's lazy enough so code could be written in following style: Or you could go for the compromise position, where the list can be part of a complex data structure so you're not relying on EOF to find the end. (warning, I don't have my compiler handy so this may not even typecheck) import Control.Monad import Data.Monoid import Data.Binary.Builder import Data.Binary.Get data ChunkedList a = Cons [a] (ChunkedList a) -- Non-null list | Nil chunkSize = 50 fromList :: [a] - ChunkedList a fromList [] = Nil fromList xs = let (front,back) = splitAt chunkSize xs in Cons front (fromList back) toList :: ChunkedList a - [a] toList Nil = [] toList (Cons front back) = front ++ toList back putList :: (a - Builder) - [a] - Builder putList f xs = putChunkedList (fromList xs) where putChunkedList Nil = singleton 0 putChunkedList (Cons front back) = mconcat [ singleton (genericLength front) , mconcat $ map f front , putChunkedList back ] getList :: Get a - Get [a] getList m = toList `liftM` getChunkedList where getChunkedList = do cLen - getWord8 case cLen of 0 - return Nil _ - Cons `liftM` replicateM (fromIntegral cLen) m `ap` getChunkedList ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANNOUNCE: text 0.2, fast and comprehensive Unicode support using stream fusion
I'm pleased to announce the availability of text 0.2, an efficient Unicode text library that uses stream fusion. New and notable in this release is support for lazy, chunked text, so you can process text files far larger than memory using a small footprint. Hackage page: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/text Darcs repo: darcs get http://code.haskell.org/text Report bugs: http://trac.haskell.org/text/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] import qualified?
Hello, I am working with some somewhat legacy code. I understand what import qualified Blah as B means but what does import qualified Blah mean? Is this a deprecated feature? I saw with user defined module as well as with import qualified System for example. REgards, Vasili ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] import qualified?
Vasili I. Galchin wrote: Hello, I am working with some somewhat legacy code. I understand what import qualified Blah as B means but what does import qualified Blah mean? Is this a deprecated feature? I saw with user defined module as well as with import qualified System for example. It just means that you must qualify the names with the module name (System). It's not deprecated, but most folks use the import qualified ... as version instead so that they can give a shorter name instead of using the full module name. -- Live well, ~wren ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] import qualified?
On Sat, May 23, 2009 at 12:39 AM, Vasili I. Galchin vigalc...@gmail.com wrote: Hello, I am working with some somewhat legacy code. I understand what import qualified Blah as B means but what does import qualified Blah mean? Is this a deprecated feature? I saw with user defined module as well as with import qualified System for example. REgards, Vasili ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe See the report, section 5.3.2: http://www.haskell.org/onlinereport/modules.html Because we tend to have long names now, you will often see people aliasing. But qualified by itself has an important role, it's not deprecated. Paulo ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe