Available formats: content-negotiated html turtle (see SIOC for the vocabulary)
Back to channel and daily index: content-negotiated html turtle
These logs are provided as an experiment in indexing discussions using IRCHub.py, Irc2RDF.hs, and SIOC.
| 00:00:10 | <persica> | Wraithan: Huh, I was unaware. |
| 00:00:24 | <erikc> | C99 variable length arrays are just sugar for alloca |
| 00:00:38 | <Cale> | romildo: You might also use a Map or IntMap, if there is the possibility of gaps between elements. |
| 00:00:54 | <Wraithan> | persica: yeah, C99 added it |
| 00:01:06 | <copumpkin> | <3 alloca |
| 00:01:40 | <newsham> | hahah. conal's blog post rules. I'm afraid conal has oved to IO (as he is having an affect on the world) |
| 00:01:47 | <newsham> | s/oved/moved/ |
| 00:02:02 | <_JFT_> | newsham: lol |
| 00:04:17 | <romildo> | Cale, there is no gap in between elements. A list is good for me. I just thought that a mutable array would be better. As a consequence of user interaction, any element in the list can be changed. So I thought that a mutable array would be apropriate. Remember that the imutable list is already stored in an IORef variable. |
| 00:05:02 | <Cale> | romildo: Perhaps Data.Sequence would improve performance for you. |
| 00:05:13 | <romildo> | Cale, with an imutable structure, every time the user changes an element, a new structure should be constructed. |
| 00:05:20 | <roconnor> | > 49000000/14000000 |
| 00:05:21 | <lambdabot> | 3.5 |
| 00:05:35 | <romildo> | Cale, I will take a look at Data.Sequence. |
| 00:05:39 | <_JFT_> | romildo: check zippers ;) |
| 00:06:04 | <romildo> | _JFT_, what are zippers? |
| 00:06:12 | <roconnor> | 49 `choose` 6 |
| 00:06:13 | <Cale> | romildo: Yes, but in Data.Sequence's case, only an amount of memory logarithmic in the size of the structure is needed to get a new structure that has all the elements in common except one. |
| 00:06:16 | <roconnor> | > 49 `choose` 6 |
| 00:06:17 | <lambdabot> | Couldn't match expected type `t1 -> t' |
| 00:06:37 | <_JFT_> | romildo: http://www.haskell.org/haskellwiki/Zipper |
| 00:06:40 | <Cale> | roconnor: It's because internally, the structure is a tree, and subtrees can be shared. |
| 00:06:53 | <roconnor> | romildo |
| 00:06:58 | <_JFT_> | romildo: something that alleviate the cost of changing part of an immutable structure |
| 00:07:15 | <Cale> | Zippers are good when you need to make lots of modifications around one particular "cursor" in the structure. |
| 00:07:25 | <roconnor> | > product [49-6+1..49] `div` product [1..6] |
| 00:07:26 | <lambdabot> | 13983816 |
| 00:07:42 | <Cale> | But if you need random access, nothing is going to do better than some kind of tree. |
| 00:10:41 | <thoughtpolice> | copumpkin: yeah for sure |
| 00:10:57 | <copumpkin> | thoughtpolice: you addicted to killzone now? :) |
| 00:10:58 | <thoughtpolice> | copumpkin: now that bootstrapping is in place again I'm trying to get HEAD working on linux ppc/ppc64 |
| 00:11:05 | <copumpkin> | oh |
| 00:11:09 | <thoughtpolice> | copumpkin: well i bought fallout 3 too |
| 00:11:14 | <copumpkin> | lol |
| 00:11:19 | <copumpkin> | that's a fun game |
| 00:12:16 | <thoughtpolice> | copumpkin: but yeah, I want to try optimized HEAD build + mac os x + 64bit + DPH and see how it goes :) |
| 00:12:27 | <copumpkin> | mmm |
| 00:12:39 | <copumpkin> | I need to get me more cores |
| 00:12:42 | <copumpkin> | only got four |
| 00:15:21 | <roconnor> | > 3.5*0.4 |
| 00:15:22 | <lambdabot> | 1.4000000000000001 |
| 00:16:20 | <p_l> | copumpkin: SiCortex? 72cores in single tower computer? :D |
| 00:16:28 | <copumpkin> | p_l: sounds good |
| 00:17:15 | <p_l> | copumpkin: it would require some work on GHC, though (for MIPS64) |
| 00:17:32 | <Badger> | :t 3.5 * 0.4 |
| 00:17:33 | <lambdabot> | forall t. (Fractional t) => t |
| 00:17:40 | <Badger> | curse thee fractional |
| 00:17:44 | <copumpkin> | p_l: yeah |
| 00:17:54 | <erikc> | gnumake -j72 |
| 00:18:20 | <p_l> | erikc: you'd max I/O before reaching 72 :) |
| 00:18:31 | <erikc> | heh, yea |
| 00:18:38 | <p_l> | (well, maybe with 10GBit RDMA NFS...) |
| 00:19:11 | <erikc> | not if some of your build tasks are generating lightmaps :) |
| 00:19:20 | <p_l> | well, true :) |
| 00:20:10 | <p_l> | IMHO 36 cores per processor board is nice package :) |
| 00:31:31 | <amckinley> | hey, could someone explain why this doesnt work? http://pastebin.com/m1e57c498 |
| 00:34:00 | <amckinley> | getting a type error: No instance for (Stream s m Char) |
| 00:34:01 | <amckinley> | arising from a use of `satisfy' at ../tmp/wtf.hs:6:17-31 |
| 00:34:56 | <kniu> | amckinley, what's the type of isUpper? |
| 00:35:08 | <persica> | amckinley: Sorry, I'm still learning Parsec myself. |
| 00:35:26 | <amckinley> | :t isUpper |
| 00:35:27 | <lambdabot> | Char -> Bool |
| 00:35:41 | <kniu> | oh hey |
| 00:35:43 | <amckinley> | :t satisfy |
| 00:35:44 | <lambdabot> | Not in scope: `satisfy' |
| 00:35:57 | <kniu> | strange. |
| 00:36:04 | <amckinley> | :t Text.Parsec.Prim.Satisfy |
| 00:36:05 | <lambdabot> | Couldn't find qualified module. |
| 00:36:09 | <amckinley> | argh |
| 00:36:18 | <amckinley> | :t Text.Parsec.Char.Satisfy |
| 00:36:19 | <lambdabot> | Couldn't find qualified module. |
| 00:36:56 | <amckinley> | satisfy :: (Stream s m Char) => |
| 00:36:56 | <amckinley> | (Char -> Bool) -> ParsecT s u m Char |
| 00:37:20 | <kniu> | my ghci > :t satisfy |
| 00:37:20 | <kniu> | satisfy :: (Char -> Bool) -> CharParser st Char |
| 00:37:35 | <amckinley> | kniu: you're using a 2.x version of parsec |
| 00:37:48 | <kniu> | and what's yours? |
| 00:37:58 | <amckinley> | 3.x |
| 00:38:32 | <amckinley> | hey Cale |
| 00:39:00 | <amckinley> | any idea why this doesnt work now that ive switched to parsec 3.x? http://pastebin.com/m1e57c498 |
| 00:39:02 | <amckinley> | :) |
| 00:40:39 | <copumpkin> | uh, not without an error :P |
| 00:40:57 | <amckinley> | No instance for (Stream s m Char) |
| 00:40:57 | <amckinley> | arising from a use of `satisfy' |
| 00:41:29 | <conal> | sclv: thanks for your blog comment. mind if i replace "lennary" with "lennart" (or "Lennart")? |
| 00:43:13 | <amckinley> | copumpkin: i feel like i need a more explicit type signature |
| 00:43:56 | <copumpkin> | probably |
| 00:44:15 | <Cale> | amckinley: Sorry about that... where is your code now? |
| 00:44:25 | <Cale> | amckinley: I'll see if I can help sort it out |
| 00:44:32 | <amckinley> | Cale: np, wb :) http://pastebin.com/m1e57c498 |
| 00:45:39 | <BMeph> | ACTION wants a T-shirt with (imagine the solidi mark new lines): "Haskell | PARENTAL ADVISORY | Explicit Type Signatures" |
| 00:46:06 | <copumpkin> | lol |
| 00:46:09 | <amckinley> | :) |
| 00:47:46 | <FunctorSalad> | nice one |
| 00:48:31 | <Cale> | amckinley: hmm |
| 00:48:40 | <Cale> | amckinley: What trouble are you having with that? |
| 00:48:52 | <amckinley> | No instance for (Stream s m Char) |
| 00:48:53 | <amckinley> | arising from a use of `satisfy' at ../tmp/wtf.hs:6:17-31 |
| 00:49:39 | <Cale> | amckinley: I don't get that error... |
| 00:50:10 | <amckinley> | amckinley:dns amckinley$ runghc ../tmp/wtf.hs |
| 00:50:10 | <amckinley> | ../tmp/wtf.hs:6:17: |
| 00:50:10 | <amckinley> | No instance for (Stream s m Char) |
| 00:50:11 | <amckinley> | arising from a use of `satisfy' at ../tmp/wtf.hs:6:17-31 |
| 00:50:11 | <amckinley> | Possible fix: add an instance declaration for (Stream s m Char) |
| 00:50:11 | <amckinley> | In the first argument of `skipMany1', namely `(satisfy isUpper)' |
| 00:50:12 | <amckinley> | In the expression: skipMany1 (satisfy isUpper) |
| 00:50:14 | <amckinley> | In the definition of `foo': foo = skipMany1 (satisfy isUpper) |
| 00:50:31 | <sclv> | conal: please do replace the typo. thx! |
| 00:50:59 | <sclv> | oh, and "the point about monads" should be "the point about monoids" oops. |
| 00:51:05 | <Cale> | amckinley: I just copied and pasted that code into a new file and loaded it in ghci with no problems |
| 00:51:15 | <FunctorSalad> | DMR? |
| 00:51:21 | <ray> | ACTION wants a t-shirt with one of those ghc error messages that tells you "possible fix: add an instance" |
| 00:51:22 | <Cale> | oh! |
| 00:51:27 | <Cale> | That might be it |
| 00:51:40 | <ray> | i'm not sure what dumb joke to work into it, though |
| 00:51:49 | <kyevan> | YES! |
| 00:51:53 | <kyevan> | er. |
| 00:51:56 | <kyevan> | Wrongchan |
| 00:52:02 | <Cale> | amckinley: Try putting {-# LANGUAGE NoMonomorphismRestriction #-} at the top of the file, and see if it helps |
| 00:52:30 | <amckinley> | that fixed it |
| 00:52:32 | <amckinley> | *awesome* |
| 00:52:52 | <amckinley> | :P |
| 00:53:16 | <amckinley> | since ive been screwing with this for an hour, i feel like i should at least know what that language pragma does |
| 00:53:26 | <copumpkin> | are there any parser combinators that work on top of Data.Text? |
| 00:53:28 | <bremner> | ACTION orders whatever kyevan is having |
| 00:55:00 | <roconnor> | the monomorphism restriction is a bit complicated and stupid. |
| 00:55:11 | <copumpkin> | I agree :/ |
| 00:55:48 | <ray> | the monomorphism restriction is widely reviled |
| 00:57:18 | <amckinley> | presumably because it results in noobies dealing with incomprehensible error messages, among other reasons? :) |
| 00:58:45 | <ray> | it certainly does that |
| 00:59:18 | <Gracenotes> | lifting the monomorphism restriction would make things that appear to be constant expressions actually be reevaluated every time |
| 00:59:27 | <Gracenotes> | especially in the way it interacts with the Num typeclass |
| 01:00:03 | <Gracenotes> | (of course, it's not guaranteed these things won't be reevaluated every time, but one can generally depend on it...) |
| 01:00:19 | <ray> | the num typeclass isn't nearly reviled enough |
| 01:00:22 | <amckinley> | the wiki article makes sense |
| 01:00:31 | <amckinley> | thanks again Cale :) |
| 01:01:23 | <aavogt> | that reevaluation issue would be better delt with by a warning, not an error IMHO |
| 01:02:32 | <Gracenotes> | the great fault of the Num typeclass is that you generally expect to be dealing with a specific type when working with numbers: that is, you have a specific type in mind, like an Int or Double |
| 01:02:52 | <Gracenotes> | imho anyway |
| 01:03:01 | <FunctorSalad> | you just have to fix the type once though, it will propagate |
| 01:03:11 | <Gracenotes> | well. Not if you have many top-level functions. |
| 01:03:41 | <FunctorSalad> | (and isn't ghc good at eliminating dictionaries anyway?) |
| 01:03:43 | <Gracenotes> | but annotation is known to improve performance. |
| 01:03:54 | <jeff_s_> | I have to say: I love functional languages. |
| 01:03:58 | <Gracenotes> | FunctorSalad: well. For whole-program compilation maybe :) |
| 01:04:31 | <eivuokko> | ..or in local scope, ie after inlining. |
| 01:04:38 | <hatds> | does ghc do whole program optimization? |
| 01:05:35 | <eivuokko> | Not explicitly, but you may get inlining that looks a lot like it. |
| 01:06:33 | <jeff_s_> | finally! Solved http://www.spoj.pl/problems/ONP/ |
| 01:07:21 | <roconnor> | solve O = NP? |
| 01:07:35 | <jeff_s_> | in Haskell? Can't. give me a better language |
| 01:08:03 | <dons> | hatds: 90% of it. |
| 01:08:49 | <dons> | Gracenotes: but the great benefit is that we get to use (+) for adding things |
| 01:09:15 | <dons> | anyway, give type decls. it's good for you. |
| 01:09:34 | <Gracenotes> | yes. But it is somewhat unintuitive, and would be worsened much more -- perfect storm, perhaps! -- with the monomorphism restriction |
| 01:09:50 | <BMeph> | Gracenotes: IMWO, the faults of the Num typeclass are so varied and full, that picking just one to be "great" is almost as Worthless as this very opinion. :) |
| 01:10:26 | <Gracenotes> | eh. I think it is the greatest: the concept of its existence and the Haskell numerical system :) others tend to be more nitpicky |
| 01:10:47 | <Gracenotes> | but there are pros to the approach, amidst the cons |
| 01:10:51 | <Gracenotes> | and the snocs |
| 01:11:01 | <Gracenotes> | anyway. my opinion, 's all. |
| 01:11:02 | <FunctorSalad> | + and * should be seperate really... |
| 01:11:03 | <dons> | i bet ghc would surprise you if you looked at the core |
| 01:11:16 | <FunctorSalad> | (for vectors, mostly) |
| 01:11:42 | <Gracenotes> | eh. non-numerical Num instances, *suspicious* |
| 01:11:49 | <conal> | sclv: i just fixed both typos. thx. :) |
| 01:12:06 | <Gracenotes> | dons: howso? |
| 01:12:07 | <BMeph> | ACTION would love to bitch-slap the genius that decided to toss Show into the Num class... |
| 01:12:16 | <gwern> | (go peacefully among the cons and snocs of the world / lispers have their place, just as you do / and no doubt all is executing as it should) |
| 01:12:16 | <FunctorSalad> | granted, it's not a big thing to use some other operator for adding vectors |
| 01:12:41 | <Gracenotes> | BMeph: perhaps an argument for typeclass synonyms from the beginning |
| 01:13:43 | <Gracenotes> | except, how would GHC know to merge (Show a, Num a) into a synonym automatically. It's all so ... hrmhrmeate9werayhwefa :/ |
| 01:13:50 | <dons> | gwern: upload the Quantum IO monad to hackage... http://www.cs.nott.ac.uk/~txa/publ/qio.pdf |
| 01:14:13 | <copumpkin> | lots of big Qs in that paper |
| 01:14:25 | <gwern> | dons: bleh, is still working on the math package! he wanted to cabalize it hisself |
| 01:14:45 | <gwern> | (foolish, since I could do it so much faster) |
| 01:15:11 | <dons> | he's sigfpe's friend |
| 01:15:51 | <Gracenotes> | 0|copumpkin> + 1|pumpkin> |
| 01:15:56 | <gwern> | no license info. figures. |
| 01:16:15 | <Gracenotes> | a non-probabilistic pumpkin bit |
| 01:16:17 | <copumpkin> | :o |
| 01:17:14 | <mux> | dons: hey! bsd-sysctl 1.0.1 should work on openbsd with numeric oids, if you want to give it a try I'd be glad |
| 01:18:10 | <gwern> | dons: who, this Alexander Green? |
| 01:19:01 | <FunctorSalad> | isn't copumpkin more like a linear functional? |
| 01:19:06 | <mux> | btw, does anyone know if the hackage build bot defines some specific macro when building haddock documentation, so that I can generate docs for the whole module even if it's built on an architecture where not all functions will be available? |
| 01:19:14 | <copumpkin> | I feel pretty constant :/ |
| 01:19:38 | <gwern> | mux: specific macro? |
| 01:19:48 | <mux> | as in cpp macro |
| 01:21:50 | <FunctorSalad> | a workaround would be to upload the docs for the bsd version somewhere and link from the description page.. |
| 01:22:12 | <gwern> | dons: ok, I've sent'em an email asking about licensiong info for QIO |
| 01:22:49 | <mux> | FunctorSalad: I'm ready to define all the functions as error calls if there are no other solutions |
| 01:22:52 | <gwern> | dons: although in retrospect I should've asked about their QML as well... |
| 01:23:12 | <gwern> | dons: 'A functional quantum programming language implemented in Haskell.' http://fop.cs.nott.ac.uk/qml/compiler/ |
| 01:24:29 | <gwern> | ack! qml's entire licensing info is '(c) Jonathan Grattage, 2008. jonathan.grattage@imag.fr' |
| 01:24:36 | <gwern> | well gee. that's helpful |
| 01:25:07 | <MyCatVerbs> | gwern: didn't even bother to write "all right reserved", huh? :/ |
| 01:25:37 | <gwern> | hey now, maybe it's really under the GPL but he was too fagged by the second line |
| 01:26:07 | <gwern> | oh, and the haskell generated by happy? it's a managed file |
| 01:26:11 | <gwern> | -_- |
| 01:26:49 | <dons> | "a managed file"? |
| 01:26:57 | <gwern> | dons: ie checked into darcs |
| 01:26:59 | <eivuokko> | I guess version controlled. |
| 01:27:17 | <gwern> | presumably if the happy grammar is ever changed, he'll rerun happy and commit those changes as well... |
| 01:27:29 | <SamB> | gwern: one hopes! |
| 01:27:38 | <gwern> | I daren't check |
| 01:27:41 | <SamB> | sometimes people forget these things |
| 01:28:14 | <eivuokko> | Happy didn't used to be self-evident, so maybe it was just easier for people playing with it. |
| 01:28:18 | <dons> | ah, so the grammar file itself isn't included? |
| 01:28:29 | <gwern> | no, the grammar file is |
| 01:28:50 | <gwern> | it includes both the grammar file and the file happy generates from the grammar file. I just consider it to be something of a wtf |
| 01:28:57 | <dons> | shrug |
| 01:28:59 | <gwern> | one wouldn't manage the contents of dist/, for example |
| 01:30:19 | <MyCatVerbs> | Yeah, I'm with gwern on this one. |
| 01:31:24 | <MyCatVerbs> | No automatically generated file should be in your version control. |
| 01:31:54 | <MyCatVerbs> | For one thing, you'll get spurious changes all over the place if people have differing versions of the generator installed. |
| 01:32:19 | <marcusb> | haskell mode for emacs doesn't get do-if-then-else indentation right :-/ |
| 01:32:32 | <gwern> | marcusb: yi does, fwiw |
| 01:32:50 | <FunctorSalad> | you need the generated file for ghci though |
| 01:35:29 | <FunctorSalad> | (of course that's just a question of convenience. I mean that someone getting the repo will be able to develop with ghci right away) |
| 01:35:50 | <gwern> | indeed. the pdf says to just load up in ghci |
| 01:41:19 | <jeff_s_> | does anyone have a more awesome haskell-y way to write http://pastebin.com/d5c29dfc5 ? |
| 01:49:08 | <conal> | hm. the "our branding sucks" haskell reddit thread got deleted (http://www.reddit.com/r/haskell/comments/8m092/why_our_branding_sucks_monads_are_okay_after_a/). anyone know why? i wrote a comment and got "that comment has been deleted". |
| 01:49:46 | <copumpkin> | :o |
| 01:50:55 | <jeff_s_> | hey! Monads are easy. it's using them properly taht's hard imo |
| 01:51:00 | <jeff_s_> | and/but I"m a newbie |
| 01:51:28 | <aavogt> | jeff_s_: use $ instead of brackets |
| 01:51:40 | <jeff_s_> | ok I will try taht |
| 01:51:55 | <Zao> | jeff_s_: getContents >>= mapM_ (print <$> toRPN . read) |
| 01:52:11 | <Zao> | What's a non-applicative variant of <$>, if any? |
| 01:52:19 | <aavogt> | liftM |
| 01:53:21 | <copumpkin> | Zao: `fmap` |
| 01:53:46 | <copumpkin> | Zao: <$> is only in the Applicative module, it actualy only relies on Functor |
| 01:53:55 | <Zao> | copumpkin: Using `fmap` in that context will make the compiler pissy about precedence parsing though. |
| 01:54:02 | <copumpkin> | true |
| 01:54:03 | <monochrom> | I think it was deleted because someone misread it as "why our branding sucks monads". |
| 01:54:23 | <copumpkin> | Zao: define your own precedence for it :P |
| 01:54:32 | <Zao> | Or just use <$>, as it makes sense :) |
| 01:54:39 | <copumpkin> | yup |
| 01:55:02 | <dons> | conal: i removed it only because i thought i was editorialising |
| 01:55:24 | <dons> | conal: but it does express what I think is a problem: the outside world sees monads as a problem, not a solution |
| 01:55:34 | <dons> | i.e. the branding sucks |
| 01:55:38 | <conal> | dons: yeah. |
| 01:55:52 | <dons> | the very thing that e.g. means their language is implementable simply as our library! |
| 01:55:53 | <monochrom> | the branding sucks monads :) |
| 01:56:05 | <conal> | dons: if you'll repost, i'll add my analysis & suggestion. |
| 01:56:09 | <dons> | will do. |
| 01:56:24 | <Zao> | Monads are like sucking. |
| 01:56:25 | <monochrom> | Phil Wadler's branding of monads is still the best to date. |
| 01:56:47 | <conal> | monochrom: what's is it? |
| 01:56:54 | <jeff_s_> | Zao - for read ghc says: Expected type Char inferred type String |
| 01:57:05 | <dons> | i want people to think: awesome! this thing i'm struggling with is a monad. now my life just got easier. |
| 01:57:14 | <Zao> | jeff_s_: Oh right, the lines. |
| 01:57:20 | <Zao> | jeff_s_: Had different test data :) |
| 01:57:21 | <conal> | dons: amen! |
| 01:57:27 | <jeff_s_> | I wondered where that was supposed to go |
| 01:57:37 | <monochrom> | "monads for functional programming" http://homepages.inf.ed.ac.uk/wadler/papers/marktoberdorf/baastad.pdf |
| 01:57:46 | <dons> | conal: http://www.reddit.com/r/haskell/comments/8m1gj/our_branding_sucks_monads_are_okay_after_a_bit/ |
| 01:58:07 | <conal> | dons: and similarly for other type classes. i think giving monads special attention is part of the problem. |
| 01:58:47 | <conal> | s/monad/Monad/ |
| 01:59:00 | <conal> | oops. s/monads/Monad/ |
| 01:59:05 | <dons> | agreed. |
| 01:59:09 | <conal> | dons: there. i just posted my comment. |
| 01:59:12 | <dons> | instead of presenting the wealth of abstraction power |
| 01:59:26 | <dons> | instead we get lost in the quicksands of IO. |
| 01:59:33 | <dons> | the stickiest ground to try to fight our battles on |
| 01:59:57 | <conal> | yeah. and we encourage people to muddle two independent powerful and relatively simple ideas. |
| 02:00:04 | <conal> | into one mysterious wad. |
| 02:00:43 | <conal> | i'd like us to be more careful with our language. for instance, i'd replace the common phrase "understanding monads" with "understanding Monad". |
| 02:01:00 | <dons> | oh, i really like this idea of talking about IO as a (data) type, like String |
| 02:01:03 | <Zao> | jeff_s_: lines <$> getContents >>= ... |
| 02:01:10 | <conal> | :) ! |
| 02:01:32 | <edwardk> | dons: i.e. as a free monad of its operations? |
| 02:01:35 | <conal> | i think the goal of "understanding monads" is a confusion, since there are infinitely many, quite different monads. |
| 02:01:43 | <dons> | asa type, with operations on it. |
| 02:01:49 | <MonadBaastad> | conal: Or even "understanding the Monad class" - except, then you risk running into all of the baggage that goes along with the name "class" |
| 02:02:09 | <jeff_s_> | say typeclass instead |
| 02:02:12 | <monochrom> | To understand "+" you already run into typeclasses. |
| 02:02:23 | <Zao> | jeff_s_: Writing Haskell code is mostly a matter of ensuring that signature impedance matches. |
| 02:02:28 | <monochrom> | Hell, to understand "0"... |
| 02:02:35 | <Zao> | jeff_s_: And being overly clever so your code is unreadable after a few days :P |
| 02:02:38 | <conal> | yeah. "understanding Monad" or "understanding the Monad typeclass" (for verbosity). |
| 02:02:47 | <dons> | time for Conal's guide to monads, (and monoids, and functors, and applicatives)... |
| 02:02:59 | <conal> | or byorgey's! |
| 02:03:10 | <dons> | "The IO monad" considered harmful |
| 02:03:14 | <dons> | there's your title |
| 02:03:29 | <conal> | yes! and the quotation marks are vital. |
| 02:03:40 | <MonadBaastad> | dons: Better: The IO Monad - Mostly Harmless! |
| 02:03:55 | <conal> | the title would draw people in with one expectation (forgetting to notice the quotes), and then surprise them. |
| 02:04:08 | <Zao> | Monads all look the same to me. |
| 02:04:16 | <dons> | hehe. bait and switch :) |
| 02:04:54 | <conal> | edwardk: no, not the free monad. the abstract IO type. |
| 02:05:23 | <marcusb> | you want a beginners opinion? I have extensive CS and math backgrounds and spent a week to learn the basics of haskell, monads, monad transformers and generic programming. |
| 02:05:35 | <edwardk> | conal: example? or do you just mean treating it like an opaque type with just the knowledge you get from the operations allowed? |
| 02:05:49 | <edwardk> | i.e. that it could be secretly implemented as data IO a = GetChar (Char -> IO a) | PutChar Char (IO a) | ... |
| 02:06:13 | <marcusb> | I think one of the problems is that most documentation follows the historical development of the language and its focus on abstractions. |
| 02:06:17 | <conal> | edwardk: right. an opaque/abstract type. |
| 02:06:35 | <conal> | edwardk: having the semantics of IO |
| 02:06:37 | <marcusb> | it would have been easier if I had seen complete(!) simple examples illustrating the concepts |
| 02:07:03 | <edwardk> | conal: fair enough, that fits with the way i've been teaching it to folks |
| 02:07:13 | <conal> | edwardk: glad to hear. :) |
| 02:07:16 | <marcusb> | this was my issue: I understood the concept of monads early (the math is no problem for me), but I had trouble figuring out how to use the state monad |
| 02:07:32 | <marcusb> | until after couple of hours of reading I found out that it is just a chain of functions |
| 02:07:37 | <marcusb> | that was a major lightbulb |
| 02:08:16 | <conal> | marcusb: i think your difficulty is another example of my recommendation to separate IO from Monad. |
| 02:08:17 | <marcusb> | by that time I had read about 12 times that a monad has a unit and a bind interface |
| 02:08:22 | <edwardk> | marcusb: yeah i think monads really clicked for me by reading one of wadlers early example papers where he just defined a whole bunch of them. (even if he did get a few 'wrong' by modern parlance, i.e. bag, set, strict, etc) |
| 02:08:29 | <conal> | marcusb: the State *type* is simple. |
| 02:08:51 | <marcusb> | conal: yes, although to be fair most tutorials I read don't start with IO, but with Maybe, List, and some others |
| 02:08:53 | <conal> | marcusb: but trying to think about State and Monad simultaneously taxes the brain. |
| 02:09:01 | <roconnor> | @type GetChar |
| 02:09:02 | <lambdabot> | Not in scope: data constructor `GetChar' |
| 02:09:04 | <roconnor> | @type getChar |
| 02:09:06 | <lambdabot> | IO Char |
| 02:09:08 | <marcusb> | "you could have invented monads" is really good |
| 02:09:24 | <conal> | marcusb: glad to hear (Maybe, List, ...). |
| 02:09:42 | <marcusb> | conal: I don't know. maybe is too trivial to make the concepts clear |
| 02:09:45 | <marcusb> | same for lists |
| 02:10:00 | <marcusb> | by the time I read that, everything I did with Maybe and Lists would have worked even if they are not monads |
| 02:10:01 | <conal> | similarly, i'd like IO tutorials to start with examples that do not involve Monad. |
| 02:10:04 | <marcusb> | (at least superficially) |
| 02:10:32 | <conal> | marcusb: similarly, lots of IO code can be written with simpler interfaces. |
| 02:10:37 | <marcusb> | I still don't actually see Maybe and Lists as Monads when hacking |
| 02:10:49 | <marcusb> | conal: I just use WriterT [String] :) |
| 02:11:10 | <conal> | marcusb: did you know that list comprehensions used to be much more general? they were *monad* comprehensions. |
| 02:11:21 | <marcusb> | conal: no, that's new to me |
| 02:11:29 | <conal> | marcusb: it was beautiful!! |
| 02:11:47 | <conal> | part of the dumbing down of haskell. i think from 1.3 to 1.4. (or was it 1.4 to 98?) |
| 02:12:02 | <marcusb> | haskell has this special flare, where the language is backed by a solid theoretical framework. as a mathematician, I can appreciate that |
| 02:12:10 | <marcusb> | but as a hacker, it's not the first thing I am interested in |
| 02:12:13 | <marcusb> | not even the second |
| 02:13:04 | <Zao> | conal: Aren't there extensions to manlify comprehensions? |
| 02:13:11 | <conal> | marcusb: graphics researchers/programmers i know are that way also. they like math and they like programming, but they don't think of them as the same thing. |
| 02:13:18 | <edwardk> | 1.4 to 98 |
| 02:13:27 | <marcusb> | the first thing is how to solve basic problems in programming. how to handle data in various formats (unicode, binary)? how to get the same support for your own types as for built in types (generic programming)? even when not yet understanding the theory behind that |
| 02:13:33 | <conal> | Zao: do you mean beyond lists? |
| 02:13:45 | <Zao> | Aye. |
| 02:13:53 | <conal> | Zao: not that i know of. |
| 02:14:10 | <Zao> | I'm having trouble bending my head around how one of those would look though. |
| 02:14:41 | <conal> | anyone else know of anything like a {-# LANGUAGE MonadComprehensions #-} pragma? |
| 02:14:45 | <marcusb> | conal: I like how I can do both in haskell with quite some elegance. I love the do notation as much as a generic map+fold over my data types. |
| 02:15:03 | <conal> | Zao: check out Wadler's "Comprehending Monads" (iirc) |
| 02:15:51 | <edwardk> | zao: no, no one has gone back and hacked monad comprehensions back into ghc. marlow and company indicated they'd take a patch, but the sugar module where the comprehensions are parsed is particularly ugly because it has so many efficiency hacks that only work for list comprehensions, so its hard to figure out where to start. |
| 02:16:13 | <conal> | ack. :p |
| 02:16:16 | <randomity> | conal: monad comprehensions aren't really any cleaner than "do", they don't visually appear to have sequencing (which is perfect for [] but bad for many monads) and they don't support ghc's parallel list comprehensions (sort of a new syntax for zip) |
| 02:16:39 | <marcusb> | conal: are there experiences/studies on teaching haskell to non-programmers, and maybe even non-scientists? |
| 02:16:48 | <marcusb> | I wonder how that works out |
| 02:17:03 | <marcusb> | I can see it go either way :) |
| 02:17:38 | <edwardk> | randomity: you can extend monad comprehensions to cover zip comprehensions you just need a notion of Zippable functor (ala Control.Functor.Zip in category-extras) |
| 02:17:48 | <IntergalacticOwl> | how do you know when you're a scientist? |
| 02:18:05 | <conal> | marcusb: i don't know. my personal conviction is that pure (no IO) functional programming is inherently suited to right-directed thinkers/creatives. and that the textual packaging obscures that suitability. elaborated on my google tech talk on tangible functional programming. |
| 02:18:12 | <marcusb> | IntergalacticOwl: I was going to write non-mathematicians, and then wanted to include engineers, etc |
| 02:18:15 | <randomity> | as far as I know, dublin IT teaches Haskell to first-years. Not sure how long they keep it up |
| 02:18:20 | <randomity> | edwardk: cool! must look at. |
| 02:18:30 | <Zao> | conal: I was misremembering, there was a discussion a few days ago with code that at first glance looked quite non-listy. |
| 02:18:32 | <IntergalacticOwl> | I thought engineers didn't consider themselves scientists. |
| 02:18:46 | <marcusb> | conal: being free of side effects is definitely easier than understanding cell-based programming, I would think |
| 02:19:00 | <monochrom> | Some engineers consider themselves scientists. Some know they aren't. |
| 02:19:07 | <IntergalacticOwl> | haha |
| 02:19:09 | <conal> | some people carve up the world into engineers, scientists, etc. some don't. |
| 02:19:24 | <edwardk> | randomity: now, there is a lack of support for the later query comprehension improvements that SPJ and Wadler put together to respond to LINQ, that would be tricky to generalize to an arbitrary monad |
| 02:20:05 | <conal> | edwardk: that's why i winced at that paper. i hate seeing monad comprehensions slip further away. |
| 02:20:05 | <edwardk> | i remember i took a quick stab at it when the paper first came out and put it down as too scary at the time. Might take a crack at it again some time. |
| 02:20:35 | <randomity> | would some LINQ-style magic generalise nicely over Arrows? |
| 02:20:51 | <jimmyjazz14> | why are there three exponent functions in haskell? |
| 02:21:03 | <monochrom> | And some people compare apples with oranges. |
| 02:21:27 | <edwardk> | randomity: i'd hoped to employ the arrow calculus at some point for something like that but there appear to be enough problems with the rederived arrow calculus that i put it down and backed away slowly ;) |
| 02:21:32 | <conal> | jimmyjazz14: the answer is probably in their types. |
| 02:21:38 | <conal> | @type (^) |
| 02:21:39 | <lambdabot> | forall a b. (Integral b, Num a) => a -> b -> a |
| 02:21:44 | <conal> | @type (^^) |
| 02:21:45 | <lambdabot> | forall a b. (Integral b, Fractional a) => a -> b -> a |
| 02:21:47 | <conal> | @type (**) |
| 02:21:48 | <lambdabot> | forall a. (Floating a) => a -> a -> a |
| 02:22:15 | <conal> | jimmyjazz14: make sense? |
| 02:22:25 | <jimmyjazz14> | mmm yeah kinda |
| 02:22:42 | <edwardk> | arrow calculus as in: http://homepages.inf.ed.ac.uk/wadler/papers/arrows/arrows.pdf and http://homepages.inf.ed.ac.uk/wadler/papers/arrows-and-idioms/arrows-and-idioms.pdf |
| 02:22:44 | <jimmyjazz14> | still learning the type system |
| 02:22:56 | <conal> | jimmyjazz14: it's a fancy one. there's a lot to learn. :) |
| 02:23:42 | <conal> | jimmyjazz14: iirc, (^) raises an error for negative exponents, since the base & result are integral. |
| 02:24:04 | <randomity> | edwardk: yeah, the actual semantics of the arrow calculus seem giant and complicated and confusing. I've never looked at it formally properly, but the intuitive notion of "generalisation of a function" is pretty cool, and you can do some pretty cool stuff with it (signal-processing-style chains of functions or erlang-style communications) |
| 02:24:11 | <gwern> | if only we had Nat! |
| 02:24:38 | <randomity> | then (-) would break on many inputs. Is this better? |
| 02:24:57 | <jimmyjazz14> | I find the number types to be more confusing |
| 02:24:57 | <gwern> | nah, - just defaults to 0 with Nats |
| 02:25:16 | <gwern> | better than _|_ lurking in half the basic numerical functions |
| 02:25:19 | <randomity> | gwern: you're joking. Really? |
| 02:25:37 | <randomity> | so (a - b) + b is something totally random? |
| 02:25:49 | <gwern> | randomity: no, that's the usual proposal for Nats. 5-10=0 |
| 02:25:58 | <conal> | "monus" |
| 02:26:07 | <jimmyjazz14> | conal: know of any good guides on easing one into the type system |
| 02:26:18 | <jimmyjazz14> | specifically numeric types |
| 02:26:30 | <conal> | jimmyjazz14: hm. not offhand. anyone else? |
| 02:27:03 | <randomity> | gentle introduction to haskell has a decent type system section |
| 02:27:05 | <conal> | jimmyjazz14 have you read "a gentle introduction to haskell" (hudak, peterson, fasel)? |
| 02:27:08 | <conal> | :) |
| 02:27:10 | <randomity> | :D |
| 02:27:16 | <jimmyjazz14> | no I havn't |
| 02:27:22 | <jimmyjazz14> | I will check it out |
| 02:27:28 | <edwardk> | randomity: i was originally trying to see if i could define a simple enough base language that it could for the most part 'compile' to the arrow calculus, to see if i could make a nice language with 'programmable application', with the arrow apply rules its equivalent to a monadic language but without the separate syntax barrier we have. |
| 02:27:34 | <conal> | it was my first exposure to haskell. i loved it. ymmv. |
| 02:27:49 | <jimmyjazz14> | I'm currently reading Real World Haskell |
| 02:27:55 | <randomity> | although when I was first learning haskell, I had to flick through that chapter initially and read the rest, then go back to it. It all makes wonderful sense eventually, and then you wonder what was so difficult at the start |
| 02:28:31 | <jimmyjazz14> | I like it although I find it goes a little quick at points (or perhaps needs a few rereadings) |
| 02:28:56 | <randomity> | edwardk: yeah, I was toying with that notion as well. I think a version of haskell where \ wasn't just lambda but was polymorphic over all arrow types would be kinda cool |
| 02:29:16 | <randomity> | but learning it would be even less possible than learning haskell currently :D |
| 02:29:41 | <randomity> | jimmyjazz14: yeah, it's great but the title's inaccurate. |
| 02:30:30 | <jeff_s_> | Zao - just saw your message from 10 minutes ago, thanks |
| 02:30:32 | <edwardk> | randomity: one thing to note: you need some extra magic for pattern matching constructors and case analysis, so getting a full haskell into it'd be a lot of work. |
| 02:31:02 | <randomity> | I think that can be done if the arrow in question is an ArrowChoice |
| 02:31:23 | <conal> | hm. my C-is-functional post is now at 117 (216-99) on reddit. i usually score *much* closer to 0. |
| 02:31:39 | <randomity> | you'd have to have this weird operation of reducing datatypes down to pairs and Eithers (prod + sum), but I think it could be done |
| 02:31:43 | <copumpkin> | sensational titles always work wonders on reddit |
| 02:31:59 | <copumpkin> | ACTION knows all about marketing! |
| 02:32:03 | <jimmyjazz14> | I feel like there should be a shorter (simpler) version of Real World Haskell as a first step intro |
| 02:32:16 | <copumpkin> | omg it's edwardk |
| 02:32:41 | <copumpkin> | edwardk: do you have a working parallel CFL parser somewhere deep in your monoids? |
| 02:33:03 | <conal> | copumpkin: rather a personal question, don't you think? |
| 02:33:08 | <copumpkin> | lol |
| 02:34:52 | <randomity> | conal: that looks awesome (the functional-c page) |
| 02:35:19 | <randomity> | actually, I think the C++ template system is purely-functional and duck-typed |
| 02:35:27 | <edwardk> | copumpkin: still working on it |
| 02:35:38 | <conal> | randomity: thx :) |
| 02:35:43 | <edwardk> | copumpkin: work picked up a bit for a week or so, hence why i've been scarce lately |
| 02:36:01 | <edwardk> | but now things are slow again, so i'm free to resume working on parsimony =) |
| 02:36:40 | <edwardk> | copumpkin: started adding some nice monoidal statistical accumulators though, i'll be pushing those up to hackage pretty soon. |
| 02:36:58 | <edwardk> | i.e. for computing mean, stddev, variance, kurtosis, skewness, etc. in parallel |
| 02:37:27 | <copumpkin> | edwardk: :o |
| 02:37:29 | <copumpkin> | nice |
| 02:37:39 | <copumpkin> | how about median ;) |
| 02:38:19 | <copumpkin> | (just kidding) |
| 02:38:22 | <edwardk> | i don't currently have a parallel median calculator =) |
| 02:40:22 | <edwardk> | there should be some monoidal encoding of kth item selection though. |
| 02:40:35 | <edwardk> | since there are decent parallel algorithms for it |
| 02:43:02 | <dmwit> | jimmyjazz14: You might also like Learn You a Haskell. |
| 02:43:04 | <dmwit> | ?where LYAH |
| 02:43:04 | <lambdabot> | www.learnyouahaskell.com |
| 02:43:11 | <Cale> | edwardk: What counts as a monoidal encoding here? |
| 02:43:19 | <edwardk> | hrmm, anyone here familiar with "monoid comprehensions?" ala the monoid comphrension calculus |
| 02:44:03 | <edwardk> | cale: well, what i'd be looking for is an efficient way to parse part of the string and another part of the string and join the intermediate results together. |
| 02:46:01 | <edwardk> | cale: in the parlance of my 'monoids' library, an "a `Reducer` m" -- is a Monoid m, with unit :: a -> m -- i.e. Num a => a `Reducer` Sum a where unit = Sum |
| 02:47:01 | <edwardk> | cale: you can in general encode any fold as a reducer like that but its not all that interesting unless you can shrink the size of the intermediate result to be smaller than a tree involving the entire input string |
| 02:47:28 | <edwardk> | so some notion of progress is usually essential to encoding something as a useful Reducer. |
| 02:50:32 | <Cale> | Curious, I just realised that the bittorrent tracker for the anime I'm downloading is apparently edwardk.info |
| 02:50:34 | <edwardk> | in practice i let a Reducer also define an efficient 'cons' and 'snoc' for prepending a value or appending a value to an already reduced result, because that is often a lot more efficient than the general monoidal operation, and then let different containers use those as they see fit |
| 02:50:47 | <copumpkin> | :o |
| 02:51:03 | <edwardk> | haha, not me though. |
| 02:51:55 | <Chicao> | anyone familiar with qtHaskell? |
| 02:52:13 | <Cale> | I'm only familiar in the sense that I've heard of it. |
| 02:53:29 | <Chicao> | Thanks Cale |
| 02:53:37 | <MonadBaastad> | Wow... I read some of that Scala thread, and...the ignorance is scary. |
| 02:53:41 | <Cale> | Chicao: What did you need to know about it? |
| 02:53:52 | <copumpkin> | MonadBaastad: what thread is that? |
| 02:54:08 | <rovar> | MonadBaastad: I'm happy as long as all of those java coders aren't coding in java anymore. |
| 02:54:17 | <Chicao> | To tell you the truth |
| 02:54:34 | <Chicao> | i'm trying to learn it right now |
| 02:54:51 | <MonadBaastad> | copumpkin: http://www.reddit.com/r/programming/comments/8krbo/erlang_is_not_functional_response_to_scala_is_not/ |
| 02:54:59 | <Chicao> | but i cant install in my computer |
| 02:55:04 | <Chicao> | got some errors |
| 02:55:22 | <MonadBaastad> | Hmm, so I guess I should call it "that Eralng response to that Scala thread"... ;p |
| 02:56:24 | <rovar> | how about we call them both imperative language so that all of those people afraid of functional languages will use them |
| 02:56:29 | <rovar> | then eventually see the light |
| 02:56:37 | <rovar> | to be honest. I came to Haskell by way of Erlang |
| 02:56:58 | <SamB> | Erlang *is* an imperative language, isn't it? |
| 02:57:01 | <rovar> | my preconception of functional programming was "it's cool, but not useful for real world stuff" |
| 02:57:15 | <SamB> | it doesn't have an imperative abstraction like Haskell does ... |
| 02:57:21 | <rovar> | erlang is an expression based language and supports tail recursion |
| 02:57:24 | <SamB> | but then neither does any other imperative language I've ever used ;-P |
| 02:57:43 | <MonadBaastad> | rovar: I think a better idea is to shoot 'em over to conal's blog post, so they can learn how "C programming" is really functional... 8D |
| 02:57:48 | <SamB> | oh, but I call CL and Scheme and Emacs Lisp imperative too |
| 02:57:49 | <rovar> | but you're right.. it's imperative. |
| 02:58:02 | <edwardk> | erlang is functional, its strict and has some baked in message passing bits, bit i can't really bash its overall functionalness |
| 02:58:13 | <rovar> | MonadBaastad: which is that? |
| 02:58:18 | <dmwit> | Hoogle has no result for "sleep"! |
| 02:58:27 | <rovar> | and it's dynamically typed,, which annoys the crap out of me |
| 02:58:34 | <rovar> | one reason i switched to haskell |
| 02:58:41 | <MonadBaastad> | rovar: http://conal.net/blog/posts/the-c-language-is-purely-functional/ |
| 02:59:17 | <rovar> | "Modulo some minor historical accidents." hahaha |
| 03:00:00 | <MonadBaastad> | conal++ |
| 03:00:08 | <dmwit> | Oh, it's called threadDelay. |
| 03:00:11 | <dmwit> | hokay |
| 03:00:13 | <MonadBaastad> | (If only for the lulz factor. ;) |
| 03:00:17 | <Gracenotes> | I like the use of "modulo" in non-mathematical sense |
| 03:00:18 | <conal> | MonadBaastad: :) thx. |
| 03:00:40 | <Gracenotes> | it's certainly acquired a life of its own. the phrase. sort of. |
| 03:01:10 | <rovar> | hahha |
| 03:01:13 | <rovar> | that is brilliant |
| 03:01:30 | <edwardk> | gracenotes: my coworkers sometimes look at me funny for using 'modulo', 'without loss of generality' and 'orthogonal' as just every day vocabulary. |
| 03:01:34 | <MonadBaastad> | conal: Thank you! I always find your posts informative and entertaining - and it's surprising at times which one is more the one than the other. ;) |
| 03:01:52 | <Gracenotes> | edwardk: hah! Surely all human beings speak like this??? |
| 03:02:39 | <edwardk> | Gracenotes: it has been called to my attention that not all humans understand these things. I have since endeavored to succeed in either enlightening them, or narrowing my social circle ;) |
| 03:03:18 | <Gracenotes> | i am truley sorry for your lots |
| 03:03:31 | <copumpkin> | ACTION facepalms |
| 03:03:58 | <monochrom> | Haskell is the finest imperative language on Earth. That's what SPJ says. |
| 03:04:19 | <rovar> | edwardk: I use orthogonal quite a bit, I also use asymptote in a non mathematical sense, which really effs with people. |
| 03:04:30 | <monochrom> | I propose to add it to whatever "about haskell" page or blurb on the haskell wiki. |
| 03:04:38 | <Gracenotes> | yes, math has proved to be a fertile cornucopia of vocabulary words |
| 03:04:48 | <Gracenotes> | if nothing else |
| 03:04:58 | <rovar> | surely it has some other redeeming qualities |
| 03:05:02 | <copumpkin> | without loss of generality, we can speak of non-mathematical concepts with mathematical terminology |
| 03:05:12 | <monochrom> | "simple group" is the best math name of all. :) |
| 03:05:33 | <Gracenotes> | it could also be used to describe people who don't understand math terminology |
| 03:05:39 | <rovar> | hehe |
| 03:05:45 | <Gracenotes> | </elitist> |
| 03:05:50 | <monochrom> | You should also begin inflicting law words such as "hitherto" to your coworkers. |
| 03:05:53 | <randomity> | or to make bad puns about a finite group of mathematicians standing in a ring |
| 03:05:54 | <dmwit> | So, uh, how do laziness and MVars interact? |
| 03:06:20 | <rovar> | randomity: if they're standing in a ring they would have to be a finite group, yes? |
| 03:06:20 | <randomity> | simply enough, MVars are in the IO monad where laziness doesn't really exist |
| 03:06:25 | <dmwit> | If I write a complicated computation into an MVar, and another thread takes that MVar, who's responsible for the expensive calculation and when did it happen? |
| 03:06:27 | <Gracenotes> | an MVar is like holding a reference... reading it is an operation that can be sequenced in IO |
| 03:06:39 | <Gracenotes> | oh, I see |
| 03:06:55 | <edwardk> | rovar: that and 'carrying capacity of a population,' 'kth weighted central moment', 'right Kan extension', 'comonad,' 'zygohistomorphic prepromorphism' or any 'free' construction that doesn't involve free food or free beer seem to zip right past most of these strange people. |
| 03:07:05 | <monochrom> | "without loss of generality, hitherto thereof we assume x>=0" |
| 03:07:05 | <randomity> | oh, ok. AFAIK, it's stored as a thunk in the Mvar so the receiving thread evaluates it |
| 03:07:20 | <Gracenotes> | I'd imagine you could put an infinite list in an MVar |
| 03:07:30 | <Gracenotes> | or an undefined |
| 03:07:36 | <edwardk> | Gracenotes: yeah |
| 03:07:44 | <dmwit> | Doesn't this sort of negate the usefulness of multiple threads? |
| 03:07:58 | <dmwit> | Maybe I should ask a different question. |
| 03:07:59 | <rovar> | edwardk: how could you possibly use the lot of those nonmathematically? |
| 03:08:10 | <monochrom> | No, the receiving thread may just give the thunk to someone else. |
| 03:08:20 | <dmwit> | If I want a responsive UI thread and a complicated computation thread, how should I ensure that the complicated computation is not being done in the UI thread? |
| 03:08:28 | <edwardk> | rovar: well, everything is a Kan extension ;) |
| 03:08:30 | <randomity> | most of the cool stuff from mvars doesn't come from sharing cpu across threads, but from writing sequential-looking code which overlaps |
| 03:08:43 | <Saizan> | dmwit: you can seq or rnf the value before you put it in the MVar |
| 03:09:12 | <dmwit> | Okay, as long as that's considered best practice, I'm fine with doing that. |
| 03:09:21 | <Gracenotes> | seq is a bit weaker than rnf |
| 03:09:35 | <edwardk> | rovar: and i had a use for using weighted moments around the origin in a business capacity when writing an MDX query the other day ;) |
| 03:09:35 | <Saizan> | well, it depends on the structure of the value |
| 03:09:38 | <randomity> | haskell isn't widely enough used to have a considered best practice :P |
| 03:09:39 | <Gracenotes> | but you do need a typeclass for rnf, which in most cases is simple to implement |
| 03:09:56 | <monochrom> | Heh, I store a thunk into an MVar, then I seq it, what happens? :) |
| 03:09:59 | <dmwit> | Yep, I understand the tradeoffs between rnf and seq. |
| 03:10:17 | <kniu> | Guys, I just had a crazy idea. |
| 03:10:27 | <Saizan> | monochrom: you get a pony |
| 03:10:43 | <edwardk> | monochrom: it gets put in the mvar, then you start evaluating it, if someone else grabs it they may or may not see it before your blackhole marks it depending on how eager the blackholing is that day |
| 03:10:51 | <rovar> | edwardk: must have been a hulluva query |
| 03:10:54 | <kniu> | I was reading trough SICP again, and came upon the bit about the separation of implementation from interface. |
| 03:10:54 | <edwardk> | so they may start evaluating it too |
| 03:11:24 | <kniu> | It is common knowledge that many data structures can be implemented with function closures. |
| 03:11:39 | <edwardk> | rovar: hah, well, 5 pages of proof to justify 3 lines of MDX ;) but its shiny and fast and it does the job |
| 03:11:51 | <monochrom> | Interesting. |
| 03:12:02 | <kniu> | Can you instance a function type with a class? |
| 03:12:04 | <Gracenotes> | kniu: well... more difficult with static types. But definitely |
| 03:12:04 | <edwardk> | kniu: s/many/any/ =) |
| 03:12:20 | <kniu> | If so, then why have types at all, right? |
| 03:12:35 | <kniu> | just create functions for every implementation, and have the classes represent types. |
| 03:12:36 | <rovar> | edwardk: I've always looked for excuses to do multidimensional analysis on data, but my hatred for RDBMS's has kept me away |
| 03:12:38 | <edwardk> | kniu: convenience |
| 03:13:04 | <randomity> | rovar: the RDBMS model is actually really nice. SQL is hideous. |
| 03:13:10 | <kniu> | So convenience is the only reason? |
| 03:13:21 | <Gracenotes> | implementing data structures with closures isn't so important that it's worth a trade-off with your entire type system |
| 03:13:35 | <Gracenotes> | imho anyway. |
| 03:13:58 | <rovar> | i agree. |
| 03:13:59 | <Gracenotes> | and quite tricky to optimize. |
| 03:14:18 | <rovar> | i actually went too far in that direction and started coding in Timber |
| 03:14:32 | <kniu> | hm |
| 03:14:57 | <edwardk> | i dunno. i find newtype Tree a = Tree { viewTree :: forall o. (Tree a -> a -> Tree a -> o) -> o -> o } -- to be an amusing encoding of a binary tree ;) |
| 03:15:11 | <jimmyjazz14> | how similar is Haskell to Erlang? |
| 03:15:44 | <Saizan> | ACTION doesn't see why that's hard with static types |
| 03:15:52 | <edwardk> | if only because if you swap the a and the first Tree a, that its in the style of.. you guessed it, a right Kan extension. ;) |
| 03:15:54 | <rovar> | jimmyjazz14: Haskell is a superset of erlang. Modulo the nasty bits such as dynamic typing |
| 03:15:55 | <Gracenotes> | edwardk: cute... hm... |
| 03:15:56 | <Saizan> | unless you hate the newtype constructor so much |
| 03:16:09 | <randomity> | they're pretty different at first. With some of Haskell's newer libraries, you can get a lot of the erlang-style communication stuff |
| 03:16:15 | <Gracenotes> | edwardk: what does the second parameter o represent? |
| 03:16:21 | <randomity> | and erlang's recently got working functional programming |
| 03:16:27 | <rovar> | and more importantly.. you can get sub-thread scheduling via forkIO |
| 03:16:39 | <MyCatVerbs> | jimmyjazz14: they're both functional. Haskell is statically typed, Erlang dynamically. They have rather different concurrency models. Concurrent Haskell is designed for SMP machines, whereas Erlang's concurrency is all message passing. |
| 03:16:50 | <randomity> | the main differences now are haskell having a truly awesome type system, and erlang having truly awesome clustering and failover abilities |
| 03:17:01 | <rovar> | oh.. and RPC |
| 03:17:20 | <rovar> | being the foundation of erlangs awesome clustering distributed blah blah |
| 03:17:21 | <edwardk> | Gracenotes: (a -> Tree a -> Tree a -> o) -- is the result from handling a Bin node and the next argument 'o' -- is the result for handling a Tip. |
| 03:17:28 | <randomity> | and erlang's live code updating (rewrite your app with no downtime) is amazing |
| 03:17:39 | <rovar> | there was a haskell project for that |
| 03:17:42 | <Gracenotes> | edwark: ah, so all Tips are handled the same way? |
| 03:17:44 | <edwardk> | the forall encodes the fact that you can extract any result type from viewing it |
| 03:17:45 | <rovar> | it appears to have been abandoned |
| 03:17:50 | <amz> | hrm, easiest way to apply "f" to "x" n times? |
| 03:17:53 | <jimmyjazz14> | so I am learning haskell but need to know erlang (for work and such) will learning Haskell a good path to having to work with Erlang in the future? |
| 03:17:54 | <edwardk> | no, thats why you need the universal quantification. |
| 03:17:54 | <Gracenotes> | hm. I suppose this make sense if Tip doesn't carry anything |
| 03:18:00 | <edwardk> | to 'case' off it you hand it two values. |
| 03:18:06 | <randomity> | of course, haskellers have such a cool type system that their code is proven correct by the compiler, so they don't need live code updating as there are no bugs :P |
| 03:18:07 | <rovar> | jimmyjazz14: yes |
| 03:18:08 | <dmwit> | amz: foldr (.) id (replicate n f) x |
| 03:18:08 | <Gracenotes> | hm... |
| 03:18:20 | <SamB> | randomity: yeah right |
| 03:18:21 | <dmwit> | amz: or maybe |
| 03:18:23 | <randomity> | hehehe |
| 03:18:24 | <amz> | dmwit: I mean as in f $ f $ f $ ... x |
| 03:18:30 | <dmwit> | amz: So do I. |
| 03:18:35 | <amz> | oh |
| 03:18:37 | <amz> | oh, I see, . |
| 03:18:41 | <Gracenotes> | edwardk: so how could you represent the typical Branch Tip 10 (Branch Tip 20 Tip) in your scheme? |
| 03:18:46 | <dmwit> | :t foldr |
| 03:18:47 | <lambdabot> | forall a b. (a -> b -> b) -> b -> [a] -> b |
| 03:18:50 | <SamB> | randomity: you're thinking of Agda, maybe, where your programs are proven *both* correct *and* incorrect by the compiler |
| 03:18:51 | <amz> | I'm trying this with a recursive function and it's stack overflowing on me |
| 03:18:52 | <dmwit> | :t ($) |
| 03:18:53 | <lambdabot> | forall a b. (a -> b) -> a -> b |
| 03:18:54 | <randomity> | jimmyjazz14: there are significant differences, but they're both a lot closer to each other than either is to, say, Java |
| 03:18:59 | <amz> | doSteps ls 0 = ls |
| 03:18:59 | <amz> | doSteps ls n = doSteps (map (\x -> step x 1.5) ls) (n-1) |
| 03:19:01 | <dmwit> | :t foldl |
| 03:19:02 | <rovar> | randomity: there is a lot of truth to that.. subtracting the huge potential for space leaks, I would trust haskell for a large project over any other language |
| 03:19:02 | <lambdabot> | forall a b. (a -> b -> a) -> a -> [b] -> a |
| 03:19:30 | <edwardk> | lookup b t = getTree t (\a l r -> case compare a b of LT -> lookup b l; EQ -> Just a; GT -> ...) Nothing |
| 03:19:35 | <dmwit> | :t foldr ($) |
| 03:19:35 | <lambdabot> | forall b. b -> [b -> b] -> b |
| 03:19:40 | <rovar> | but we've had space leaks in c++ that caused our production system to crash after 2 months of running |
| 03:19:41 | <randomity> | it's the first language I've used where I've felt the compiler was actually on my side (unlike, say, Python where the compiler doesn't seem to exist, or C++ where it's actively working against you) |
| 03:19:59 | <copumpkin> | is it just me or has a really trollish user showed up on the haskell subreddit recently, called grauenwolf? :P |
| 03:20:01 | <dmwit> | amz: foldr ($) x (replicate n f) -- could also work |
| 03:20:06 | <kniu> | really? |
| 03:20:07 | <rovar> | randomity: that's the fault of c++ idioms |
| 03:20:10 | <rovar> | idioms of idiots |
| 03:20:11 | <kniu> | Sometimes, I think GHC hates me. |
| 03:20:16 | <dmwit> | copumpkin: He's been around a while. |
| 03:20:18 | <rovar> | kniu: it's firm, but fair |
| 03:20:19 | <SamB> | randomity: yeah, in C++ it seems like the point of the compiler is to insert lots of code that I didn't write, most of which exists mostly to cause unexpected segfaults ... |
| 03:20:26 | <randomity> | nah, it's the fault of the C++ "type system". |
| 03:20:30 | <Gracenotes> | edwardk: hm. So you do you get the tree in the first place? Seems a bit.. making-something-out-of-nothing-ish :) |
| 03:20:34 | <edwardk> | Gracenotes: just define two combinators branch a l r = Tree (\k _ -> k a l r); tip = Tree (\_ t -> t) |
| 03:20:41 | <copumpkin> | dmwit: ah, I guess I only just had the pleasure of reading his comments |
| 03:20:48 | <kniu> | The error messages are so cryptic, it's like a chick playing hard-to-get. |
| 03:20:56 | <erikc`> | it's the fault of c++ users secretly wanting a good language and trying to build language features out of popsicle sticks and glue |
| 03:20:56 | <MyCatVerbs> | edwardk: is that a continuation-passing binary tree? :) |
| 03:20:59 | <edwardk> | gracenotes and then use them as smart constructors |
| 03:21:01 | <Gracenotes> | ah. continuation style.... |
| 03:21:03 | <edwardk> | mycatverbs: yeah |
| 03:21:09 | <rovar> | the full c++ type system is pretty awesome.. if people would use it.. but people don't because it involves a crapload of <>'s and pure functional, type based programming |
| 03:21:17 | <jbhatta> | hmmmmmmmmm, anybody know a good algorithm for finding the median of a list of Ords? |
| 03:21:20 | <SamB> | kniu: which ones ? |
| 03:21:35 | <randomity> | templates take type parameters which are typechecked by "whether or not they support this set of named operations", and pass them onto more templates, and so on until you get a giant backtrace of why substitution failed with one type error covering pages of useless output |
| 03:21:50 | <SamB> | randomity: not even that, really |
| 03:21:50 | <edwardk> | nicely you can make up new constructors for building 'flattened' trees, etc. and the api doesn't change ;) |
| 03:21:51 | <rovar> | that output can be fixed |
| 03:21:53 | <kniu> | since I'm not really working on anything right now, there are none that I can name off the top of my head. |
| 03:22:06 | <MyCatVerbs> | edwardk: Why? Were you struck by a sudden urge to use Church-style data structures instead of the usual pattern matching on constructors malarkey? |
| 03:22:13 | <SamB> | I wish I could declare even that much typing about template parameters ... |
| 03:22:32 | <edwardk> | MyCatVerbs: someone above mentioned you can replace many data types with functions, and i replied s/many/any |
| 03:22:40 | <edwardk> | and someone asked about trees or something like that |
| 03:22:41 | <monochrom> | generic programming without theorem proving is really strange |
| 03:22:42 | <amz> | dmwit: both are still giving me a stack overflow :( |
| 03:22:43 | <kniu> | That's me. |
| 03:22:45 | <randomity> | it's more the duck typing of the templates that annoys me. Even in java I can say that I don't just want a T, I want a "T extends SomeInterface". In C++ you can't specify what type you want, the compiler just keeps bashing until enough substs fail |
| 03:22:45 | <amz> | even forcing strictness |
| 03:22:59 | <SamB> | randomity: that's just what I mean |
| 03:23:00 | <monochrom> | hell, aspect-oriented programming without theorem proving is strange too |
| 03:23:04 | <rovar> | read chapter 3 c++ metaprogramming it makes an incredibly powerful statement about the strength of the c++ type system |
| 03:23:07 | <dmwit> | amz: There's also iterate f x !! n |
| 03:23:10 | <MyCatVerbs> | edwardk: sooo... "because I can", then. Don't get me wrong, I personally believe that to be an excellent reason. :) |
| 03:23:16 | <dmwit> | amz: Which is probably the first thing I should have thought of. =P |
| 03:23:16 | <randomity> | monochrom: aspect-oriented programming is strange all by itself |
| 03:23:36 | <rovar> | the problem is the strong type system that you produce takes a crapload of code to get there. whereas haskell's is there from the start |
| 03:23:40 | <dmwit> | amz: If you're using sizes of 'n' big enough to give stack overflow, than may I suggest using something more sophisticated? |
| 03:23:43 | <randomity> | rovar: is this turing completeness? that's doesn't make it powerful. Brainfuck is not powerful. |
| 03:23:45 | <Gracenotes> | edwardk: and newtype List a = List (forall o. (a -> List a -> o) -> o -> o), sumList (List xs) = xs (\y ys -> y + sumList ys) 0 |
| 03:23:54 | <amz> | dmwit: I'm accepting suggestions :) |
| 03:23:56 | <dmwit> | amz: Is f associative? If so, something similar to repeated squaring might be nice. |
| 03:23:57 | <copumpkin> | > (thrice thrice) (+1) $ 4 |
| 03:23:57 | <edwardk> | MyCatVerbs: i have other reasons that i've been exploring, mostly to do with fooling the unpacker |
| 03:23:59 | <lambdabot> | 31 |
| 03:24:21 | <rovar> | randomity: no.. not at all.. it creates a system whereby you can annotate values with units to ensure that they can be operated on.. i.e. |
| 03:24:23 | <copumpkin> | > iterate thrice (+1) $ 0 |
| 03:24:24 | <edwardk> | Gracenotes: yeah thats a list monad as a right kan extension. |
| 03:24:24 | <randomity> | it's just soooo much work to define a parametrised type in C++. I need a separate template <typename T> on every single function! |
| 03:24:25 | <lambdabot> | Couldn't match expected type `a -> b' |
| 03:24:29 | <amz> | dmwit: no, it's a map that applies a "step" function to a list of objects, that return their next "step" (think of a bunch of objects in a simulation advancing in time) |
| 03:24:41 | <rovar> | you create 3.5 mass and 2 velocity. |
| 03:24:43 | <Gracenotes> | edwardk: category theory! noooooo :P |
| 03:24:49 | <edwardk> | Gracenotes: =) |
| 03:24:52 | <MyCatVerbs> | edwardk: that sounds innnteresting. More a topic for #-in-depth than here though, perhaps? |
| 03:24:56 | <erikc`> | rovar: f# has that and it doesnt suck in f# :) |
| 03:24:56 | <rovar> | you can't add them because they're not compatible.. but you can multiply them |
| 03:24:58 | <randomity> | rovar: oh, yeah, seen some of those. They're really nice, but they take sooooo much code to implement |
| 03:25:03 | <randomity> | the interface is beautiful though |
| 03:25:03 | <SamB> | rovar: but then it probably takes two pages of code to write what should take 1 line |
| 03:25:08 | <edwardk> | mycatverbs: perhaps |
| 03:25:14 | <rovar> | randomity, SamB: that's my point |
| 03:25:14 | <randomity> | there were a couple proposed for Boost, not sure if any ever got in |
| 03:25:31 | <copumpkin> | > iterate thrice (+1) <*> [0] |
| 03:25:33 | <lambdabot> | [1,3,9,27,81,243,729,2187,6561,19683,59049,177147,* Exception: stack overflow |
| 03:25:44 | <SamB> | 99% of which is about types which you shouldn't even need to mention |
| 03:25:52 | <rovar> | my point is that it is possible.. the c++ type system can be great, but man is it a harsh mistress. |
| 03:25:53 | <edwardk> | hrmm |
| 03:26:12 | <erikc`> | without gc and type inferencing, it's a chore |
| 03:26:23 | <rovar> | and it's rather ironic that it order to utilize c |
| 03:26:32 | <rovar> | ++ to its fullest, you need to know functional programming |
| 03:26:40 | <edwardk> | actually those fail to be right kan extensions |
| 03:26:45 | <edwardk> | just noticed that |
| 03:26:45 | <randomity> | ok, granted. Using C++, you can make a gorgeous interface to your types. I consider implementation simplicity just as important as interface simplicity though (I realise others don't) and I find it's rarely worth the internal ugliness of a nice C++ interface |
| 03:26:45 | <rovar> | hah |
| 03:26:56 | <dmwit> | amz: And iterate is giving stack overflow? If so, you're not doing enough forcing. |
| 03:27:15 | <amz> | this is my code: |
| 03:27:16 | <amz> | doSteps' x n = iterate f x !! n |
| 03:27:16 | <amz> | where f x = map (\y -> step y 1.5) x |
| 03:27:16 | <MyCatVerbs> | rovar: I found C++ template programming to be a great introduction to Haskell. |
| 03:27:28 | <amz> | I removed the seqs now |
| 03:27:31 | <rovar> | my friend describes c++ as coffee.. a lot of people drink coffee..it has a lot of redeeming qualities.. but the huge majority have to do crazy things to their coffee to make it halfway palletable |
| 03:27:33 | <SamB> | except of course that Haskell has types other than int |
| 03:27:35 | <rovar> | pallatable? |
| 03:27:37 | <SamB> | right? |
| 03:28:35 | <randomity> | rovar: I like black coffee :D |
| 03:28:46 | <amz> | I think that the problem might be with my "step" function, since my definition is recursive and very bizarre |
| 03:28:51 | <amz> | I couldn't figure out a better way to do it |
| 03:29:12 | <Saizan> | @hpaste |
| 03:29:12 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 03:29:14 | <Saizan> | amz ^^^ |
| 03:29:17 | <MyCatVerbs> | rovar: once you've managed to get some not-completely-trivial computation to run in the template instantiation, switching to Haskell (where, by Church, you suddenly have actual features to play with!) feels like an enormous relief, and not any harder at all. :) |
| 03:29:26 | <rovar> | randomity: I take milk in mine, and I code in c++ for a living, and have maintained my sanity with the help of boost |
| 03:29:44 | <MyCatVerbs> | SamB: yes, Haskell has types other than int. That's a bloody good start. :) |
| 03:29:48 | <amz> | ok, hold on |
| 03:30:15 | <amz> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5090#a5090 |
| 03:30:31 | <randomity> | boost is amazing. It really shouldn't exist. So many really smart people have wasted so much thought designing and implementing amazing code when they could have just been popularising a better language (where the amazing feats they wished to perform were trivial) |
| 03:30:34 | <amz> | the idea is that I want a list of "entities", where each entity has a different behavior |
| 03:30:39 | <amz> | so they have different implementations of "step" |
| 03:30:44 | <rovar> | MyCatVerbs: I agree in general. I have been coding in c++ for 10 years and still can't get code to compile (much less run) on the 1st try. |
| 03:30:45 | <amz> | that move themselves to the next step |
| 03:31:00 | <amz> | they happen to both store a float, but that isn't really necessary, e.g. one could be storing a string |
| 03:31:05 | <amz> | [in fact, I should have done something like that] |
| 03:31:08 | <rovar> | in haskell.. it takes me some time to compile.. but once it does.. i don't even need to test it.. it just works |
| 03:31:09 | <randomity> | but still, boost is really, really good |
| 03:31:23 | <amz> | rovar: same here :) |
| 03:31:24 | <rovar> | randomity: yea.. a lot of smart people wasted a lot of effort on that :) |
| 03:31:32 | <copumpkin> | as good as possible given the shitty language it's implemented in |
| 03:31:47 | <MyCatVerbs> | rovar: just wait until you discover the (fix) combinator. We'll soon cure you of that little old "if it compiles, it probably works" idea. ;) |
| 03:31:54 | <randomity> | hehehe |
| 03:32:02 | <rovar> | boost.spirit.phoenix is effing *awesome* because it makes c++ functional :) |
| 03:32:04 | <erikc`> | randomity: amen, and a whole lot of compiler developers could have focused on things other than their frontends being accidental virtual machines |
| 03:32:10 | <rovar> | but boy is there a lot of crap in there |
| 03:32:26 | <randomity> | if it compiles in haskell, it won't produce the wrong answer. Divergence is possible. |
| 03:32:41 | <SamB> | randomity: unless it expresses the wrong question! |
| 03:32:47 | <MonadBaastad> | randomity: So, Boost is like having a crutch with a built-in rocket pack? ;p |
| 03:32:48 | <copumpkin> | > let addOne = (+1) in addOne 4 |
| 03:32:49 | <rovar> | MyCatVerbs: so I just pass all of my functions in to "fix" and they're magically not broken+ |
| 03:32:50 | <lambdabot> | 5 |
| 03:32:54 | <copumpkin> | > let addOne = (+3) in addOne 4 |
| 03:32:56 | <randomity> | MonadBaastad: :D :D :D oh yes. |
| 03:32:56 | <lambdabot> | 7 |
| 03:33:00 | <MyCatVerbs> | rovar: quite the opposite, actually. :) |
| 03:33:18 | <SamB> | MonadBaastad: as in, you'll probably end up as a stain on the side of a cliff somewhere ? |
| 03:33:24 | <MyCatVerbs> | randomity: erk! atan2 won't magically catch your mistake if you pass it x and y backwards, causing all your angles to be calculated wrong. For example. |
| 03:33:57 | <rovar> | i worked on D for a while.. was very involved in working on the std libs.. again i put lots of effort into making the language into something it wasn't.. one day I gave up.. a month later I downloaded ghc |
| 03:34:25 | <randomity> | yeah, true. I'm just comparing my <notHaskell> code to my Haskell code. It seems difficult to write valid incorrect haskell code by accident, at least compared to other languages |
| 03:34:39 | <SamB> | randomity: well, yeah |
| 03:34:46 | <SamB> | compared to other languages |
| 03:34:48 | <monochrom> | Haha that's a great real story. "I was trying to design a sensible language... then I downloaded ghc." |
| 03:35:06 | <SamB> | at least you *probably* don't have a type error if your Haskell code all compiled ... |
| 03:35:13 | <amz> | Haskell looks so beautiful, I just can't figure how to do such simple stuff in it ;) |
| 03:35:22 | <gwern> | @remember monochrom I was trying to design a sensible language... then I downloaded ghc. |
| 03:35:22 | <lambdabot> | It is forever etched in my memory. |
| 03:35:25 | <gwern> | @flush |
| 03:35:29 | <randomity> | rovar: I never really got into D, it always seemed like it was suffering from the same disease C++ has. It seems to cherry-pick useful features from languages where they work well, without realising that usefullness does not combine additively |
| 03:35:31 | <amz> | I wonder if I'm even doing this the right way |
| 03:36:03 | <jeffwheeler> | amz: Haskell just takes practice and play |
| 03:36:05 | <gwern> | if it isn't a one-liner involving folds, ur doing it rong |
| 03:36:08 | <SamB> | randomity: in what sense does C++ do that ? |
| 03:36:17 | <rovar> | randomity: there was a laundry list of beefs with c++ which were very valid (mostly made by the boost contributors) D fixed those problems.. and made the syntax a little friendlier |
| 03:36:50 | <randomity> | yeah, and C++ was made by a going through a laundry list of features to add to C. I think at some point you have to redesign. |
| 03:36:53 | <amz> | haven't tried C#, but it looks pretty cool, except for the poor cross-platform support |
| 03:36:57 | <Cale> | Does D have proper functions? |
| 03:37:03 | <gwern> | amz: yeah, I think you're doing some of it wrong. like, I don't see the point of doDraw |
| 03:37:17 | <rovar> | but yea.. haskell has this grasp on the most fundamental constructs which make coding in any paradigm seem natural |
| 03:37:30 | <amz> | gwern: This is a design test... different objects could hypothetically have different "draws" |
| 03:37:34 | <gwern> | amz: eg. I don't see why you couldn't derive Show |
| 03:37:37 | <amz> | I should rewrite this a bit to make the purpose clearer |
| 03:37:41 | <rovar> | amz: D is basically a natively compiled c# |
| 03:37:41 | <amz> | hold on |
| 03:37:54 | <gwern> | amz: but isn't like, the perfect usecase for typeclasses? |
| 03:38:14 | <SamB> | rovar: wouldn't it make more sense to ... just compile C# natively ? |
| 03:38:20 | <SamB> | or better, just use C# ? |
| 03:38:37 | <amz> | typeclasses wouldn't work here, I need multiple different behaviors in the same list |
| 03:38:50 | <rovar> | Cale: D1 offers delegates, which keep their stack around so that they can be passed to other functions.. in D2, that stack is created on the heap, so that those delegates can be returned from functions |
| 03:39:10 | <jmcarthur> | Cale: by proper do you mean pure? |
| 03:39:15 | <SamB> | rovar: okay, that's a nice feature ;-) |
| 03:39:18 | <randomity> | by the way, what time is it for you all? I'm in Ireland, and it's 4.30 am. I intend to get up tomorrow, I know I'll be cursing #haskell... |
| 03:39:19 | <Cale> | jmcarthur: I mean first-class. |
| 03:39:23 | <jmcarthur> | ah |
| 03:39:24 | <SamB> | GNU C has the former but not the latter |
| 03:39:26 | <Cale> | Pure would be even better. |
| 03:39:46 | <gwern> | randomity: pushing midnight here |
| 03:39:56 | <jmcarthur> | you *can* make first class functions, but they are really just sugar for objects |
| 03:40:02 | <Cale> | rovar: Is the syntax for it nice, or something awkward? |
| 03:40:18 | <SamB> | randomity: apparantly I live in the same place as gwern ... |
| 03:40:18 | <gwern> | randomity: my fix for that sort of thing is to take a big dose of melatonin. it'll crush my mind into sleepiness so I can't help but go to bed |
| 03:40:24 | <jmcarthur> | Cale: actually, D seems to encourage purity a lot more than other imperative languages do |
| 03:40:34 | <gwern> | SamB: scary! |
| 03:40:48 | <SamB> | well, I mean, time-zone-wise |
| 03:40:51 | <gwern> | jmcarthur: indeed. doesn't it have keywords so you can tell the compiler when you are being pure? |
| 03:41:04 | <jmcarthur> | Cale: the delegate syntax is not anywhere near as nice as a simple lambda |
| 03:41:11 | <SamB> | gwern: another GNU C feature ... |
| 03:41:11 | <jmcarthur> | gwern: among other things |
| 03:41:21 | <randomity> | GNU C has an odd sort of first-class function. You can create nested functions, and you can pass them down and pass them up if they don't close over locals (basically, that which is trivial with stack frames) |
| 03:41:25 | <SamB> | except GNU C doesn't actually have the keywords ... |
| 03:41:47 | <gwern> | wonder what sort of C haskellers produce |
| 03:41:48 | <randomity> | gwern: oh, I'll have no problem sleeping. I'm half dead at the moment. It's just the strain of stopping irc... |
| 03:41:51 | <jmcarthur> | gwern: from what i've seen, it is typical to design data structures to be copy-on-write in D |
| 03:42:07 | <SamB> | yeah, but GNU C's nested functions don't get much use, since you never know when you're going to need a real closure ... |
| 03:42:08 | <gwern> | ACTION wonders whether haskell data structures are COW |
| 03:42:26 | <rovar> | actually... D's strings are immutable.. and are absolutely spot-on |
| 03:42:30 | <gwern> | wait, we don't really 'write'... hm. I guess the analogue would be sharing structure |
| 03:42:35 | <randomity> | well, there's no W, so COW doesn't make much sense |
| 03:42:43 | <rovar> | not only safer, but much more efficient than c++ or c style strings |
| 03:42:49 | <jmcarthur> | our "write" is "construct" |
| 03:42:56 | <randomity> | and sharing structure is common and usually explicit (x:z and y:z share a tail) |
| 03:42:56 | <SamB> | rovar: that's the same way Python does strings ;-) |
| 03:43:04 | <jmcarthur> | rovar: yeah, D gets strings nearly perfectly right |
| 03:43:32 | <SamB> | it's, like, one of 5 things python does totally right |
| 03:43:38 | <gwern> | is there any writeup on how d strings are so awesome? |
| 03:43:42 | <SamB> | ACTION doesn't have a clue what the other 4 are |
| 03:43:45 | <rovar> | if python were statically typed, i'd rather like it |
| 03:43:53 | <randomity> | rovar: there's a nice feature like that in Lua. Strings are immutable, and have a precomputed hashcode. Since the main operation is looking up a string (e.g. variable name) in a hashtable (e.g. local variable symbol table), it makes it really fast |
| 03:43:59 | <SamB> | rovar: that's a wierd thought |
| 03:44:20 | <Saizan> | amz: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5090#a5091 |
| 03:44:21 | <rovar> | with some hindley milner type inferencing.. it could be done |
| 03:44:37 | <rovar> | and the syntax could remain unchanged |
| 03:44:44 | <Cale> | I don't understand why a language would bother to distinguish things in this funny way that D seems to have chosen with 'delegates' and 'functions' |
| 03:44:44 | <gwern> | I could swear I saw python type inference in haskell once... |
| 03:44:45 | <Associat0r> | boo |
| 03:44:49 | <randomity> | not really... loads of Python code relies on special names as interfaces |
| 03:44:56 | <Cale> | Associat0r: hello |
| 03:45:07 | <Associat0r> | I mean Boo Languge |
| 03:45:07 | <jmcarthur> | Cale: it is actually (frustratingly) common in OO languages |
| 03:45:13 | <randomity> | like "this function takes an object supporting these three names" |
| 03:45:23 | <SamB> | seems like you'd eliminate the entire point of using Python by doing HM-style type inference ... |
| 03:45:40 | <rovar> | boo is cool |
| 03:45:46 | <rovar> | i wish it weren't .net |
| 03:46:06 | <Cale> | How does Boo handle procedures/functions? |
| 03:46:13 | <amz> | Saizan: thanks, I'll take a look |
| 03:46:13 | <jmcarthur> | Cale: iirc, a "delegate" can be a closure, but a "function" cannot. somebody else will probably say i'm wrong though. it's been a while since i used such atrocious things |
| 03:46:18 | <Associat0r> | there are some other non .net python like experiments |
| 03:46:18 | <randomity> | hmmm, at night this channel grows fangs and turns into #anything-but-haskell. awesome. |
| 03:46:54 | <amz> | says that foldl' is not on scope |
| 03:47:08 | <Ycros> | rovar: also Cobra |
| 03:47:13 | <Associat0r> | yeah Cobra |
| 03:47:20 | <rovar> | jmcarthur: that's basically it... a delegate keeps a ptr to the stack on which it was created (e.g. a class instance) whereas a function ptr does not.. so you would make a delegate from a class method.. and a function ptr from a static method |
| 03:47:24 | <Associat0r> | Cale : in what way? |
| 03:47:26 | <rovar> | haven't looked at cobra |
| 03:47:51 | <Cale> | Associat0r: Well, that's sort of what we've been discussing -- how various languages handle functions/procedures. |
| 03:47:53 | <Ycros> | rovar: it's also inspired by Python, like boo, but supposedly better |
| 03:47:58 | <rovar> | also a delegate would be an inner function |
| 03:48:05 | <Saizan> | amz: see at the top, i've added import Data.List |
| 03:48:10 | <gwern> | randomity: even the #haskeller who is pure and programs aright / may chat off-topic when the conversation blossoms and the moon is bright |
| 03:48:12 | <amz> | ah |
| 03:48:15 | <Ycros> | rovar: personally I just can't wait for Python to get some nice speedups thanks to Google's unladen swallow project |
| 03:48:37 | <Ycros> | has anyone played with the Pure language? |
| 03:49:04 | <Cale> | jmcarthur: I'm not sure when you'd ever want a procedure definition *not* to close over the values of the variables that are in scope when it is defined. Is it that people think using a closure to store those values is too expensive? |
| 03:49:28 | <erikc`> | Cale: yes, it is |
| 03:49:38 | <Cale> | (We should show these people something like graph reduction ;) |
| 03:50:00 | <amz> | Saizan: still stack overflows for me :( |
| 03:50:16 | <amz> | let me paste an updated version, whose purpose should be clearer |
| 03:50:18 | <Cale> | erikc`: In what way? |
| 03:50:28 | <randomity> | gwern: *sheds a tear at the unrivalled beauty* :D |
| 03:50:45 | <amz> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5090#a5092 |
| 03:50:50 | <erikc`> | they think it's too expensive |
| 03:51:12 | <Cale> | It seems strange. Such a small price to pay for sanity. |
| 03:51:39 | <erikc`> | of course, c/c++ programmers not aware of their machine abi dont realize they've already dedicated a machine register to a pointer to a table of CAFs :P |
| 03:51:43 | <erikc`> | so all C functions are closures anyway |
| 03:51:49 | <gwern> | ACTION bows. gwern, inflicting humor on #haskell since 2007. I'll be here all week |
| 03:51:54 | <erikc`> | now i sound like conal :) |
| 03:53:09 | <randomity> | ok, now it is 5am. Goodnight #haskell, before I fall asleep on the keyboard |
| 03:53:13 | <Cale> | I wonder where the word 'delegate' comes from too.. |
| 03:53:13 | <MonadBaastad> | ACTION thinks that "unladen swallow" smacks faintly of pr0n... |
| 03:53:15 | <rovar> | nite |
| 03:53:25 | <rovar> | haha |
| 03:53:28 | <randomity> | night |
| 03:53:29 | <Cale> | That seems like an awfully strange word for 'procedure' |
| 03:54:01 | <dibblego> | @where yaht |
| 03:54:02 | <lambdabot> | PDF: http://darcs.haskell.org/yaht/yaht.pdf Wikibook: http://en.wikibooks.org/wiki/Haskell/YAHT |
| 03:54:24 | <erikc`> | Cale: as far as i know microsoft introduced the term with .net |
| 03:54:41 | <gwern> | MonadBaastad: could be worse. they've could've picked tits or boobies as their bird of choice |
| 03:55:10 | <MonadBaastad> | gwern: Double-breasted chickadees? >;) |
| 03:55:36 | <gwern> | ACTION saw a fine tit the other day on wikipedia |
| 03:55:43 | <Cale> | erikc`: heh, it sounds like something a business person would come up with... "I'm not going to need a procedure to do this, I'll just delegate it." |
| 03:55:59 | <dibblego> | delegate is a C# keyword for emulating HOFs |
| 03:56:14 | <gwern> | DELEGATE procedure GIVING VOID |
| 03:56:19 | <jmcarthur> | Cale: i think it comes from OO speak. a delegate is basically an object that can be stored locally to determine how certain operations should be carried out. that is, it replaces local functionality with foreign functionality. kind of similar to a strategy |
| 03:56:40 | <dibblego> | @where lyah |
| 03:56:40 | <lambdabot> | www.learnyouahaskell.com |
| 03:56:52 | <Cale> | dibblego: I'm wondering about the etymology of it. |
| 03:56:53 | <rovar> | lyah++ |
| 03:56:54 | <jmcarthur> | i've been running into a lot of crap with OO programming at work this week and am tired of design patterns crap though, so i'm done beyond this point |
| 03:57:35 | <Cale> | jmcarthur: Interesting... though I'm not sure exactly the way that sense relates to the fact that it captures the values of variables that are in scope where it's defined. |
| 03:57:42 | <jmcarthur> | basically, it's a fancy word for a concept that shouldn't be so fancy |
| 03:57:52 | <Saizan> | amz: updated with added strictness http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5090#a5093 |
| 03:58:12 | <jmcarthur> | Cale: in implementation, C#'s and D's delegates are just objects that represent the closure with a method which invokes the "function" |
| 03:58:28 | <MonadBaastad> | Weird: http://en.wikipedia.org/wiki/Delegate_(.NET) looks like someone sat down and deliberately tried to make a clunky CPS system... :\ |
| 03:58:43 | <jmcarthur> | one could say it is an abstraction leak to call it a delegate like that |
| 03:58:57 | <Cale> | Wait, what? Represent the closure? |
| 03:59:09 | <jmcarthur> | well, it *is* the closure, really |
| 03:59:10 | <amz> | Saizan: awesome, that works :) |
| 03:59:15 | <amz> | if only I knew why... :) |
| 03:59:17 | <jmcarthur> | it's hack |
| 03:59:20 | <jmcarthur> | *a hack |
| 03:59:34 | <amz> | but thanks a lot |
| 03:59:34 | <Cale> | Yeah, a closure is an implementation mechanism for a procedure, as far as my definitions go :) |
| 03:59:38 | <jmcarthur> | i'm not going to be able to explain it properly |
| 03:59:39 | <amz> | I'll study this black magic |
| 03:59:46 | <Cale> | But maybe I see what you mean |
| 04:00:05 | <Saizan> | amz: well, the point is to not construct huge thunks of strict functions, but evaluate the application of each function step by step |
| 04:00:19 | <Cale> | You have an object with a method for the code, and instance variables for the captured variables? |
| 04:00:57 | <Saizan> | amz: it's the same concept of foldl (+) 0 vs. foldl' (+) 0 |
| 04:01:07 | <Saizan> | @wiki Stack Overflow |
| 04:01:07 | <lambdabot> | http://www.haskell.org/haskellwiki/Stack_Overflow |
| 04:01:30 | <Saizan> | http://www.haskell.org/haskellwiki/Stack_overflow <- actually |
| 04:01:32 | <amz> | this is still way above my level, I can barely code anything in Haskell, but I'll try to decypher it |
| 04:01:36 | <Gracenotes> | sans the capital o |
| 04:01:43 | <Gracenotes> | wiki titles are case sensitive... yeah you got it :) |
| 04:01:52 | <Gracenotes> | except for the first letter |
| 04:02:13 | <jmcarthur> | Cale: "Delegates to non-static nested functions contain two pieces of data: the pointer to the stack frame of the lexically enclosing function (called the frame pointer) and the address of the function. This is analogous to struct/class non-static member function delegates consisting of a this pointer and the address of the member function. Both forms of delegates are interchangeable, and are actually the same type" |
| 04:02:45 | <Cale> | okay |
| 04:03:05 | <Cale> | That's pretty much a closure, yeah. |
| 04:03:25 | <jmcarthur> | "A function pointer can point to a static nested function" ... "A delegate can be set to a non-static nested function" |
| 04:05:21 | <erikc`> | and since a non-static function is just a function with a hidden this parameter...they are the same thing :P |
| 04:05:41 | <jmcarthur> | D even has explicit lazy evaluation |
| 04:06:18 | <erikc`> | yea |
| 04:06:43 | <erikc`> | those features fall out naturally once you give in to garbage collection + heap allocation of stack frames :) |
| 04:06:58 | <jmcarthur> | yeah, but most imperative languages ignore such obvious ideas |
| 04:07:21 | <jmcarthur> | and D does not mandate garbage collection, either |
| 04:07:28 | <jmcarthur> | it can be manual, if you wish |
| 04:08:29 | <erikc`> | so you need to manually free your closures i guess |
| 04:08:32 | <mmorrow_> | D heap-allocates stack frames? does it have real callcc? |
| 04:10:14 | <jmcarthur> | you could probably do it with delegates, although i don't know whether it will optimize tail calls or just confuse the garbage collector or whatever |
| 04:10:39 | <mmorrow_> | ah, hmm |
| 04:11:22 | <mmorrow_> | so i guess you don't have access to the stack frames as if they were "just some closure" or something |
| 04:12:09 | <Associat0r> | anyone seen http://delight.sourceforge.net/ ? |
| 04:12:50 | <jmcarthur> | you can even get raw pointers to the stack frames if you want, i think |
| 04:13:32 | <jmcarthur> | but even without that, i think the closures are true closures... just hackish because it's done in OO-speak |
| 04:13:50 | <mmorrow_> | hmm, cool. i guess the only question then is whether stack frames are deallocated after a function returns unconditionally, or if they're gc'ed only if there're no live ptrs to them |
| 04:13:57 | <jmcarthur> | right |
| 04:14:53 | <jmcarthur> | i suspect it is the latter |
| 04:15:00 | <Associat0r> | http://www.bitc-lang.org/ does closures on the stack too without GC |
| 04:15:06 | <mmorrow_> | ACTION is reading http://www.digitalmars.com/d/2.0/memory.html |
| 04:38:22 | <travisbrady> | how can i do patterns in a case statement with ByteStrings? ala 'case x of "A" -> print "hey" "B" -> print "no"' |
| 04:42:05 | <codebliss> | @i getFile |
| 04:42:05 | <lambdabot> | Maybe you meant: id ignore index instances instances-importing irc-connect . ? @ v |
| 04:42:19 | <codebliss> | @src getFile |
| 04:42:20 | <lambdabot> | Source not found. The more you drive -- the dumber you get. |
| 04:42:32 | <codebliss> | @t getFile |
| 04:42:33 | <lambdabot> | Maybe you meant: tell thank you thanks thx ticker time todo todo-add todo-delete topic-cons topic-init topic-null topic-snoc topic-tail topic-tell type . ? @ ft v |
| 04:42:47 | <codebliss> | How does lambdabot do :t? XD |
| 04:43:33 | <codebliss> | Oh, it's readFile... |
| 04:45:54 | <jimmyjazz14> | is there a !! counterpart that works with Integer types? |
| 04:48:01 | <Saizan> | genericIndex |
| 04:50:03 | <jimmyjazz14> | thanks |
| 04:51:22 | <dmwit> | Yes! I now have what is essentially a very, very complicated way to draw a line across the screen. =P |
| 05:03:08 | <amckinley> | would anyone like to help me write a small chunk of the parser im working on? :) |
| 05:18:20 | <A1kmm> | Hey, has anyone managed to get uvector working with trunk? |
| 05:18:26 | <A1kmm> | (version of ghc) |
| 05:20:23 | <dmwit> | amckinley: hpaste.org, maybe? |
| 05:22:55 | <amckinley> | dmwit: actually ive got to run; hopefully ill be back later :) thanks though |
| 05:29:25 | <A1kmm> | Does anyone know what the following error message (from the latest darcs version of ghc): Data/Array/Vector/Prim/BUArr.hs:89:0: |
| 05:29:27 | <A1kmm> | Failed to load interface for `GHC.Prim': |
| 05:30:05 | <A1kmm> | Isn't GHC.Prim part of the wired-in ghc-prim package? |
| 05:30:21 | <thoughtpolice> | A1kmm: in ./ghc/libraries/ghc-prim/ghc-prim.cabal, you can see GHC.Prim is hidden by default with a flag |
| 05:30:49 | <A1kmm> | Ah... so packages need to explicitly enable it? |
| 05:31:14 | <thoughtpolice> | not sure |
| 05:31:28 | <thoughtpolice> | i would think there was a patch introduced which hides GHC.Prim by default |
| 05:31:33 | <thoughtpolice> | which isn't in the 6.10 branch |
| 05:33:34 | <solrize_> | @seen lemmih |
| 05:33:35 | <lambdabot> | lemmih is in #haskell. I don't know when lemmih last spoke. |
| 05:33:41 | <solrize_> | lemmih ? |
| 05:34:13 | <solrize_> | @seen thoughtpolice |
| 05:34:13 | <lambdabot> | thoughtpolice is in #haskell-blah, #haskell-in-depth, #ghc and #haskell. I last heard thoughtpolice speak 2m 40s ago. |
| 05:34:23 | <solrize_> | thoughtpolice ? |
| 05:34:36 | <dmwit> | You are SOL tonight. |
| 05:34:40 | <solrize_> | heh |
| 05:34:44 | <solrize_> | i had a dumb question about lhc |
| 05:34:52 | <A1kmm> | thoughpolice: flag include-ghc-prim { |
| 05:34:54 | <A1kmm> | Description: Include GHC.Prim in exposed-modules |
| 05:34:56 | <A1kmm> | default: False |
| 05:34:57 | <A1kmm> | } |
| 05:35:37 | <Lemmih> | solrize_: ? |
| 05:36:44 | <Lemmih> | GHC.Prim doesn't exist. It's only generated for documentation purposes. |
| 05:36:47 | <solrize_> | lemmih, yeah, i was wondering if lhc uses the same dictionary avoiding typeclass scheme as lhc |
| 05:36:58 | <solrize_> | i remember asking something about this before |
| 05:37:06 | <solrize_> | oops "same as ... jhc" |
| 05:37:23 | <thoughtpolice> | solrize_: ? |
| 05:37:27 | <Lemmih> | solrize_: Yes and no. |
| 05:37:31 | <dmwit> | Typeclasses without dictionaries, eh? |
| 05:37:32 | <solrize_> | 'cause i remember that the jhc blurb explained that as why it used a fancy type system in its intermediate lang |
| 05:37:35 | <solrize_> | dmwit, yeah |
| 05:37:39 | <A1kmm> | Lemmih: uvector uses it, but it won't compile for trunk ghc. |
| 05:37:52 | <solrize_> | and ghc core's type system doesn't have the high powered capabilities |
| 05:38:00 | <RyanT5000> | is there a policy about advertising Haskell jobs in this chatroom? |
| 05:38:03 | <Lemmih> | solrize_: We use normal dictionaries but we can optimize them away. |
| 05:38:21 | <Lemmih> | solrize_: JHC takes a different approach and doesn't create the dictionaries in the first place. |
| 05:38:26 | <Lemmih> | solrize_: The end result is the same. |
| 05:38:29 | <solrize_> | hmm |
| 05:38:31 | <solrize_> | cool |
| 05:38:41 | <dmwit> | RyanT5000: It seems fine to me, though I'm not in any position of authority. You'll almost certainly get better response from haskell-cafe, though. |
| 05:39:24 | <RyanT5000> | dmwit: ah, that's a good point; i'll send something to that at some point |
| 05:39:36 | <Lemmih> | solrize_: Our approach requires a bit more CPU time but it is easier to work with. We had lots of trouble getting the dictionaries to work correctly in JHC. |
| 05:39:44 | <RyanT5000> | on the basis of that non-authoritative response, i'm going to go ahead and say it :P |
| 05:39:52 | <solrize_> | ryant5000 i think it's ok, since there are so few. putting it at -cafe will probably get it into HWN which is very visible |
| 05:40:02 | <solrize_> | ryant5000 :) |
| 05:40:04 | <RyanT5000> | solrize_: yeah, that's a good point |
| 05:40:41 | <RyanT5000> | i'm starting a game studio writing in haskell; email me at ryant5000@gmail.com if you're interested |
| 05:41:14 | <solrize_> | lemmih, interesting. i never understood that angle of jhc. but since you have the whole program right there it seems natural that you can specialize every function |
| 05:41:25 | <dmwit> | Whoa; have you got a game in mind already? |
| 05:41:31 | <solrize_> | game studio?!!! yow |
| 05:41:31 | <RyanT5000> | dmwit: yeah |
| 05:41:38 | <dmwit> | ?yow! |
| 05:41:38 | <lambdabot> | You mean you don't want to watch WRESTLING from ATLANTA? |
| 05:41:43 | <RyanT5000> | solrize_: yep :) |
| 05:41:48 | <solrize_> | dmwit hee |
| 05:41:53 | <RyanT5000> | it'll be tough |
| 05:42:06 | <RyanT5000> | and i imagine we'll end up contributing to GHC quite a bit if we manage to survive |
| 05:42:14 | <solrize_> | ryant5000 did you ever see tim sweeney's presentation about game dev. languages? |
| 05:42:19 | <RyanT5000> | but i think it has a lot of potential - and Tim Sweeney backs me up |
| 05:42:25 | <solrize_> | hehe jinx |
| 05:42:25 | <RyanT5000> | solrize_: yup :) |
| 05:42:29 | <RyanT5000> | lol |
| 05:42:32 | <Lemmih> | A1kmm: Oh, sorry, I misunderstood. I don't know what the problem is. |
| 05:42:41 | <dmwit> | So you're going for the high-end games, then? (Not casual games.) |
| 05:43:07 | <solrize_> | you gonna program GPU's with haskell ? |
| 05:43:18 | <solrize_> | (the answer must be yes, haskell can do that) |
| 05:43:23 | <RyanT5000> | we're looking into everything |
| 05:43:32 | <RyanT5000> | porting to weird platforms or chips is a core part of our strategy |
| 05:43:51 | <RyanT5000> | (another core part is this chatroom and all the untapped talent it represents) |
| 05:44:15 | <RyanT5000> | (in my opinion, there's not enough demand for Haskell programmers) |
| 05:44:22 | <solrize_> | i've felt like haskell needs an internal low level DSL for micro-optimizing cpu intensive functions |
| 05:44:42 | <dmwit> | Harpy? |
| 05:44:43 | <twb> | Does GHC 6.10.3 include haskeline? That's what Debian seems to think. |
| 05:44:51 | <solrize_> | harpy = assembler, not what i had in mind :) |
| 05:44:54 | <RyanT5000> | twb: release notes say yes |
| 05:45:03 | <Ycros> | RyanT5000: are you starting a real game dev studio, ie. a business, or just like an indie one |
| 05:45:31 | <RyanT5000> | Ycros: it's a real game dev studio, although it won't be developing mainstream PC or big-box console titles (at least not in the short-term) |
| 05:45:47 | <twb> | RyanT5000: thanks. |
| 05:45:54 | <RyanT5000> | twb: np |
| 05:46:07 | <RyanT5000> | Ycros: we haven't totally worked out financing yet - in particular because the availability of Haskell talent is more or less an unknown quantity right now |
| 05:46:11 | <solrize_> | lemmih are you generating asm code or C? |
| 05:46:51 | <Ycros> | RyanT5000: financing is the important part :P |
| 05:47:03 | <Ycros> | RyanT5000: where are you located? |
| 05:47:07 | <RyanT5000> | i have a feeling that Haskell programmers are self-selected in interesting and useful ways, and that Haskell itself has a lot of potential (again, in line with Tim Sweeney's presentation), but it's hard to go to VC or other financing with just a gut feeling |
| 05:47:33 | <RyanT5000> | Ycros: you're right, financing is a huge deal; we have some - enough to possibly get one game out the door |
| 05:47:39 | <solrize_> | ryant5000, an anecdote, skydeck (company writing some kind of telecom related software in ocaml) used to advertise for python(?) programmers because they didn't want to scare people by mentioning ocaml. but once word got out they were actually using ocaml, the way i heard it, tons of fp nerds all wanted to work there. |
| 05:47:44 | <RyanT5000> | Ycros: we're in Boston, Massachusetts |
| 05:48:05 | <RyanT5000> | solrize_: huh, that's interesting |
| 05:48:18 | <Ycros> | RyanT5000: ah well, way too far away for me anyway :P |
| 05:48:23 | <Lemmih> | solrize_: Neither. Right now we're interpreting GRIN code. An LLVM backend will be added soonish. |
| 05:48:55 | <RyanT5000> | Ycros: ah, that's too bad |
| 05:49:09 | <solrize_> | hmm, i guess you've done CPS conversion already, so no issue with LVM not compiling tail recursion away |
| 05:49:37 | <RyanT5000> | Ycros: you sound like you have some experience with startups; is that the case? |
| 05:50:48 | <Ycros> | RyanT5000: Not really, but I hang around people who do the startup thing, I've also started a business some months ago and might be starting another soon :P |
| 05:50:49 | <solrize_> | ACTION worked at a game startup but am not enough of a haskell expert to qualify for a haskell startup and anyway already has a job :) |
| 05:50:58 | <Lemmih> | solrize_: We /will/ depend on llvm optimising tail recursive calls. |
| 05:51:10 | <RyanT5000> | Ycros: sounds good |
| 05:51:15 | <solrize_> | lemmih hmm they have fixed that (or will fix it)? |
| 05:52:03 | <solrize_> | lemmih can you add a compiler flag that makes Int arithmetic check for overflow and raise an exception? |
| 05:52:20 | <RyanT5000> | alright, well, i've got to head off, but if anyone's interested - or knows anyone who might be interested - in writing games in Haskell, my email is ryant5000@gmail.com |
| 05:52:43 | <solrize_> | ryant5000 i'm sure you'll get takers. there are already some haskell games including a FPS |
| 05:52:43 | <Lemmih> | solrize_: I don't see why not. |
| 05:53:02 | <solrize_> | lemmih cool, i think that would catch some bugs |
| 05:53:27 | <solrize_> | are you going to be able to use the existing ghc runtime for stuff like gc? |
| 05:54:10 | <solrize_> | is there much of a haskell->llvm interface currently? |
| 05:54:51 | <solrize_> | oh haha, i'm looking at the llvm release notes and it says they now support int overflow traps |
| 06:11:20 | <halberd> | what does it mean in type theory when they say "primitive non-canonical constant"? example: apply is the primitive non-canonical constant for the Pi-set |
| 06:12:17 | <lispy> | halberd: I can honestly say, I'm not sure |
| 06:12:33 | <dmwit> | helpful |
| 06:25:40 | <halberd> | I guess the canonical constants for a set are the constructors, and primitive simply means defined, so a primitive non-canonical constant would just be a defined constant that is not a constructor |
| 06:27:34 | <halberd> | and that operates on elements of the set |
| 06:37:04 | <cads> | hey, how's bsd for haskell? |
| 06:39:35 | <MyCatVerbs> | OpenBSD's fine. I haven't tried any of the others myself. |
| 06:39:47 | <MyCatVerbs> | I think FreeBSD's good too, but I couldn't tell you for certain. |
| 06:46:16 | <cads> | does openbsd come with a useable desktop configuration? |
| 06:54:07 | <MyCatVerbs> | cads: blowed if I can remember, but it does have a Hell of a good FAQ. |
| 06:57:26 | <cads> | MyCatVerbs: it seems very secure |
| 06:57:48 | <MyCatVerbs> | Well, they're almost paranoid enough. ^_^ |
| 07:03:00 | <lpjhjdh> | so the haskell98 standard says "uniSymbol -> any Unicode symbol or punctuation" is there a more concrete definition of "any"? |
| 07:03:44 | <dmwit> | :t isSymbol |
| 07:03:45 | <lambdabot> | Char -> Bool |
| 07:03:49 | <dmwit> | :t isPunctuation |
| 07:03:51 | <lambdabot> | Char -> Bool |
| 07:04:11 | <dmwit> | > filter (liftM2 (||) isSymbol isPunctuation) ['\0'..] |
| 07:04:12 | <lambdabot> | "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~\161\162\163\164\165\166\167\168\169\171... |
| 07:04:46 | <dmwit> | Depending on where this is used, that may or may not be correct. |
| 07:05:03 | <lpjhjdh> | I see, thanks. |
| 07:05:08 | <dmwit> | As you can see, some things like ", (, ) are in there. |
| 07:05:50 | <dmwit> | @, \, [, ], {, }, |, and ~ are also special... |
| 07:05:50 | <lambdabot> | Maybe you meant: . ? @ v |
| 07:06:44 | <MyCatVerbs> | dmwit: ~? |
| 07:07:02 | <MyCatVerbs> | I can't remember anywhere in Haskell's grammar where ~ is used? |
| 07:07:03 | <lpjhjdh> | hmm, so essentially anything not reserved? |
| 07:07:20 | <dmwit> | MyCatVerbs: lazy patterns |
| 07:07:20 | <ivanm> | @src partition |
| 07:07:21 | <lambdabot> | partition p xs = foldr (select p) ([],[]) xs |
| 07:07:21 | <lambdabot> | where select p x ~(ts,fs) | p x = (x:ts,fs) |
| 07:07:21 | <lambdabot> | | otherwise = (ts, x:fs) |
| 07:07:24 | <ivanm> | MyCatVerbs: ^^ |
| 07:07:36 | <ivanm> | so it's not undefined |
| 07:07:36 | <MyCatVerbs> | dmwit: oh yes! I am full of forgetfullness and no caffeine. |
| 07:07:54 | <lpjhjdh> | @hoogle isSymbol |
| 07:07:54 | <lambdabot> | Data.Char isSymbol :: Char -> Bool |
| 07:11:23 | <solrize_> | does 6.8.2 not have data.binary? should i upgrade to what is it now, 6.10.3? |
| 07:14:07 | <lpjhjdh> | @hoogle alexGetChar |
| 07:14:07 | <lambdabot> | No results found |
| 07:23:01 | <PetRat> | I'm trying to understand the expression "join (*) 5". Apparently this has to do with the monad ((->) e). |
| 07:23:27 | <PetRat> | (*) :: Int -> Int -> Int |
| 07:23:53 | <dmwit> | yep |
| 07:23:59 | <dmwit> | :t join |
| 07:24:00 | <lambdabot> | forall (m :: * -> *) a. (Monad m) => m (m a) -> m a |
| 07:24:18 | <PetRat> | Apparently (*) is a monad and so is (5 *)? |
| 07:24:22 | <dmwit> | So, in the case of the (e ->) monad, join :: (e -> e -> a) -> (e -> a) |
| 07:25:10 | <dmwit> | i.e. given a function that expects two environments, return a function that takes only one environment and supplies two copies of it to the passed-in function. |
| 07:25:28 | <dmwit> | So (join (*)) is a function that takes one argument and puts it on both sides of the multiplication. |
| 07:25:35 | <dmwit> | join (*) 5 = 5 * 5 |
| 07:25:44 | <PetRat> | I am still trying to work that out from my understanding of the definitions. |
| 07:25:56 | <dmwit> | ?src join |
| 07:25:56 | <lambdabot> | join x = x >>= id |
| 07:26:04 | <PetRat> | join = do y <- x; v <- y; return v |
| 07:26:12 | <dmwit> | right |
| 07:26:18 | <PetRat> | what is x? |
| 07:26:30 | <dmwit> | uh |
| 07:26:31 | <shachaf> | join x = ... |
| 07:26:32 | <dmwit> | I think that's |
| 07:26:34 | <dmwit> | join x = ... |
| 07:26:35 | <dmwit> | yeah |
| 07:26:40 | <shachaf> | PetRat: Isn't that redundant, though? |
| 07:26:46 | <shachaf> | join x = do y <- x; y |
| 07:27:05 | <dmwit> | Damn, shachaf is fast. I was about to suggest that, too, but can't type nearly as quickly. =P |
| 07:27:11 | <shachaf> | PetRat: My advice: Look at the types instead of the implementations. At least at first. |
| 07:27:35 | <shachaf> | PetRat: They're simpler, and there's one obvious implementation for each. |
| 07:27:38 | <PetRat> | So join (*) = do y <- (*) ; y |
| 07:27:42 | <shachaf> | @src (->) >>= |
| 07:27:42 | <lambdabot> | Source not found. |
| 07:27:47 | <shachaf> | @src (->) (>>=) |
| 07:27:48 | <lambdabot> | f >>= k = \ r -> k (f r) r |
| 07:27:49 | <PetRat> | shachaf: I'm trying to do both. |
| 07:28:14 | <shachaf> | PetRat: Another bit of advice: Think of it in terms of join/fmap/return instead of (>>=)/return. :-) |
| 07:28:50 | <dmwit> | f >>= k = \r -> k (f r) r |
| 07:28:57 | <dmwit> | f >>= id = \r -> id (f r) r |
| 07:29:03 | <PetRat> | I'm looking at an exercise to define >>= in terms of fmap and join. Thinking about trying to do that. I just want to understand join (*) 5 |
| 07:29:04 | <dmwit> | f >>= id = \r -> (f r) r |
| 07:29:10 | <dmwit> | f >>= id = \r -> f r r |
| 07:29:16 | <Gracenotes> | but nonetheless, >>= does make for some spiffy one-liners |
| 07:29:18 | <dmwit> | join f = f >>= id = \r -> f r r |
| 07:29:37 | <dmwit> | ACTION stops flooding |
| 07:30:22 | <shachaf> | PetRat: OK, those are two separate exercises. |
| 07:30:36 | <shachaf> | PetRat: As I said before, look at the types. |
| 07:30:38 | <shachaf> | @ty join |
| 07:30:39 | <lambdabot> | forall (m :: * -> *) a. (Monad m) => m (m a) -> m a |
| 07:30:41 | <shachaf> | @ty fmap |
| 07:30:42 | <lambdabot> | forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b |
| 07:30:44 | <shachaf> | @ty (>>=) |
| 07:30:45 | <lambdabot> | forall (m :: * -> *) a b. (Monad m) => m a -> (a -> m b) -> m b |
| 07:31:02 | <PetRat> | Last night I worked out x >>= f = \e -> f (x e) e |
| 07:31:29 | <dmwit> | PetRat: Nice! |
| 07:31:32 | <PetRat> | join :: m (m a) -> m a |
| 07:32:22 | <PetRat> | so m (m a) is e -> (e -> a) ? |
| 07:32:27 | <dmwit> | Right. |
| 07:32:37 | <PetRat> | m a is e -> a |
| 07:32:43 | <dmwit> | Spot on. |
| 07:32:58 | <shachaf> | @ty flip (>>=) -- Hint: fmap is similar to flip (>>=). |
| 07:32:58 | <lambdabot> | forall (m :: * -> *) a b. (Monad m) => (a -> m b) -> m a -> m b |
| 07:33:10 | <shachaf> | (Now that I think about it, that isn't a very helpful hint. Ignore me. :-) ) |
| 07:33:49 | <PetRat> | so join takes a function of two arguments and changes to a function of one argument. The specific implementation does that by supplying the one argument twice. I guess there's nothing else you CAN do, if you have only one argument for a function of two arguments. (Nothing else useful.) |
| 07:33:54 | <zakwilson> | I'm using a Mac for a few days. Is Fink or Darwinports a sane way to get GHC and the like? |
| 07:34:05 | <dmwit> | PetRat: exactly |
| 07:34:52 | <shachaf> | PetRat: You'll find that it's that way with just about all the (r ->) functions. |
| 07:34:56 | <shachaf> | For example: |
| 07:34:57 | <shachaf> | @ty return |
| 07:34:58 | <lambdabot> | forall a (m :: * -> *). (Monad m) => a -> m a |
| 07:35:21 | <shachaf> | a -> m a = a -> (r -> a) |
| 07:35:32 | <shachaf> | What's the most obvious way of accomplishing that? :-) |
| 07:35:43 | <PetRat> | I want to understand the implementation, though. join x = do y <- x; y. how is this expressed with >>=? |
| 07:36:02 | <shachaf> | PetRat: do is syntax sugar for >>=, remember. |
| 07:36:05 | <PetRat> | shachaf: \_ -> a? |
| 07:36:11 | <shachaf> | PetRat: Yep. |
| 07:36:17 | <shachaf> | Or rather, \a _ -> a |
| 07:36:32 | <dmwit> | ?undo \x -> do { y <- x; y } |
| 07:36:32 | <lambdabot> | \ x -> x >>= \ y -> y |
| 07:36:43 | <dmwit> | The latter is just fancy notation for id. |
| 07:36:46 | <dmwit> | \x -> x >>= id |
| 07:37:01 | <dmwit> | You'll note the similarity to the Prelude: |
| 07:37:03 | <dmwit> | ?src join |
| 07:37:04 | <lambdabot> | join x = x >>= id |
| 07:37:04 | <dmwit> | ;-) |
| 07:37:33 | <shachaf> | @. pl undo join x = do { y <- x; y } |
| 07:37:34 | <lambdabot> | join = join |
| 07:37:38 | <shachaf> | Er, yes. |
| 07:37:46 | <dmwit> | hehehe |
| 07:37:47 | <PetRat> | join x = x >>= id ? |
| 07:39:41 | <shachaf> | PetRat: For any monad, yes. That's the Prelude's definition. |
| 07:39:57 | <shachaf> | You might find it clearer to start with join and fmap, though. :-) |
| 07:40:09 | <kau> | hello! Can you give me some pointers on "if then else" being desugared to arrowChoice? |
| 07:40:49 | <kau> | can't find it on google :( |
| 07:41:35 | <dmwit> | Have you looked at the papers on proc notation? |
| 07:41:41 | <kau> | no |
| 07:41:43 | <dmwit> | That's where I'd expect the details to be. |
| 07:41:43 | <PetRat> | okay so \e -> f (x e) e ==> \e -> id (e *) e ===> (e *) e ===> e * e |
| 07:41:55 | <kau> | i dont know proc notation ;) |
| 07:42:24 | <kau> | it's for defining new keywords? |
| 07:42:33 | <dmwit> | Uh, no, it's for using Arrows. |
| 07:42:55 | <dmwit> | It's a bit like do notation, but for Arrows, not Monads. |
| 07:43:00 | <dmwit> | And not as good as Wadler's notation. =) |
| 07:43:17 | <dmwit> | The Haskell wiki page on arrows should have links to papers about it. |
| 07:44:27 | <kau> | ok thanks i'll have a look |
| 07:44:51 | <Saizan> | the ghc manual also has it |
| 07:45:28 | <Saizan> | ?type (|||) |
| 07:45:29 | <lambdabot> | forall (a :: * -> * -> *) b d c. (ArrowChoice a) => a b d -> a c d -> a (Either b c) d |
| 07:45:56 | <Saizan> | ?type constA |
| 07:45:57 | <lambdabot> | Not in scope: `constA' |
| 07:46:52 | <PetRat> | So >>= implemented in terms of fmap and join. I think it's x >>= f = join $ fmap f x |
| 07:47:39 | <Saizan> | let constA a = arr (const a) in \t f -> arr (\x -> if x then Left () else Right ()) >>> (constA t ||| constA f) |
| 07:47:46 | <Saizan> | PetRat: right |
| 07:47:56 | <shachaf> | @ty \f m -> join (fmap f m) -- Yep. |
| 07:47:57 | <lambdabot> | forall a (m :: * -> *) a1. (Monad m, Functor m) => (a -> m a1) -> m a -> m a1 |
| 07:47:59 | <shachaf> | Well, flipped, anyway. |
| 07:49:20 | <PetRat> | It's amazing to me that you can work out that definition by "following the types", as though you are ignoring implementation. But I guess the idea is that when any particular monad is implemented, the implementor follows the types and the monad laws, which is what guarantees my simple definition will always work. Is it something like that? |
| 07:50:10 | <shachaf> | PetRat: Yep. That's the whole point of having a Monad class. |
| 07:50:19 | <Cale> | PetRat: There are often not that many possibilities for implementation of a highly polymorphic type. |
| 07:50:30 | <dmwit> | Actually, in a lot of cases, you can prove rigorously that all truly polymorphic implementations that matches a particular type will be identical. |
| 07:50:43 | <dmwit> | s/matches/match/ |
| 07:52:42 | <Cale> | As another example, consider the type (a -> b) -> [a] -> [b], the type of map. What functions have this type? Well, it's not just map, but we can say that every other function which has that type produces a list consisting of elements produced by passing elements of the given list to the given function. |
| 07:53:17 | <Cale> | This makes it really hard to mess up your implementation and still get the type to match. You basically have to be trying. |
| 07:53:53 | <Cale> | Often the implementation with the nicest properties, the one you really want, will also be the simplest one as well. |
| 07:54:31 | <PetRat> | Cale: what if you implement map' f xs = [f (head xs)] . Is that "trying to mess it up?" |
| 07:55:44 | <dmwit> | Yep, about the best you can say is that the behavior of a function matching that type will depend only on the length of the list. |
| 07:55:56 | <dmwit> | However, there's still a lot you can make rigorous. |
| 07:55:56 | <Cale> | Well, I suppose it's possible that you're not trying to mess up there if you actually don't know the language very well. |
| 07:56:12 | <Cale> | dmwit: And the permutation of the elements given. |
| 07:56:20 | <Cale> | (and duplicates) |
| 07:56:22 | <dmwit> | Cale: No, it can't depend on that. |
| 07:56:27 | <dmwit> | Not at that type. |
| 07:56:43 | <Cale> | oh, I see what you're saying |
| 07:56:45 | <PetRat> | Cale: I mean "trying" more in the sense of, failing to observe basic principles. |
| 07:57:16 | <solrize_> | map' f xs = [] |
| 07:57:21 | <solrize_> | doesn't depend on length xs :) |
| 07:57:24 | <Cale> | dmwit: I accidentally misinterpreted which list you were talking about |
| 07:57:34 | <dmwit> | solrize_: Sure it does. |
| 07:57:48 | <dmwit> | solrize_: In fact, it doesn't depend on anything *but* the length of xs. |
| 07:57:48 | <MyCatVerbs> | solrize_: is too polymorphic, has type a -> b -> [c]. |
| 07:58:03 | <solrize_> | hmm ok |
| 07:58:03 | <Cale> | dmwit: It gives the same result regardless of xs though... |
| 07:58:06 | <MyCatVerbs> | forall a b c., even. |
| 07:58:19 | <dmwit> | Cale: Yep, I know. |
| 07:58:43 | <dmwit> | solrize_: Or, another way to put it is: saying that a thing depends "only on the length of the list" does not imply that it definitely does depend on the length of the list. |
| 07:58:45 | <Cale> | So that one doesn't even depend on the length of xs, it depends on nothing... |
| 07:59:15 | <PetRat> | There's a term like the "most general type"... something about the most general type that is not too general. |
| 07:59:18 | <dmwit> | solrize_: So the behavior of map' depends only on the length of the list... and not even on that. =) |
| 07:59:25 | <dmwit> | PetRat: "principal" |
| 08:00:35 | <PetRat> | Beginners often think that foldr :: (a -> a -> a) -> a -> [a] |
| 08:00:56 | <dmwit> | Maybe you meant (a -> a -> a) -> [a] -> a? |
| 08:01:12 | <Cale> | Or (a -> a -> a) -> a -> [a] -> a |
| 08:01:12 | <dmwit> | :t buildr |
| 08:01:13 | <lambdabot> | Not in scope: `buildr' |
| 08:01:20 | <PetRat> | Cale : you said it |
| 08:01:42 | <PetRat> | but it is actually something like (b -> a -> b) -> b -> [a] -> b |
| 08:02:04 | <Cale> | (a -> b -> b) -> b -> [a] -> b |
| 08:02:14 | <Cale> | (similar) |
| 08:02:35 | <dmwit> | :t foldl -- maybe what PetRat was thinking of |
| 08:02:36 | <lambdabot> | forall a b. (a -> b -> a) -> a -> [b] -> a |
| 08:02:41 | <PetRat> | Oh I see. Yes I tr to think of the supplied "starting" value as going on the right, for foldr |
| 08:03:23 | <Cale> | For foldr f z, it's best to think of f as a replacement for (:) and z as a replacement for [] |
| 08:03:39 | <PetRat> | dmwit: I was thinking of foldr but just forgetting that the supplied value "goes on the right" of the operator. |
| 08:04:02 | <Cale> | PetRat: Have you seen my diagrams? |
| 08:04:11 | <PetRat> | Stupid mibbit changes all (:) to smileys. |
| 08:04:11 | <Cale> | http://cale.yi.org/index.php/Fold_Diagrams |
| 08:04:36 | <PetRat> | Cale: I got 404 error on that link. |
| 08:04:36 | <Cale> | Does it change (:[]) into a robot monkey? |
| 08:04:42 | <Cale> | hmm |
| 08:05:17 | <Cale> | 99.247.248.73 |
| 08:05:34 | <Cale> | oh |
| 08:05:38 | <Cale> | I might know |
| 08:05:46 | <Cale> | Maybe the router switched us around again :P |
| 08:05:58 | <PetRat> | Cale: I saw the diagrams on the Wikipedia page. |
| 08:06:09 | <ivanm> | Cale: a windows message? :s |
| 08:06:41 | <ivanm> | I take it that's you singing/playing rather than providing illegal music for the RIAA to find? |
| 08:07:41 | <Cale_> | There we are. Any better? |
| 08:09:02 | <ivanm> | awww.... there's no oops message anymore :( |
| 08:09:16 | <Cale> | heh, that was from my dad's computer, I think |
| 08:10:19 | <ivanm> | it's not just that you've been gaming? |
| 08:11:07 | <PetRat> | Nice diagrams. |
| 08:11:39 | <Cale> | Nope, my machine doesn't have windows on it. |
| 08:12:53 | <Cale> | PetRat: actually, I did make the diagrams on Wikipedia as well |
| 08:12:54 | <FunctorSalad_> | how is scanr formed? |
| 08:13:06 | <Cale> | @src scanr |
| 08:13:07 | <lambdabot> | scanr _ q0 [] = [q0] |
| 08:13:07 | <lambdabot> | scanr f q0 (x:xs) = f x q : qs |
| 08:13:07 | <lambdabot> | where qs@(q:_) = scanr f q0 xs |
| 08:13:41 | <FunctorSalad_> | hmm it just yields all the intermediate values of the foldr? |
| 08:13:47 | <ivanm> | yup |
| 08:13:58 | <Cale> | yeah, starting with the whole thing |
| 08:14:08 | <Cale> | > scanr (+) 0 [1,2,3,4,5] |
| 08:14:10 | <lambdabot> | [15,14,12,9,5,0] |
| 08:14:32 | <Cale> | > scanr (+) 0 [1,10,100,1000,10000] |
| 08:14:34 | <lambdabot> | [11111,11110,11100,11000,10000,0] |
| 08:15:04 | <Cale> | > scanr f z [1,2,3,4,5] |
| 08:15:06 | <lambdabot> | [f 1 (f 2 (f 3 (f 4 (f 5 z)))),f 2 (f 3 (f 4 (f 5 z))),f 3 (f 4 (f 5 z)),f ... |
| 08:15:39 | <dmwit> | It is one of the mysteries of laziness that foldr is preferable to foldl, but scanl is preferable to scanr. |
| 08:16:05 | <dmwit> | They say the even the initiate must ponder this each time, before he recalls why. |
| 08:16:07 | <FunctorSalad_> | except where foldl' is preferable? :) |
| 08:16:27 | <dmwit> | Well, of course. ;-) |
| 08:16:45 | <dmwit> | But this temple is strictly lazy. |
| 08:17:03 | <Cale> | > map (take 5) . scanr (:) [] $ [1..] |
| 08:17:05 | <lambdabot> | [[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8],[5,6,7,8,9],[6,7,8,9,10],[... |
| 08:17:54 | <Cale> | Sometimes even scanr is nice :) |
| 08:18:19 | <PetRat> | dmwit: I've noticed that anything I "learned" today will probably be mysterious tomorrow. Certain exercises I've worked about four or five times now and I still have to ponder it. |
| 08:18:33 | <dmwit> | PetRat: It's normal, don't worry. |
| 08:18:35 | <PetRat> | Eventually will be second nature, though. |
| 08:18:46 | <dmwit> | After 40 or 50 times, you'll only think briefly. |
| 08:18:57 | <Cale> | > foldl (flip (:)) [] [1,2,3,4,5] |
| 08:18:59 | <lambdabot> | [5,4,3,2,1] |
| 08:19:00 | <dmwit> | And next year, you'll wonder what was so mysterious. =) |
| 08:19:38 | <Cale> | I think the diagram sort of makes clear why scanl is nice compared to foldl |
| 08:20:04 | <PetRat> | dmwit: That's the sense I get. This stuff fits together naturally. It only seems difficult to the imperative programmer because one has to go back to a very early stage of development. We forget how much work it took before imperative programming was second nature. |
| 08:20:39 | <dmwit> | One of those Google guys has a nice essay called "Learn Programming in Seven Years" that rants against the "Learn Programming in Seven Days" series of books. |
| 08:20:46 | <dmwit> | Norvig |
| 08:21:01 | <dmwit> | PetRat: Yes, exactly. |
| 08:21:50 | <Gracenotes> | it was 10 years, iirc |
| 08:22:19 | <PetRat> | An adult who has some kind of movement difficulties like pain, stiffness, balance problems, etc., can feel like they barely function. But look at a baby waving its arms and legs around, and the great accomplishment for a baby is bringing its fist to its mouth without a lot of wasted effort. We have come a long way. |
| 08:23:55 | <PetRat> | Yes it was learn programming in 10 years. If you go to borders, there are a slew of books called "Learn SQL in 24 hours," "Learn SQL in 10 days," maybe other variants. I forget the publisher but they have numerous titles like that. |
| 08:27:35 | <PetRat> | > id (5 *) 5 |
| 08:27:36 | <lambdabot> | 25 |
| 08:28:09 | <PetRat> | I like how initially "id (5 *) 5" looks wrong because id takes only one argument. |
| 08:30:45 | <shachaf> | PetRat: All functions take only one argument. |
| 08:31:12 | <shachaf> | Would you prefer "($) (5 *) 5"? |
| 08:33:43 | <tibbe> | any windows user out there that can verify that network-2.2.1.2 build (i.e. do "cabal update" followed by "cabal upgrade network")? |
| 08:36:43 | <Gracenotes> | PetRat: you might say (id (5*)) 5... |
| 08:37:07 | <Gracenotes> | > id id id id id id id id id id id id (*5) 5 |
| 08:37:08 | <lambdabot> | 25 |
| 08:37:48 | <Cale> | Anything which returns a result of an arbitrary type can appear to take an arbitrary number of parameters |
| 08:39:07 | <ziman> | :t const undefined 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
| 08:39:08 | <lambdabot> | forall t. t |
| 08:41:07 | <Cale> | > foldr (.) id [(*2),(+3),(*5)] 10 |
| 08:41:10 | <lambdabot> | 106 |
| 08:48:10 | <dibblego> | @src replicateM |
| 08:48:11 | <lambdabot> | replicateM n x = sequence (replicate n x) |
| 09:15:02 | <dibblego> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5099#a5099 where am I screwing up? |
| 09:18:42 | <doserj> | dibblego: value always succeeds without consuming input |
| 09:19:51 | <dibblego> | ah yeah I think I want \x -> satisfy(== x) |
| 09:19:57 | <dibblego> | thanks |
| 09:20:59 | <doserj> | that makes value and satisfy mutually recursive, though :) |
| 09:21:17 | <dibblego> | no, I won't change value |
| 09:21:40 | <dibblego> | I'm just not using the right function (I need another function with the same sig) |
| 09:21:46 | <doserj> | ah, ok |
| 11:04:06 | <nisse> | Hi all. |
| 11:04:28 | <nisse> | I've been studying Haskell for a while now. |
| 11:04:36 | <Tobsan> | great :) |
| 11:04:45 | <nisse> | I'm in a point where I start to understand laziness and the typesystem |
| 11:04:59 | <nisse> | and the purity :) |
| 11:06:01 | <PeakerWork> | nisse: after understanding it, I had trouble seeing what I had trouble understanding :-) |
| 11:06:03 | <PeakerWork> | Its so simple :) |
| 11:06:19 | <nisse> | And I've started to realize that Haskell is _really_ different language than "traditional" languages |
| 11:06:33 | <nisse> | (algol based) |
| 11:06:45 | <tetha> | you can use Monoid in a sensible way in a program... that certainly is different :) |
| 11:06:55 | <PeakerWork> | Laziness does not run as deep into my brain as other stuff, now I just see it as an implicit memoizing lambda around everything :() |
| 11:07:45 | <nisse> | The more I understand the Haskell philosophy the more I realize that other languages are just ... wrong |
| 11:08:23 | <tetha> | I would not call it wrong, I would call it simpler |
| 11:08:55 | <dibblego> | I call it wrong and excessively complex and not simple enough |
| 11:09:09 | <nisse> | tetha: Well like comparing JS to Basic. |
| 11:09:18 | <nisse> | dibblego: ! |
| 11:09:39 | <tetha> | dibblego: hm. yes, you are right, simple and difficult are the wrong terms, even though I do not know better terms |
| 11:09:56 | <dibblego> | nisse, yes? I compounded your statement with conjunction, I hope you don't mind |
| 11:09:58 | <PeakerWork> | tetha: what's simpler, other languages? |
| 11:10:17 | <nisse> | dibblego: You said what I was trying to say :) |
| 11:10:27 | <tetha> | PeakerWork: I would argue that "just using a string" instead of thinking of monoids requires a smaller initial brain effort |
| 11:10:30 | <nisse> | dibblego: Kinda like crystallized |
| 11:10:45 | <tetha> | PeakerWork: certainly, once you understood everything, monoids are simpler and much more flexible |
| 11:11:40 | <nisse> | So is there some area of computing where Haskell is less practical than some strict language? |
| 11:11:52 | <IntergalacticOwl> | The initial effort barrier is a problem for average programmers though. |
| 11:12:11 | <tetha> | IntergalacticOwl: that is my point :) |
| 11:13:03 | <dibblego> | nisse, it is not about lazy language versus strict -- it is about which is the default -- for the general case, lazy is the correct default |
| 11:13:36 | <nisse> | dibblego: well, the in some langs the laziness is kind of hidden |
| 11:13:47 | <IntergalacticOwl> | I can't say too much since I'm still learning Haskell, but I do not think that I would even be able to start explaining it to anyone I know irl. |
| 11:14:25 | <Botje> | it's easier to express what you want to do |
| 11:14:33 | <Botje> | without all that mucking around with iterators or indexes |
| 11:16:49 | <nisse> | dibblego: Haskell seems to be too good to be true. |
| 11:17:06 | <nisse> | dibblego: Is there some horrible catch that I've perhaps missed? |
| 11:17:18 | <dibblego> | not really |
| 11:17:44 | <IntergalacticOwl> | It is in general pretty amazing so far |
| 11:18:42 | <IntergalacticOwl> | Maybe one of the catches is convincing your employer to let you use it for work though |
| 11:19:23 | <thirsteh> | and that's probably gonna be harder than learning the language :-) |
| 11:19:28 | <thirsteh> | for now... |
| 11:20:41 | <IntergalacticOwl> | Last I was employed, I had to learn Visual Basic .NET on the job, haha |
| 11:21:34 | <solrize> | the main catches seem to be space leaks, and the complexity of nesting monads |
| 11:22:20 | <zachk> | and cabal doesnt work so great on windows haskell |
| 11:22:33 | <zachk> | but frag does compile and run |
| 11:22:40 | <Baughn> | Nah, that's a catch with windows, not with haskell |
| 11:23:10 | <ivanm> | what does the new LHC do? |
| 11:23:13 | <nisse> | solrize: can you elaborate? |
| 11:23:16 | <ray> | a catch with haskell is similar to one that many language communities have |
| 11:23:22 | <ray> | they're too attached to UNIAX ;) |
| 11:23:30 | <Baughn> | ivanm: ..LHC? Not the collider? |
| 11:23:34 | <ivanm> | ray: *shrug* I have no problem with that ;-) |
| 11:23:41 | <ivanm> | Baughn: no, Lemmih's LHC |
| 11:23:42 | <ivanm> | ;-) |
| 11:23:55 | <ray> | well, it's not so bad with haskell |
| 11:23:58 | <ray> | avoid success and all |
| 11:24:20 | <ray> | large haskell collider |
| 11:24:25 | <IntergalacticOwl> | I've been having trouble getting Cabal to work on debian, actually. Bootstrap.sh ate all my memory linking something and then hours later, spat out errors. |
| 11:24:33 | <ray> | that's what monad transformers use under the hood |
| 11:24:50 | <ray> | if it's debian, maybe you're missing key libraries |
| 11:25:36 | <ray> | you might have to install more of the packages with names like libghc6-*-dev |
| 11:27:14 | <IntergalacticOwl> | I made sure I had network and parsec |
| 11:28:25 | <ivanm> | IntergalacticOwl: are you talking about Cabal or Cabal-Install? |
| 11:28:41 | <ivanm> | ACTION notices dcoutts conveniently left when questions about Cabal came up... >_> |
| 11:28:57 | <IntergalacticOwl> | cabal-install sorry |
| 11:32:49 | <Saizan> | IntergalacticOwl: long linking times are not unknown for ghc |
| 11:33:05 | <IntergalacticOwl> | I see |
| 11:34:04 | <Baughn> | IntergalacticOwl: Shouldn't be /that/ long, but if you're running out of memory.. |
| 11:34:19 | <Saizan> | depends on how much memory you have, i guess |
| 11:35:46 | <Baughn> | Mm. If I'm reading this right, linking GHC takes about 2GB. |
| 11:36:28 | <Saizan> | he's linking cabal-install though |
| 11:37:03 | <PeakerWork> | ACTION finally understood why djinn is a theorem prover :) |
| 11:37:21 | <mux> | does hackage use "cabal haddock" to generate the documentation? |
| 11:37:22 | <PeakerWork> | it could be awesome to have background @djinn'ing in my code editor that proves my code using some heuristics while I edit it |
| 11:39:30 | <ivanm> | mux: not sure if hackage uses cabal-install |
| 11:39:47 | <ivanm> | but it would be using cabal-the-library most probably in some way to call haddock |
| 11:41:14 | <mux> | I'm looking for some C macro that I could use to know this is haddock generating documentation so that I can avoid having some code #ifdef'ed out |
| 11:42:14 | <Saizan> | since 2.0 haddock doesn't define anything like that |
| 11:42:16 | <mux> | ACTION reads Distribution/Simple/PreProcess.hs |
| 11:42:37 | <ivanm> | Saizan: yes it does |
| 11:42:45 | <ivanm> | I just saw it in the haddock docs the other day |
| 11:43:07 | <ivanm> | mux: somewhere around here: http://www.haskell.org/haddock/doc/html/module-attributes.html |
| 11:43:09 | <Saizan> | the documentation might be outdated |
| 11:44:02 | <mux> | I don't see anything with those attributes that could help |
| 11:44:06 | <Saizan> | Haddock does not |
| 11:44:08 | <Saizan> | define any cpp macros at all (unless GHC defines any by default). |
| 11:44:20 | <mux> | that would be Cabal's job anyways |
| 11:44:24 | <Saizan> | in an email from haddock's maintainer :) |
| 11:44:32 | <mux> | it's cabal that does the preprocessing |
| 11:45:23 | <Saizan> | mux: that's not entirely true in practice |
| 11:45:45 | <mux> | indeed, I know see that the preprocessors are passed to preprocessModule |
| 11:45:50 | <ivanm> | Saizan: ahhh, I missed that mux wanted it to be CPP |
| 11:46:13 | <mux> | not really CPP, but this is a .hsc file so it has CPP macros too |
| 11:47:11 | <Saizan> | unless you've CPP in the extensions there won't be a separate cpp pass |
| 11:47:27 | <mux> | I mean that hs2c does that |
| 12:17:08 | <jeff_s_> | when I "import Data.ByteString.Char8 as B" and I call an unqualified function like "getContents", it's annoying that ghc warns me about a conflict between Prelude and ...Char8. Is there a way I can import something like BytesString but not have to prefix every Prelude function with "Prelude"? |
| 12:17:37 | <Baughn> | jeff_s_: import Prelude hiding (foo,bar) |
| 12:17:58 | <Baughn> | jeff_s_: Or, do you mean having both getContents imported at the same time? |
| 12:18:19 | <Baughn> | ..that would be what typeclasses are for. We could probably use more of them. |
| 12:18:27 | <jeff_s_> | I want to be able to write ByteString.getContents and getContents, where the unqualified name is Prelude |
| 12:18:55 | <Baughn> | jeff_s_: So, import qualified Data.ByteString.Char8 as ByteString? |
| 12:19:08 | <jeff_s_> | Maybe I'm missing some haskell style though. What I'm looking for is waht I'm used to from ML. |
| 12:19:26 | <jeff_s_> | I imported it qualified but I get the same problem :\ |
| 12:19:50 | <jeff_s_> | Ambiguous occurrence `tail' |
| 12:19:51 | <jeff_s_> | It could refer to either `Prelude.tail', imported from Prelude |
| 12:19:51 | <jeff_s_> | or `B.tail', imported from Data.ByteString.Char8 at 2. |
| 12:20:14 | <Baughn> | jeff_s_: What's you r/exact/ import line? |
| 12:20:21 | <doserj> | jeff_s_: there is a difference between "import M as B" and "import qualified M as B" |
| 12:20:27 | <jeff_s_> | OH |
| 12:20:30 | <jeff_s_> | duh, thanks |
| 12:21:20 | <jeff_s_> | ok ya, that was exactly what I wanted. Thanks! |
| 12:23:54 | <ivanm> | doserj: is there any time where import unqualified with an alias is useful? |
| 12:24:11 | <Baughn> | jeff_s_: You can also have multiple import lines, eg. to import type names unqualified |
| 12:25:38 | <doserj> | ivanm: I don't think I ever used that |
| 12:26:16 | <ivanm> | I wonder if there is ever use for it |
| 12:26:26 | <Baughn> | I've never seen it used anywhere |
| 12:26:42 | <ivanm> | unless you have only one or two clashes, and can't be bothered doing P.blah for all functions, whereas you can do so for those that _do_ clash |
| 12:35:58 | <saml> | data (->) a b -- how should i understand this? |
| 12:36:02 | <saml> | > 1 -> 2 |
| 12:36:05 | <lambdabot> | <no location info>: parse error on input `->' |
| 12:36:20 | <Saizan> | (->) is a type constructor there |
| 12:36:56 | <saml> | ah i think i get it now |
| 12:37:00 | <athos> | @type a >- b |
| 12:37:01 | <lambdabot> | Not in scope: `>-' |
| 12:37:04 | <athos> | @type a -> b |
| 12:37:05 | <lambdabot> | parse error on input `->' |
| 12:37:13 | <saml> | @kind (->) |
| 12:37:15 | <lambdabot> | ?? -> ? -> * |
| 12:37:17 | <athos> | :) |
| 12:39:57 | <saml> | > (succ >>> succ) 0 |
| 12:39:59 | <lambdabot> | 2 |
| 12:40:28 | <tombom> | @kind (>>>) |
| 12:40:29 | <lambdabot> | Not in scope: type variable `>>>' |
| 12:40:46 | <tombom> | @type (>>>) |
| 12:40:47 | <lambdabot> | forall (a :: * -> * -> *) b c d. (Arrow a) => a b c -> a c d -> a b d |
| 12:41:11 | <saml> | A class for categories. id and (.) must form a monoid. |
| 12:41:26 | <saml> | wtf is monid |
| 12:43:09 | <EvilTerran> | a monoid is a set with an associative binary operation, and an element that is a left- and right-identity element of that operation |
| 12:43:32 | <EvilTerran> | ish. |
| 12:43:32 | <MyCatVerbs> | saml: a Monoid is a type that you can glue two of them together (mappend), and for which there is an identity element (mempty). |
| 12:44:01 | <MyCatVerbs> | EvilTerran: please don't tack "ish" onto correct definitions. It makes people nervous. ;P |
| 12:44:17 | <Botje> | they should be! |
| 12:44:43 | <ivanm> | EvilTerran: "operationish"? |
| 12:44:45 | <athos> | > [1] `mappend` [2] |
| 12:44:46 | <EvilTerran> | MyCatVerbs, it was to indicate my own non-confidence in the accuracy |
| 12:44:47 | <lambdabot> | [1,2] |
| 12:44:58 | <athos> | > [1] `mappend` mempty |
| 12:45:00 | <lambdabot> | [1] |
| 12:45:21 | <ivanm> | > mempty `mappend` mempty |
| 12:45:22 | <ivanm> | ;-) |
| 12:45:22 | <lambdabot> | () |
| 12:45:25 | <MyCatVerbs> | EvilTerran: oh, well. *checks*. Yes, you were correct. |
| 12:45:29 | <ivanm> | :o it has a default instance? :o |
| 12:45:38 | <ivanm> | @type mempty `mappend` mempty |
| 12:45:39 | <lambdabot> | forall a. (Monoid a) => a |
| 12:45:46 | <saml> | ., >>>, mappend.. they sound all similar |
| 12:45:50 | <ivanm> | why did lambdabot default to ()? |
| 12:45:54 | <ivanm> | @type (>>>) |
| 12:45:55 | <lambdabot> | forall (a :: * -> * -> *) b c d. (Arrow a) => a b c -> a c d -> a b d |
| 12:46:04 | <MyCatVerbs> | ivanm: No. () is an instance of Monoid. So if you don't give any type whatsoever beyond (Monoid m, Show m), then the type inferrer may guess (). |
| 12:46:09 | <ivanm> | saml: >>> uses different types |
| 12:46:22 | <ivanm> | MyCatVerbs: yes, but I was wondering why lambdabot defaulted to it rather than complaining |
| 12:46:25 | <saml> | can we unify all of those composition stuff? |
| 12:46:35 | <ivanm> | AFAIK, only Integral and Floating have default type |
| 12:46:37 | <ivanm> | *types |
| 12:46:41 | <Saizan> | saml: a Category is a parametrized Monoid, roughly |
| 12:46:43 | <ivanm> | saml: see the Typeclassopedia |
| 12:46:47 | <EvilTerran> | ivanm, extended defaulting is a ghc extension |
| 12:46:55 | <Saizan> | saml: so it's expected :) |
| 12:46:55 | <ivanm> | Saizan: and a Monad is a Monoid in the Category of Endofunctors? |
| 12:46:57 | <ivanm> | ;-) |
| 12:46:58 | <marcot> | What should I use to generate a .cabal file? Is there a library like haskell-src for Cabal? |
| 12:47:01 | <ivanm> | EvilTerran: ahhh |
| 12:47:02 | <MyCatVerbs> | ivanm: *checks*, GHCi does too. |
| 12:47:04 | <EvilTerran> | @check \x y -> x == y -- all things are equal! |
| 12:47:05 | <lambdabot> | "OK, passed 500 tests." |
| 12:47:07 | <ivanm> | that I didn't know about |
| 12:47:11 | <Botje> | marcot: mkcabal |
| 12:47:14 | <Saizan> | ivanm: sure, what's funny about that? |
| 12:47:18 | <ivanm> | Botje: it's dead |
| 12:47:22 | <Botje> | uh? |
| 12:47:23 | <ivanm> | and doesn't build with new ghc, etc. :( |
| 12:47:31 | <Botje> | oh |
| 12:47:35 | <ivanm> | Botje: mkcabal is dead, dons told me he wasn't working on it anymore |
| 12:47:43 | <Botje> | i used mkcabal for my thesis and it worked fine |
| 12:47:45 | <MyCatVerbs> | I thought everybody just copied someone else's cabal file and altered it? |
| 12:47:46 | <ivanm> | Saizan: didn't you read that blog post? |
| 12:47:47 | <Botje> | but that was 6.8 |
| 12:48:00 | <ivanm> | Botje: yeah, doesn't like new exceptions IIRC |
| 12:48:20 | <marcot> | I don't have a problem about generating it, I just want a library to makes thing easier if there is one already. |
| 12:48:42 | <marcot> | So I could generate a Tree instead of a String. |
| 12:49:02 | <ivanm> | marcot: ummm... what does a Tree have anything to do with a .cabal file? |
| 12:49:03 | <Saizan> | Cabal has functions for parsing and prettyprinting it |
| 12:49:08 | <yaxu> | ACTION gets his new haskell music thingie working |
| 12:49:22 | <yaxu> | ready for a gig in the science museum tonight.. |
| 12:49:31 | <Saizan> | look for PackageDescription, or maybe GenericPackageDescription |
| 12:49:39 | <marcot> | Saizan: ok, thanks, I'll take a look. |
| 12:49:49 | <marcot> | Saizan: I was in doubt about so many Cabal types.. |
| 12:50:07 | <ivanm> | is there a default function I can use to check if a character is within A-Za-z0-9+_.-] ? |
| 12:50:19 | <ivanm> | or just use isAlpha + checks for the four characters? |
| 12:50:19 | <Saizan> | marcot: there's a small guide to cabal's codebase on the trac wiki |
| 12:50:25 | <ivanm> | s/characters/symbols/ |
| 12:50:34 | <ivanm> | (that square bracket shouldn't be there) |
| 12:50:35 | <EvilTerran> | ivanm, i'd use isAlpha and `elem` |
| 12:50:50 | <ivanm> | EvilTerran: elem rather than explicitly doing so? |
| 12:51:08 | <EvilTerran> | \c -> isAlpha c || c `elem` "+_.-" |
| 12:51:14 | <ivanm> | *nod* |
| 12:51:27 | <EvilTerran> | snappier than writing it out explicitly |
| 12:51:30 | <ivanm> | does ghc unroll static elems? |
| 12:52:06 | <marcot> | Saizan: good to know, I'm reading it. Thanks. |
| 12:52:16 | <marcot> | ivanm: The Tree is the parsed file. |
| 12:52:16 | <EvilTerran> | ivanm, oy, no premature optimisation! :P |
| 12:52:41 | <ivanm> | EvilTerran: heh |
| 12:53:04 | <ivanm> | marcot: ummmm.... you're trying to programmatically generate the .cabal file? |
| 12:53:09 | <ivanm> | I still don't see how it's a tree... |
| 12:53:48 | <marcot> | marcot: Yes. Maybe not a Tree, but a Map. |
| 12:53:57 | <ivanm> | marcot: stop talking to yourself! :p |
| 12:54:06 | <ivanm> | but a Map would make more sense than a Tree |
| 12:54:27 | <marcot> | ivanm: in that context it made sense to talk to my self... =P |
| 12:54:32 | <ivanm> | heh |
| 12:54:41 | <ivanm> | that's the first sign of madness, you know... |
| 13:00:26 | <xian> | I am going through the tcopedia right now and I was trying to come up with an instance declaration of Pointed for ((->) e). What I've got now is pure y = \x -> y Is this correct? |
| 13:02:19 | <BONUS> | yeah |
| 13:02:36 | <saml> | it is. . . well, I'll let you work it out. (Just follow the types!) |
| 13:03:22 | <BONUS> | yeah for any of those (functor, pointed, applicative, monad) just write out what the type would be for the particular instance |
| 13:03:27 | <BONUS> | and then it's pretty easy to implement it |
| 13:12:06 | <ivanm> | is there any "simple" way I can implement the following rule to implement a "parsing" function (or type "ReadS String") ? |
| 13:12:18 | <ivanm> | "A package name may contain any of the characters [A-Za-z0-9+_-]. It must not begin with a hyphen, and must not end in a hyphen followed by one or more digits." |
| 13:12:52 | <mlysgaard> | ivan Regexp? |
| 13:12:57 | <ivanm> | in particular, I'm not sure how to do the not-ending-in-hyphen-followed-via-digits bit |
| 13:13:03 | <ivanm> | mlysgaard: I'd rather not |
| 13:13:56 | <ivanm> | trying to keep the deps to a minimum |
| 13:14:31 | <mlysgaard> | ivanm: Explain to me what you wan't to parse once again? An example |
| 13:14:39 | <ivanm> | exactly what that rule says |
| 13:15:22 | <Berengal> | State machine? |
| 13:15:37 | <ivanm> | ummm... what? |
| 13:15:47 | <ivanm> | I'm after simple String stuff if possible ;-) |
| 13:16:21 | <ivanm> | ACTION could just parse it without that final constraint and then reverse it and remove the final digits, etc. ... |
| 13:16:23 | <Berengal> | A bunch of mutually recursive functions, each representing a state in a state machine, and each state parsing a single char or accepting |
| 13:16:52 | <Berengal> | But that's just regexps without the library |
| 13:17:07 | <ivanm> | *nod* |
| 13:17:16 | <MyCatVerbs> | Berengal: no, that's LL(1) without the library. :) |
| 13:17:52 | <Berengal> | MyCatVerbs: Details :P |
| 13:18:17 | <EvilTerran> | ivanm, i'd be inclined to use parsec, tbh |
| 13:18:25 | <ivanm> | hmmmm.... I might just keep applying break (== '-'), and dropping the rest if it's an integer |
| 13:18:28 | <ivanm> | EvilTerran: no deps |
| 13:18:36 | <ivanm> | *I don't want to have any other deps |
| 13:19:44 | <mlysgaard> | ivanm: What you wan't to do is to get a pacage name from a package, like: "gnome-20.0219e0.02" would become "gnome"? |
| 13:19:47 | <MyCatVerbs> | Berengal: well, not *quite*, you need to carry more state than that, but yes you can implement an LR(1) or LL(1) using a big bouncy pile of continuations to represent the parsing tables. |
| 13:19:49 | <FunctorSal> | ivanm: not ( last ( group ( map isDigit str ) ) && last ( last ( group ( map (=='-') ) ) ) ) |
| 13:19:53 | <FunctorSal> | ;o |
| 13:19:59 | <ivanm> | mlysgaard: no, in this case it would be the whole thing |
| 13:20:06 | <ivanm> | FunctorSal: :o |
| 13:20:14 | <ivanm> | ACTION tries to work out wtf that does |
| 13:20:19 | <FunctorSal> | > group ( map isDigit "fooo!!99a1" ) |
| 13:20:20 | <lambdabot> | [[False,False,False,False,False,False],[True,True],[False],[True]] |
| 13:20:25 | <ivanm> | mlysgaard: since the 'e' there makes it legit |
| 13:20:33 | <FunctorSal> | hmm, still need to collapse the groups |
| 13:21:31 | <FunctorSal> | ivanm: also, isAlphaNum from Data.Char |
| 13:21:40 | <ivanm> | yeah |
| 13:21:42 | <mlysgaard> | ivanm: Ok, but if it's "gnome-2.10.14892" would be parsed "gnome"? |
| 13:22:03 | <FunctorSal> | let legal c = isAlphaNum c || elem c "+_-" in all legal str |
| 13:22:29 | <ivanm> | mlysgaard: well, '.' isn't allowed, so it wouldn't include anything after the . |
| 13:22:30 | <ivanm> | but yes |
| 13:22:34 | <FunctorSal> | of course peformance won't be greatt |
| 13:22:44 | <ivanm> | FunctorSal: yeah, I've got that |
| 13:22:45 | <MyCatVerbs> | legal = liftM2 (||) isAlphaNum (flip elem "+_-") |
| 13:23:01 | <ivanm> | it's making sure it doesn't end in "-<number>" that's the problem |
| 13:23:21 | <doserj> | > not . all isDigit . fst . break (=='-') . reverse $ "blah-2" |
| 13:23:23 | <lambdabot> | False |
| 13:23:47 | <FunctorSal> | :o |
| 13:24:05 | <ivanm> | bugger... I'm parsing a bunch of different components; some things I'm allowed '.', others aren't :@ |
| 13:24:27 | <ivanm> | so I have to have two seperate Char -> Bool functions, one which allowes '.' and the other which doesn't |
| 13:26:07 | <mlysgaard> | By the way, what's the options in graphical toolkits when working in haskell? |
| 13:26:25 | <ivanm> | gtk2hs, wxhaskell |
| 13:26:37 | <ivanm> | there's qt bindings, but haven't heard much about them in a while |
| 13:26:43 | <ray> | opengl, for a wider definition of "graphical toolkits" than the one you probably mean |
| 13:29:50 | <mlysgaard> | Hmm, well, I'd like to draw mathematical expressions, and edit them in real time. Quite unusual. |
| 13:30:11 | <mauke> | oh, a text editor? |
| 13:30:17 | <FunctorSal> | ftgl? ;) |
| 13:30:47 | <FunctorSal> | would be a bit of a pain to do subscripts etc. manually though |
| 13:30:52 | <mlysgaard> | Well, it would need to support all kinds of strange math symbols |
| 13:31:07 | <FunctorSal> | more than are in unicode? |
| 13:31:33 | <mlysgaard> | No, i think unicode would work |
| 13:31:53 | <FunctorSal> | (table 33 and 34) |
| 13:31:56 | <EvilTerran> | mlysgaard, ah, that's really not that unusual. i think most maths/compsci students want that :) |
| 13:31:57 | <mlysgaard> | but arbitrary sub/superscript |
| 13:32:13 | <mlysgaard> | Hehe ;) |
| 13:32:38 | <EvilTerran> | ACTION does, anyway |
| 13:32:52 | <FunctorSal> | mlysgaard, are you trying to make an editor that has some (possibly incomplete) understanding of semantics? |
| 13:33:25 | <ivanm> | mlysgaard: auctex + previewlatex ;-) |
| 13:33:30 | <EvilTerran> | ACTION would take it further, into full-blown shiney-graphics proof-assistant territory |
| 13:33:44 | <ivanm> | EvilTerran: "shiny"? |
| 13:33:53 | <mlysgaard> | Well, yeah. I wold like to make an editor that could edit symbolic expressions in real time. Looking like latex formulas |
| 13:34:13 | <FunctorSal> | EvilTerran: believe it or not, I've started some 3d commutative diagrams thing with specular arrows ;o |
| 13:34:28 | <ivanm> | whizzytex IIRC has something like this (though it's more like it draws the preview in real time) |
| 13:35:02 | <Saizan> | and bidirectional conversion between diagrams and equations for CT |
| 13:35:11 | <EvilTerran> | FunctorSal, ooo |
| 13:35:46 | <FunctorSal> | I'm not sure what to use as underlying logic though :-( |
| 13:36:13 | <FunctorSal> | writing a complete logic toolkit with unification and stuff from scratch seems a bit daunting |
| 13:36:37 | <EvilTerran> | it is, i've tried =/ |
| 13:38:19 | <FunctorSal> | maybe the first-order theory of the category of sets would be a fitting foundation |
| 13:38:47 | <mlysgaard> | Well, what my goal is to make some sort of digital mathematical blackboard. Anyone tried the HP 40gs calculators they have this function |
| 13:41:03 | <jbauman> | mlysgaard, a CAS like mathematica? |
| 13:42:57 | <mlysgaard> | Well, im just a high scool student so i'm just fooling around. Made some symbolic math types and some simple simplify functions and i'd like to make a good interface to it. |
| 13:43:20 | <mlysgaard> | jbauman: But in a essence a CAS, just wery simple |
| 13:48:59 | <wli> | I got burned trying to de-nest radical expressions. |
| 13:49:23 | <wli> | The polynomial factorization methods turned out to be beyond my power. |
| 13:50:18 | <jacobian> | Is it correct to say that inf=inr(inf) is the limit point of the monad nu X . 1 + X |
| 13:51:11 | <wli> | I never got far enough to try to compute integral bases for radical extension rings. |
| 13:52:54 | <marcot> | @hoogle String -> ReadP a -> a |
| 13:52:55 | <lambdabot> | Did you mean: String -> ReadP a a -> a /count=20 |
| 13:52:55 | <lambdabot> | Debug.Trace trace :: String -> a -> a |
| 13:52:55 | <lambdabot> | Distribution.ParseUtils field :: String -> (a -> Doc) -> ReadP a a -> FieldDescr a |
| 13:53:22 | <EvilTerran> | ACTION feebly pokes at the sizable write-up he really needs to get done |
| 13:53:25 | <marcot> | How can I get the parsed result of a ReadP? Do I have to convert it to ReadS? |
| 13:53:41 | <EvilTerran> | marcot, i believe that's whatthe docs suggest, yeah |
| 13:53:53 | <marcot> | EvilTerran: ok, thanks. |
| 13:54:21 | <EvilTerran> | "Converts a parser into a Haskell ReadS-style function. This is the main way in which you can "run" a ReadP parser: the expanded type is readP_to_S :: ReadP a -> String -> [(a,String)]" |
| 13:56:32 | <sayyestolife> | hello |
| 13:56:47 | <sayyestolife> | Isn't there some site for haskell "snippets"? |
| 13:57:14 | <EvilTerran> | hpaste.org ? |
| 13:57:35 | <FunctorSal> | I can make a substitution idempotent by composing it with itself until it becomes stable, right? |
| 13:58:06 | <FunctorSal> | (premature optimization be damned ;)) |
| 13:58:15 | <sayyestolife> | EvilTerran I'm thinking more in the terms of http://www.djangosnippets.org, where only "useful" stuff gets posted |
| 13:58:26 | <sayyestolife> | not some temporary paste |
| 13:58:52 | <EvilTerran> | oh right |
| 13:59:01 | <doserj> | *cough* useful snippets end up on hackage *cough* |
| 13:59:18 | <EvilTerran> | i think the norm is to write a blog post and link it on reddit |
| 13:59:36 | <sayyestolife> | EvilTerran hmm.. okay |
| 14:00:01 | <sayyestolife> | but I'm thinking about something more like almost wikilike |
| 14:00:18 | <EvilTerran> | i don't think that particular niche has been filled yet |
| 14:00:35 | <EvilTerran> | although some of the haskellwiki pages are effectively useful code snippets |
| 14:08:09 | <sayyestolife> | EvilTerran okay thanks! |
| 14:22:01 | <tibbe> | I was playing around with the Haddock CSS a bit: http://johantibell.com/haddock.png (design stolen from all over the place) |
| 14:26:52 | <xian> | Is there any easy way to overwrite instance declarations in case ghc is complaining that there is more than one for a specific type? (I'm playing around with typeclasses at the moment, so I get this quite often) |
| 14:28:32 | <EvilTerran> | xian, instances are global, unfortunately; it's a limitation of the typesystem |
| 14:29:05 | <EvilTerran> | the semantics would have to be changed substantially to allow local instances, as i understand it |
| 14:29:17 | <EvilTerran> | xian, although you could write your instances for a newtype-wrapped version of the type |
| 14:29:56 | <xian> | Yeah, that seems like a good idea. But I couldn't use functions defined on the original type then, could I? |
| 14:30:23 | <EvilTerran> | "newtype MyInt = MyI Int deriving (<whatever classes you want derived>); instance Ord MyInt where ...", say |
| 14:30:45 | <EvilTerran> | xian, well, you could use the deriving mechanism to get instances of Eq, Ord, Read, Show etc for free, |
| 14:34:01 | <Philonous> | Concurrent programming in haskell really is fun, (at least compared to C or Java). Maybe that should be emphasised when advertising haskell. |
| 14:34:15 | <xian> | What I mean is that in the above case I couldn't call functions defined specifically on Int even though MyInt is basically the same as Int. |
| 14:35:53 | <EvilTerran> | xian, yeah, you'd have to add/remove the newtype's constructor if you wanted to do that |
| 14:36:21 | <Jedai> | xian: No you couldn't, on the other hand if you want to use your type exactly like an Int except on some very rare occasion, maybe you should just create some new functions rather than try to modify the current ones |
| 14:36:55 | <ray> | generalized newtype deriving would let you get instances of anything the actual type's an instance of for free |
| 14:37:10 | <Jedai> | xian: also one thing that is useful on newtypes is that you can "derive" any typeclass that was instancied for the original type, even the one that can't be derived usually |
| 14:37:12 | <EvilTerran> | ray, but you'd still be stuck on functions that aren't class methods |
| 14:37:28 | <ray> | yeah, functions that aren't class methods are such a pain |
| 14:37:40 | <ray> | general types ftw |
| 14:37:48 | <Fred320> | @pl \x z -> x ++ y:z |
| 14:37:49 | <lambdabot> | (. (y :)) . (++) |
| 14:38:09 | <ray> | also, polymorphic functions, not just methods |
| 14:39:19 | <EvilTerran> | true, i meant classwise polymorphic functions |
| 14:43:53 | <CalJohn> | I'm starting a new project, but Setup insists that the dependancy bencode is missing, but I am sure it is installed |
| 14:44:06 | <CalJohn> | do i need to add .cabal to the path or something? |
| 14:44:58 | <mauke> | no, you need to list your dependencies in your cabal file |
| 14:45:12 | <mauke> | wait, hmm |
| 14:45:19 | <mauke> | what's the exact error message? |
| 14:45:25 | <ksf> | quite OT, but can someone point me to a good book leading up to SICM? |
| 14:46:39 | <CalJohn> | mauke: "at least the following dependancies are missing: bencode -any" |
| 14:46:53 | <CalJohn> | mauke: i have listed them in my cabal file |
| 14:47:00 | <mauke> | yes |
| 14:47:13 | <mauke> | what does 'ghc-pkg list bencode' say? |
| 14:47:13 | <lilac> | ksf: you mean SICP? |
| 14:47:14 | <lambdabot> | lilac: You have 3 new messages. '/msg lambdabot @messages' to read them. |
| 14:47:24 | <ksf> | nope, SICM. |
| 14:47:32 | <CalJohn> | lilac: no, the newish scheme book for classical mech |
| 14:47:32 | <ksf> | http://mitpress.mit.edu/SICM |
| 14:47:55 | <ksf> | ...if you need something leading up to SICM, you're in trouble. |
| 14:47:59 | <CalJohn> | mauke: /usr/lib/ghc-6.8.2/package.conf: |
| 14:48:00 | <CalJohn> | /home/cal/.ghc/i386-linux-6.8.2/package.conf: bencode-0.3 |
| 14:48:02 | <ksf> | s/sicm/sicp |
| 14:48:12 | <lilac> | damn you sussman! |
| 14:48:20 | <mauke> | CalJohn: try Setup configure --user |
| 14:48:37 | <CalJohn> | mauke: seems to work fine, why? |
| 14:48:46 | <doserj> | CalJohn: or just cabal install |
| 14:48:55 | <mauke> | you installed bencode as a user package |
| 14:49:07 | <mauke> | a system package can't depend on a user package |
| 14:49:19 | <mauke> | so you need to build your new project as a user package too |
| 14:49:49 | <CalJohn> | mauke: i see, thankyou |
| 14:56:57 | <ksf> | ACTION wonders why he spent years at school studying stuff that was already obsolete in 1750. |
| 14:57:15 | <mauke> | ... latin? |
| 14:57:26 | <ksf> | newtonian mechanics. |
| 14:57:49 | <p_l> | ksf: because for a big part of the time, they are good enough approximation? |
| 14:58:27 | <p_l> | ACTION thought that first lesson in physics was "if you can, approximate" |
| 14:58:45 | <ksf> | so I thought, but it figures that around 1750, better formalisms were introduced that capture the same range of phenomena, and those are the same formalisms that are used for relativity and quantum mechanics. |
| 14:59:20 | <p_l> | ksf: but are you going to use them while dealing with the same range as newtonian mechanics do? |
| 14:59:29 | <p_l> | as in "what is easier" |
| 15:00:22 | <ksf> | no idea, I was never able to figure out why my newtonian calculations were wrong, and don't grok lagrange yet. |
| 15:01:07 | <wli> | The calc of variations is big. |
| 15:01:26 | <EvilTerran> | and scary! |
| 15:02:28 | <p_l> | there are whole computationally heavy areas in physics/engineering that don't care about quantum mechanics or relativity, for the simple reason they deal with "relatively" low speeds in macroscale :) |
| 15:03:02 | <wli> | Yeah, Newtonian mechanics are by no means obsolete. |
| 15:04:22 | <p_l> | ACTION recalls how "HOWTO for ANSYS clusters, by scientist to scientist" noticed everyone "keep CFD guys out, they *always* eat all processing power, no matter how much there is" |
| 15:05:10 | <ksf> | tbh, I'm just attracted to the idea of just grokking a few lines of scheme to understand stuff, as opposed to figuring out the flaws in a particular incarnation of "standard notation". |
| 15:05:43 | <gwern> | ksf: you sound like the Structure & Interpretation of Classical Mechanics book :) |
| 15:06:00 | <ksf> | ACTION doesn't think it's the reader's job to sort the writer's thoughts. |
| 15:07:00 | <ksf> | ...or figure out arguments by abstract hand-waving. |
| 15:11:20 | <ksf> | ...according to wikipedia, lagrange gets rid of a lot of constraints you have to solve. |
| 15:11:53 | <wli> | Take the Lagrangian, Luke. |
| 15:14:24 | <Flugaren> | Does anyone here have any experience with HList? |
| 15:26:36 | <marcot> | Where can I get an example of TH [d| |]? |
| 15:28:58 | <EvilTerran> | , [d| len [] = 0; len (x:xs) = 1 + len xs |] |
| 15:28:59 | <lunabot> | FunD len [Clause [ConP [] []] (NormalB (LitE (IntegerL 0))) [],Clause [In... |
| 15:34:34 | <acieroid> | hi |
| 15:36:58 | <acieroid> | is there some function like System.getEnv, but for setting a env's variable ? |
| 15:37:15 | <marcot> | EvilTerran: but what should I so with it? I have f = [d| len [] = 0; len (x:xs) = 1 + len xs |]; f :: Language.Haskell.TH.Syntax.Q [Language.Haskell.TH.Syntax.Dec] . Now how can I use it? |
| 15:37:31 | <QtPlaty[HireMe]> | acieroid: You can't set an enviroment verable in the Posix model |
| 15:37:58 | <QtPlaty[HireMe]> | Well programs can't anyway. |
| 15:38:04 | <acieroid> | hmm |
| 15:38:19 | <acieroid> | how a shell can change variables so ? |
| 15:39:10 | <QtPlaty[HireMe]> | acieroid: The shell can change variables because the variables are part of the shell. The programs that are spawned by the shell can't change the enviroment vars of there perents. |
| 15:39:28 | <acieroid> | ok |
| 15:40:05 | <acieroid> | and, how the shell passes his environment to his child processes ? |
| 15:40:40 | <QtPlaty[HireMe]> | acieroid: Its an argument to the exec call it makes IIRC |
| 15:41:09 | <EvilTerran> | marcot, writing "$f" in a list of defintions would be the same as writing "len [] = 0; len (x:xs) = 1 + len xs" |
| 15:41:29 | <doserj> | acieroid: there is System.Posix.Env |
| 15:41:43 | <acieroid> | hmm, I'll look at that, thanks |
| 15:51:07 | <marcot> | EvilTerran: Where do I use a list of definitions? That's what I'm not understanding. |
| 15:51:32 | <EvilTerran> | marcot, the top-level of a module |
| 15:52:33 | <doserj> | or inside a let or where block |
| 15:52:45 | <EvilTerran> | marcot, if you want to use TH in where or let clauses, i'd suggest using [|...|] and writing "someName = $(...)", rather than including the "someName =" in a TH construction |
| 15:52:57 | <EvilTerran> | doserj, can you? lunabot doesn't seem to like it, at least |
| 15:53:20 | <marcot> | EvilTerran: My goal is to write a instance using TH. |
| 15:53:22 | <EvilTerran> | , let $([d| x = () |]) in () |
| 15:53:23 | <lunabot> | luna: parse error on input `in' |
| 15:53:57 | <doserj> | hmm |
| 15:54:26 | <EvilTerran> | doserj, [d|...|] includes data, instance, etc declerations, so doesn't strike me as appropriate for let/where clauses |
| 15:56:46 | <doserj> | true, [d|..|] only does top-level declarations, not arbitrary declarations |
| 15:57:44 | <EvilTerran> | ?where derive |
| 15:57:44 | <lambdabot> | http://www.cs.york.ac.uk/fp/darcs/derive |
| 16:01:52 | <Deewiant> | Gah, has anybody managed to compile Catch? |
| 16:04:37 | <TomMD> | Deewiant: I used catch a little back when it was new and Niel still worked on yhc. Haven't touched it since. |
| 16:05:20 | <TomMD> | Deewiant: It sounded like Neil did some initial work to bring Catch to GHC but hes time is all taken up by his day job now. |
| 16:05:24 | <TomMD> | @seen ndm |
| 16:05:25 | <lambdabot> | I haven't seen ndm. |
| 16:06:29 | <Deewiant> | Yes, I suppose I should have added "recently" to my query... I'm getting type errors in Catch's use of the Yhc core lib |
| 16:06:33 | <dons> | i'd love to see an analysis framework for ghc core |
| 16:06:40 | <dons> | so we can write catch and other things. |
| 16:06:49 | <dons> | i mean, they have CiL et al for C code. so why no lib for haskell analysis? |
| 16:06:50 | <Deewiant> | I don't mind the fact that it uses Yhc, compiling Yhc was the easy bit :-P |
| 16:06:59 | <pejo> | I think Neil was considering using external core output from GHC for Catch. But not sure how much time he has on his hands now with the daytime job. |
| 16:07:00 | <dons> | well, it makes it less useful for real code |
| 16:07:09 | <mauke> | preflex: seen ndm |
| 16:07:10 | <preflex> | ndm was last seen on #haskell 12 days, 5 hours, 50 minutes and 30 seconds ago, saying: plus with current compiler technology, it would be slower |
| 16:07:17 | <dons> | i'd just like a description of the analysis, so we could reimplement it |
| 16:07:49 | <Deewiant> | I'd just like these two programs by the same author to compile against each other :-P |
| 16:07:52 | <pejo> | dons, have you looked at the catch paper? |
| 16:08:03 | <dons> | TomMD: know much about separation logic? |
| 16:08:05 | <dons> | pejo: yes. |
| 16:08:26 | <pejo> | dons, didn't he describe the analysis there? |
| 16:08:53 | <dons> | I don't recall a formal description, but I might be wrong. |
| 16:09:23 | <dons> | I'm wary of the hand wavy use of the term "proof" around ad hoc analysis |
| 16:10:36 | <pejo> | dons, I think you need to assemble all the figures. |
| 16:10:59 | <dons> | yes, it looks like there's a fair bit of material now. much more than when I used catch on xmonad back in the day. |
| 16:11:02 | <pejo> | (Not making any claims about the proof, I'm guessing you want it mechanized). |
| 16:11:13 | <dons> | well, i just want to know what the underlying theory is. |
| 16:12:05 | <dons> | and a characterisation of what it finds, and what it won't, and why. |
| 16:12:20 | <pejo> | dons, what would the underlying theory be for "Assemble a bunch of constraints according to the semantics, and prove that you can't get a pattern mismatch"? |
| 16:12:24 | <dons> | of course, any static analysis that finds a bug we didn't spot is useful. |
| 16:13:09 | <dons> | pejo: so its some kind of symbolic interpretation? the code is evaluated, symbolically, yielding constraints on types, that are used to refine the types at pattern match time. |
| 16:13:13 | <mmorrow_> | dons: a standardized (external) "core" language (compiler-indep) for haskell would be awesome |
| 16:13:14 | <pejo> | dons, I've been thinking about characterisations for what Supero can remove, but it's far from trivial. Even if you accept pen and paper proofs. |
| 16:13:16 | <Deewiant> | So I take it nobody has any idea of the newest Yhc version that the latest Catch accepts? (Or, likewise, the newest Catch version that compiles against the latest Yhc) |
| 16:13:39 | <dons> | or is it a kind of type inference? |
| 16:14:16 | <mmorrow_> | there's a core-erlang pkg on hackage with a similar thing for that |
| 16:14:58 | <pejo> | dons, how many existing analyses do you know of that characterises what it can find and can't find, and prove it? |
| 16:15:40 | <dons> | pejo: i'm at a conference this week that's full of such things :) |
| 16:15:58 | <dons> | but yes, there's a scale in the static analysis world from formal stuff to ad hoc 'lint'-like tools |
| 16:16:00 | <mmorrow_> | links? |
| 16:16:05 | <dan> | does anyone know if there's a way to add a path to the search path where ghci looks for files to :load? |
| 16:16:17 | <mmorrow_> | dan: it's relative to your pwd |
| 16:16:20 | <pejo> | dons, small disclaimer: I'm in no way an expert on catch. I'd just like it to work for GHC. We know it's not complete, but I think it would be useful. |
| 16:16:22 | <dons> | mmorrow_: i'll dig around to see if something's online. |
| 16:16:28 | <dons> | pejo: agreed! |
| 16:16:41 | <dons> | it was very useful for xmonad. |
| 16:16:48 | <dons> | and we need more tools like this. |
| 16:16:54 | <mmorrow_> | dons: excellent |
| 16:16:57 | <dan> | mmorrow_: Is there anyway to make a relative import? |
| 16:17:06 | <pejo> | dons, the tools that people actually *use* are far closer to Lint than what the researchers are working on I think. |
| 16:17:06 | <dan> | import mysubdir/mymodule |
| 16:17:44 | <mmorrow_> | :m + Asdf.Qwerty.Jkl ====> ./Asdf/Qwerty/Jkl.hs |
| 16:17:57 | <mmorrow_> | err, sorry :l |
| 16:18:08 | <dons> | pejo: yep. |
| 16:18:20 | <pejo> | dons, (I know Galois does crazy stuff and proves stuff with Isabelle/HOL, but that's an exception, just like the Airbus stuff). |
| 16:18:45 | <dan> | i just don't know what is the correct way to set up a haskell workspace. Do I have to put all my modules which I am importing in a single dir?... |
| 16:19:32 | <dons> | pejo: right, but we are a community that should be precise when using words like 'proof' |
| 16:20:16 | <pejo> | dons, even as a community we disagree on what a proof means. Some want constuctive proofs, .. |
| 16:21:31 | <pejo> | dons, have to run. Let's get back to this later. I have a couple of more questions about your statements. ;) |
| 16:21:37 | <dons> | just stating what formal system is used to produce the proof, is all. if it is 'a haskell program that does some analysis' , that's fine. |
| 16:22:04 | <gwern> | maybe we could just agree that anything more rigorous than quickcheck is a proof |
| 16:22:06 | <marcot> | EvilTerran: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5100#a5100 |
| 16:22:32 | <dons> | gwern: no, there's clear notions of soundness and completeness. this is something we can be formal about. |
| 16:22:35 | <marcot> | EvilTerran: I still don't get how can I use Dec in TH. I'm searching about this, but I could not find any start point. |
| 16:23:06 | <paper_cc> | dan: If you don't use hierachical modules, then yes (except library modules - that are searched automatically). |
| 16:23:51 | <paper_cc> | marcot: you should define f in a different module, as it says |
| 16:25:31 | <marcot> | paper_cc: and how can I use the definition inside f in the module which imports it? |
| 16:26:01 | <marcot> | paper_cc: Do you know where can I find a use of Dec? |
| 16:26:17 | <paper_cc> | marcot: $f I think |
| 16:26:57 | <marcot> | paper_cc: ok, I think it worked. Why is there a restriction to use it in the same module? |
| 16:28:09 | <paper_cc> | marcot: it isn't only for Dec (also for quasiquoting). the reason for the restriction is that TH is a single-pass thing I think |
| 16:28:26 | <marcot> | paper_cc: ok.. Thanks. =) |
| 16:32:24 | <dan> | paper_cc: thank you |
| 16:34:06 | <paper_cc> | marcot: the deriveShow example at the very end of http://www.haskell.org/bz/thdoc.htm does generate declarations |
| 16:37:35 | <marcot> | paper_cc: Thanks, I haven't seen that. |
| 16:43:36 | <marcot> | Is there a way for a Cabal package to produces more than one library? |
| 16:44:24 | <tibbe__> | when can you actually sign up for icfp? |
| 16:48:51 | <PeakerWork> | are there SSL wrappers for Haskell? |
| 16:49:23 | <PeakerWork> | HsOpenSSL/hopenssl on hackage -- which do I choose, hmm |
| 16:52:10 | <dan> | is there a natural way to define types in haskell which have value limitations on them? Say, a list of ascending numbers? I don't want to give it a data constructor from just a list, because then i would have to throw some sort of exception if a mismatching list is given in the constructor |
| 16:52:31 | <ray> | tibbe__: at least one of the previous contests had you sign up by submitting your solution |
| 16:52:47 | <kpreid> | dan: no |
| 16:52:50 | <tibbe__> | ray: the conference, not the competition ;) |
| 16:53:01 | <ray> | there's a conference? |
| 16:53:03 | <ray> | :) |
| 16:53:03 | <augustss> | dan: not without dependent types |
| 16:53:07 | <kpreid> | dan: all you can do is write a type which does can't represent the values |
| 16:53:41 | <paper_cc> | ACTION is interested |
| 16:54:04 | <PeakerWork> | dan: hey :-) its called "subtypes", I believe, and Haskell doesn't have them directly. But you can use a representation of your own which can only be interpreted in correct ways.. For example, use a list of positive integers (Word8, for example) and have each represent the delta rather than the value |
| 16:54:05 | <paper_cc> | augustuss: what can one do with TypeFamilies? |
| 16:54:26 | <burp_> | is there some environment variable or other easy way for additional library paths ghc(i) should use? |
| 16:54:29 | <paper_cc> | s/augustuss/augustss/, sorry |
| 16:54:46 | <burp_> | so I don't have to type ghci -lgsl -latlas -lcblas -llapack -lf77blas -L./mylocallibs/lib |
| 16:55:38 | <dan> | PeakerWork: Interesting... |
| 16:55:41 | <augustss> | paper_cc: not in a general way |
| 16:55:42 | <mmorrow_> | alias ghci1337='.....' |
| 16:56:11 | <mmorrow_> | GHCILEET='...'; $GHCILEET |
| 16:56:39 | <dan> | how about if i want a list of unique values? |
| 16:56:43 | <dan> | as a type |
| 16:56:58 | <mauke> | Set |
| 17:00:36 | <dan> | how about if i want a list of 2-tuples, where the fst values are all unique (equal to their own Set), with no limitation on the snd values? is there any way to make a data type for that list in a way that doesn't let anyone construct a malformed one? |
| 17:00:53 | <lilac> | Data.Map? |
| 17:01:13 | <lilac> | basically, these restrictions are enforced by construction in haskell |
| 17:01:30 | <lilac> | you define an abstract data type and only provide operations which maintain whichever invariant you want |
| 17:02:35 | <bo0ts__> | Hi, noob question: I use $ ghci 2>&1 | HsColour -tty for coloured output in ghci put I always gets the linebreaks wrong which is quite annoying. |
| 17:02:42 | <bo0ts__> | Is there any workaround? |
| 17:02:47 | <dan> | Data.Map is just another way of saying "take your regular list of 2-tuples, and if you have som repeating fst values, join them up together" - which is NOT what i want |
| 17:03:13 | <Beelsebob> | bo0ts__: awesome idea... no idea how to solve it though :( |
| 17:03:27 | <bo0ts__> | Beelsebob: The wiki told me to do so ;> |
| 17:03:32 | <lilac> | dan: dan join them up together? |
| 17:03:37 | <lilac> | -dan |
| 17:03:57 | <lilac> | Data.Map is usually right-biased; new things override old things (iirc) |
| 17:04:25 | <lilac> | unless you want the type checker to notice if you try to add the same key twice, i'm not sure what else you could want from it |
| 17:04:42 | <bo0ts__> | Beelsebob: And I just confirmed that it happens with xterm as well. So aint a emulator problem. |
| 17:05:25 | <dan> | lilac: I'm guessing the type checker can't do this for Data.Map - and so this isn't a good solution for my problem |
| 17:06:25 | <lilac> | dan: if you want to statically check that there aren't duplicate keys, i think you could do that with something like oleg's HList |
| 17:07:24 | <lilac> | bo0ts__: by "gets the linebreaks wrong", what do you mean? it seems to be sorta-wroking for me |
| 17:08:13 | <bo0ts__> | Well, if I have a syntax error "Prelude>" will be on the same line as the last output. |
| 17:08:29 | <bo0ts__> | lilac: It's rather: The last linebreak is missing. |
| 17:09:14 | <PeakerWork> | dan: how can you prove at compile-time that all run-time values you'll give to the map are unique? |
| 17:09:32 | <PeakerWork> | dan: if they are otherwise arbitrary? |
| 17:09:37 | <lilac> | bo0ts__: interesting. i'm trying this on a ghci without readline support, maybe that's the issue? |
| 17:10:29 | <bo0ts__> | lilac: I'm using ghci from arch testing repositories. |
| 17:10:46 | <bo0ts__> | lilac: Do I need to recompile to disable readine? |
| 17:10:48 | <nominolo> | @seen MarcWeber |
| 17:10:49 | <lambdabot> | I saw MarcWeber leaving #haskell 4m 3d 7h 54m 11s ago, and . |
| 17:12:59 | <lilac> | bo0ts__: i'm not sure that'd be step forwards :) |
| 17:13:05 | <lilac> | ghci without readline is painful |
| 17:13:48 | <mauke> | cat | ghci |
| 17:14:04 | <copumpkin> | meow |
| 17:16:58 | <dan> | lilac: Thank you, will check that out |
| 17:17:01 | <bo0ts__> | lilac: No, coloured ghci for me :< I'm going back to ruby! ; ) |
| 17:17:04 | <Cale> | bo0ts__: If you're using 6.10.1 or 6.10.2 it probably uses editline which is terrible but isn't GPLed. 6.10.3 uses haskeline which is decent and again BSD licensed. |
| 17:17:26 | <Cale> | Coloured? |
| 17:17:38 | <copumpkin> | a repl with syntax highlighting :o how would that work? |
| 17:17:44 | <lament> | beautifully |
| 17:17:48 | <Twey> | Slowly :-P |
| 17:17:50 | <copumpkin> | I want! |
| 17:18:12 | <eivuokko> | Coloured envious of haskell features. Naturally ghci doesn't need to be envious. |
| 17:18:51 | <bo0ts__> | Cale: Not much of a difference anyway. It was just the output. |
| 17:19:11 | <Cale> | Oh, I would have imagined it would just be the input. |
| 17:19:28 | <Twey> | The input would make more sense. |
| 17:19:33 | <eivuokko> | Indeed. |
| 17:19:34 | <Twey> | Why, the output may not even be Haskell code! |
| 17:20:36 | <lilac> | hooray, "cat | ghci 2>&1 | HsColour -tty" works pretty well |
| 17:20:58 | <Twey> | But cat has no readline |
| 17:21:06 | <lilac> | nor does my ghci |
| 17:21:14 | <Twey> | Ah :-P |
| 17:22:09 | <Cale> | http://www.smbc-comics.com/ -- ahaha, today's is good :) |
| 17:22:35 | <bo0ts__> | lilac: Hm, and it corrupts tab completion. |
| 17:22:54 | <Twey> | Hahaha, Cale |
| 17:23:58 | <lilac> | bo0ts__: hmm, tab completion in ghci would be nice... |
| 17:24:10 | <Cale> | ghci normally has tab completion |
| 17:24:13 | <lilac> | ACTION still walking uphill backwards barefoot in the snow |
| 17:24:23 | <lilac> | Cale: see above re no readline ;-) |
| 17:24:34 | <lilac> | my ghci doesn't even have working backspace |
| 17:24:38 | <Cale> | readline is also unnecessary for it to work ;) |
| 17:24:46 | <Cale> | You're using one of the editline versions |
| 17:24:52 | <Cale> | Get 6.10.3 |
| 17:24:52 | <bo0ts__> | lilac: Another "feature" cat broke xD |
| 17:24:56 | <nominolo> | anyone know how to get the current process ID in Haskell? I want to write a deamon. |
| 17:25:00 | <Gracenotes> | rlwrap |
| 17:25:09 | <lilac> | Cale: 6.10.1 not good enough? :( |
| 17:25:10 | <Gracenotes> | mehbeh |
| 17:25:13 | <Cale> | lilac: Right. |
| 17:25:27 | <Cale> | lilac: 6.10.1 and 6.10.2 used editline which is crap |
| 17:25:28 | <lilac> | @hoogle processID |
| 17:25:29 | <lambdabot> | System.Posix.Types type ProcessID = CPid |
| 17:25:37 | <lilac> | @hoogle IO ProcessID |
| 17:25:37 | <lambdabot> | Did you mean: :: IO ProcessID /count=20 |
| 17:25:37 | <lambdabot> | No results found |
| 17:25:40 | <mauke> | lilac: 6.10.{1,2} are better if you patch and compile them yourself |
| 17:25:43 | <Twey> | System.IO.Posix.getProcessID |
| 17:25:50 | <Twey> | Er |
| 17:25:53 | <Twey> | System.Posix.getProcessID |
| 17:25:54 | <Twey> | Rather |
| 17:25:59 | <Cale> | mauke: But don't bother doing that. Just get 6.10.3 :) |
| 17:26:02 | <mauke> | lilac: 6.10.3 is not entirely broken (like editline) but still inferior to readline |
| 17:26:11 | <Cale> | In what way? |
| 17:26:19 | <Cale> | It works perfectly. |
| 17:26:19 | <mauke> | mappings |
| 17:26:21 | <wli> | ACTION hasn't bothered upgrading. |
| 17:26:24 | <copumpkin> | it doen't have RMS' stamp of approval on it |
| 17:26:37 | <mauke> | Cale: its history works completely differently |
| 17:26:40 | <lilac> | ACTION fails to understand how editline can be so bad |
| 17:27:21 | <wli> | vi keybindings ... woops it doesn't do those, does it? |
| 17:27:35 | <Cale> | lilac: I fail to understand that as well. It has a number of shameful bugs in it. You can bind the delete key, but even then it doesn't work properly |
| 17:27:35 | <Twey> | It is not as nice as readline, indeed |
| 17:27:38 | <PeakerWork> | Does Network.Socket / Network.BSD expose me to byte-ordering issues? |
| 17:27:46 | <lilac> | people actually *use* vi keybindings in line editors? |
| 17:27:51 | <mauke> | "\C-[[A": history-search-backward |
| 17:27:52 | <Twey> | Of course not |
| 17:27:58 | <PeakerWork> | I am getting connection refused when I try to connect to a port that I know is open, using Network.Socket.connect with (PortNum ..) constructor |
| 17:28:04 | <Twey> | :-P |
| 17:28:05 | <wli> | ACTION uses vi keybindings. |
| 17:28:12 | <Twey> | ACTION uses emacs keybindings |
| 17:28:15 | <mauke> | ^ you can't do that with haskeline, not even by writing custom Haskell code |
| 17:28:28 | <Cale> | PeakerWork: Don't use the constructor |
| 17:28:31 | <lilac> | ACTION uses emacs keybindings in zsh but edits in vim |
| 17:28:35 | <Cale> | er... |
| 17:28:37 | <PeakerWork> | Cale: how do I use Network.Socket.connect? |
| 17:28:39 | <Twey> | ACTION thinks lilac is bonkers |
| 17:28:42 | <Twey> | :-P |
| 17:28:55 | <PeakerWork> | Cale: It wants a SockAddr -- whose SockAddrInet constructor wants a PortNumber |
| 17:29:13 | <mauke> | PeakerWork: yes. do not use the PortNum constructor. |
| 17:29:18 | <dmwit> | PortNumber is an instance of Num. |
| 17:29:20 | <Cale> | Just use numeric literals for values of type PortNumber |
| 17:29:41 | <Cale> | It's intended to take care of the byte ordering for you. |
| 17:29:43 | <PeakerWork> | ah, I see, thanks |
| 17:29:52 | <PeakerWork> | shouldn't expose the constructor then, IMO |
| 17:31:17 | <Cale> | Interestingly, the haddock documentation for the network library doesn't seem to mention the constructor anymore. |
| 17:31:47 | <Cale> | Oh, it does in Network.Socket |
| 17:32:32 | <lilac> | Twey: i have emacs keybindings set up for ex mode in vim... |
| 17:32:48 | <frankks> | @src ($) |
| 17:32:48 | <lambdabot> | f $ x = f x |
| 17:32:55 | <lilac> | ($) = id |
| 17:33:07 | <frankks> | hm? |
| 17:33:35 | <Cale> | frankks: Basically, the important thing about $ is that it has very low precedence |
| 17:33:39 | <Gracenotes> | ($) f x = f x |
| 17:34:03 | <Cale> | frankks: Which means that if you have an expression like foo . bar . baz $ x + y |
| 17:34:14 | <Cale> | It means the same as (foo . bar . baz) (x + y) |
| 17:34:32 | <Twey> | > (+1) |
| 17:34:33 | <lambdabot> | Overlapping instances for Show (a -> a) |
| 17:34:33 | <lambdabot> | arising from a use of `s... |
| 17:34:35 | <Twey> | > (+1) 3 |
| 17:34:37 | <lambdabot> | 4 |
| 17:34:39 | <lilac> | ... because it means the same as (foo . bar . baz) $ (x + y) |
| 17:34:42 | <Twey> | > id (+1) |
| 17:34:43 | <lambdabot> | Overlapping instances for Show (a -> a) |
| 17:34:43 | <lambdabot> | arising from a use of `s... |
| 17:34:44 | <Twey> | > id (+1) 3 |
| 17:34:46 | <lambdabot> | 4 |
| 17:34:51 | <Twey> | > (+1) `id` 3 |
| 17:34:52 | <lambdabot> | 4 |
| 17:34:54 | <Twey> | > (+1) $ 3 |
| 17:34:55 | <lambdabot> | 4 |
| 17:34:58 | <Twey> | Like so. |
| 17:34:58 | <frankks> | i see |
| 17:35:21 | <Twey> | Where id (+1) 3 means (id (+1)) 3, of course, like all function application in Haskell |
| 17:35:26 | <lilac> | ($) takes the function on its left hand side, does nothing to it, and then applies it to the value on its right hand side |
| 17:36:09 | <frankks> | i'm just using it in the sense of length $ function [(string),(string),string)] |
| 17:36:25 | <frankks> | ah ok |
| 17:36:25 | <Twey> | ACTION nods. |
| 17:36:30 | <frankks> | sorry just read what you write |
| 17:36:31 | <frankks> | wrote |
| 17:37:30 | <Gracenotes> | yeah, a simple way to think about it is in terms of replacing parens |
| 17:38:23 | <lilac> | > let ($) = id in (4$) |
| 17:38:25 | <lambdabot> | 4 |
| 17:38:32 | <lilac> | > let ($) = id in length $ [1,2,3] |
| 17:38:33 | <lambdabot> | 3 |
| 17:38:58 | <frankks> | surely |
| 17:39:03 | <frankks> | > length [1,2,3] |
| 17:39:05 | <lambdabot> | 3 |
| 17:39:08 | <frankks> | produces the same result |
| 17:39:16 | <frankks> | so.. what's the need? |
| 17:39:40 | <Gracenotes> | > filter odd $ map (^2) [1..] |
| 17:39:41 | <lambdabot> | [1,9,25,49,81,121,169,225,289,361,441,529,625,729,841,961,1089,1225,1369,15... |
| 17:39:54 | <Gracenotes> | > filter odd map (^2) [1..] |
| 17:39:56 | <lambdabot> | Couldn't match expected type `[a]' |
| 17:40:04 | <mmorrow_> | , zipWith id (fmap (*) [0..]) (repeat 2) |
| 17:40:06 | <lunabot> | [0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50... |
| 17:40:19 | <frankks> | so it allows you to apply a function to a value which hasn't yet been determined? |
| 17:40:33 | <frankks> | so f $ f value |
| 17:40:36 | <Gracenotes> | well. It's a lazy language.. technically all values haven't been determined :) |
| 17:40:43 | <Gracenotes> | it's a way to avoid parens |
| 17:40:46 | <mmorrow_> | since functions are values, you can apply functions to other functions/values to get yet more functions |
| 17:40:47 | <Gracenotes> | in practice |
| 17:40:55 | <frankks> | k |
| 17:40:56 | <Gracenotes> | normally you'd write the above like, filter odd (map (^2) [1..]) |
| 17:41:32 | <mmorrow_> | @type (filter . odd . fmap (^2)) |
| 17:41:34 | <lambdabot> | Couldn't match expected type `a -> Bool' |
| 17:41:34 | <lambdabot> | against inferred type `Bool' |
| 17:41:34 | <lambdabot> | Probable cause: `.' is applied to too many arguments |
| 17:41:43 | <mmorrow_> | @type (filter odd . fmap (^2)) |
| 17:41:45 | <lambdabot> | forall a. (Integral a) => [a] -> [a] |
| 17:42:41 | <mmorrow_> | @type [($),id] |
| 17:42:43 | <lambdabot> | forall a b. [(a -> b) -> a -> b] |
| 17:43:05 | <Raevel> | that was cool, somehow |
| 17:43:29 | <mmorrow_> | unite! |
| 17:43:29 | <Gracenotes> | IT ALWAYS IS |
| 17:43:36 | <lilac> | > map (sum . map snd) . groupBy (on(==)fst) . map (head &&& length) . sort $ words "four frolicking foxes flitted feverishly through the furrow" |
| 17:43:38 | <lambdabot> | [42,10] |
| 17:43:54 | <frankks> | @src (\) |
| 17:43:55 | <lambdabot> | Source not found. Are you on drugs? |
| 17:44:06 | <Berengal> | What's the complexity of nub? |
| 17:44:18 | <lilac> | @src nub |
| 17:44:19 | <lambdabot> | nub = nubBy (==) |
| 17:44:21 | <lilac> | @src nubBy |
| 17:44:21 | <lambdabot> | nubBy eq [] = [] |
| 17:44:22 | <lambdabot> | nubBy eq (x:xs) = x : nubBy eq (filter (\ y -> not (eq x y)) xs) |
| 17:44:22 | <Gracenotes> | ⍥ |
| 17:44:29 | <Gracenotes> | nub is somewhat inefficient |
| 17:44:29 | <lilac> | Berengal: hideous. |
| 17:44:38 | <lilac> | Berengal: (it's quadratic) |
| 17:44:45 | <Berengal> | O(n^2) looks like |
| 17:45:03 | <Berengal> | So assuming I want a sorted nubbed list, map head. group . sort is the way to go, right? |
| 17:45:16 | <Gracenotes> | well... |
| 17:45:16 | <lilac> | Berengal: yep. |
| 17:45:18 | <Gracenotes> | @src groupBy |
| 17:45:19 | <lambdabot> | groupBy _ [] = [] |
| 17:45:19 | <lambdabot> | groupBy eq (x:xs) = (x:ys) : groupBy eq zs |
| 17:45:19 | <lambdabot> | where (ys,zs) = span (eq x) xs |
| 17:45:31 | <Gracenotes> | hm. better, it seems. |
| 17:45:37 | <pejo> | lilac, is that how it's implemented in the Prelude as well? |
| 17:45:58 | <lilac> | pejo: i believe so. |
| 17:46:08 | <lilac> | (or at least something equivalent) |
| 17:46:27 | <Berengal> | Or are sets the way to go? |
| 17:46:28 | <tombom> | why is it implemented like that if it's so bad |
| 17:46:45 | <frankks> | @src (\\) |
| 17:46:46 | <lambdabot> | (\\) = foldl (flip delete) |
| 17:46:54 | <mmorrow_> | > let histo = sortBy (flip compare `on` snd) . Map.toList . (\m -> let n = fromIntegral (Map.size m) in Map.map (\x -> fromIntegral x / n) m) . foldl' (\m a -> Map.insertWith' (+) a 1 m) mempty in histo "four frolicking foxes flitted feverishly through the furrow" |
| 17:46:56 | <lambdabot> | [(' ',0.35),('f',0.3),('r',0.3),('e',0.25),('o',0.25),('h',0.2),('i',0.2),(... |
| 17:47:02 | <lilac> | pejo: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html |
| 17:47:24 | <Berengal> | tombom: I assume it's because nub preserves order |
| 17:47:29 | <copumpkin> | zomg histo! zygohistomorphic prepromorphism? |
| 17:47:35 | <mmorrow_> | the r's snuck in there unnoticed |
| 17:47:39 | <lilac> | tombom: nub preserves order and doesn't require a (<) |
| 17:47:50 | <mmorrow_> | at the expense of O(n^2) |
| 17:48:01 | <Gracenotes> | real nubBy, coming through |
| 17:48:04 | <tombom> | are thanks |
| 17:48:09 | <tombom> | *ah oops |
| 17:48:24 | <Gracenotes> | nubBy eq l = nubBy' l [] |
| 17:48:26 | <Gracenotes> | where nubBy' [] _ = [] |
| 17:48:28 | <Gracenotes> | nubBy' (y:ys) xs | elem_by eq y xs = nubBy' ys xs |
| 17:48:30 | <Gracenotes> | | otherwise = y : nubBy' ys (y:xs) |
| 17:48:31 | <Gracenotes> | elem_by :: (a -> a -> Bool) -> a -> [a] -> Bool (sort of an 'or' for two parameters) |
| 17:48:44 | <mmorrow_> | Berengal: i'd do Set.fromList . Set.toList probably |
| 17:48:51 | <mmorrow_> | err |
| 17:49:01 | <mmorrow_> | Set.toList . Set.fromList |
| 17:49:03 | <Berengal> | mmorrow_: Reverse those |
| 17:49:06 | <mmorrow_> | heh |
| 17:49:12 | <lilac> | Gracenotes: still quadratic though |
| 17:49:15 | <Gracenotes> | the real nubBy is.. .still |
| 17:49:17 | <Gracenotes> | yeah |
| 17:49:21 | <Berengal> | Yeah, that should work fine. Doesn't look as impressive though :P |
| 17:49:45 | <Gracenotes> | lilac: it might be possible to make a more fine-tuned version that's O(n) |
| 17:49:57 | <copumpkin> | nope |
| 17:50:01 | <lilac> | not for a general datatype |
| 17:50:03 | <Gracenotes> | ...maybe. If you have an accumulator of the variable-to-be-compared-to? |
| 17:50:03 | <Berengal> | Gracenotes: I believe O(n) requires a sorted list |
| 17:50:04 | <copumpkin> | unless you know something beforehand |
| 17:50:12 | <Gracenotes> | value that is |
| 17:50:40 | <frankks> | O(n) is an unsorted list I think. Because it's possible you will have to look at every element to find what you're searching for |
| 17:50:54 | <copumpkin> | frankks: that's just for finding one element though |
| 17:51:18 | <frankks> | (didn't read it in context. oops.) |
| 17:51:19 | <copumpkin> | if you're searching for n elements, you get O(n^2) |
| 17:51:27 | <Berengal> | Well, if there's only a few values in the type being nubbed, such as Ordering, you could get O(n)... |
| 17:51:53 | <Gracenotes> | maybe I'm thinking of a different algorithm from the one actually implement |
| 17:51:57 | <Gracenotes> | ed |
| 17:51:57 | <copumpkin> | if you assume a hashtable is O(1), and everything is hashable, then maybe |
| 17:52:29 | <Gracenotes> | but, for instance, nubBy (==) [1,2,3,4,3,2,2]. You just check adjacent elements, and if you find a run, keep following it and continue at the end |
| 17:52:39 | <lilac> | > const 0 M.fromList |
| 17:52:41 | <lambdabot> | /tmp/4852686047885518090:70:44: Not in scope: `M.fromList' |
| 17:52:42 | <lilac> | @type M.fromList |
| 17:52:44 | <lambdabot> | forall k a. (Ord k) => [(k, a)] -> M.Map k a |
| 17:52:45 | <lilac> | :( |
| 17:52:48 | <Gracenotes> | Map. |
| 17:52:52 | <tibbe_> | I was playing around a bit with the Haddock CSS: http://johantibell.com/haddock/Network-Socket-ByteString.html |
| 17:52:55 | <copumpkin> | Gracenotes: that wouldn't work? |
| 17:52:59 | <tibbe_> | tibbe_: pretty much stolen from Google |
| 17:52:59 | <Twey> | Gracenotes: I think nubBy checks previous elements |
| 17:53:03 | <tibbe_> | but I find it pretty |
| 17:53:14 | <Twey> | > nub [1, 2, 1] |
| 17:53:15 | <lambdabot> | [1,2] |
| 17:53:17 | <lilac> | Gracenotes: that returns [1,2,3,4] not [1,2,3,4,3,2] |
| 17:53:23 | <Gracenotes> | oh. that sucks |
| 17:53:39 | <Gracenotes> | but no other way to do it of course. |
| 17:53:40 | <copumpkin> | if you have an ord, you can do it in nlogn time with map head . group . sort |
| 17:53:41 | <Berengal> | nubBy does a filter on the remaining list |
| 17:53:46 | <Gracenotes> | groupBy is more lenient |
| 17:54:08 | <Gracenotes> | argh. they're not complements at all |
| 17:54:26 | <copumpkin> | tibbe_: I like it, but the header looks ugly, and that lambda in the upper right corner in particular must go |
| 17:54:33 | <copumpkin> | tibbe_: but the body of the text looks nice |
| 17:54:50 | <tibbe_> | copumpkin: it's the standard heading, I didn't do anything to that part |
| 17:54:57 | <FunctorSalad_> | maybe nub has rewrite rules for the common cases |
| 17:54:59 | <copumpkin> | tibbe_: yeah :) exactly |
| 17:54:59 | <FunctorSalad_> | ? |
| 17:55:11 | <copumpkin> | I'd definitely support replacing the default haddock css with the one you made |
| 17:55:21 | <copumpkin> | FunctorSalad_: not as far as I've seen |
| 17:55:38 | <Gracenotes> | :⍵ |
| 17:55:47 | <mauke> | ω̈ |
| 17:55:52 | <FunctorSalad_> | copumpkin: hmm, I seemed to remember something about the sort-based nub not being faster after all in some simple example |
| 17:55:57 | <FunctorSalad_> | but not sure |
| 17:56:06 | <copumpkin> | it wouldn't be safe to do a nub replace any Ord instance's nub with a map head . group . sort |
| 17:56:12 | <copumpkin> | because one isn't lazy |
| 17:56:22 | <mauke> | > nub [2,1] |
| 17:56:23 | <lambdabot> | [2,1] |
| 17:56:29 | <FunctorSalad_> | oh |
| 17:56:31 | <copumpkin> | oh, and also it doesn't maintain order :P |
| 17:56:40 | <FunctorSalad_> | hmm ok |
| 17:56:52 | <copumpkin> | but the nub can lazily consume the entire list too |
| 17:56:52 | <Gracenotes> | ╳╳╳╳╳╳╳╳╳╳ |
| 17:57:06 | <mauke> | > nub [0..] |
| 17:57:07 | <lambdabot> | [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,... |
| 17:57:12 | <Hunner> | What in the world are those? |
| 17:57:19 | <lilac> | > map ($"four frolicking foxes flitted feverishly through the furrow") [nub, fmap snd . toList . fromList . fmap (snd &&& fst) . toList . fromList . flip zip [0,-1..] . reverse] |
| 17:57:19 | <mauke> | U+2573 (e2 95 b3): BOX DRAWINGS LIGHT DIAGONAL CROSS [╳] |
| 17:57:20 | <lambdabot> | Not in scope: `toList'Not in scope: `fromList'Not in scope: `toList'Not in ... |
| 17:57:58 | <copumpkin> | tibbe_: one minor point is that I feel the type signature of a function could be separated more from the text describing it... it's noticeable with your recvFrom function |
| 17:58:02 | <Gracenotes> | > nub [0..] !! 100000 |
| 17:58:14 | <tibbe_> | copumpkin: I agree |
| 17:58:18 | <lambdabot> | thread killed |
| 17:58:27 | <tibbe_> | copumpkin: didn't do anything there either, the markup really needs to be cleaned up |
| 17:58:32 | <copumpkin> | yeah :) |
| 17:58:38 | <tibbe_> | copumpkin: it's pretty gruesome |
| 17:58:39 | <Berengal> | Gracenotes: Welcome to O(n^2) |
| 17:58:51 | <copumpkin> | > nub [0..] !! 100 |
| 17:58:53 | <lambdabot> | 100 |
| 17:58:54 | <copumpkin> | whee! |
| 17:58:55 | <Gracenotes> | well. I had to try out some values in ghci |
| 17:58:57 | <copumpkin> | I win |
| 17:58:58 | <lilac> | @type map snd . M.toList . M.fromList . map (snd &&& fst) . M.toList . M.fromList . flip zip [0,-1..] . reverse] |
| 17:59:00 | <lambdabot> | parse error on input `]' |
| 17:59:01 | <lilac> | 17:57 < mauke> U+2573 (e2 95 b3): BOX DRAWINGS LIGHT DIAGONAL CROSS [╳] |
| 17:59:04 | <FunctorSalad_> | fasterNub = go mempty where { go seen (x:xs) | member x seen = go xs; go seen (x:xs) = x:(go (insert x seen) xs); go _ [] = [] } |
| 17:59:05 | <Gracenotes> | the rest of them didn't grow so fast >_> |
| 17:59:17 | <lilac> | gah damn copy-past grr |
| 17:59:20 | <copumpkin> | lol |
| 17:59:20 | <FunctorSalad_> | that would be lazy and preserve order I think, copumpkin |
| 17:59:25 | <Gracenotes> | FunctorSalad_: good point |
| 17:59:39 | <lilac> | @type map snd . M.toList . M.fromList . map (snd &&& fst) . M.toList . M.fromList . flip zip [0,-1..] . reverse |
| 17:59:41 | <lambdabot> | forall a. (Ord a) => [a] -> [a] |
| 17:59:41 | <copumpkin> | > let fasterNub = go mempty where { go seen (x:xs) | member x seen = go xs; go seen (x:xs) = x:(go (insert x seen) xs); go _ [] = [] } in fasterNub [0..] |
| 17:59:42 | <lilac> | ^^ faster nub |
| 17:59:43 | <lambdabot> | Not in scope: `member' |
| 17:59:44 | <Gracenotes> | er, implementation, too. |
| 17:59:51 | <Gracenotes> | Set. |
| 17:59:52 | <FunctorSalad_> | err the mempty is supposed to be a Data.Set btw ;) |
| 17:59:54 | <Gracenotes> | dot |
| 18:00:07 | <copumpkin> | > let fasterNub = go Set.mempty where { go seen (x:xs) | Set.member x seen = go xs; go seen (x:xs) = x:(go (Set.insert x seen) xs); go _ [] = [] } in fasterNub [0..] |
| 18:00:08 | <lambdabot> | Failed to load interface for `Set': |
| 18:00:08 | <lambdabot> | Use -v to see a list of the ... |
| 18:00:20 | <copumpkin> | FunctorSalad_: if it's Data.Set, it'd be n log n again though |
| 18:00:23 | <FunctorSalad_> | hmm lambda doesn't have Set? :( |
| 18:00:23 | <copumpkin> | but I guess better than sort |
| 18:00:24 | <Gracenotes> | or... Data.Set. |
| 18:00:30 | <Berengal> | @type S.toList |
| 18:00:31 | <lambdabot> | forall a. S.Set a -> [a] |
| 18:00:43 | <copumpkin> | I hate that @type has a different namespace setup than > |
| 18:00:44 | <lilac> | Cale! Data.Set and Data.Map aren't working in lambdabot! ;-( |
| 18:00:46 | <Gracenotes> | namespaces for Sets and Maps and ByteStrings are effed up |
| 18:00:59 | <dons> | why? |
| 18:00:59 | <copumpkin> | > let fasterNub = go Data.Set.mempty where { go seen (x:xs) | Data.Set.member x seen = go xs; go seen (x:xs) = x:(go (Data.Set.insert x seen) xs); go _ [] = [] } in fasterNub [0..] |
| 18:01:02 | <lambdabot> | Not in scope: `Data.Set.mempty' |
| 18:01:04 | <Gracenotes> | and anything else that's qualified in L.js |
| 18:01:06 | <Gracenotes> | *hs |
| 18:01:07 | <FunctorSalad_> | mempty is in Monoid... |
| 18:01:10 | <copumpkin> | > let fasterNub = go mempty where { go seen (x:xs) | Data.Set.member x seen = go xs; go seen (x:xs) = x:(go (Data.Set.insert x seen) xs); go _ [] = [] } in fasterNub [0..] |
| 18:01:11 | <lambdabot> | Add a type signature |
| 18:01:12 | <lilac> | > const True Data.Map.fromList |
| 18:01:12 | <copumpkin> | yeah, I realized that :P |
| 18:01:13 | <lambdabot> | /tmp/4946381460955546030:70:43: Not in scope: `Data.Map.fromList' |
| 18:01:16 | <Cale> | lilac: 本当に?まったく… |
| 18:01:17 | <FunctorSalad_> | I think there's also Data.Set.empty |
| 18:01:34 | <mauke> | > M.fromList [] |
| 18:01:35 | <lambdabot> | /tmp/513599841387006425:70:32: Not in scope: `M.fromList' |
| 18:01:36 | <copumpkin> | > let fasterNub = go Data.Set.empty where { go seen (x:xs) | Data.Set.member x seen = go xs; go seen (x:xs) = x:(go (Data.Set.insert x seen) xs); go _ [] = [] } in fasterNub [0..] :: [Int] |
| 18:01:37 | <lambdabot> | Couldn't match expected type `[t]' against inferred type `S.Set t' |
| 18:01:38 | <Cale> | > let fasterNub = go mempty where { go seen (x:xs) | S.member x seen = go xs; go seen (x:xs) = x:(go (S.insert x seen) xs); go _ [] = [] } in fasterNub [0..] |
| 18:01:40 | <lambdabot> | Add a type signature |
| 18:01:43 | <mauke> | my emperor! |
| 18:01:44 | <copumpkin> | I give up :) |
| 18:01:45 | <Berengal> | Data.Set is called S, Data.Map is called M, simple as that |
| 18:01:51 | <Gracenotes> | ugh. more screwed up than usual? |
| 18:01:55 | <Cale> | > S.empty |
| 18:01:55 | <copumpkin> | Berengal: except if you ask for @type |
| 18:01:57 | <lambdabot> | /tmp/521710655770533761:70:32: Not in scope: `S.empty' |
| 18:01:59 | <Cale> | ... |
| 18:02:00 | <Cale> | hmm |
| 18:02:11 | <Gracenotes> | > Set.empty |
| 18:02:12 | <lambdabot> | fromList [] |
| 18:02:14 | <Gracenotes> | > Data.Set.empty |
| 18:02:15 | <lambdabot> | /tmp/2311465051563539008:70:32: Not in scope: `Data.Set.empty' |
| 18:02:17 | <Gracenotes> | wha |
| 18:02:25 | <FunctorSalad_> | whoa |
| 18:02:34 | <copumpkin> | > let fasterNub = go Set.empty where { go seen (x:xs) | Set.member x seen = go xs; go seen (x:xs) = x:(go (Set.insert x seen) xs); go _ [] = [] } in fasterNub [0..] :: [Int] |
| 18:02:35 | <lambdabot> | Couldn't match expected type `[t]' against inferred type `S.Set t' |
| 18:02:39 | <FunctorSalad_> | @let emptySet = S.empty |
| 18:02:40 | <lambdabot> | Defined. |
| 18:02:42 | <FunctorSalad_> | yay |
| 18:02:42 | <copumpkin> | okay, not my fault |
| 18:03:02 | <FunctorSalad_> | @let insertSet = S.insert |
| 18:03:03 | <lambdabot> | Defined. |
| 18:03:11 | <FunctorSalad_> | @let memberSet = S.member |
| 18:03:12 | <lambdabot> | Defined. |
| 18:03:13 | <copumpkin> | this is ugly |
| 18:03:17 | <FunctorSalad_> | =) |
| 18:03:24 | <lilac> | > Map.fromList [] |
| 18:03:26 | <lambdabot> | fromList [] |
| 18:03:27 | <Gracenotes> | hm. I don't see where the type error is. |
| 18:03:44 | <Gracenotes> | Oh! the recursive case for Set.member x seen doesn't have enough params |
| 18:04:00 | <FunctorSalad_> | sorry |
| 18:04:00 | <lilac> | @check \xs -> (map snd . Map.toList . Map.fromList . map (snd &&& fst) . Map.toList . Map.fromList . flip zip [0,-1..] . reverse) xs == nub xs |
| 18:04:02 | <lambdabot> | "OK, passed 500 tests." |
| 18:04:08 | <lilac> | yay, fast nub success |
| 18:04:24 | <lilac> | @hoogle (a, b) -> (b, a) |
| 18:04:25 | <lambdabot> | System.Random randomR :: (Random a, RandomGen g) => (a, a) -> g -> (a, g) |
| 18:04:25 | <lambdabot> | Control.Arrow (^<<) :: Arrow a => (c -> d) -> a b c -> a b d |
| 18:04:25 | <lambdabot> | Control.Arrow (<<<) :: Arrow a => a c d -> a b c -> a b d |
| 18:04:27 | <Gracenotes> | Set is sorta fine... too... |
| 18:04:34 | <copumpkin> | > (map snd . Map.toList . Map.fromList . map (snd &&& fst) . Map.toList . Map.fromList . flip zip [0,-1..] . reverse) [0..] |
| 18:04:47 | <copumpkin> | tsk tsk :) |
| 18:04:51 | <lilac> | copumpkin: ;-) |
| 18:04:54 | <Gracenotes> | Thread keeled |
| 18:04:57 | <lambdabot> | thread killed |
| 18:04:59 | <copumpkin> | don't keel! |
| 18:05:13 | <lilac> | ACTION is clearly inadequately lazy |
| 18:06:05 | <FunctorSalad_> | @let fasterNub = go emptySet where { go seen (x:xs) | memberSet x seen = go seen xs; go seen (x:xs) = x:(go (insertSet x seen) xs); go _ [] = [] } |
| 18:06:19 | <Gracenotes> | Defined. . ... . .(>) |
| 18:06:25 | <FunctorSalad_> | hehe |
| 18:06:25 | <Gracenotes> | still. lots of GC overhead from the more "efficient" nubs |
| 18:06:34 | <Gracenotes> | that is the constant! |
| 18:06:55 | <Fred320> | @src foldr |
| 18:07:03 | <Cale> | > Set.empty |
| 18:07:13 | <FunctorSalad_> | lambdabot has gone home? |
| 18:07:16 | <Cale> | Oh, what did you do!? |
| 18:07:18 | <Cale> | hehe |
| 18:07:35 | <copumpkin> | ACTION strokes lambdabot |
| 18:07:39 | <Cale> | Probably just have to wait, it'll come back. |
| 18:07:53 | <Cale> | It was running for months unattended. |
| 18:08:03 | <Gracenotes> | ACTION tickles lambdabot |
| 18:08:20 | <lilac> | copumpkin: interim pumpkinbot time? |
| 18:08:38 | <copumpkin> | I can bring him (her?) in if you think I should |
| 18:08:56 | <lilac> | copumpkin: i feel cold and lonely without a lambdabot here |
| 18:09:26 | <FunctorSalad_> | Gracenotes: any better idea with respect to GC? |
| 18:09:47 | <Gracenotes> | uh. binary heaps with mutable arrays? :) |
| 18:09:49 | <copumpkin> | lambdabot authentication is so sophisticated ;) |
| 18:10:04 | <Gracenotes> | Haskell is a heavily GC'd language any way you put it... |
| 18:10:25 | <lilac> | > Set.empty |
| 18:10:26 | <pumpkinbot> | Failed to load interface for `Set': |
| 18:10:26 | <pumpkinbot> | Use -v to see a list of the ... |
| 18:10:31 | <copumpkin> | lol |
| 18:10:37 | <copumpkin> | > S.empty |
| 18:10:38 | <pumpkinbot> | mueval: Prelude.read: no parse |
| 18:10:41 | <copumpkin> | fail |
| 18:10:45 | <Raevel> | copumpkin: hah, i had to do the exact same thing earlier |
| 18:10:46 | <lilac> | > fail "fail!" |
| 18:10:47 | <pumpkinbot> | No instance for (Show (m a)) |
| 18:10:47 | <pumpkinbot> | arising from a use of `show' at <in... |
| 18:10:50 | <FunctorSalad_> | > fix fail |
| 18:10:52 | <pumpkinbot> | "" |
| 18:10:58 | <copumpkin> | wow, it really fails |
| 18:11:03 | <lilac> | lol |
| 18:11:21 | <FunctorSalad_> | oh, list monad |
| 18:11:22 | <copumpkin> | no Data.Set for you! |
| 18:11:57 | <lilac> | well that's no fun at all |
| 18:12:05 | <copumpkin> | :( |
| 18:12:05 | <ray> | no set monad for you |
| 18:12:11 | <copumpkin> | rmonad! |
| 18:12:20 | <copumpkin> | maybe I'll get RMonad on my bot |
| 18:12:43 | <copumpkin> | > text "Segmentation fault" |
| 18:12:45 | <pumpkinbot> | Segmentation fault |
| 18:12:53 | <ray> | > text "thread killed" |
| 18:12:54 | <pumpkinbot> | thread killed |
| 18:12:56 | <copumpkin> | wow, my lambdabot barfs every time someone sends a message |
| 18:13:00 | <copumpkin> | not only to it |
| 18:13:06 | <copumpkin> | Main: caught (and ignoring) too few bytes. Failed reading at byte position 8 |
| 18:13:07 | <Gracenotes> | lol |
| 18:13:12 | <copumpkin> | that's what it says every time anyone says anything |
| 18:13:24 | <Gracenotes> | CATCH THIS, PUMPYBOT! |
| 18:13:36 | <copumpkin> | just a sec |
| 18:14:11 | <copumpkin> | how is it that screen's keys are always so messed up |
| 18:14:48 | <FunctorSalad_> | is there some simple way to make stuff clickable in an opengl scene? |
| 18:14:53 | <FunctorSalad_> | :( |
| 18:15:09 | <lambdabot> | Defined. |
| 18:15:09 | <lambdabot> | foldr f z [] = z |
| 18:15:09 | <lambdabot> | foldr f z (x:xs) = f x (foldr f z xs) |
| 18:15:11 | <lambdabot> | mueval: Prelude.read: no parse |
| 18:15:12 | <lambdabot> | mueval: GhcException mkTopLevEnv: not a hom... |
| 18:15:14 | <lambdabot> | Terminated |
| 18:15:21 | <FunctorSalad_> | I think I'll make "clickability centers" and see which center is closest to the line clicked on |
| 18:15:37 | <FunctorSalad_> | sounds way easier than calculating the intersection with actual geometry |
| 18:15:56 | <Gracenotes> | > "hello thar" |
| 18:15:58 | <lambdabot> | "hello thar" |
| 18:16:03 | <lilac> | @type map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) |
| 18:16:04 | <lambdabot> | Couldn't find qualified module. |
| 18:16:20 | <lilac> | @type map fst . filter (not . uncurry S.member) . (zip `ap` scanl (flip S.insert) S.empty) |
| 18:16:21 | <lambdabot> | forall b. (Ord b) => [b] -> [b] |
| 18:16:36 | <lilac> | @check \xs -> map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) $ xs == nub xs |
| 18:16:37 | <lambdabot> | Couldn't match expected type `[b]' against inferred type `Bool' |
| 18:16:49 | <lilac> | @check \xs -> (map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) $ xs) == nub xs |
| 18:16:50 | <lambdabot> | "OK, passed 500 tests." |
| 18:17:01 | <lilac> | > map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) [0..] |
| 18:17:02 | <lambdabot> | Couldn't match expected type `a -> [(a1, S.Set a1)]' |
| 18:17:08 | <lilac> | > map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) $ [0..] |
| 18:17:10 | <lambdabot> | [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,... |
| 18:17:12 | <lilac> | hooray |
| 18:17:34 | <lilac> | @hoogle scanl' |
| 18:17:35 | <lambdabot> | No results found |
| 18:20:07 | <Fred320> | @src fold |
| 18:20:07 | <lambdabot> | Source not found. Where did you learn to type? |
| 18:20:09 | <Fred320> | @src foldl |
| 18:20:09 | <lambdabot> | foldl f z [] = z |
| 18:20:10 | <lambdabot> | foldl f z (x:xs) = foldl f (f z x) xs |
| 18:20:13 | <lilac> | FunctorSalad_: render each of your objects in turn (nearest first) offscreen onto a pbuffer, then check to see if the depth buffer is set at the clicked point |
| 18:20:19 | <lilac> | *ducks* |
| 18:20:45 | <lilac> | @type let fasterNub = map fst . filter (not . uncurry Set.member) . (zip `ap` scanl (flip Set.insert) Set.empty) in fasterNub |
| 18:20:46 | <lambdabot> | Couldn't find qualified module. |
| 18:21:20 | <FunctorSalad_> | hmm I'd have to look up "pbuffer" |
| 18:21:37 | <ray> | it's short for pteriffic buffer |
| 18:22:19 | <Fred320> | @src foldr |
| 18:22:19 | <lambdabot> | foldr f z [] = z |
| 18:22:20 | <lambdabot> | foldr f z (x:xs) = f x (foldr f z xs) |
| 18:27:45 | <Cale> | Fred320: A good way to think about how foldr f z works is that it replaces each (:) in the list with f and the [] at the end with z |
| 18:28:08 | <Fred320> | thanks... i just wrote my own folds for exercise and wanted to compare to the original |
| 18:28:13 | <Cale> | :) |
| 18:28:58 | <Fred320> | i had a hard time understanding the difference between left and right fold at first, but that was only because the first examples produce a t form a list of t, and the often it does not matter which fold you choose |
| 18:29:03 | <Cale> | foldr has the rather nice property that after each recursive step, the next thing to evaluate is always f, so if f doesn't need its second parameter, the foldr never continues |
| 18:29:06 | <Fred320> | for example fold (+) 0 [1,2,3] |
| 18:29:38 | <Fred320> | and foldl has the nice property of being tail recursive :) |
| 18:29:44 | <Cale> | Whereas foldl always just calls itself selfishly until it reaches the end of the list. So it will never work on infinite lists. |
| 18:30:23 | <tetha> | hm, this is fun on a very strange level. I started with removing redundancy and now Im implementing symbolic simplications with neutral and absorbing elements |
| 18:30:41 | <zoheb> | @pl (\x -> if (x > 0) then fact (x-1) else 1 |
| 18:30:42 | <lambdabot> | (line 1, column 41): |
| 18:30:42 | <lambdabot> | unexpected end of input |
| 18:30:42 | <lambdabot> | expecting digit, variable, "(", operator or ")" |
| 18:30:45 | <zoheb> | @pl (\x -> if (x > 0) then fact (x-1) else 1) |
| 18:30:46 | <lambdabot> | flip (liftM2 if' (> 0) (fact . subtract 1)) 1 |
| 18:30:49 | <tetha> | (in some hobby-expression-evaluator, that is) |
| 18:31:07 | <zoheb> | @type liftM2 |
| 18:31:08 | <lambdabot> | forall a1 a2 r (m :: * -> *). (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r |
| 18:31:25 | <Cale> | The tail recursiveness of foldl can be a useful property to exploit, but since lazy evaluation doesn't use a stack in the same way as the evaluators for most strict languages use one, it's less critical. |
| 18:31:30 | <Fred320> | Cale: the fold really clicked for me with rev = foldl (flip (:)) [] |
| 18:31:34 | <Cale> | yeah :) |
| 18:32:01 | <Fred320> | and of course app xs ys = foldr (:) ys xs |
| 18:32:37 | <Fred320> | > foldr (:) "world!" "hello " |
| 18:32:38 | <lambdabot> | "hello world!" |
| 18:32:51 | <Cale> | The occasional trouble with foldl is when you give it a function that can't build something immediately using its second parameter. It can build up a very large expression before giving it any chance to be evaluated. |
| 18:32:53 | <zoheb> | @pl (\x -> if (x > 0) then x*fact (x-1) else 1) |
| 18:32:53 | <lambdabot> | flip (liftM2 if' (> 0) (ap (*) (fact . subtract 1))) 1 |
| 18:32:54 | <Cale> | For example... |
| 18:32:58 | <Cale> | foldl (+) 0 [1,2,3] |
| 18:33:04 | <Cale> | -> foldl (+) (0+1) [2,3] |
| 18:33:09 | <Cale> | -> foldl (+) ((0+1)+2) [3] |
| 18:33:14 | <Cale> | -> foldl (+) (((0+1)+2)+3) [] |
| 18:33:19 | <Cale> | -> ((0+1)+2)+3 |
| 18:33:27 | <Fred320> | That's what foldl' is for, right? |
| 18:33:30 | <Cale> | Yeah |
| 18:33:39 | <Cale> | Those steps I just showed didn't use any stack. |
| 18:34:14 | <FunctorSalad_> | is whnf the thing seq forces? |
| 18:34:15 | <Cale> | But now, evaluating this result will require the stack, because (...) + 3 can't immediately result in something |
| 18:34:20 | <Cale> | FunctorSalad_: yes |
| 18:34:48 | <FunctorSalad_> | hmm |
| 18:34:55 | <Fred320> | @src reverse |
| 18:34:55 | <lambdabot> | reverse = foldl (flip (:)) [] |
| 18:34:59 | <Cale> | FunctorSalad_: WHNF means evaluate up to determining the top-level constructor, and if you just have a lambda, leave it alone. |
| 18:35:22 | <FunctorSalad_> | I see |
| 18:35:40 | <Cale> | (that is, don't start evaluating inside it) |
| 18:37:02 | <Wraithan> | Ooo, a local code get together and they have a haskell session |
| 18:37:07 | <Wraithan> | Think I will go attend that |
| 18:37:07 | <Cale> | Fred320: So, (...) + 3 will get pushed on the stack, and then (...) + 2, and then we'll reach (0+1) which will evaluate, and we'll start coming back up. |
| 18:37:11 | <Wraithan> | http://portlandcodecamp.org/sessions.aspx?tag=Haskell |
| 18:37:18 | <zoheb> | @type liftM2 if' |
| 18:37:19 | <lambdabot> | Not in scope: `if'' |
| 18:38:00 | <Cale> | Fred320: If the list was very long, this might blow up the stack, so foldl' solves the problem by forcing the evaluation of the accumulating parameter on each step. |
| 18:38:11 | <Fred320> | @src foldl' |
| 18:38:12 | <lambdabot> | foldl' f a [] = a |
| 18:38:12 | <lambdabot> | foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs |
| 18:38:12 | <Cale> | That way, the expression never gets very large |
| 18:38:26 | <Fred320> | thanks |
| 18:38:33 | <Cale> | foldl' (+) 0 [1,2,3] |
| 18:38:41 | <zoheb> | @type liftM2 if' |
| 18:38:42 | <lambdabot> | Not in scope: `if'' |
| 18:38:46 | <Cale> | -> let y = 0 + 1 in foldl' (+) y [1,2,3] |
| 18:38:50 | <Cale> | oops |
| 18:38:57 | <Cale> | -> let y = 0 + 1 in y `seq` foldl' (+) y [1,2,3] -- rather |
| 18:39:08 | <zoheb> | @type liftM2 (\x y z -> if x then y else z) |
| 18:39:09 | <Cale> | -> let y = 1 in foldl' (+) y [1,2,3] |
| 18:39:09 | <lambdabot> | forall a2 (m :: * -> *). (Monad m) => m Bool -> m a2 -> m (a2 -> a2) |
| 18:39:22 | <Fred320> | you mwean [2,3] |
| 18:39:24 | <Cale> | damn, I'm making mistakes ;) |
| 18:39:25 | <Cale> | yes |
| 18:39:30 | <Fred320> | i get it ;) |
| 18:39:42 | <Cale> | But yeah, it'll evaluate the 0+1 before recursing |
| 18:39:56 | <Cale> | and then the 1+2, and then the 3+3 |
| 18:40:08 | <Cale> | so that by the time it's done, the 6 will already be evaluated |
| 18:40:13 | <zoheb> | @type liftM2 (\x y z -> if x then y else z) True |
| 18:40:14 | <lambdabot> | Couldn't match expected type `m Bool' against inferred type `Bool' |
| 18:40:14 | <lambdabot> | In the second argument of `liftM2', namely `True' |
| 18:40:18 | <Cale> | > foldl (+) 0 [1..1000000] |
| 18:40:21 | <lambdabot> | * Exception: stack overflow |
| 18:40:23 | <Cale> | > foldl' (+) 0 [1..1000000] |
| 18:40:25 | <lambdabot> | 500000500000 |
| 18:40:29 | <zoheb> | @type liftM2 (\x y z -> if x then y else z) (Just True) |
| 18:40:30 | <lambdabot> | forall a2. Maybe a2 -> Maybe (a2 -> a2) |
| 18:40:33 | <Cale> | It can make a difference :) |
| 18:40:56 | <zoheb> | @type ap |
| 18:40:57 | <lambdabot> | forall (m :: * -> *) a b. (Monad m) => m (a -> b) -> m a -> m b |
| 18:40:58 | <stroan> | @src foldl' |
| 18:40:59 | <lambdabot> | foldl' f a [] = a |
| 18:40:59 | <lambdabot> | foldl' f a (x:xs) = let a' = f a x in a' `seq` foldl' f a' xs |
| 18:41:57 | <zoheb> | @type liftM2 (\x y z -> if x then y else z) (> 0) |
| 18:41:58 | <lambdabot> | forall a2 a. (Ord a, Num a) => (a -> a2) -> a -> a2 -> a2 |
| 18:42:42 | <paper_cc> | is it possible to define an alias for a type context? (for example, I want to write (IsKeyType k) instead of (Ord k, Typeable k)) |
| 18:42:56 | <FunctorSalad_> | paper_cc: it's a proposal :( |
| 18:43:10 | <FunctorSalad_> | paper_cc: a workaround is CPP |
| 18:43:11 | <zoheb> | Is -> a Monad? |
| 18:43:20 | <paper_cc> | zoheb: no |
| 18:43:23 | <ray> | ((->) e) is |
| 18:43:39 | <zoheb> | ray what does that mean? |
| 18:43:56 | <ray> | functions from some type e |
| 18:43:56 | <zoheb> | I am trying to make sense of the following |
| 18:44:01 | <paper_cc> | FunctorSalad: :-/ |
| 18:44:05 | <zoheb> | @type liftM2 (\x y z -> if x then y else z) |
| 18:44:06 | <lambdabot> | forall a2 (m :: * -> *). (Monad m) => m Bool -> m a2 -> m (a2 -> a2) |
| 18:44:16 | <zoheb> | @type liftM2 (\x y z -> if x then y else z) (> 0) |
| 18:44:17 | <lambdabot> | forall a2 a. (Ord a, Num a) => (a -> a2) -> a -> a2 -> a2 |
| 18:44:35 | <zoheb> | Am I using the ((->) e) monad here? |
| 18:44:47 | <FunctorSalad_> | we need some agreed syntax for type meta-variables |
| 18:44:53 | <paper_cc> | zoheb: yes |
| 18:45:07 | <paper_cc> | FunctorSalad_: type meta-variables == ? |
| 18:45:08 | <FunctorSalad_> | (->) E is a monad for every type E |
| 18:45:18 | <ray> | yeah, (> 0) is your m Bool there |
| 18:45:25 | <ray> | in this case, m Bool is e -> Bool |
| 18:45:44 | <zoheb> | ok |
| 18:45:54 | <FunctorSalad_> | hmm |
| 18:45:56 | <frankks> | @src (\\) |
| 18:45:57 | <lambdabot> | (\\) = foldl (flip delete) |
| 18:46:12 | <FunctorSalad_> | I'm a bit confuse |
| 18:46:26 | <ray> | i'm a confusion bit |
| 18:47:14 | <FunctorSalad_> | so do we really mean the monad that maps some type A to the polymorphic type e -> A? |
| 18:47:27 | <kpreid> | confusionBit <- [(False)..] |
| 18:47:38 | <FunctorSalad_> | that type would be a bit pointless |
| 18:48:07 | <paper_cc> | FunctorSalad_: to a *monomorphic* type E -> A for some fixed E |
| 18:48:20 | <FunctorSalad_> | paper_cc: right, that's the ambiguity I meant |
| 18:48:29 | <paper_cc> | aha =) |
| 18:48:29 | <Cale> | FunctorSalad_: No, for *each* e, (->) e is a monad. |
| 18:48:43 | <Cale> | right |
| 18:48:54 | <paper_cc> | @quote fugue |
| 18:48:55 | <lambdabot> | monochrom says: Welcome to #haskell, where your questions are answered in contrapuntal fugues. |
| 18:48:55 | <FunctorSalad_> | Cale: that's what I was trying to say with "e is a meta-variable" |
| 18:49:03 | <FunctorSalad_> | since a type variable makes polymorphic types... |
| 18:49:12 | <zoheb> | I can't find source definitions for the ((->),e) Monad, is it built into the compiler? |
| 18:49:27 | <copumpkin> | control.monad.instances |
| 18:49:34 | <ray> | they have this silly Reader thing |
| 18:49:36 | <paper_cc> | zoheb: no. essentially ((->) e) is the same as (Reader e) |
| 18:49:37 | <Cale> | lol, there's a video here of a top US starcraft player playing in 26 poker games at once. |
| 18:49:41 | <frankks> | could anyone explain what flip delete 'basically' does? |
| 18:49:45 | <Cale> | They accused him of using bots. |
| 18:50:06 | <ray> | a top starcraft player? only 26 poker games? |
| 18:50:10 | <copumpkin> | :t delete |
| 18:50:12 | <lambdabot> | forall a. (Eq a) => a -> [a] -> [a] |
| 18:50:12 | <Cale> | ray: Well, US. |
| 18:50:19 | <copumpkin> | > delete 2 [1..10] |
| 18:50:21 | <paper_cc> | frankks: well, (flip delete) is the same as delete, but with arguments flipped =) |
| 18:50:21 | <lambdabot> | [1,3,4,5,6,7,8,9,10] |
| 18:50:25 | <Cale> | ray: Probably the korean guys could do 100 ;) |
| 18:50:28 | <copumpkin> | > flip delete [1..10] 2 |
| 18:50:30 | <lambdabot> | [1,3,4,5,6,7,8,9,10] |
| 18:50:45 | <ray> | a top korean starcraft player could play 26 poker games at once while also playing starcraft |
| 18:50:50 | <Cale> | haha |
| 18:51:04 | <copumpkin> | :t foldr delete |
| 18:51:05 | <lambdabot> | forall a. (Eq a) => [a] -> [a] -> [a] |
| 18:51:11 | <tetha> | Cale: a korean starcraft player could play so many poker games that joining them takes longer than the first poker game! ;) |
| 18:51:14 | <copumpkin> | that's a useful function :P |
| 18:51:37 | <copumpkin> | > foldr delete [] [1..10] |
| 18:51:38 | <copumpkin> | mmm |
| 18:51:38 | <lambdabot> | [] |
| 18:51:39 | <copumpkin> | :P |
| 18:51:55 | <Cale> | > foldr delete [1..10] [2,4,7] |
| 18:51:57 | <lambdabot> | [1,3,5,6,8,9,10] |
| 18:52:05 | <FunctorSalad_> | I guess the difference is between (pseudo-haskell) "forall e. instance Monad (\a -> e -> a)" and "instance Monad (\a -> forall e. e -> a)" |
| 18:52:13 | <gwern> | anyone familiar with this error in cabal? |
| 18:52:14 | <gwern> | Preprocessing library HaskellForMaths-0.1... |
| 18:52:14 | <gwern> | c:\Program Files\GnuWin32\bin\tar.exe: Cannot fork: Function not implemented |
| 18:52:15 | <gwern> | c:\Program Files\GnuWin32\bin\tar.exe: Error is not recoverable: exiting now |
| 18:52:19 | <gwern> | (sdist) |
| 18:52:19 | <Cale> | FunctorSalad_: yeah |
| 18:52:35 | <gwern> | no dcoutts is not here! |
| 18:52:47 | <Cale> | gwern: Looks like you have a broken implementation of posix |
| 18:53:10 | <paper_cc> | gwern: maybe you should use Cygwin? |
| 18:53:17 | <gwern> | Cale: oh, it's not me. I'm not on windows thank goodness. but I was wondering if tar was installed at all, but I guess that doesn't match |
| 18:55:22 | <PetRat> | test |
| 18:56:03 | <PetRat> | I'm working some exercises in typeclassopedia. One of them is implementing liftM in terms of >>= and return. I get liftM g x = x >>= return . g ? |
| 18:56:32 | <Cale> | yep |
| 18:56:47 | <Cale> | :t \g x -> x >>= return . g |
| 18:56:48 | <lambdabot> | forall a b (m :: * -> *). (Monad m) => (a -> b) -> m a -> m b |
| 18:57:33 | <Cale> | It's prettier in terms of =<< and return |
| 18:57:40 | <Cale> | return . g =<< x |
| 18:57:43 | <edwardk> | @seen saizan |
| 18:57:44 | <lambdabot> | saizan is in #haskell-in-depth, #ghc, #haskell-soc, #haskell-blah, #haskell-overflow, #haskell.it and #haskell. I don't know when saizan last spoke. |
| 18:58:20 | <byorgey> | @pl \g x -> x >>= return . g |
| 18:58:21 | <lambdabot> | fmap |
| 18:58:34 | <ray> | tee hee |
| 18:58:55 | <byorgey> | nice! I didn't realize that @pl knows all monads are functors =) |
| 18:59:29 | <PetRat> | Cale: because it says intuitively "return (inject) the result of applying g to x"? |
| 18:59:37 | <SamB> | it does, in fact, know things that Haskell 98 does not know :-( |
| 18:59:41 | <edwardk> | byorgey: i suppose it could say 'liftM' to be a little more correct |
| 18:59:55 | <Cale> | PetRat: That it applies g to the result of executing x |
| 18:59:56 | <byorgey> | it could. |
| 19:00:20 | <frankks> | have a variable a, which is a list if strings [(string),(string),(string)] etc, and a variable t which is, ([(string),(string),(string)..],[[(string),(string),(string)..]]) - and the expression (a\\(fst t)). I understand it outputs what I want it to, but I can't work out exactly what \\ is doing. Can anyone explain? |
| 19:00:26 | <Cale> | PetRat: In do-notation, it'd be liftM g x = do v <- x; return (g v) |
| 19:00:26 | <frankks> | (sorry for wall of text..) |
| 19:00:37 | <SamB> | but this way, @pl helps us find library bugs |
| 19:00:54 | <Cale> | frankks: \\ is list subtraction |
| 19:01:07 | <byorgey> | frankks: well, if t is a pair of two lists, then fst t is the first of the two lists |
| 19:01:23 | <Cale> | > "mississippi" \\ "miss piggy" |
| 19:01:23 | <frankks> | so it's subtracting the first element from the list t ? |
| 19:01:25 | <lambdabot> | "ssipi" |
| 19:01:32 | <byorgey> | oh, you're asking about \\ in particular. sorry =) |
| 19:01:55 | <Cale> | It removes elements of the second list from the first list. |
| 19:02:04 | <byorgey> | but only one of each. |
| 19:02:07 | <byorgey> | > [1,1,1] \\ [1] |
| 19:02:08 | <Cale> | right |
| 19:02:09 | <lambdabot> | [1,1] |
| 19:02:15 | <Cale> | > [1,1,1] \\ [1,1] |
| 19:02:17 | <lambdabot> | [1] |
| 19:02:24 | <edwardk> | oh, nice, i was thinking about an iterative deepening monad for a toy parser and found that Sebastian Fischer already wrote one. |
| 19:02:37 | <frankks> | ok thanks chaps |
| 19:03:20 | <gwern> | iterative deepening? == breadth-first? |
| 19:04:05 | <tetha> | gwern: limited depth first with increasing limit |
| 19:04:11 | <edwardk> | iterative deepening is depth-first-search to a fixed bound that you keep increasing as you go, starting from 1. so you get the traversal of BFS, with the space efficiency of DFS at the cost of retraversing stuff near the root |
| 19:04:30 | <gwern> | hm. interesting compromise |
| 19:04:41 | <edwardk> | if your branching factor is high you get a huge space win in exchange for a small recomputation cost. |
| 19:05:03 | <edwardk> | i.e. 10-11% extra computation for a branching factor of 10 but huge asymptotic space wins |
| 19:06:04 | <edwardk> | its commonly used in little chess engines, etc. because it combines really really nicely with MTD-f |
| 19:08:23 | <paper_cc> | is it possible to write a Map with keys of type (forall a. Boxed a => Box a), provided that (Boxed a) => (Ord a)? |
| 19:08:46 | <copumpkin> | how would it compare keys of different types? |
| 19:09:14 | <edwardk> | i basically had the strange idea of trying to see if i can improve the asymptotics of a weird parser by treating it like a game, either of parser against string or more likely of parsing top down vs. bottom up cutting off possible parses |
| 19:09:48 | <gwern> | go go game semantics? |
| 19:10:01 | <edwardk> | or much more simply parsing left to right and right to left simultaneously and pruning parses that conflict as i walk left to right and right to left towards the center |
| 19:10:32 | <paper_cc> | copumpkin: yes, it can't do that directly. Not specifically a Map, but a mapping type |
| 19:10:49 | <copumpkin> | I mean, for any mapping type |
| 19:10:54 | <copumpkin> | how would that happen? |
| 19:10:56 | <paper_cc> | ACTION found TypeRep -> IO Int |
| 19:10:58 | <PetRat> | Okay, next exercise is implement ap in terms of >>= and return. (I'm going to use liftM because I already did.) ap x y = x >>= \g -> liftM g y ?? |
| 19:11:22 | <PetRat> | :t x >>= \g -> liftM g y |
| 19:11:23 | <lambdabot> | Couldn't match expected type `m a' against inferred type `Expr' |
| 19:11:23 | <lambdabot> | In the first argument of `(>>=)', namely `x' |
| 19:11:23 | <paper_cc> | copumpkin: I forgot :( (Boxed a) => Typeable a |
| 19:11:46 | <dmwit> | :t \x y -> x >>= \g -> liftM g y |
| 19:11:48 | <lambdabot> | forall (m :: * -> *) a1 b. (Monad m) => m (a1 -> b) -> m a1 -> m b |
| 19:11:52 | <PetRat> | :t \x y -> x >>= \g -> liftM g y |
| 19:11:54 | <lambdabot> | forall (m :: * -> *) a1 b. (Monad m) => m (a1 -> b) -> m a1 -> m b |
| 19:12:27 | <PetRat> | So the types match, which in monad land pretty much guarantees the implementation is correct, no? |
| 19:14:29 | <frankks> | > [2,3,4] \\ [4] |
| 19:14:31 | <lambdabot> | [2,3] |
| 19:14:47 | <frankks> | > [4,3,2] \\ [4] |
| 19:14:49 | <lambdabot> | [3,2] |
| 19:15:36 | <Athas``> | How widespread is Template Haskell in practice? |
| 19:16:52 | <sjanssen> | Athas``: it's not used incredibly frequently, but is used in some projects |
| 19:20:12 | <paper_cc> | copumpkin: so, is it impossible to use TypeReps as keys? (show for TypeRep seems inefficient) |
| 19:21:24 | <copumpkin> | paper_cc: so you'd compare the types of the keys and then their values if their types were equal? |
| 19:21:59 | <paper_cc> | copumpkin: yes, but there doesn't seem to be a stable key for TypeReps |
| 19:23:17 | <copumpkin> | paper_cc: I don't see why you shouldn't be able to use it though |
| 19:23:33 | <copumpkin> | the ordering of the keys is meaningless but should be enough for you to build a map |
| 19:23:40 | <copumpkin> | you can probably unsafePerformIO it too |
| 19:23:48 | <copumpkin> | that typeRepKey function, that is |
| 19:24:40 | <copumpkin> | its implementation just returns a value into IO |
| 19:24:47 | <paper_cc> | copumpkin: the docs say that it isn't guaranteed to be persistent across multiple program executions. |
| 19:24:48 | <paper_cc> | oh |
| 19:24:54 | <paper_cc> | ACTION looks up |
| 19:24:57 | <copumpkin> | well yeah, but neither is your Map |
| 19:26:38 | <paper_cc> | copumpkin: my Map represents a persistent cache and is marshalled between program executions |
| 19:26:50 | <copumpkin> | oh |
| 19:28:43 | <PetRat> | Okay, next exercise is implement sequence in terms of >>= and return (and liftM). How about seq' [] = return [] ;;; seq' (x:xs) = x >>= \y -> liftM (y:) (seq' xs) ??? |
| 19:29:34 | <PetRat> | Is copumkin and pumkin be the same person? |
| 19:30:05 | <jacobian> | self dual? |
| 19:30:07 | <Zao> | I'd say it's his dual :P |
| 19:30:53 | <copumpkin> | yeah, I'm pumpkin's dual |
| 19:31:00 | <copumpkin> | (-core macbook pro) |
| 19:31:39 | <jacobian> | wow, that's a pretty complicated pun |
| 19:32:11 | <copumpkin> | lol, that wasn't why I started using it |
| 19:32:29 | <copumpkin> | it was poking fun at all the co- terms that get thrown around in this community :) |
| 19:33:04 | <Zao> | I'd say it's cofun. |
| 19:34:01 | <PetRat> | Can I use lambdabot to check my work in the above definition of sequence? how do I ask it for the type of a recursive function? |
| 19:37:21 | <PetRat> | :t \g xs -> sequence $ map g xs |
| 19:37:22 | <lambdabot> | forall (m :: * -> *) a a1. (Monad m) => (a1 -> m a) -> [a1] -> m [a] |
| 19:40:08 | <copumpkin> | has anyone made a SQL monad? basically a little DSL that is isomorphic to SQL? |
| 19:40:41 | <Beelsebob> | I thought about making something like that |
| 19:40:54 | <Beelsebob> | then got deep into "how can I make Haskell check my sql statements are type safe" |
| 19:41:00 | <Beelsebob> | and got bored |
| 19:41:31 | <copumpkin> | lol |
| 19:43:39 | <sjanssen> | copumpkin: haskelldb has one, I think? |
| 19:46:14 | <copumpkin> | I see |
| 19:48:50 | <koeien> | this is like HaskellDB, but that has bitrotted |
| 19:49:30 | <Heffalump> | copumpkin: SQL isn't really a monad |
| 19:49:52 | <Heffalump> | ACTION has done some work on a SQL DSL using associated type synonyms, but it's rather incomplete |
| 19:51:09 | <monadic_kid> | Heffalump: query comphrensions is probably what you want to look at |
| 19:52:20 | <Heffalump> | monadic_kid: as in the Wadler/SPJ paper? |
| 19:56:02 | <voker57__> | can i see usage examples of Text.JSON or RJson somewhere? |
| 19:56:11 | <voker57__> | like some app that uses on of those |
| 19:56:55 | <voker57__> | in google people tend to write JSON parsers themselves |
| 19:57:39 | <edwardk> | ACTION has a json parser in javascript already, its called eval ;) |
| 19:58:22 | <voker57__> | eh... is that #javascript? |
| 19:58:32 | <gwern> | voker57__: well, you could download all of hackage, untar it all, and grep for the package names :) |
| 19:59:13 | <edwardk> | voker57__: i tried talking in #javascript for a while, but they give me even more grief than the folks around here when I start talking about comonads. |
| 19:59:26 | <Raevel> | :-D |
| 19:59:30 | <gwern> | edwardk: they don' |
| 19:59:36 | <gwern> | t even being to have the background |
| 19:59:59 | <gwern> | so I don't really blame them. if someone came here chattering in lojban about epigram, we'd probably give them grief too |
| 20:00:15 | <edwardk> | i've seen a couple of javascript "monadic" parser combinator libraries and monad implementations. |
| 20:00:16 | <Raevel> | edwardk: maybe they'll listen after you rewrite their script so confirm stops no worky:ing |
| 20:00:33 | <edwardk> | gwern: nah i think there are at least 4-5 people on here that understand lojban ;) |
| 20:00:39 | <Twey> | .i zo'o mi se cinri la .epigram. |
| 20:00:47 | <gwern> | surely there can't be that many? |
| 20:00:52 | <Twey> | Think so |
| 20:00:59 | <Heffalump> | ACTION would still like to see a useful abstraction provided by comonads |
| 20:01:00 | <Twey> | There's a fairly substantial overlap between the communities |
| 20:01:04 | <gwern> | @seen |
| 20:01:11 | <gwern> | @users |
| 20:01:12 | <edwardk> | i've had several discussions on here about it with various folks |
| 20:01:12 | <lambdabot> | Maximum users seen in #haskell: 658, currently: 644 (97.9%), active: 23 (3.6%) |
| 20:01:33 | <Twey> | edwardk: eval() parses considerably more than JSON |
| 20:01:36 | <edwardk> | Heffalump: i trip over cofree comonads all over the place. |
| 20:01:39 | <gwern> | wait, if there are 23 active users, and 1 has claimed lojban knowledge, then I should infer that... |
| 20:01:47 | <gwern> | > 658 * (1/23) |
| 20:01:49 | <lambdabot> | 28.608695652173914 |
| 20:01:53 | <Twey> | That's a fair few people |
| 20:01:59 | <gwern> | 28 lojban users? -_- |
| 20:02:02 | <edwardk> | Twey: sure. and that was said slightly tongue in cheek. i understand the security reasons, etc. but its also hard to argue with parsing 50-100x faster ;) |
| 20:02:08 | <Twey> | gwern: Point six! |
| 20:02:10 | <Raevel> | more like 29! |
| 20:02:35 | <gwern> | Twey: sure, we'll count the headless armless torso in the corner over there |
| 20:02:45 | <Twey> | edwardk: Well, it is possible to do a check for valid JSON first, then apply eval() for the actual parsing |
| 20:02:52 | <Twey> | Don't know how worthwhile that is, though |
| 20:02:59 | <Heffalump> | edwardk: can you give an example of some generic code that is useful over such structures? |
| 20:03:01 | <Twey> | gwern: *grin* |
| 20:04:36 | <edwardk> | Heffalump: i have some comonadic cellular automata code around here somewhere, i use the cofree comonad for incremental folds, in particular i use it to annotate tree structures (applicatives) with sharing information in a reasonably safe manner |
| 20:05:52 | <edwardk> | Heffalump: g_cata is defined for any comonad you can find distributive laws for, there are a bunch of those which give rise to destructive half of Control.Morphism.* in category-extras |
| 20:06:27 | <edwardk> | i use those mostly as an aid for my thought patterns when i'm trying to figure out if a particular fold-like function can even exist |
| 20:07:41 | <TomMD> | Are there rational trig functions in prelude somewhere? |
| 20:08:03 | <roconnor> | rational trig functions? Like spread? |
| 20:08:07 | <edwardk> | another use i've had for them, which feeds back to the cofree comonad as fixed-point + incremental fold is for dealing with attribute grammars |
| 20:08:22 | <TomMD> | sin, cos, etc |
| 20:08:36 | <roconnor> | are those called rational trig functions? |
| 20:08:38 | <edwardk> | tomMD: like CORDIC versions of the traditional trig functions? |
| 20:08:38 | <roconnor> | anyhow |
| 20:08:45 | <roconnor> | > sin(pi/2) |
| 20:08:46 | <TomMD> | Rational being 'Ratio Integer' |
| 20:08:47 | <lambdabot> | 1.0 |
| 20:08:55 | <TomMD> | > sin (pi / 2) :: Rational |
| 20:08:56 | <lambdabot> | No instance for (Floating Rational) |
| 20:08:56 | <lambdabot> | arising from a use of `pi' a... |
| 20:09:02 | <TomMD> | > sin (toRational pi / 2) :: Rational |
| 20:09:03 | <lambdabot> | No instance for (Floating Rational) |
| 20:09:03 | <lambdabot> | arising from a use of `sin' ... |
| 20:09:06 | <Heffalump> | edwardk: I guess I'd have to see some code to understand properly, but thanks |
| 20:09:09 | <edwardk> | tomMD: the problem is when do you stop. thats kind of the definition of Real vs. Rational ;) |
| 20:09:20 | <roconnor> | TomMD: you cannot get more transcendtal that trig functions. |
| 20:09:39 | <edwardk> | Heffalump: http://comonad.com/ my last post on incremental folds uses a cofree comonad, it just doesn't bother to call attention to it very much |
| 20:09:48 | <roconnor> | The defining property of real numbers is practically that you can do sin and cos in them. |
| 20:10:09 | <joeally> | What is the difference between LHC and GHC |
| 20:10:13 | <TomMD> | Damn reals |
| 20:10:17 | <joeally> | should I stick with GHC |
| 20:10:25 | <TomMD> | joeally: GHC is usable as a full compiler - so yes |
| 20:10:33 | <joeally> | okay |
| 20:10:35 | <roconnor> | well, the result of sin and cos are real numbers, You can easily pass them rational numbers. |
| 20:10:36 | <TomMD> | joeally: LHC has became a backend to GHC. |
| 20:10:40 | <joeally> | oh |
| 20:10:43 | <roconnor> | > sin (fromRational (5/2)) |
| 20:10:44 | <lambdabot> | 0.5984721441039565 |
| 20:10:49 | <joeally> | TomMD:thanks |
| 20:10:57 | <TomMD> | roconnor: Yes, I understand - I'll just have to do much conversion. Thanks. |
| 20:11:02 | <Twey> | What's LHC? |
| 20:11:05 | <Twey> | First I've heard of that one |
| 20:11:10 | <Philippa> | edwardk: what's the quick definition of 'cofree'? I'm not quite sure why, but I'm having trouble picturing it |
| 20:11:16 | <TomMD> | Twey: LHC used to be a JHC fork |
| 20:11:28 | <roconnor> | TomMD: please say that you only require rational inputs to these. |
| 20:11:34 | <TomMD> | Twey: LHC is now being redefined as a GRIN optimizing backend for GHC. |
| 20:11:45 | <edwardk> | Philippa: newtype Cofree f a = Cofree { runCofree :: (a, f (Cofree f a)) } |
| 20:11:47 | <roconnor> | TomMD: what are you doing anyways? |
| 20:11:48 | <TomMD> | roconnor: I only require rational inputs and outputs. |
| 20:12:02 | <Twey> | Aha |
| 20:12:04 | <roconnor> | TomMD: you aren't going to get rational outputs out of trig functions. |
| 20:12:12 | <Heffalump> | edwardk: is any f a valid parameter there? |
| 20:12:18 | <TomMD> | roconnor: Its for a GPS library. Double will do, but I figured people who want more accuracy might use Rational and people who don't care can make a very simple conversion. |
| 20:12:23 | <inimino> | Large Haskell Collider? |
| 20:12:27 | <roconnor> | TomMD: certainly not for rational inputs. |
| 20:12:28 | <Lemmih> | Twey: It's the Luxurious Haskell Compiler. A highly optimising backend for GHC. |
| 20:12:34 | <edwardk> | Heffalump: unlike Codensity/Density you need f to be a Functor. |
| 20:12:40 | <TomMD> | roconnor: Yes, I understand. |
| 20:12:44 | <roconnor> | TomMD: people who want more accuracy use CReal :P |
| 20:12:51 | <roconnor> | > cos (10^100) :: CReal |
| 20:12:52 | <lambdabot> | -0.9280819050746553434561946437769559281832 |
| 20:12:59 | <roconnor> | > cos (10^100) -- :( |
| 20:13:00 | <lambdabot> | -0.9994551172253643 |
| 20:13:11 | <TomMD> | roconnor: I keep hearing CReal, but I'm not clear on its properties. Is it a 128bit float or some such? |
| 20:13:12 | <Heffalump> | TomMD: I have some random bits and pieces of GPS code, btw. I'd be interested in seeing what you're doing. |
| 20:13:13 | <edwardk> | since you have to fmap (fmap a) to drill into f (Cofree f a) -- for fmap purposes |
| 20:13:20 | <Philippa> | edwardk: that's a cofree comonad rather than a cofree object in general, no? |
| 20:13:27 | <roconnor> | TomMD: nope, it is infinite precision. |
| 20:13:36 | <TomMD> | Heffalump: I proposed the basic API on haskell-proposals reddit a bit ago. |
| 20:13:37 | <edwardk> | Philippa: as i understand the world, yes. |
| 20:13:47 | <Heffalump> | TomMD: yeah, I saw that. Didn't get round to commenting. |
| 20:13:51 | <TomMD> | Heffalump: I'll cabalize / upload to hackage /blog when I finish. |
| 20:13:59 | <roconnor> | TomMD: there is an arbitrary precision floating point library out there too. |
| 20:14:13 | <Heffalump> | most of what I have is code to talk to the two sources of GPS data I have |
| 20:14:39 | <TomMD> | roconnor: I'll use CReal then - it sound like just the ticket (so long as people can convert to Fractional a as they desire) |
| 20:14:49 | <roconnor> | TomMD: In theory you don't need real numbers to do geometry |
| 20:14:58 | <TomMD> | Heffalump: I'm doing GPS computations (heading, distance, vectors) |
| 20:15:04 | <roconnor> | TomMD: be aware that CReals is potentially slow |
| 20:15:08 | <Heffalump> | TomMD: what's the point in using more precision that the data you'll be working with? |
| 20:15:09 | <TomMD> | speed... trail smoothing (to eliminate invalid points) |
| 20:15:12 | <Heffalump> | just use Double and be done with it.. |
| 20:15:32 | <TomMD> | Heffalump: It all depends the precision of what people work with I suppose. |
| 20:15:44 | <Philippa> | edwardk: I meant cofreeness in general - I think I've got a grasp on what it is to be 'free', though I wouldn't want to put it into words while I'm feeling dopey |
| 20:15:50 | <roconnor> | CReals could be 1000x slower that Double. Maybe more? |
| 20:15:58 | <Philippa> | at least, not if there's any penalty for inaccuracy :-) |
| 20:16:00 | <TomMD> | But rational was overkill, I admit. Without an Earth model that uses height, I probably don't need double. |
| 20:16:01 | <Heffalump> | I haven't worked it out, but I'd expect Double to be several orders of magnitude more precise than GPS. |
| 20:16:19 | <edwardk> | Philippa: i.e. as in 'left adjoint to a forgetful functor'? |
| 20:16:32 | <TomMD> | Heffalump: Its more just becuase I figured this could get used by systems that have rationals in other sections, so I'd just remain consistent with what I thought was the best type. |
| 20:16:43 | <Philippa> | edwardk: I tend to think of it as "all syntax, no semantics", but yes |
| 20:17:08 | <Heffalump> | I'd say Double is the best type. Rational is pretty inefficient too. |
| 20:17:34 | <Heffalump> | unless you think there's a significant likelihood of FP roundoff problems |
| 20:17:34 | <TomMD> | Its an easy change - mostly I'll just change my type X = Rational to type X = Double in a couple spots. |
| 20:17:58 | <TomMD> | Heffalump: One FP round off problem is more than too much. |
| 20:18:10 | <TomMD> | @google patriot missle failure |
| 20:18:11 | <lambdabot> | http://www.ima.umn.edu/~arnold/disasters/patriot.html |
| 20:18:11 | <lambdabot> | Title: The Patriot Missile Failure |
| 20:18:42 | <Heffalump> | overloading the entire library on the type might also be feasible |
| 20:18:55 | <Heffalump> | looking at your proposal, why is Coordinate a type class but Vector not? |
| 20:19:13 | <TomMD> | I'm wary of too many typeclasses, but I will consider it. |
| 20:19:46 | <roconnor> | TomMD: FP round off is usually only a problem when accumulating values, which you may or may not be doing here. |
| 20:20:14 | <Heffalump> | there's rarely a reason to accumulate values with a GPS, because you get brought back to reality by the next point |
| 20:20:23 | <roconnor> | TomMD: the sort of it is that, CReal is slow exactly when FP round off is problematic. |
| 20:20:39 | <Heffalump> | I tend to agree about overloading on that being too many typeclasses. |
| 20:21:15 | <TomMD> | I'm going to switch it to Double for now but give it more thought before uploading / doing anything complex. |
| 20:22:16 | <h0tzenpl0tz> | does anyone know the exact scrabble-rules? i wonder if i may complete multiple side-by-side words like " foo bar " with "XXfooXbarXXXXX". would this be an allowed move? |
| 20:22:58 | <Beelsebob> | h0tzenpl0tz: all letters must be placed in a single line |
| 20:23:05 | <Beelsebob> | and make up one word along that line |
| 20:23:13 | <roconnor> | h0tzenpl0tz: what are the X's? |
| 20:23:14 | <Beelsebob> | they may also make other words intersecting with it |
| 20:23:24 | <Beelsebob> | but no more than one word on that line |
| 20:23:26 | <h0tzenpl0tz> | the x is a tile from my rack |
| 20:23:44 | <Philippa> | if you can find a word in the dictionary that fits that pattern, yes |
| 20:23:52 | <Beelsebob> | h0tzenpl0tz: yes, that's an allowed move then, if foo bar were already on the board |
| 20:24:10 | <Twey> | h0tzenpl0tz: You can only place a word side-by-side if each letter makes a word horizontally |
| 20:24:17 | <Philippa> | talking of which, is fubar an allowable word under current rules? |
| 20:24:35 | <Beelsebob> | Philippa: depends what country you're playing in |
| 20:24:45 | <Twey> | E.G. you can't have foo\nbar because ‘fb’, and ‘oa’ aren't words |
| 20:24:56 | <roconnor> | Rumour has it that the top Scrabble player is a Chinese man who doesn't speak English. |
| 20:25:02 | <Twey> | Beelsebob: There's an international English Scrabble dictionary |
| 20:25:02 | <Philippa> | Beelsebob: different rules, or different dictionary of choice? |
| 20:25:12 | <Twey> | Which is generally held to be the standard |
| 20:25:26 | <Beelsebob> | Twey: yeh, but that doesn't stop people playing by different dictionaries in different countries |
| 20:25:54 | <h0tzenpl0tz> | thank you all |
| 20:26:09 | <Philippa> | Beelsebob: including, of course, the cat dictionary |
| 20:26:14 | <h0tzenpl0tz> | thats pretty disgusting to implement :( |
| 20:26:18 | <h0tzenpl0tz> | over & out |
| 20:26:22 | <Beelsebob> | h0tzenpl0tz: not at all |
| 20:26:25 | <Beelsebob> | that's easy to implement |
| 20:26:33 | <h0tzenpl0tz> | i wouldnt know how |
| 20:26:53 | <Beelsebob> | 3 conditions must hold... all letters must be in a line; all letters must form a complete word along that line; and all combinations they form must be words |
| 20:27:00 | <Philippa> | Beelsebob: I think h0tzenpl0tz means for an AI player? It's easy to validate the move... |
| 20:27:01 | <Beelsebob> | each of those is easy to implement |
| 20:27:14 | <Beelsebob> | Philippa: oh, yeh, for AI it may be harder |
| 20:27:21 | <h0tzenpl0tz> | indeed ;) |
| 20:27:30 | <h0tzenpl0tz> | thanks nevertheless |
| 20:27:34 | <Beelsebob> | ACTION would suspect for a scrabble AI you might need to have an algorithm for spotting places to play |
| 20:27:38 | <Beelsebob> | before coming up with words |
| 20:27:48 | <sinelaw> | @djinn a->a->a |
| 20:27:50 | <Beelsebob> | i.e. a heuristic search of places it wants letters to land |
| 20:27:50 | <lambdabot> | f _ a = a |
| 20:28:13 | <h0tzenpl0tz> | yeah that works but it doesnt connect multiple side-by-side words :( |
| 20:28:16 | <h0tzenpl0tz> | tryin harder... |
| 20:28:24 | <Beelsebob> | hehe, fun |
| 20:28:49 | <Philippa> | h0tzenpl0tz: look for all 1-letter, 2-letter etc plays. Squares first, then the dictionary bash |
| 20:29:22 | <Philippa> | the point being to calculate the connections made with each play so you've got your validation burdens |
| 20:29:58 | <Beelsebob> | Philippa: I would expect you can significantly narrow down your options by doing things like "I have a z, I want it on the tripple letter, this means I can grep the dictionary for z..a.h" etc |
| 20:30:36 | <h0tzenpl0tz> | build a dictionary before that allows these patterns efficiently :) |
| 20:30:40 | <Philippa> | Beelsebob: *nod*. But I leave that to people who're good at AI, you can rearrange the problem at will once you know what it looks like :-) |
| 20:31:21 | <Beelsebob> | true |
| 20:41:30 | <Philonous> | Is there a way to kill external processes once the programm invoking them gets shut down? |
| 20:43:24 | <vininim_> | gosh, importing parsec qualified is not a good idea if you want to use the operators |
| 20:43:36 | <PeakerWork> | Philonous: I think normally processes get a SIGHUP in Unix when their parent process dies |
| 20:43:52 | <PeakerWork> | Philonous: You can also keep a pipe between the parent and the children, and the children can die when they hit EOF on that pipe |
| 20:44:25 | <Tobsan> | PeakerWork: you can also do runCommand with some kind of pkill if you want to do it the ugly way |
| 20:44:28 | <Philonous> | I was incoking from inside a haskell thread and it kept running when I killed the haskell process |
| 20:44:31 | <Philonous> | invoking* |
| 20:44:52 | <marcot> | vininim_: qualified operators are not very nice. |
| 20:47:20 | <PeakerWork> | vininim_: Use: import Blah((*), (|||), ...) |
| 20:47:34 | <PeakerWork> | Its nicer than having to guess where operators come from |
| 20:47:43 | <PeakerWork> | (not qualified operators, but explicitly named operators) |
| 20:47:54 | <aempirei> | lol |
| 20:49:44 | <vininim_> | marcot: hello \o |
| 20:49:51 | <camio> | How did the new #haskell-in-depth come about? |
| 20:51:41 | <Heffalump> | camio: reduce traffic volume on here |
| 20:53:51 | <camio> | Juding from the traffic there, it doesn't seem like it took of a significant chunk of traffic away so far. |
| 20:54:09 | <camio> | s/ of// |
| 20:56:26 | <camio> | Maybe the confusion of having two channels would induce someone to just leave. That could reduce traffic :) |
| 20:56:49 | <Heffalump> | it does allow slower paced discussions on there, too |
| 20:56:55 | <Heffalump> | I think it's worked fairly well |
| 20:57:15 | <marcot> | vininim_: /j #haskell.pt |
| 20:57:44 | <camio> | cool |
| 21:06:55 | <lament> | what's a pretty way to find, in a sorted list of numbers, the greatest number (if it exists) s.t. the list contains 6 numbers in a row including that one? |
| 21:07:23 | <Heffalump> | 6 numbers the same> |
| 21:07:24 | <Heffalump> | ? |
| 21:07:34 | <Philippa> | in sequence |
| 21:07:39 | <lament> | no, in a row, like 4,5,6,7,8,9 |
| 21:07:44 | <mxc> | well, already sorted |
| 21:07:46 | <Philippa> | eg 1234567 would yield 7 |
| 21:07:48 | <lament> | yes |
| 21:07:49 | <Heffalump> | oh, right |
| 21:07:51 | <mxc> | so like 1,2,2,2,2,2,4,5 would return 2? |
| 21:07:52 | <solrize_> | groupBy |
| 21:07:54 | <solrize_> | :t groupBy |
| 21:07:55 | <lambdabot> | forall a. (a -> a -> Bool) -> [a] -> [[a]] |
| 21:08:07 | <lament> | mxc: sorted, no duplicates |
| 21:08:31 | <mm_freak> | lament: how about taking the last element? or the first |
| 21:08:35 | <mm_freak> | if the list is sorted |
| 21:08:37 | <Heffalump> | I'd calculate successive differences, then map (take 6) . tails |
| 21:08:37 | <lament> | > group by (\x y -> y = x + 1) [1,2,3,4,5,6,7,9,10] |
| 21:08:38 | <lambdabot> | <no location info>: parse error on input `=' |
| 21:08:42 | <lament> | > group by (\x y -> y == x + 1) [1,2,3,4,5,6,7,9,10] |
| 21:08:44 | <lambdabot> | Not in scope: `by' |
| 21:08:47 | <lament> | > groupBy (\x y -> y == x + 1) [1,2,3,4,5,6,7,9,10] |
| 21:08:49 | <lambdabot> | [[1,2],[3,4],[5,6],[7],[9,10]] |
| 21:08:54 | <Heffalump> | then filter by all (==1) |
| 21:09:02 | <mm_freak> | > last . sort $ [3,5,1,7,4,4] |
| 21:09:03 | <lambdabot> | 7 |
| 21:09:08 | <Philippa> | lament: accumulate "consecutive numbers" and "biggest number where consecutive >= 6"? |
| 21:09:25 | <Heffalump> | that finds you the sequences but doesn't tell you what they actually were, so zip with the original numbers at some point before the filter |
| 21:09:30 | <Philippa> | (which also means accumulating last number) |
| 21:09:30 | <Heffalump> | and then just take the last |
| 21:09:44 | <camio> | lament: What do those numbers represent? Why are they in sorted order in the first place? |
| 21:09:44 | <solrize_> | > groupBy (==) $ zipWith (-) [1,4,5,7,8,9,10,11,12,13,15,30] [1..] |
| 21:09:46 | <lambdabot> | [[0],[2,2],[3,3,3,3,3,3,3],[4],[18]] |
| 21:09:46 | <Philippa> | admittedly that's a really imperative way of doing it :-) |
| 21:10:18 | <lament> | solrize_: oo |
| 21:10:18 | <solrize_> | > last $ filter ((>=6) . length) $ groupBy (==) $ zipWith (-) [1,4,5,7,8,9,10,11,12,13,15,30] [1..] |
| 21:10:20 | <lambdabot> | [3,3,3,3,3,3,3] |
| 21:10:25 | <mm_freak> | i don't get it, what's the difficulty of extracting the largest element of an already-sorted list? |
| 21:10:48 | <lament> | mm_freak: given [1,2,3,4,5,6,8] the functions should return 6. |
| 21:10:55 | <lament> | *function |
| 21:11:05 | <Heffalump> | mm_freak: the last element with a particular property |
| 21:11:11 | <lament> | (or rather Just 6 since there may not be an answer) |
| 21:11:11 | <Heffalump> | identifying the property is the tricky bit |
| 21:11:15 | <mm_freak> | in what sense is 6 larger than 8? |
| 21:11:24 | <lament> | in none. |
| 21:11:30 | <Heffalump> | mm_freak: 8 isn't part of a sequence |
| 21:11:38 | <Philippa> | last . last . filter (longEnough) . groupBy (isOneGreaterThan) ? |
| 21:11:39 | <mm_freak> | ah, ok, in sequence |
| 21:11:44 | <Philippa> | with the predicates filled in? |
| 21:12:15 | <solrize_> | > last $ filter ((>=6) . length) $ groupBy \(a,b) -> (a-b == 1) $ zip (-) [1,4,5,7,8,9,10,11,12,13,15,30] [1..] |
| 21:12:16 | <lambdabot> | <no location info>: parse error on input `\' |
| 21:12:37 | <solrize_> | > last $ filter ((>=6) . length) $ groupBy (\(a,b) -> a-b == 1) $ zip (-) [1,4,5,7,8,9,10,11,12,13,15,30] [1..] |
| 21:12:38 | <lambdabot> | Couldn't match expected type `(t, t) -> Bool' |
| 21:12:49 | <solrize_> | > last $ filter ((>=6) . length) $ groupBy (\(a,b) -> (a-b == 1)) $ zip (-) [1,4,5,7,8,9,10,11,12,13,15,30] [1..] |
| 21:12:50 | <lambdabot> | Couldn't match expected type `(t, t) -> Bool' |
| 21:12:57 | <solrize_> | hmm. well you get the idea |
| 21:14:25 | <lament> | groupBy takes two arguments |
| 21:15:12 | <lament> | > groupBy (\(a,b) (c,d) -> (a-b == c-d)) $ zip (-) [1,2,3,4,5,6,7,9] [1..] |
| 21:15:13 | <lambdabot> | Couldn't match expected type `[a]' |
| 21:15:42 | <lament> | (i meant the predicate to groupBy) |
| 21:16:40 | <mm_freak> | lament: at which point do you consider numbers "in sequence"? at least two consequtive numbers? |
| 21:17:03 | <mm_freak> | s/q/c/ |
| 21:17:23 | <lament> | yes |
| 21:17:41 | <lament> | so the largest number in a sequence of at least 6 consecutive numbers |
| 21:17:51 | <mm_freak> | at least 6, ok |
| 21:18:59 | <Heffalump> | TomMD: my GPS stuff is here if you are interested: http://urchin.earth.li/darcs/ganesh/gps/ |
| 21:19:21 | <mm_freak> | groupBy would work nicely if it compared with the preceding element, not with the first element of a group |
| 21:19:25 | <mm_freak> | that's very annoying |
| 21:19:39 | <mm_freak> | > groupBy (\x y -> y == x+1) [1,2,3,5,6,7,8,9,11,13,14,15] |
| 21:19:40 | <lambdabot> | [[1,2],[3],[5,6],[7,8],[9],[11],[13,14],[15]] |
| 21:20:01 | <mm_freak> | i'd write an own version of groupBy and use it |
| 21:20:36 | <mm_freak> | then just apply: maximum . map last . filter ((>6) . length) |
| 21:21:08 | <centrinia> | Uh, why isn't [5,6,7,8,9] in a group? |
| 21:21:31 | <mm_freak> | centrinia: because groupBy compares each element with 5, not with the preceding element |
| 21:21:41 | <mm_freak> | i.e. with the first group member |
| 21:22:33 | <mm_freak> | uhm yeah, and replace >6 by >=6 =) |
| 21:33:04 | <lament> | > (fst . last . last) $ filter ((>=6) . length) $ groupBy (\(a,b) (c,d) -> a-b == c-d) $ zip [1,2,3,4,5,6,7,9,11,12,13,14,15,16,20] [1..] |
| 21:33:05 | <lambdabot> | 16 |
| 21:33:09 | <lament> | this works. But i did ask for a pretty way :) |
| 21:33:13 | <TomMD> | Is there a package with a Binary instance for Double that people have agreed on? |
| 21:37:06 | <dons> | Data.Binary comes with instances for Double |
| 21:37:11 | <dons> | just not ieee ones, haskell ones. |
| 21:40:45 | <byorgey> | http://haskell.org/haskellwiki/Hac_%CF%86 |
| 21:41:08 | <byorgey> | Hackathon in Philadelphia! sign up now, limited space! ;) |
| 21:41:34 | <skorpan> | someone please tell me what is HP? haskell platform? |
| 21:41:38 | <skorpan> | or haskell prime? |
| 21:41:49 | <Lemmih> | Hit points? |
| 21:41:51 | <c_wraith> | possibly Harry Potter. kids these days... |
| 21:41:57 | <skorpan> | ... |
| 21:42:14 | <Vq^> | HP Sauce? |
| 21:42:15 | <eivuokko> | skorpan, I am afraid the quality of answers is dependent on additional context you can give. |
| 21:42:22 | <byorgey> | skorpan: probably Haskell Platform. Haskell prime is usually abbreviated Haskell' . |
| 21:42:42 | <skorpan> | eivuokko: the context is the mailing list. |
| 21:42:58 | <Philonous> | Hewlett Packard? |
| 21:43:19 | <skorpan> | okay, so let's assume it's the haskell platform. what *is* the haskell platform? new hackage? new cabal? |
| 21:43:35 | <eivuokko> | Standard set of tools. |
| 21:43:43 | <Vq^> | Horsepower? |
| 21:43:49 | <Zao> | http://www.haskell.org/haskellwiki/Haskell_Platform <- that'a'thing |
| 21:43:50 | <dons> | go upenn http://www.haskell.org/haskellwiki/Hac_φ |
| 21:43:55 | <skorpan> | kind of haskell stdlib? |
| 21:44:06 | <dons> | skorpan: kinda a haskell extended stdlib |
| 21:44:10 | <dons> | like super extended |
| 21:44:33 | <Zao> | dons: I've heard that escaping URLs helps with communicating. |
| 21:44:38 | <roconnor> | ``The platform prevents you from picking and choosing the best Haskell libraries and tools to use for a task. |
| 21:44:40 | <xs> | why is a rose tree called a rose tree, and who named it thus? |
| 21:44:46 | <Zao> | Unless you intended to link to "Hac Æ" |
| 21:44:49 | <skorpan> | so this is supposed to replace the thousands of haskell libraries in arch's repos? |
| 21:44:54 | <dons> | roconnor: i don't think that's a quote |
| 21:45:06 | <dons> | skorpan: no. |
| 21:45:30 | <roconnor> | close enough |
| 21:45:31 | <gwern> | skorpan: the platform is just an organizational idea |
| 21:45:51 | <Zao> | http://www.haskell.org/haskellwiki/Hac_%CF%86 <- clever use of phi though :) |
| 21:45:53 | <gwern> | to use a WP metaphor: the platform is a category; all the articles remain as before |
| 21:45:55 | <dons> | roconnor: why? |
| 21:46:12 | <skorpan> | gwern: that's a metaphor i can understand |
| 21:46:20 | <dons> | if you want to pick and choose, install the platform, then fire up cabal-install |
| 21:46:23 | <skorpan> | and hackage is a supercategory of haskell platform? |
| 21:46:24 | <Philonous> | Is there a package for command line options parsing? |
| 21:46:29 | <gwern> | ACTION is obscurely pleased |
| 21:46:34 | <gwern> | skorpan: hackage is Special:Allpages |
| 21:46:41 | <skorpan> | yeah, cool :) |
| 21:46:45 | <gwern> | (because if it's not on hackage it doesn't exist!) |
| 21:47:03 | <dons> | Philonous: in the base library |
| 21:47:11 | <roconnor> | dons: exactly. so why platform. |
| 21:47:20 | <Philonous> | thanks dons |
| 21:47:41 | <skorpan> | will there always be exactly one version of each package in HP? |
| 21:47:43 | <roconnor> | ... actually the platform makes sense given that cabal cannot properly track version interfaces. |
| 21:48:07 | <roconnor> | I'd rather see cabal fixed, but I suppose that is a much more difficult task. |
| 21:48:57 | <dons> | roconnor: for people who don't use cabal-install |
| 21:49:01 | <skorpan> | on a completely unrelated topic: when will darcs cease to be the norm for haskell projects? |
| 21:49:16 | <dons> | and who don't want the latest version of everything |
| 21:49:19 | <gwern> | skorpan: hopefully never |
| 21:49:23 | <dons> | skorpan: 2020? |
| 21:49:24 | <skorpan> | dons: the yi project ;P |
| 21:49:30 | <dons> | git has a small inroad, but that's it |
| 21:49:39 | <Zao> | dons: People who want to use previous versions due to source incompatibilities? |
| 21:49:40 | <skorpan> | dons: but that's only because new versions tend to break other packages |
| 21:49:57 | <Zao> | ACTION shakes a fist at people who make breaking changes in subminor version bumps. |
| 21:50:02 | <roconnor> | and new versions only break packages because cabal doesn't track version interfaces properly. |
| 21:50:04 | <Zao> | Yes vector-space, I'm looking at you. |
| 21:50:13 | <dons> | no, a lot of users who don't hang out on #haskell don't want every minor version, or to choose the cutting edge of everything |
| 21:50:14 | <roconnor> | well, I guess not "only", but largely |
| 21:50:16 | <dons> | i.e. industrial users |
| 21:50:27 | <PeakerWork> | git is pretty cool -- if someone wrote a sane UI around it, and added some more meta-data to rebases, it would have all of darcs' advantages, and I think even without it its already preferable |
| 21:50:30 | <dons> | who just want a stable set that builds stable things for years, without having to do research |
| 21:50:35 | <dons> | these people generally don't hang out here. |
| 21:50:38 | <dons> | so you need both |
| 21:50:48 | <dons> | a cutting edge set for developers (hackage), and a stable base for everyone else |
| 21:51:12 | <gwern> | PeakerWork: I am moderately sure that git doesn't have all of darcs's patch manipulation stuff |
| 21:51:12 | <roconnor> | dons: you could be right, but I'm still skeptical. |
| 21:51:31 | <dons> | that's fine. there's already been 1000s of downloads :) |
| 21:51:39 | <roconnor> | yep |
| 21:51:40 | <roconnor> | :) |
| 21:51:41 | <gwern> | (release early, release often!) |
| 21:51:54 | <roconnor> | entrenching the mtl for life :P |
| 21:52:08 | <dons> | the other thing is to ensure that the platform is on every system |
| 21:52:08 | <PeakerWork> | gwern: I think it can relatively easy have them in the form of rebases, except rebases currently lack meta-data |
| 21:52:15 | <dons> | so you can't get away with say, ubuntu being 2 years out of date |
| 21:52:24 | <dons> | unless we /tell/ distros whta to package, they make arbitrary choices |
| 21:52:36 | <skorpan> | good thing arch exists |
| 21:53:08 | <roconnor> | dons: hmm, I find that distros argument is more compelling. |
| 21:53:21 | <gwern> | yes, that's a good point about the HP. now we can complain that they've only got x% of the HP |
| 21:53:27 | <Philonous> | dons: Do you know which Module contains the options parsing? |
| 21:54:18 | <dons> | System.Console.GetOpt |
| 21:54:21 | <PeakerWork> | gwern: git lets you do any kind of cherry picking of patches that darcs does - except you can retroactively choose different diff strategies for patch generation, when doing the cherry picks, which is more powerful than what darcs can - as darcs commits to a specific way of diffing in the whole repo |
| 21:54:23 | <Philonous> | Thanks |
| 21:54:31 | <skorpan> | Philonous: or try parseargs |
| 21:55:06 | <skorpan> | is there any generalized version of (\\)? i wrote my own one, bug included |
| 21:55:26 | <gwern> | PeakerWork: I'm not too up on DVCSs, but I've been assured by the other darcs dev that darcs can commute patches in ways git won't/can't |
| 21:55:35 | <gwern> | although I'm glad git can at least cherry pick changes... |
| 21:55:48 | <skorpan> | gwern++ |
| 21:55:58 | <skorpan> | that's one of the big things i miss in hg |
| 21:56:59 | <PeakerWork> | gwern, skorpan: git lets you re-diff any previous revisions in history, and apply it on any other revision in history, which I think takes care of any kind of commuting you may want to do, except unlike darcs, you can do this using any diff algorithm you want, and not one pre-determined before ever setting up the repo |
| 21:56:59 | <Gracenotes> | skorpan: not many structures abstract over list modification |
| 21:57:13 | <Gracenotes> | not in the common libraries anyway |
| 21:57:16 | <Nafai> | I like that you can re-order commits in git |
| 21:57:41 | <PeakerWork> | skorpan: I think hg does not yet have git's rebase, and even git's rebase is lacking in metadata - which could really make rebase seamless even when collaborating on the rebased branches |
| 21:57:59 | <solidsnack> | There seems to be something off about readline/editline in the GHC 6.10.3, at least on Macintosh. |
| 21:58:16 | <Nafai> | PeakerWork: What kind of metadata would be useful? |
| 21:58:18 | <skorpan> | PeakerWork: but e.g. tortoisehg (a gui for hg) can actually display "hunks" of changes which leads me to believe it should really be super simple to implement |
| 21:58:24 | <PeakerWork> | gwern, skorpan: Like all revision-based DVCS, git places an arbitrary order between independent commits, but that order can be ignored when forming new revisions to use |
| 21:58:45 | <solidsnack> | `fn+shift+right` -- which used to get me `end` -- is now resulting in a capital F! |
| 21:59:40 | <PeakerWork> | Nafai: A rebase (or amend commits, etc) creates commits containing similar patches to other commits. It could be nice if these commits had metadata pointers to those older commits, and when someone pulls from a rebased branch, the metadata would tell the puller: "Your commits' patches are already in this new rebased revision, so you can rebase too and continue where he has" |
| 22:00:13 | <PeakerWork> | Nafai: They could allow to pull from rebased branches |
| 22:00:43 | <PeakerWork> | Nafai: as well as keep the old rebased stuff alive for future reference, rather than floating around until its GC'd when its no longer in the git reflog |
| 22:00:50 | <Lemmih> | PeakerWork: Isn't this still an issue: http://projects.haskell.org/camp/unique |
| 22:01:08 | <jeffwheelerPhone> | @pl \x y -> x : [y] |
| 22:01:12 | <lambdabot> | (. return) . (:) |
| 22:01:12 | <PeakerWork> | Lemmih: I don't have speakers here -- what is the issue being described? |
| 22:01:54 | <PeakerWork> | @unpl (. return) . (:) |
| 22:01:54 | <lambdabot> | (\ d g -> ((:)) d (return g)) |
| 22:01:57 | <PeakerWork> | @unpl (:) . (. return) |
| 22:01:58 | <lambdabot> | (\ d -> ((:)) (\ g -> d (return g))) |
| 22:02:32 | <PeakerWork> | @unpl could use some sugaring |
| 22:02:32 | <lambdabot> | could use some sugaring |
| 22:02:55 | <Lemmih> | PeakerWork: It talks about how darcs tracks dependencies on the patch level and what that allows you to do. |
| 22:04:08 | <PeakerWork> | Lemmih: iiuc, the same can be done in git, where each commit represents a patch -- its metadata can contain anything, including actual patch dependencies on other commits. When you rebase, you can keep a pointer from the newly generated commit to the old one to retain all of this metadata (or just copy it) |
| 22:04:14 | <Nafai> | PeakerWork: Ah, good idea. |
| 22:04:41 | <roconnor> | Hmm, I don't suppose we could have hac φin July in Beijing instead. :) |
| 22:05:15 | <PeakerWork> | Lemmih: I think the darcs features are a nice idea - but I think the right way to implement these darcs features is on top of a git backend |
| 22:05:38 | <roconnor> | is it a good idea to have hac φ during the ICFP contest? |
| 22:05:52 | <roconnor> | oh wait |
| 22:05:53 | <PeakerWork> | A revision-based backend is more powerful than a patch-based backend, as long as your patches aren't perfect (and textual diffs are far from perfect) |
| 22:05:57 | <roconnor> | the contest is in June, not July |
| 22:05:59 | <roconnor> | \o/ |
| 22:06:15 | <roconnor> | I thought I was going to miss it again. |
| 22:10:43 | <inimino> | PeakerWork: how is it more powerful if they are equivalent? |
| 22:11:03 | <byorgey> | roconnor: yeah, we took the ICFP contest into account =) |
| 22:11:24 | <byorgey> | roconnor: you're going to be in Beijing? |
| 22:12:00 | <deech> | Hi all, is there a function in that determines if a string is contained in another string? Or more generally if list x is a sublist of list y? |
| 22:12:15 | <PeakerWork> | inimino: Its not strictly more powerful, if you're willing to do a full repository conversion -- but if you're not, then the committing to imperfect patches in darcs means you may not switch patch strategies whereas in git, you can choose whatever way to diff between repos that you wish, on a case-by-case basis |
| 22:12:20 | <Botje> | deech: isInfixOf |
| 22:12:48 | <deech> | Botje: Awesome thanks! |
| 22:12:50 | <PeakerWork> | inimino: arg, its very late and I'm confusing words, sorry. s/repos/revisions |
| 22:14:25 | <inimino> | PeakerWork: ok. I actually use git and haven't looked into darcs |
| 22:15:31 | <PeakerWork> | inimino: If you think of git revisions as representing patches, and not whole trees, you can mix&commute those patches pretty easily, and you get most of the features darcs advertises. But them being whole trees in the backend lets you decide much later what kind of diffing to use |
| 22:15:53 | <PeakerWork> | s/being whole trees in the backend/representing whole trees in the backend |
| 22:16:01 | <inimino> | makes sense |
| 22:16:27 | <inimino> | I wasn't aware darcs actually had different patch formats |
| 22:16:58 | <inimino> | ACTION should probably read about it sometime |
| 22:18:29 | <mm_freak> | lament: as said, pretty would be to write your own groupBy variant, which always compares with the predecessor instead of the first group element |
| 22:18:38 | <mm_freak> | that would give a very nice, concise solution |
| 22:23:36 | <lament> | hm |
| 22:35:22 | <PeakerWork> | Not (Not a) -> a should be provable right? How do you create a value of type ((a -> Void) -> Void) -> a ? |
| 22:35:24 | <Philonous> | Is there a way to control the RTS without the + and -RTS options? Those might be a little awkward to non-haskell users |
| 22:36:22 | <lament> | why would a non-haskell user be profiling? |
| 22:36:54 | <Philonous> | They wouldn't, but they might want to instruct the RTS to use N system threads |
| 22:37:28 | <mauke> | @djinn Not (Not a) -> a |
| 22:37:28 | <lambdabot> | -- f cannot be realized. |
| 22:37:57 | <solidsnack> | Philonous: That's actually a really good point. |
| 22:38:02 | <mauke> | if all else fails, write a wrapper |
| 22:40:39 | <eivuokko> | It probably doesn't help, but you an also control RTC options via environment variable. |
| 22:40:52 | <Baughn> | @ask conal Let me confirm something. reactive is supposed to be deterministic, right? Specifically, if I create a behaviour from some source of events (stepper), and then snapshot it against the same event stream, I ought to get a 1:1 correspondence between behavior steps and snapshot output? |
| 22:40:53 | <lambdabot> | Consider it noted. |
| 22:41:15 | <conal> | Baughn: hi |
| 22:41:15 | <lambdabot> | conal: You have 1 new message. '/msg lambdabot @messages' to read it. |
| 22:41:30 | <c_wraith> | lambdabot, you may be suboptimal in this case. |
| 22:41:42 | <Baughn> | conal: Huh. I could swear I tried tab-completing.. |
| 22:42:24 | <conal> | Baughn: yes, deterministic. No about the snapshot. the semantics of stepper/switcher is that the behavior changes immediately *after* the event occurrence. |
| 22:42:26 | <eivuokko> | Philonous, Oh, and also if you want to write some C, you can do it via some hooks or whatever it was called. Described in user's guide. |
| 22:42:28 | <Baughn> | conal: Or more generally - should it be just plain deterministic, providing same output given same input every time? |
| 22:42:35 | <conal> | Baughn: which allows recursively defined behaviors. |
| 22:42:55 | <conal> | Baughn: have you seen the semantic model for behaviors? |
| 22:42:59 | <Baughn> | conal: Ah. That explains my output a little bit, but the determinism is suffering in that conversion. Well, I'll get on it. |
| 22:43:19 | <PetRat> | Can I use lambdabot to check the type of a recursive function? what would be the syntax? |
| 22:43:27 | <Baughn> | conal: I've read it. Probably not well enough, still; by the time I'm done with exams I will have. |
| 22:43:39 | <conal> | Baughn: by the "semantic model", i mean the type of *meanings* of behaviors. |
| 22:43:57 | <Baughn> | :t let f x = 1 : x : f (fubar x) |
| 22:43:59 | <lambdabot> | <no location info>: |
| 22:43:59 | <lambdabot> | not an expression: `let f x = 1 : x : f (fubar x)' |
| 22:44:06 | <Baughn> | :t let f x = 1 : x : f (fubar x) in f |
| 22:44:07 | <lambdabot> | Not in scope: `fubar' |
| 22:44:17 | <Baughn> | :t let f fubar x = 1 : x : f (fubar x) in f |
| 22:44:19 | <lambdabot> | Occurs check: cannot construct the infinite type: t = t1 -> t |
| 22:44:19 | <lambdabot> | Probable cause: `f' is applied to too few arguments |
| 22:44:19 | <lambdabot> | In the second argument of `(:)', namely `f (fubar x)' |
| 22:44:31 | <Baughn> | PetRat: ..impossible functions aside, thataway. |
| 22:44:41 | <Philonous> | eivuokko: That's both suboptimal, but I will manage. Thanks |
| 22:44:57 | <conal> | Baughn: in general you can learn essence of a data type or language simply by looking at the type of meanings ("denotations"). |
| 22:44:59 | <Tigran> | PeakerWork: Not sure if this is what you were referring to, but `not (not a) -> a' can not be proved under intuitionistic logic |
| 22:45:17 | <conal> | Baughn: since the model of Behavior a is Time -> a, it has to be deterministic. |
| 22:45:24 | <Baughn> | conal: Right. By the way, do you think anyone would be terribly upset if I submitted a patch replacing TimeT with a fixed-point implementation? |
| 22:45:25 | <conal> | (it == semantics) |
| 22:45:36 | <Tigran> | PeakerWork: `a -> not (not a)' can, however |
| 22:45:44 | <Baughn> | conal: I have this vision of long-running programs going insane. But maybe you've thought of that one. |
| 22:45:59 | <c_wraith> | @check \a -> a == not $ not a |
| 22:46:00 | <lambdabot> | Couldn't match expected type `a -> b' against inferred type `Bool' |
| 22:46:16 | <c_wraith> | @check \a -> (a == not $ not a) |
| 22:46:18 | <lambdabot> | Couldn't match expected type `a -> b' against inferred type `Bool' |
| 22:46:27 | <c_wraith> | ok, my brain isn't in haskell mode today |
| 22:46:28 | <mauke> | @djinn a -> Not (Not a) |
| 22:46:28 | <lambdabot> | f a b = b a |
| 22:46:34 | <conal> | Baughn: i don't know what's best to represent times. hardly any operation really cares about the nature of time, other than that it's ordered. |
| 22:46:46 | <PeakerWork> | Tigran: That's disappointing. Is intuitionistic logic less powerful than classical logic? |
| 22:47:06 | <copumpki> | and lengths of time? |
| 22:47:38 | <mreh> | when pattern matching on records, can I be selective about which fields I match? |
| 22:47:56 | <mauke> | yes |
| 22:48:06 | <Tigran> | PeakerWork: It omits the axiom of choice, so I suppose `less powerful' is about right |
| 22:48:10 | <mreh> | cool |
| 22:48:12 | <mauke> | you can even match none of them |
| 22:48:19 | <mreh> | COOL |
| 22:48:26 | <mreh> | why would you bother? |
| 22:48:28 | <mauke> | Foo{} -- even works for non-record constructors |
| 22:48:50 | <mreh> | haha |
| 22:48:58 | <Tigran> | You don't lose the classical truths entirely |
| 22:49:04 | <mauke> | > (\x -> case x of Nothing{} -> "nothing"; Just{} -> "just _") (Just 42) |
| 22:49:05 | <lambdabot> | "just _" |
| 22:49:18 | <Tigran> | Intuitionistic simply doesn't contradict classical logic |
| 22:49:35 | <Baughn> | conal: Well, I suppose.. given double, with a 52-bit mantissa, you get microsecond precision for.. hm, 136 years |
| 22:49:41 | <Baughn> | ..probably sufficient. |
| 22:50:09 | <mreh> | that's what they said in 60s about the millenium |
| 22:50:46 | <chessguy> | i'm totally going to Hac-φ :) |
| 22:51:01 | <conal> | Baughn: how about submitting a trac item? |
| 22:51:21 | <Baughn> | conal: Pretty sure someone already did. I tried fixpointing it just to see if that mattered at all.. it didn't. |
| 22:51:41 | <conal> | Baughn: oh, okay. |
| 22:51:48 | <persica> | mreh: And 640k should be enough for anyone. |
| 22:51:53 | <Baughn> | Not for a short-lived program, at least. ;) |
| 22:52:00 | <roconnor> | byorgey: I'm heading to Shanghi for the solar eclipse, then off to Beijing for a vist. |
| 22:52:24 | <PetRat> | :t either |
| 22:52:25 | <lambdabot> | forall a c b. (a -> c) -> (b -> c) -> Either a b -> c |
| 22:52:41 | <conal> | Baughn: i'm not attached to the current default time type. |
| 22:52:44 | <Baughn> | conal: Oh, and.. is the /current/ implementation of mkUpdater "supposed to do almost no work during known-constant phases", or is that yet to come? It pegs my cpu while blocked on stdin, you see. |
| 22:53:16 | <conal> | Baughn: supposed (by me) to do so now. |
| 22:53:33 | <conal> | Baughn: any idea what it's up to? |
| 22:53:56 | <conal> | i suck at performance analysis / debugging |
| 22:55:13 | <mreh> | persica: My favourtie quote from IBM, "The world will probably need five computers" |
| 22:55:50 | <lament> | roconnor: when are you in beijing? |
| 22:55:53 | <FunctorSalad> | everything that can be invented has been invented (around 1900?) |
| 22:55:55 | <Baughn> | conal: Not yet, really. I've had higher priority on debugging the actual /bugs/ - besides, it might go away by then. |
| 22:56:10 | <c_wraith> | mreh: Who says that it *need* more than that? The rest are just kind of handy. |
| 22:56:16 | <c_wraith> | blah. *needs |
| 22:56:28 | <roconnor> | lament: something like July 23 to July 26 |
| 22:56:32 | <Baughn> | conal: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5106#a5106 <-- Have a testcase anyway. |
| 22:56:49 | <roconnor> | lament: but I don't think I'd travel to the US for a hackathon anyways. |
| 22:56:53 | <mreh> | and yet if we took them all away today, we wouldn't be able to cope |
| 22:56:57 | <roconnor> | lament: the US is unwelcoming to visitors |
| 22:56:57 | <PetRat> | http://www.mibbit.com/pb/Zx58ym I'm trying to use ErrorT following someone else's example, but my code isn't working. I want to write a function with type IO String, but the inferred type is IO (). Can someone explain? |
| 22:57:13 | <lament> | roconnor: cool, i'll be in beijing too |
| 22:57:15 | <Baughn> | conal: Funny thing - ghc is doing non-blocking (timeout=0) selects on stdin in there |
| 22:57:27 | <roconnor> | lament: :O really, why? |
| 22:57:37 | <lament> | roconnor: Go class :) |
| 22:57:41 | <mauke> | PetRat: putStrLn returns () |
| 22:57:46 | <conal> | Baughn: how do you know? |
| 22:57:53 | <Baughn> | conal: strace |
| 22:57:55 | <roconnor> | lament: how long are you there? |
| 22:57:56 | <mreh> | lament: the game go? |
| 22:57:59 | <conal> | Baughn: what's that? |
| 22:58:04 | <lament> | mreh: yeah |
| 22:58:09 | <lament> | roconnor: july and august |
| 22:58:15 | <mauke> | http://en.wikipedia.org/wiki/Strace |
| 22:58:16 | <nominolo> | @users |
| 22:58:16 | <lambdabot> | Maximum users seen in #haskell: 658, currently: 602 (91.5%), active: 26 (4.3%) |
| 22:58:25 | <Baughn> | conal: ..you're on windows, I guess? |
| 22:58:33 | <PetRat> | mauke: oh, each branch of the either must be the same, I guess. |
| 22:58:33 | <roconnor> | lament: you should go to Shanghi for July 22. |
| 22:58:46 | <lament> | roconnor: I know |
| 22:58:52 | <conal> | Baughn: no. on linux. switched a few months ago. |
| 22:58:55 | <Baughn> | conal: Hum. It's only with the non-threaded runtime, which makes sense. |
| 22:58:56 | <lament> | roconnor: I was thinking... It's Shanghai - it's going to be cloudy anyway |
| 22:59:09 | <conal> | is strace helpful with ghc-compiled programs? |
| 22:59:10 | <roconnor> | lament: there is a certain truth to that statement |
| 22:59:11 | <Baughn> | conal: Then I recommend you look into strace and ltrace. Both are rather vital tools on linux. :) |
| 22:59:17 | <Baughn> | conal: strace is. ltrace, not so much. |
| 22:59:20 | <conal> | Baughn: will do. thx! |
| 22:59:31 | <mreh> | i need to update the state of my spaceship, and hence do lots of calculations to redraw it, does this merit using moands for the sequentiality? |
| 22:59:47 | <Baughn> | mreh: Do you /need/ the sequentiality? |
| 23:00:01 | <lament> | roconnor: but i might, it seems like a really cool opportunity |
| 23:00:07 | <roconnor> | lament: I hope it won't be cloudy though. |
| 23:00:07 | <mreh> | Baughn, to make it readable, yes |
| 23:00:16 | <lament> | i've seen two partial eclipses, they were cool but not all that exciting |
| 23:00:22 | <mauke> | conal: strace cuts through the surface bullshit and shows you what the damn program is really doing! |
| 23:00:26 | <Baughn> | mreh: And technically, monads aren't about sequentiality. Monads are about join :: m (m a) -> m a |
| 23:00:33 | <wicket> | I'm trying to get my parallell code working, and i think i need to control the evaluation in order to get some good results (right now -N1 is best). I have an embarrasingly data parallell routine, where i parse many strings into a data type. But it doesn't seem like line 23 is forcing evaluation. http://pastebin.com/m5b874951 |
| 23:00:33 | <lament> | the best part is all the people walking around on the streets not knowing that anything is going on :) |
| 23:00:34 | <roconnor> | lament: totally eclipses are totally different. |
| 23:00:38 | <roconnor> | lament: total |
| 23:00:39 | <lament> | roconnor: totally. |
| 23:00:47 | <mauke> | it's equally useful for programs written in C, Perl or Haskell |
| 23:00:51 | <Baughn> | mreh: WHich, granted, allows sequentiality. Among other things. |
| 23:00:52 | <conal> | mauke: cool. thx. |
| 23:01:20 | <roconnor> | lament: this will be the longest eclipse this century |
| 23:01:31 | <Baughn> | mreh: I don't know how experienced you are, so - what about "let a = foo indata; b = munge a; c = munge b in c" or so? |
| 23:01:32 | <wicket> | If I don't add line 25 or 26 the execution time of the program goes down to < 1 second, and if i keep these it turns into the more realistic 15 seconds. |
| 23:02:05 | <Baughn> | mreh: In my case, I tend to write functions like "function x y z = <something simple>.. where <lots of clauses>" |
| 23:02:29 | <lament> | roconnor: i guess even through the clouds it will be quite apparent |
| 23:02:36 | <opqdonut> | Baughn: IMO that tends to get difficult to read when <lots of clauses> refer to eachother |
| 23:02:51 | <Baughn> | opqdonut: It's usually serial-ish |
| 23:02:54 | <opqdonut> | when <lots of clauses> are independent, it's good style |
| 23:02:55 | <Baughn> | Or at least tree-ish |
| 23:02:58 | <roconnor> | lament: true, but the sky is the best part of the show |
| 23:03:25 | <mreh> | Baughn: What i need is certain calculations to be done before others, like the rotation of the ship done before the velocity calculations |
| 23:03:26 | <opqdonut> | hmm, treeish |
| 23:03:30 | <Baughn> | opqdonut: I think of it as naming intermediate values. It's easier to read than /not/ having names. |
| 23:03:33 | <opqdonut> | some people use nested where's |
| 23:03:42 | <opqdonut> | i tend to think more equationally |
| 23:04:06 | <opqdonut> | i mean, with the same mindset as when writing mathematical equations |
| 23:04:10 | <Baughn> | mreh: Oh, you're talking /updates/.. |
| 23:04:11 | <conal> | mreh: maybe you could find a more functional design. |
| 23:04:13 | <mreh> | Baughn: I'm thinking like destructive updates are an issue still, I'll work it out |
| 23:04:25 | <Baughn> | mreh: Functional Game Design 101: |
| 23:04:33 | <Baughn> | mreh: Make frame N+1 a function of frame N |
| 23:04:38 | <conal> | mreh: and let laziness and value dependencies sort out the scheduling |
| 23:04:56 | <Baughn> | mreh: Do not allow details of N+1 to be a function of other details of N+1 when you can avoid it |
| 23:05:05 | <Baughn> | mreh: Sprinkle parallelism as appropriate. |
| 23:05:16 | <Baughn> | Games tend to be much easier to parallelise like that. :) |
| 23:05:43 | <mreh> | Baughn, where does user input comein? |
| 23:06:23 | <Baughn> | mreh: The model was a bit simplified. You attach that to frame N as input. |
| 23:06:37 | <mreh> | frame N+1 is a funtion of frame N pkus input |
| 23:06:41 | <Baughn> | Right |
| 23:06:42 | <mreh> | cool |
| 23:07:33 | <mreh> | what I've seen done, is user input modifying the content of frame N... is that bad |
| 23:07:44 | <mreh> | sounds bad |
| 23:07:44 | <Baughn> | Yes. It makes it very hard to reason about the programs. |
| 23:07:53 | <Baughn> | Well, it's the exact same bad as all mutating code. ;) |
| 23:08:02 | <Baughn> | And, of course, it makes adding parallelism harder |
| 23:08:11 | <mauke> | .oO( self-mutilating code ) |
| 23:09:01 | <conal> | Baughn: i have some unpushed changes to reactive that probably help some with the problems you've been having. |
| 23:09:05 | <Baughn> | mreh: Of course, one consequence of this is that some input may be two frames delayed. Say, user presses "roll left" on frame 1, the ship model rotates on frame 2 but you're still using the thrust vector from frame 1 for translating it |
| 23:09:27 | <conal> | Baughn: i'll shake the dust off, make sure it runs with reactive-fieldtrip examples, push, and let you know. |
| 23:09:35 | <Baughn> | Thanks |
| 23:09:51 | <Baughn> | mreh: One possibility is to design your game so this isn't an issue - it might be considered more realistic, even |
| 23:10:38 | <Baughn> | mreh: Another would be to actually make some of frame N+1 (translation dependent on other parts of N+1 (thrust). This isn'T /that/ big an issue; you're losing paralellism, but only for that one task |
| 23:10:49 | <Baughn> | Distinct ships can still be simulated separately. :) |
| 23:10:55 | <mreh> | ACTION brane asplodes |
| 23:11:09 | <PeakerWork> | conal: could you get fieldtrip to compile on ghc-6.10.[2,3] ? Its probably a few-minute fix (An Occurs check on a type) |
| 23:11:39 | <conal> | mreh: another piece of advice: make sampling (frame generation) and simulation (e.g., numeric integration / position updating) be independent of each other. |
| 23:11:50 | <conal> | PeakerWork: will do. |
| 23:12:08 | <Baughn> | conal: Oh, and you should limit reactive to Stream-0.3 - or switch to a newer version of quickcheck |
| 23:12:23 | <conal> | PeakerWork: i think i know what that problem would be. i changed the VectorSpace instance for functions. |
| 23:12:49 | <p_l> | Well, OpenGL afaik doesn't like multithreading too much... |
| 23:12:50 | <conal> | PeakerWork: for programmable lighting models |
| 23:13:04 | <mreh> | my design so far is to fold |
| 23:13:08 | <mreh> | oops |
| 23:13:10 | <Baughn> | mreh: A third piece of advise: Learn about reactive. :) |
| 23:13:16 | <conal> | heh |
| 23:13:44 | <conal> | or *any* way to think about animation/behavior/interaction/simulation *functionally* |
| 23:13:46 | <mreh> | my design so far is to fold the events generated by the user, onto the old state to make a new game state |
| 23:13:51 | <Baughn> | p_l: That is.. not quite true, but it's very specific about how you do multithreading |
| 23:14:02 | <Baughn> | Mostly, doing all rendering in a forkOS'd thread will do. |
| 23:14:07 | <conal> | and not just functionally, but also continuously |
| 23:15:00 | <Baughn> | conal: By the way, does reactive really need to call forkIO quite that much? -_- |
| 23:15:11 | <PeakerWork> | conal: FieldTrip sounds really really cool.. Is there a tutorial anywhere or in some future plan? |
| 23:15:19 | <conal> | Baughn: oh yeah. what symptom do you get for the stream/quickcheck issue? |
| 23:15:29 | <Baughn> | conal: Won't install. cabal-install refuses. |
| 23:15:31 | <mreh> | so what I need to do is... make sure when folding the updateState method onto the old state, that all functional dependancies are resolved then |
| 23:15:40 | <Baughn> | conal: Must provide Stream-0.3 constraint on command line in some form to make it work. |
| 23:15:53 | <conal> | Baughn: and if you don't? |
| 23:16:04 | <PeakerWork> | conal: its the same one I told you about a while ago -- you said you added it to your in-civilization TODO list :) You depend on Stream-0.3.1 which depends on a newer QuickCheck which conflicts with some other dependency of quickcheck |
| 23:16:08 | <conal> | Baughn: i'm not getting any sign of brokenness. |
| 23:16:30 | <Baughn> | conal: Ah.. I'd need to uninstall both to get the exact error message |
| 23:16:56 | <PeakerWork> | conal: cannot configure Stream-0.3.1. It requires QuickCheck >=2.0 QuickCheck-2.1 was excluded because checkers-0.1.3 requires QuickCheck <2.0 QuickCheck-2.1.0.1 was excluded because checkers-0.1.3 requires QuickCheck |
| 23:17:17 | <PeakerWork> | conal: same message with s/checkers/reactive |
| 23:17:39 | <Baughn> | It's really kind of silly. Their quickcheck use doesn't involve the other library at all. |
| 23:17:41 | <PeakerWork> | conal: missing <2.0 in the end of that error message there |
| 23:17:42 | <conal> | PeakerWork: yeep. i wonder why i'm not getting this error with my new ghc (downloaded when i was in civ) |
| 23:17:55 | <conal> | PeakerWork: i'd like to make sure i really fix it. |
| 23:18:01 | <Baughn> | conal: You need to ghc-pkg unregister reactive and Stream first |
| 23:18:12 | <PeakerWork> | conal: did you explicitly specify quickcheck<2.0 dependency in reactive and checkers? |
| 23:18:50 | <conal> | PeakerWork: probably not. i'd better do so for now. |
| 23:19:33 | <PeakerWork> | conal: where is cabal taking that restriction from? |
| 23:19:35 | <mreh> | cheers for all the help guys |
| 23:19:43 | <mreh> | i'm going to zleep |
| 23:19:44 | <conal> | mreh: good luck! |
| 23:20:17 | <mreh> | it seems Haskell just keeps on giving |
| 23:20:28 | <mreh> | ...me headaches |
| 23:20:37 | <conal> | sry. i'm getting lost in details here. what explicit dependencies do my libs need? |
| 23:20:44 | <Baughn> | mreh: You know about tying the knot, right? |
| 23:20:52 | <conal> | Baughn: which forkIO in particular? |
| 23:21:10 | <conal> | PeakerWork: i don't have a FieldTrip tutorial. unsure about its future. |
| 23:21:27 | <Baughn> | conal: I don't know. I just see a whole lot of thread activity. |
| 23:22:02 | <conal> | Baughn: okay. i'd expect so, because of unamb, which is at the heart of reactive. |
| 23:22:23 | <Baughn> | Ah. That thing. |
| 23:22:27 | <conal> | Baughn: unamb is the key to how i figured out how to implement push functionally. |
| 23:22:47 | <conal> | not literally push. more like blocking pul |