Experimental IRC log haskell-2008-01-11

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:09:54<dmwit>:t all
00:10:10<lambdabot>forall a. (a -> Bool) -> [a] -> Bool
00:10:13<dmwit>:t and
00:10:15<lambdabot>[Bool] -> Bool
00:12:49<glguy>:t or
00:12:50<lambdabot>[Bool] -> Bool
00:12:52<glguy>:t any
00:12:53<lambdabot>forall a. (a -> Bool) -> [a] -> Bool
00:16:23<hpaste> faxlore annotated "silly theorem prover" with "less silly" at http://hpaste.org/4911#a1
00:16:34<faxlore>There is a slightly better one
00:18:55<faxlore>any suggestions?
00:19:00<faxlore>(to improve)
00:21:53<litb>now, i'm working with haskell two days, and knocking on the doors of Monads. i hope i get in some day
00:22:16<shapr>Have you read Cale's intro, or sigfpe's intro?
00:22:33<litb>nope. my only source has been yaht
00:23:06<litb>is Cales intro or 1/0 into good?
00:23:15<litb>s/into/intro/
00:23:16<dons>yeah
00:23:31<ddarius>Just read Wadler's paper(s).
00:23:53<shapr>I enjoyed http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html
00:23:53<dons>there's lots of good monad papers
00:23:54<lambdabot>Title: A Neighborhood of Infinity: You Could Have Invented Monads! (And Maybe You Alrea ..., http://tinyurl.com/ecqzl
00:23:56<shapr>But I already knew monads...
00:24:05<dons>so maybe shapr already had
00:24:25<litb>shapr: you already know them?
00:24:31<litb>*knew
00:24:38<litb>oh i see
00:24:40<faxlore>I think I understood what Monads are when I learned what a Vector Space is
00:24:47<litb>missed your previous line :)
00:25:02<faxlore>because of seeing it as that kind of mathematical structure
00:29:22<balodja>Is there any article(or even resource!), that is concentrated on different occurrences of monads in mathematics, physics, computer science etc (may be real world too)?
00:29:57<litb>o.O i suppose you have to have an IQ of above 140 to understand haskell :D
00:30:10<litb>anyway, thanks for teaching me. see you tomorrow :)
00:30:10<LoganCapaldo>i hope not
00:31:13<faxlore>?djinn f -> z -> s -> n -> (f -> z) -> ((f -> n) -> (f -> (s -> n))) -> (f -> n)
00:31:13<lambdabot>f a _ b c _ d e = d (\ _ -> d (\ _ -> c) e b) a b
00:31:36<dons>litb: shouldn't be necessary, its just another programming language. a good one, but still, its not theorem proving :)
00:32:00<faxlore>dons I wrote a theorem prover in haskell :D
00:32:05<faxlore>(really really simple)
00:32:24<Pseudonym>Cool.
00:32:38<Pseudonym>Of course, a lot of programs in Haskell are theorem provers in disguise.
00:32:38<faxlore>I must add some data types to it
00:32:41<Pseudonym>e.g. the type checker
00:32:56<ddarius>balodja: Most of them? John Baez has interesting articles on category theory applied to physics. Usually categorical ideas are presented as unifying a wide-spread of notions.
00:32:58<faxlore>oh I know that a type checker can work by unification
00:33:18<Pseudonym>Unification is only one kind of theorem proving primitive.
00:33:26<Pseudonym>The thing is, a type checker "proves" that a program is type correct.
00:33:47<kmcallister>a type checker without inference is just a proof checker
00:33:50<Pseudonym>It's a smaller theory than full-on FOPL, but still.
00:34:26<faxlore>What's the most expressive type system you could still check in finite time?
00:34:38<faxlore>I guess haskell is not far off?
00:34:40<ddarius>faxlore: There isn't a single one.
00:34:53<ddarius>faxlore: You can always make a more expressive type system.
00:35:03<faxlore>but have it still checkable in finte time?
00:35:08<balodja>ddarius: That's good. Because I've already get tired with "list, maybe, reader, writer, continuation and state" as monads. I want to understand what monad really is, not just in application to haskell. And without "simple" examples from topology :)
00:35:35<Pseudonym>Any reasonable proof system has proofs that are _checkable_ in finite time.
00:35:47<kmcallister>but type inference requires actually generating parts of the proofs
00:35:52<kmcallister>and thus is often undecidable
00:36:01<litb> I want to understand what
00:36:02<litb> monad really is
00:36:14<litb>lols, that sounds philosophical. anyway, /parting...
00:36:15<dons>i want to know what numbers really are too
00:36:19<shapr>aww
00:36:20<ddarius>balodja: Most of the Haskell examples are -the same- examples as monads in e.g. logic and monads in topology.
00:36:31<ddarius>(and monads in algebra)
00:36:52<ddarius>faxlore: Yes. If you remove that restriction then there is a "most expressive type system"
00:36:55<shapr>dons: I think the best thing for 2008 would be a Haskell' that encompasses all the extensions what people actually use in GHC.
00:37:02<dons>monads are the building blocks for effects in programming languages? programmable semi colons? apples and nuclear waste in the ocean?
00:37:11<faxlore>What is it? :D
00:37:19<ddarius>faxlore: Any Turing complete language.
00:37:21<EvilTerran>marble run!
00:37:53<dons>shapr: you think? i can see some benefit from that, but not a lot -- the main benefit from H' might already be that the extensions are all tagged and sorted, and we've consensus on what's good, what's bad, and not to enable everything with -fglasgow-exts
00:38:24<dons>it might lead to more confidence in the language by outsiders, perhaps
00:38:25<shapr>dons: I'd love to have naturally parallel Haskell libs for 2008.
00:38:33<shapr>Yeah, I think we need more outsiders.
00:38:40<shapr>PROSELYTIZE!
00:38:50<dons>ASSIMILATE!
00:38:59<dons>RESISTANCE IS FUTILE!
00:39:05<dons>YOU WILL BETA REDUCE!
00:39:09<shapr>Hopefully I'll have enough spare time to start up a Boston HUG. edwardk suggested that I start it up in Somerville so it'd be HUGS.
00:39:14<balodja>dons: "i want to know what numbers really are too", so we have great number of examples of occurencies of numbers in real life. and what about monads? :)
00:39:15<dons>awesome.
00:39:37<kmcallister>balodja, you use the Maybe monad all the time in real life
00:39:38<dons>balodja: nuclear waste barrels? dreams?
00:39:41<balodja>Is there something, that could help to understand them more deeply?
00:39:41<shapr>dons: What do you think would be good for 2008?
00:39:52<shapr>Maybe more GUI code?
00:39:59<faxlore>balodja: (>>=) = flip concatMap
00:40:05<shapr>I'm not sure what the next big goal would be.
00:40:22<dons>a bytestring network stack, a bytestring parser stack, bitwise serialisation, more hackage improvements, more parallel stuff
00:40:28<dons>bytestring xml
00:40:35<dons>we need to do a survey
00:40:49<dcoutts_>dons: haxml uses polyparse and polyparse can work on bytestrings I believe
00:41:15<dcoutts_>dons: a unicode bytestring will be important for xml stuff and is important generally
00:41:20<LoganCapaldo>@where polyparse
00:41:20<lambdabot>http://www.cs.york.ac.uk/fp/polyparse/
00:41:25<dons>unicode/utf8 yep
00:41:25<Cale>Heh, "what is a monad?" has become sort of like "what is a tensor?" in that it's a mathematical question which has become almost a philosophical one.
00:41:28<balodja>dons: What kind of monads do dreams represent?
00:41:35<balodja>*does
00:41:39<balodja>*do :)
00:41:51<dons>balodja: well, dreams are like strange encapsulated monads where different evaluation strategies apply
00:42:02<dons>and you can run them, but they shouldn't escape into normal life
00:42:06<dons>aka the Life monad
00:42:10<shapr>dons: I dunno, I think bytestring stuff might be too specific to improve Haskell as a community.
00:42:19<luqui>eh, I think dreams are probably closest to Cont
00:42:22<dons>unsafeSleepWalk is a dangerous op, with a proof obligation
00:42:25<Cale>hmm, like a FakeRootIO monad :)
00:42:27<LoganCapaldo>what's a tensor?
00:42:31<resiak>thoughtpolice: Hey; if you're interested, `ls` now works in BindFS. However, if you mount BindFS on /foo/bar and then do anything that would stat /foo/bar/foo/bar (such as `ls /foo/bar/foo`), you'll deadlock BindFS and leave yourself with an unkillable BindFS and ls, so don't do that. :-)
00:42:36<cpst>there is another sense of monads used in mathematics that is probably more high profile
00:42:39<LoganCapaldo>is there a space suit analogy for them?
00:42:42<cpst>Horrocks' monads that come up in ADHM theory
00:42:43<dons>shapr: possibly.
00:42:54<dcoutts_>shapr: for community stuff I think we need more hackage work
00:42:55<dons>for high perf stuff, but maybe people don't care about more speed
00:43:06<dons>they're happy with ruby and erlang after all
00:43:29<Cale>cpst: Is that really higher profile? I'm not sure.
00:43:33<dons>strategy is hard
00:43:40<luqui>everybody always whines about speed, but they really don't care as much as they say they do
00:44:11<idnar>I wouldn't exactly call ruby "high performance" :P
00:44:32<cpst>Cale: 3 of those 4 letters are Fields medalists
00:44:53<dcoutts_>shapr: so haskell is great for building reusable libraries, so to make full advantage of that we need using other people's libs to be as simple and reliable as possible, hence the importance of hackage
00:45:03<ddarius>LoganCapaldo: It's the representation of the functor Bilin(U,V; -) which takes a vector space W to the set of bilinear transformations from U and V to W.
00:45:49<shapr>dcoutts_: Good point
00:45:57<Cale>cpst: But still, ADHM theory seems more obscure than category theory at this point.
00:46:01<dcoutts_>shapr: we need to develop ways to make it easy for users to select amongst libs using measurable statistics like usage, test coverage etc
00:46:19<shapr>Yeah, that would be good.
00:46:41<cpst>Cale: what I meant is that if you went around to mathematicians and asked them what a monad was, you would probably get more people who heard of it because of ADHM
00:46:44<dcoutts_>shapr: we can optimise what we can measure, so making more QA stats public automatically should help to improve quality generally
00:46:51<cpst>Cale: Instanton moduli spaces are a pretty hot topic of research right now
00:46:57<cpst>Cale: thank string theory for that one
00:47:04<shapr>dcoutts_: Very much so.
00:47:26<ndm>dcoutts_: i think you are just setting things up to get rigged, people to get their ego bruised, and likely you are going to get it wrong in some way
00:47:35<shapr>Attaching notes like "tested with ghc 6.6 6.8, nhc" and that sort of thing would help.
00:47:50<ddarius>ACTION poos on string theory.
00:48:17<dcoutts_>ndm: it doesn't need to be a strict ranking, but for example it'd distinguish a lib with 90% test coverage from one with no tests at all
00:48:18<shapr>ACTION poos on character theory
00:49:48<ndm>dcoutts_: things like works on which platforms, test coverage etc. are good to make available, as well as things like "other people would use this package instead to do a similar thing" - but ranking by use/dependency can go wrong very easily
00:50:22<Cale>@keal
00:50:22<lambdabot>can you make a macro that builds the expression accoridng to a genetic algorithm where you decide what is good and what is bad?
00:50:36<dcoutts_>ndm: if the stat is divorced from it's meaning then that's quite likely
00:51:03<dcoutts_>ndm: eg rewarding packages that have high usage with higher and not letting others break in
00:51:35<gwern>doesn't cabal have a field for 'tested-with'?
00:51:39<ndm>i would love to see links between packages saying these are alternatives, i.e. tagsoup, haxml, hxt etc should all have links between them
00:51:42<dcoutts_>gwern: yes
00:51:47<ndm>ditto uniplate vs syb
00:51:59<ndm>so people can see what the other options are, and at least casuallly evaluate them
00:52:08<dcoutts_>ndm: perhaps via keywords/category?
00:52:19<dcoutts_>ndm: but on the other hand if it's clear what the statistic is then people can make up their mind if they want to go with the herd or try something else
00:52:39<ndm>dcoutts_: not good enough, i want "if you use this package, you could probably use this package instead"
00:53:00<ndm>unless the categories are fine grained enough to allow that, but it almost goes against tags and categories, since its too fine grained
00:53:05<dcoutts_>ndm: currently category is encouraged to be singular rather than a tag where it'd encourage
00:53:26<ndm>i.e. most packages should be in their own unique group for inter-recommendation
00:53:27<dcoutts_>ndm: ... where it'd encourage people to put in lots of tags, to use them more like links
00:53:51<dcoutts_>ndm: there's no reason we could not add extra tags after a package has been uploaded
00:53:58<dcoutts_>ndm: via the web ui
00:54:22<dcoutts_>ndm: the .cabal file is kept outside of the .tar.gz partly so we can add/modify the metadata
00:54:45<ndm>dcoutts_: i wouldn't want it even to be in the .cabal file, most just a general concensus and grouping thing
00:54:54<ndm>by hand
00:55:06<ndm>to be fair, there aren't that many libraries that overlap
00:55:19<ndm>and where there are, we do a bad job of saying where the overlap is, and what the solution is
00:55:26<dcoutts_>ndm: right, package authors are not the best people to decide what links should be
00:55:39<ndm>i.e. you should link between haskellqt, wxHaskell, gtk2hs - and my vote would be gtk2hs
00:55:47<ndm>dcoutts_: i'd say the worst people :)
00:55:52<dcoutts_>aye :-)
00:56:14<ndm>but its almost going to go against the idea of wxhaskell to recommend people might also try gtk2hs
00:56:22<dcoutts_>ndm: well, it's a good idea as that's one of the things users have to try and evaluate, "which of these packages would fit my needs"
00:56:34<dcoutts_>so anything we can do to help inform that decision is good
00:56:37<shapr>It'd be nice to have similar examples for all of the GUI toolkits.
00:56:51<dcoutts_>we'd need a good design for such a system
00:57:13<ndm>dcoutts_: yes, but its a rare circumstance - we maybe have 8 sets of libraries where there are many libraries overlapping - we don't need an automated system, we need some humans
00:57:47<dcoutts_>ndm: right, but how do we present that kind of information, where do we keep the info, how is it structured?
00:57:57<dcoutts_>how does it evolve as new package version are added etc
00:58:02<ndm>dcoutts_: a wiki
00:58:20<dcoutts_>ndm: and is it linked from the hackage pages? how do people know where to look?
00:58:35<ndm>dcoutts_: i want to use a GUI toolkit that looks quite native on windows and has a strong developer commitment behind it - no statistic will give me that
00:58:47<ndm>dcoutts_: we can link it in from hackage
00:58:55<dcoutts_>well, it will a bit
00:59:01<ndm>not really
00:59:11<ndm>any statistic that is automatically generated won't reflect reality
00:59:12<dcoutts_>you can see the project activity in terms of releases and darcs changes
00:59:17<ndm>that's irrelevant
00:59:23<dcoutts_>not totally
00:59:30<dcoutts_>eg compare hsql and hdbc
00:59:32<ndm>not totally, but not as important as other things
00:59:43<dcoutts_>hsql: 0 dev activity, hdbc: lots
00:59:49<ndm>i think the real solution might be real world haskell book to give the answer
01:00:04<dcoutts_>that'll get out of date before it's published :-)
01:00:06<ndm>who does hsql? can it be officially abandoned and suggest people move over to hdbc?
01:00:21<ndm>ideally, we should be funnelling development, and abandoning the old stuff
01:00:31<dcoutts_>ndm: well exactly, how would we reflect that kind of thing in hackage
01:00:37<ndm>and where there are genuine alternatives, i.e. XML processing, all the pages should group
01:00:44<dcoutts_>ndm: at the moment there is no reflection of bitrot on the hackage pages
01:00:49<MyCatVerbs>ndm: I get the impression that this is what SPJ meant by "avoid success at all costs".
01:00:55<shapr>I'm considering attending http://stuff.mit.edu/iap/#hackhaskell . Does anyone else want to go with me? :-)
01:00:55<lambdabot>Title: SIPB IAP 2008 Activities
01:01:01<shapr>It's free!
01:01:11<ndm>dcoutts_: the author of hsql could write in the cabal package "For new projects I recommend the use of hdbc"
01:01:25<dcoutts_>ndm: he'd have to make a new release to do that :-)
01:01:31<MyCatVerbs>ndm: Haskell has a sufficiently tiny and propellerheaded userbase that it's still currently perfectly acceptable to say, "$library sucks, everyone should switch to $betterlibrary, k?"
01:01:44<dcoutts_>ndm: see, we need some way of managing packages that does not rely on the package maintainers
01:01:48<ndm>MyCatVerbs: exactly :)
01:02:01<ndm>dcoutts_: download, modify the .cabal file, upload - sounds like a few minutes work to me
01:02:09<dcoutts_>ndm: we need to manage it a bit more like a linux distro where the distro maintainers can do stuff
01:02:20<Pseudonym>We need a way to program that doesn't involve programmers.
01:02:23<ndm>dcoutts: we aren't that big yet
01:02:30<dcoutts_>ndm: but you cannot reasonably make new version number releases of a package you're not maintainer of
01:02:33<ndm>we don't need policy, we need people to do clever things
01:02:42<ndm>dcoutts_: then someone should email the maintainer, asking their intentions
01:03:18<dcoutts_>ndm: my point is rather that we do not have the infrastructure to do this stuff effectively without a lot of manual work from lots of people
01:03:32<dcoutts_>ndm: I know because I help maintain >100 gentoo haskell packages
01:04:31<MyCatVerbs>ndm: oh, that and the, "has $problem been bugging you lately? Try $complicated_language_extension_requiring_foreknowledge_of_entirity_of_human_mathematics." And people do. ;)
01:05:22<kfish>how about reddit-style up/down ratings for hackage packages? ;-)
01:05:40<ndm>dcoutts: i'm just worried it won't reflect stuff accurately, but if you have the time to give it a try, it could be good
01:06:00<ndm>MyCatVerbs: i program in H98 + heirarchical modules
01:06:25<ndm>(plus MPTC in one instance)
01:06:34<dcoutts_>ndm: I'm of the opinion that maximum automation is necessary to keep any information up to date and minimise ongoing busy work by hackage maintainers/developers
01:08:04<EvilTerran>ACTION is happy to use that, too, most of the time
01:08:27<dcoutts_>kfish: that's ok but rather easy to "ballot stuff", there are probably more objective measures
01:08:32<EvilTerran>although i occasionally wander into GADTS, fundeps, pattern guards, ...
01:08:32<MyCatVerbs>ndm: I don't even use all of H98. The higher stuff scares me. :)
01:09:16<EvilTerran>-XNoMonomorphismRestriction, when i'm feeling lazy ;)
01:09:18<dcoutts_>kfish: but how about a more general comment/endorsement system where people put their name to a comment on a package, that gives more free-form info and discourages multiple voting
01:09:25<MyCatVerbs>ndm: (well, verrrrry simple fundeps and multiple parameter type classes are fun. But I don't use those for serious work, instead just when usin Haskell to experiment with interesting random chunks of mathematics).
01:09:36<BMeph>kfish: s/reddit/Download.com/ ;)
01:09:38<dcoutts_>kfish: and probably just the comments are enough, no need to make a ranking from that info
01:10:02<kfish>yay social hackage :-)
01:10:29<MyCatVerbs>dcoutts_: how about "My name is $foo, I'm working on project $bar (find us at $bar.sourceforge.net/www.cs.$whatever.edu/$bar), we use libraries $baz, $beep and $beedle"?
01:11:08<dcoutts_>MyCatVerbs: I'm not sure I get what you're suggesting
01:12:02<MyCatVerbs>dcoutts_: so that for any project you're writing where you use hackage libs, you can go through and tell hackage which you're using, and leave contact details in case the maintainers want to mail-bomb you.
01:12:09<EvilTerran>"my name is $foo"? "...and here's my son; we call him little Bobby Tables" ;)
01:12:35<dcoutts_>MyCatVerbs: we can get much of that info from downloads and build reports
01:12:35<gwern>hm. so I see hs-plugins and yi are using crazy tricks to get the output of 'ghc --print-libdir' and use it to initialize a GHC API session
01:12:47<EvilTerran>ew
01:12:48<gwern>is anyone here familiar with that and how to improve it?
01:12:52<MyCatVerbs>EvilTerran: wanna know a secret? QBASIC has long ago corrupted my brain: I now read (and have since I was about, oh, eight?) the character '$' as "string" instead of "dollar". :)
01:12:57<dcoutts_>MyCatVerbs: and if the package that they're writing gets uploaded to hackage then we can see the package deps
01:13:14<EvilTerran>MyCatVerbs, I read it as "scalar" =/
01:13:19<MyCatVerbs>dcoutts_: then in that case, perhaps it isn't neccessary to use anything other than just that?
01:13:23<EvilTerran>(roo much perl)
01:13:33<dcoutts_>MyCatVerbs: right, that was my point
01:13:45<MyCatVerbs>dcoutts_: but...
01:13:49<EvilTerran>although I also sometimes read it as "low-precedence application" or "TH splice" :P
01:14:06<dcoutts_>gwern: you mean how do you capture the output of a program in a nice way?
01:14:12<gwern>god is Real unless declared Ineger?
01:14:32<gwern>dcoutts_: well, I figure maybe it should be standardized as a GHC API function or just built into newSession
01:14:35<EvilTerran>I rely on source highlighting to keep me sane; i can get very confused when looking at unhighlit perl, say...
01:14:40<gwern>and then --print-libdir could call that new function
01:14:44<EvilTerran>gwern, i'd say god's really quite complex...
01:15:00<MyCatVerbs>dcoutts_: in that case, it'd help if everybody was encouraged really really strongly to put all their programs and libraries on hackage.
01:15:03<gwern>dcoutts_: it's just nuts that hs-plugins, for example, is going 'GHC_LIB_PATH=`$GHC --print-libdir | tr -d '\r'`' to get it
01:15:24<EvilTerran>although whether he's rational is a matter of some debate ;)
01:15:55<gwern>dcoutts_: I mean, does anyone *not* want their GHC API session to be started with the libpath of the ghc being called? would that even work? I don't think it does, based on my experiments
01:16:06<ndm>dcoutts: to make these stats accurate we will need more programs on hackage, as now that doesn't seem to be common
01:16:12<dcoutts_>gwern: but that information is not actually known
01:16:29<dcoutts_>gwern: the ghc library does not have the paths baked into it
01:16:58<gwern>dcoutts_: but it can get it, how else could yi and hs-plugins work?
01:17:25<dcoutts_>gwern: because ghc knows it, but the ghc api library does not
01:17:48<dcoutts_>gwern: ghc knows it because the ghc program is actually as script that passes -B${GHC_LIB_DIR}
01:17:58<MyCatVerbs>dcoutts_: I'm thinking maybe a "Cabal for dumbasses" tutorial or two (I could sure as Hell use one myself), -strong- exhortations in some of the central places that the Haskell community is wrapped around ("a call for apps on hackage" or something on the front page of haskell.org?) and also splitting of hackage into "good" and "crap" sections, since tidying up a library to a sufficient standard that it's not embarassing to upload is a fairly large
01:18:22<thoughtpolice>resiak: i'll pull the patches and keep it in mind :)
01:18:30<MyCatVerbs>(This being, of course, the academic "we". I'm far too lazy to do anything but whine. ;)
01:18:36<gwern>dcoutts_: hm. so any solution won't be simple
01:19:03<dcoutts_>ndm: right, dependencies are not good for home grown / in house / one off programs that are not uploaded, so we need something else in that case
01:19:07<MyCatVerbs>EvilTerran: gotta be irrational.
01:19:27<dcoutts_>ndm: we can get download stats and if people turn on build reporting in cabal-install then we can get that info too
01:19:34<MyCatVerbs>EvilTerran: since it's impossible to completely describe a deity using any finite quantity of digits. :)
01:19:56<dcoutts_>ndm: but yes, that doesn't tell us which libs really end up getting used seriously in programs
01:20:10<EvilTerran>"0"?
01:20:13<EvilTerran>*gr+r*
01:20:19<EvilTerran>er, *gd+r*
01:20:52<MyCatVerbs>dcoutts_: to me the natural solution is to make a low barrier to entry section of hackage and get everyone to upload everything to it that they possibly can.
01:21:02<gwern>dcoutts_: where the libdir will be is known as part of the configuration at the compile time of GHC, right?
01:21:42<dcoutts_>MyCatVerbs: right, then it is essential that we have the infrastructure to distinguish high quality packages from low quality or we'll be overwhelmed by mediocrity
01:21:56<dcoutts_>gwern: no, at install time of ghc
01:22:34<gwern>ACTION doesn't understand. you ./configure --prefix=/foo, and then you 'make'
01:22:59<dcoutts_>gwern: a binary version of ghc can still be installed anywhere
01:23:09<dcoutts_>that's why the ghc binary does not bake in the paths
01:23:24<dcoutts_>it gets passed those paths by a script which is generated at install time
01:23:45<dcoutts_>(or on windows it uses a win32 api call to find the dir it's running from)
01:23:55<gwern>gah!
01:24:33<gwern>a solution to this must be found. it's intolerable to either hardwire in a guess as to the libdir or to do bizarre stuff with cabal or shell commands just to get it
01:24:44<MyCatVerbs>dcoutts_: I'm tempted to suggest rather naïve community-consensus measurement methods for working that out, since Haskell currently has such a tight-knit community that they'd work, for now.
01:25:03<gwern>maybe I'll study how yi does it. it somehow goes through cabal and extracts libdir
01:25:44<dcoutts_>MyCatVerbs: well yes we all have that information in our heads, the question is how to helpfully present that information on the hackage website so newbies can make sensible decisions about which packages to pick
01:26:00<dcoutts_>gwern: I think it does some custom stuff in Setup.hs
01:26:04<MyCatVerbs>dcoutts_: oh, I see.
01:26:27<dcoutts_>gwern: basically calling ghc --print-libdir at configure time
01:26:34<MyCatVerbs>Perhaps the sane thing to do would be to add a command line argument to ghc that makes it dump the current libdir.
01:26:45<dcoutts_>$ ghc --print-libdir
01:26:46<dcoutts_>/usr/lib64/ghc-6.8.2
01:26:48<MyCatVerbs>Oh hey, it already has that. heheheh.
01:26:51<gwern>MyCatVerbs: that's what --print-libdir does :)
01:26:52<dcoutts_>MyCatVerbs: like that ^^ ? :-)
01:27:18<MyCatVerbs>Sorry, thought that didn't exist, since there seemed to be a problem.
01:27:23<gwern>MyCatVerbs: my problem is that it drives me nuts that you can only get that info through calling a shell script. I want it compiled in!
01:27:23<MyCatVerbs>gwern: you can use that, right?
01:28:15<MyCatVerbs>gwern: chillax. yo. It uses, what, a hundred twenty milliseconds of CPU time to call that shell script?
01:28:19<gwern>MyCatVerbs: not really. how does a program get to that IO String? I'm starting to think I'll just have to use unsafePerformIO and Template haskell...
01:28:38<gwern>it complexifies the configuration!
01:29:04<dcoutts_>gwern: perhaps the best thing would be to call ghc --print-libdir when your program initialises itself
01:29:19<dcoutts_>ie do it at runtime rather than configure/compile time
01:29:26<gwern>dcoutts_: but then that might not be the ghc it was compiled against
01:29:39<gwern>@where cpuperf
01:29:39<lambdabot>I know nothing about cpuperf.
01:29:50<dcoutts_>gwern: you'd also want to call --version I suppose to make sure it's the same version
01:30:06<dcoutts_>gwern: the opposite problem is that someone could move ghc but keep the same version
01:30:28<gwern>>.<
01:30:29<dcoutts_>though perhaps that's unlikely and you're prepared to break in that case
01:32:16<MyCatVerbs>dcoutts_: s/break/break the user's face/
01:32:31<dcoutts_>heh heh
01:32:56<dcoutts_>gentoo used to do that btw, have both ghc-bin and ghc installed in different dirs but be the same version
01:33:17<dcoutts_>and users could and would occasionally switch from one to the other without recompiling other apps/libs
01:33:38<MyCatVerbs>Jinkies.
01:34:20<LoganCapaldo> would you keep ghc in the same place for a scooby snack?
01:34:41<gwern>(interesting. I didn't know you *could* define main with a type sig besides main :: IO ())
01:34:59<luqui>gwern, what's this then?
01:35:20<ddarius>gwern: The obvious most general type is IO a
01:35:40<gwern>luqui: messing with dons's cpuperf. one file defines 'main', but with the type sig main ∷ IO (Either String a)
01:36:07<monochrom>hehe
01:36:30<ddarius>That's mildly obscene, though I can see why it might be done.
01:37:06<MyCatVerbs>LoganCapaldo: I suspect the scoobie snacks are actually magic brownies.
01:37:24<MyCatVerbs>LoganCapaldo: it'd certainly explain a lot of the gang's behavoir.
01:38:04<MyCatVerbs>ddarius: what? No, that's fine. Just have the program always end with exitWith, that's fine. :)
01:39:36<ddarius>MyCatVerbs: There's no need for exitWith. The type of main is IO a which suggests that it simply discards whatever is returned.
01:40:11<MyCatVerbs>ddarius: oh, I see.
01:40:13<monochrom>You should try main = print whee >> return undefined some time.
01:40:41<ddarius>main = print "foo" >> main
01:40:58<EvilTerran>main = putStr s >> print s where s = "main = putStr s >> print s where s = "
01:41:23<monochrom>haha
01:41:35<faxlore>> putStr s >> print s where s = "> putStr s >> print s where s = "
01:41:36<lambdabot> Parse error at "where" (column 21)
01:41:44<faxlore>awwww
01:42:07<MyCatVerbs>faxlore: \bot doesn't let you do any IO, for safety's sake. :)
01:42:24<Saizan>dcoutts_: ping
01:42:31<dcoutts_>Saizan: pong
01:42:37<BMeph>There is no IO in the Champagne Room. ;p
01:43:31<Saizan>dcoutts_: after your refactoring, cabal install and cabal upgrade die with a fromFlag call, presumably because they are used with commandAddActionWithEmptyFlags rather than commandAddAction ?
01:43:48<Saizan>dcoutts_: the fromFlag call is the one for verbosity
01:43:52<dcoutts_>Saizan: ah, thanks
01:44:26<gwern>dons is at dons@galois.com these days, right?
01:55:39<MyCatVerbs>dcoutts_: oh and you were totally right, using IOUArrays was a huge PITA. ByteStrings much more fun. ^_^
01:55:49<dcoutts_>:-)
01:57:05<dons>dcoutts_: here's a fun puzzle (and i have an answer) -- regarding bytestrings..
01:57:17<dons>so, if i have: x = pack "abcdef"
01:57:28<dons>how is the bytestring constructed?
01:57:38<dons>its a PS addr 0 len, right?
01:58:19<dons>now, in the case of a compile-time constant string, the length is computed via a strlen call, and a rewrite rule replaces the pack with a literal PS constructor, right?
01:59:21<dons>so, what happens when we have: x = pack "abc\0def" :)
01:59:40<LoganCapaldo>:(
01:59:41<dcoutts_>hah
01:59:56<dcoutts_>strlen is very C null terminated string
02:00:05<dons>dcoutts_: but... something saves us :)
02:00:06<dcoutts_>dons: so it breaks and you get "abc"
02:00:09<dcoutts_>really?
02:00:20<glguy>utf8!
02:00:28<dons>yes. so ghc turns string literals into C string literals, right?
02:00:36<MyCatVerbs>glguy: no, ByteStrings work on word8s, not unicode.
02:00:47<dons>however, if there's an embedded \0, it *doesn't use a C string literal*
02:00:54<glguy>dons: what does it use?
02:00:59<dons>so the rule never fires, since we never see a: pack "foo"#
02:01:05<dcoutts_>dons: oh, I see
02:01:13<dons>unpackUTF8String#
02:01:37<glguy>\o/
02:01:48<dcoutts_>dons: it should really store constant strings as length prefixed rather than null terminated
02:01:52<MyCatVerbs>dons: pity. If you do see a compile-time constant string literal in C, can't you hit it over the head with sizeof()?
02:02:20<dons>dcoutts_: yes, i think we should lobby for strings to turn into CStrLens or something
02:02:30<dons>so we can get at that length safely in rewrite rules
02:02:48<MyCatVerbs>"Lobby"? oO
02:03:02<dons>and the correctness of the packAddress rewrite rule depends on a ghc compilation technique
02:03:10<dcoutts_>lobby == send patches and/or persuade JaffaCake
02:03:14<dons>and its utf8 checking (and the special case for \0)
02:04:27<MyCatVerbs>ACTION tries it. Yes you can.
02:04:32<ddarius>In America we usually use mony.
02:04:44<ddarius>s/mony/money
02:04:57<gwern>and women. don't forget the dc madam
02:05:05<MyCatVerbs>dons: it's a compile time constant, so why can't you use C's sizeof() to get its length, rather than relying on strlen()?
02:05:12<gwern>first you get de office, then you get de money, then you get de women...
02:05:17<MyCatVerbs>dcoutts_: ahhh, I see.
02:05:21<faxlore>sizeof is done aat compile time...
02:05:47<MyCatVerbs>faxlore: jah, and zeez are compile time constants that're under discussion.
02:06:09<faxlore>oh .. right, I forgot that GHC is generating C code
02:06:13<MyCatVerbs>Or am I missing some subtlety here?
02:06:22<faxlore>nah I'm just confused
02:06:32<MyCatVerbs>faxlore: although it won't be for long, hopefully. :)
02:06:41<faxlore>what will be the replacement?
02:06:47<Saizan>it's not the default anymore
02:06:50<ddarius>MyCatVerbs: It already uses a native code generator by default.
02:07:30<hpaste> lz pasted "sum List" at http://hpaste.org/4913
02:07:41<MyCatVerbs>ddarius: the higher optimization levels still turn -fvia-C on by default though, don't they?
02:08:56<MyCatVerbs>faxlore: the native code generator should over the course of the next few years get to be faster than -fvia-C has been, assuming that what gets discussed on the mailing lists will come to pass. :)
02:09:13<LZ_2008>hello ppl can any one help me with this "sum List" at http://hpaste.org/4913
02:09:19<ddarius>http://www.haskell.org/ghc/docs/latest/html/users_guide/options-optimise.html
02:09:20<lambdabot>Title: 5.9. Optimisation (code improvement), http://tinyurl.com/254c66
02:10:07<LoganCapaldo>LZ_2008: ddi you try it?
02:10:24<faxlore>MyCatVerbs: I wrote a simple theorem prover!
02:10:25<LZ_2008>yes but i get error
02:10:28<faxlore>Really.. simple..
02:10:48<LoganCapaldo>well your type annotation is incorrect which is probably the soure of the rror
02:11:12<LoganCapaldo>soma :: [[Int]] -> [Int]
02:11:13<gwern>can you specify list length in a sig like that?
02:11:17<LoganCapaldo>no
02:11:18<MyCatVerbs>faxlore: that puts your count of theorem provers written thus far at least one higher than mine, then. Nice going. :)
02:12:01<LoganCapaldo>oh wait
02:12:01<LZ_2008>let me tri that but i dont think it will work
02:12:06<MyCatVerbs>LZ_2008: perhaps you wanted tuples, not lists?
02:12:07<LoganCapaldo>that's the wrong type too <g>
02:12:23<MyCatVerbs>[(Int, Int, Int)] -> (Int, Int, Int) instead.
02:12:34<LoganCapaldo>@type soma b n m = [ x + c + v | x <- b, c <- n, v <- m ]
02:12:36<lambdabot>parse error on input `='
02:12:46<LoganCapaldo>@type let soma b n m = [ x + c + v | x <- b, c <- n, v <- m ] in soma
02:12:47<lambdabot>forall t. (Num t) => [t] -> [t] -> [t] -> [t]
02:13:10<LoganCapaldo>als
02:13:13<LoganCapaldo>*also
02:13:50<LoganCapaldo>> [ (x,y, x + y ) | x <- [1,2,3], y <- [10, 20, 30] ]
02:13:51<lambdabot> [(1,10,11),(1,20,21),(1,30,31),(2,10,12),(2,20,22),(2,30,32),(3,10,13),(3,20...
02:14:24<LoganCapaldo>> zipWith (\x y -> (x, y, x + y)) [1,2,3] [10,20,30]
02:14:25<lambdabot> [(1,10,11),(2,20,22),(3,30,33)]
02:15:01<MyCatVerbs>LZ_2008: tiny tip to save you some head scratching: haskell uses -- for comments, rather than //. (no idea why, presumably some of the Haskell developers like the idea of using // as an operator)
02:15:41<LZ_2008>sorry about that
02:16:05<LZ_2008>[[1,2,3],[4,5,6],[7,8,9]]
02:16:05<LZ_2008>[12,15,18]
02:16:17<faxlore>:t (//)
02:16:18<lambdabot>forall i e. (Ix i) => Array i e -> [(i, e)] -> Array i e
02:16:23<MyCatVerbs>LZ_2008: what on Earth are you apologising for? :) I'm just trying to save you some time.
02:16:58<MyCatVerbs>LZ_2008: is the number of elements in each of those lists fixed?
02:16:59<Pseudonym>Miranda used ||
02:17:03<ddarius>> let f [[1,2,3],[4,5,6],[7,8,9]] = [12,15,18] in f [[1,2,3],[4,5,6],[7,8,9]]
02:17:04<lambdabot> [12,15,18]
02:17:22<Pseudonym>But || was too useful for "or".
02:17:28<MyCatVerbs>Pseudonym: well, it's nice to know that nobody's bothered basing what to use on what anyone else uses, then. ;)
02:17:30<Pseudonym>So -- was the closest equivalent.
02:17:39<LZ_2008>yes its fixed
02:17:49<faxlore>:t (||)
02:17:50<lambdabot>Bool -> Bool -> Bool
02:17:51<LZ_2008>but i can do to not fixed if its more easy
02:17:52<MyCatVerbs>Pseudonym: ahhh. What does ML use, out of curiosity? (If you happen to know offhand.)
02:18:00<faxlore>(* ... *)
02:18:02<Pseudonym>Well, Miranda used || because it was close to a certain type of mathematical notation.
02:18:09<MyCatVerbs>ddarius: that was mean. :)
02:18:35<MyCatVerbs>faxlore: ahhhh, yes. Oh well.
02:19:39<MyCatVerbs>faxlore: at least the various functional languages tend to *look* fairly distinctive. No chance of confusing Haskell for OCaML, unlike the near-incestuous similarities between the curly-braces languages (C(++), Java, C#...)
02:19:46<LoganCapaldo>don't forget about {-- --}
02:19:53<MyCatVerbs>Pseudonym: hair enough.
02:20:08<MyCatVerbs>*fair... no, actually, I prefer "hair enough", sounds cooler.
02:20:15<LoganCapaldo>I dunno, let x = 1 is valid haskell and ocaml :P
02:20:33<dcoutts_>ACTION has hair enough
02:21:34<MyCatVerbs>ACTION has hair too much, and should possibly consult a barber.
02:22:03<aFlag>Pseudonym, miranda used || for comments?
02:22:07<MyCatVerbs>LoganCapaldo: well, if you're going to be pedantic, that's also valid QBASIC. =D
02:22:29<aFlag>LoganCapaldo, {- -}, no? you don't need the extra -
02:22:33<aFlag>I don't think
02:22:43<ddarius>(* *)
02:22:43<ddarius>Does it have line comments? I forget.
02:23:02<MyCatVerbs>aFlag: you're right, but {--- foo! swear words and to HELL with the world! ---} is prettier.
02:23:12<aFlag>how come?
02:23:29<dcoutts_>ACTION notes that cabal install can install cabal and indeed cabal-install
02:23:52<MyCatVerbs>aFlag: they look like stabbing implements.
02:24:10<Pseudonym>aFlag: IIRC, yes.
02:24:17<ddarius>Pseudonym: Which?
02:24:31<aFlag>I like -- for comments. It's kinda how you comment on text -- at least in English and Portuguese.
02:25:08<Pseudonym>Miranda using || for comments.
02:25:29<aFlag>|| looks weird for comments, I'm too used to || being or
02:25:57<MyCatVerbs>aFlag: personally, I would prefer nesting versions of // and /* */
02:27:16<ddarius>Pseudonym: I was wondering which mathematical notation.
02:27:27<LZ_2008>aFlag do you speak pt?
02:27:34<MyCatVerbs>aFlag: but only by a tiny margin and, fuck it, syntax is irrelevant by comparison to the importance of semantics. I'd be happy using Scheme syntax, or even Prolog's, for Pete's sake (do you know anyone called Pete? Me neither), in return for nice enough language semantics. :)
02:27:38<Pseudonym>Oh, right.
02:28:05<Pseudonym>I think it's rare, but I have seen two vertical lines for a comment-like remark.
02:28:20<aFlag>LZ_2008, yep
02:28:51<LZ_2008>br or pt
02:28:53<aFlag>I don't think prolog syntax is that bad
02:28:54<aFlag>br
02:29:06<faxlore>you gotta write in CPS though
02:29:13<LZ_2008>nice to now im from pt
02:29:16<gwern>MyCatVerbs: actually, I did know someone named Pete. he was one of my taekwondo instructors until he left to run his own school
02:29:17<faxlore>unless you have evaluators
02:29:18<aFlag>cool
02:29:40<BMeph>Speaking of Portuguese, Lua also uses "--" for one-line comments.
02:29:47<aFlag>I never tried lua
02:29:49<allbery_b>sql
02:29:49<aFlag>seems nice
02:30:25<aFlag>LZ_2008, where in portugal are you from?
02:30:37<LZ_2008>algarve
02:32:19<aFlag>cool, a cousin of mine attended one semester to an university in lisboa
02:32:44<ddarius>ACTION thinks we should all switch to Smalltalk style comments
02:32:59<aFlag>what are those like?
02:33:06<ddarius>"comment"
02:33:19<dcoutts_>or basic? :-)
02:33:22<dcoutts_>REM blah blah
02:33:29<Saizan>and string literals?
02:33:43<aFlag>REM what does that mean? short for REMOVE?
02:33:48<ddarius>'string'
02:33:49<jcreigh>REMARK, I think
02:33:49<ddarius>remark
02:33:54<LoganCapaldo>'this is a msall talk string literal'
02:33:58<MyCatVerbs>BMeph: oh cool. I've never used Lua myself, but I vaguely know a few people who do and none of them seem to hate it.
02:34:00<LoganCapaldo>*smalltalk
02:34:05<diltsman>How do I export functions I imported from a different module?
02:34:08<dcoutts_>and m4 uses:
02:34:09<dcoutts_>dnl this is a comment
02:34:28<dcoutts_>so that's things like configure.ac and include.m4 files
02:34:40<allbery_b>that';s only half the story
02:34:42<aFlag>I kinda like lisp's comment. The ; is right there, easy to type, only one character, makes C programmers mad...
02:34:46<diltsman>Not BASIC comments, please. Anything but those....how about C99 comments?
02:35:02<faxlore>prolog uses % for one liners
02:35:06<Saizan>diltsman: put them in the export list
02:35:10<allbery_b># is a comment but m4 can expand stuff inside comments, so you need dnl to deleete the result
02:35:15<ddarius>faxlore: As does postscript
02:35:22<LoganCapaldo>bf comments are good too
02:35:40<Saizan>diltsman: you can even put whole modules there, with "module Foo"
02:35:41<LoganCapaldo>heck that sentecne was one :)
02:36:11<dcoutts_>allbery_b: yeah, I head it was something like that but from the outside it looks like madness :-)
02:36:40<allbery_b>most of m4 looks like madness from the outside
02:36:42<MyCatVerbs>diltsman: those are just stolen (and rightfully so) C++ comments, though.
02:36:56<allbery_b>ACTION hacked m4 for years in a previous job
02:37:25<allbery_b>money quote (from the original m4 manpage) "use of the -e option requires a special state of mind"
02:37:38<aFlag>allbery_b, what did you use it for?
02:37:38<runar>Is it possible to parameterize modules?
02:37:45<MyCatVerbs>allbery_b: oh damn, hilarious and scary at the same time. Hilariously scary?
02:37:53<diltsman>Saizan: That was what I needed, thanks.
02:38:25<allbery_b>(m4 -e: to wrap an interactive shell. **shudder**)
02:38:45<MyCatVerbs>Whoaaaaaa
02:38:56<MyCatVerbs>m4 was originally designed for *RATFOR*!?
02:39:01<allbery_b>I worked with Unify's Accell 4GL. which had at least 3 incompatible versions (and partially compatible sub-versions). some of which I had to support simultaneously
02:39:04<MyCatVerbs>That's some pedigree. I mean, nice.
02:39:35<allbery_b>I wrote up some huge m4 macro packages (20K+ lines) to make it possible to write a singel form script which would work with all versions
02:39:39<diltsman>I'm just lucky, all I have to deal with at work is VC++ 6.0 because they won't upgrade their Fortran compiler.
02:39:54<hpaste> travisbrady pasted "Column summer in re to LZ_2008" at http://hpaste.org/4914
02:40:08<allbery_b>scary stuff.
02:40:31<allbery_b>m4 is actually quite consistent and logical --- but in a way that human minds don't handle very well.
02:40:47<aFlag>diltsman, do you program with fortran?
02:41:01<allbery_b>"requires a special state of mind" applies to much of m4, not just the old -e option
02:41:23<MyCatVerbs>allbery_b: I can't seem to (easily) find a specification, or any sort of tutorial on m4 through googling.
02:41:46<runar>For instance, I would like to write a module such that its user can specify for the entire module whether it uses Float or Double.
02:41:52<aFlag>working with m4 must be real nasty
02:41:57<allbery_b>I don't think I've ever seen one.
02:42:00<MyCatVerbs>allbery_b: or, Hell, any links to such from the GNU m4 site. Where'd you pick it up?
02:42:13<allbery_b>I learned it from volume 2 of the unix programmer's manual, the part that wasn't manpages
02:42:44<MyCatVerbs>Oh wait, GNU re-did their m4 site. A lot. It's actually useful now. x_x
02:42:51<allbery_b>mostly academic-style papers (wonder where else I've seen that?) on awk, m4, lexx, yacc, various other programming-related utilities
02:43:04<gwern>(a lot of hackage is broken. I'm barely through the bs and I already have 5 I should try to fix)
02:43:06<EvilTerran>runar, you can put the entire module in a typeclass, if you want
02:43:23<EvilTerran>?instances RealFrac
02:43:26<lambdabot>Double, Float
02:43:46<allbery_b>unfortunately I don't think anyone ships it any more and it's not freely available that I've seen
02:43:46<EvilTerran>or just have individual functions be appropriately polymorphic
02:43:47<MyCatVerbs>Hahahaha. "Some people find m4 to be fairly addictive. They first use m4 for simple problems, then take bigger and bigger challenges, learning how to write complex sets of m4 macros along the way. Once really addicted, users pursue writing of sophisticated m4 applications even to solve simple problems, devoting more time debugging their m4 scripts than doing real work. Beware that m4 may be dangerous for the health of compulsive programmers."
02:44:00<MyCatVerbs>From the GNU m4 manual. XD
02:44:12<gwern>hee hee, 'cabal install cabal-install'
02:44:21<gwern>it works :)
02:44:37<aFlag>allbery_b, did you get addict to it?
02:44:42<allbery_b>nope
02:45:05<allbery_b>I came to understand it, but never came to like it
02:45:13<MyCatVerbs>ACTION could see himself getting addicted. Weird things that require one to twist one's brain sideways tend to attract him.
02:45:19<gwern>(hm. cabal-test and cabal-upload don't though)
02:45:24<allbery_b>(same with sendmail.cf. yug)
02:45:39<runar>EvilTerran: What do you mean by "put the entire module in a typeclass"?
02:46:06<EvilTerran>runar, on reflection, i'm not sure what that was supposed to mean
02:46:14<runar>:-)
02:46:25<MyCatVerbs>allbery_b: is sendmail.cf Turing-complete? :)
02:46:33<runar>I will use RealFrac. Thanks!
02:46:36<EvilTerran>runar, but type-parameterised modules're made pretty obselete by class-based polymorphism
02:46:57<allbery_b>MyCatVerbs: thing is, it's not a very interesting form of sideways
02:47:18<diltsman>aFlag: I don't program Fortran (I can read it), but the guy who started the project 2-3 years ago was a Fortran programmer. Since some of the stuff doesn't have any way to interface with Fortran, I'm doing the interfacing in C/C++.
02:47:34<EvilTerran>runar, i guess i meant module MyModule (...) where class MyModule a where { all the functions of the module, as methods with default implementations }
02:47:34<gwern>MyCatVerbs: http://okmij.org/ftp/Computation/sendmail-as-turing-machine.txt :)
02:47:53<runar>Oh? What to do if I have several classes, all of which share the same type parameter?
02:48:01<MyCatVerbs>gwern: heh. I had heard something along those lines.
02:48:17<EvilTerran>runar, as then you could introduce an instance for any particular type you wanted to work with the module on
02:48:17<runar>My module contains classes. I didn't think classes could be nested.
02:48:25<gwern>'stack overflow: use +RTS -K<size> to increase it' <-- o.0 not sure I ever got that error compiling before
02:48:28<MyCatVerbs>allbery_b: what, m4 or sendmail.cf? Sendmail.cf is bollocks, yesh. m4, I'm not so sure about.
02:48:28<EvilTerran>but, that's abusing the typeclass system. don't do it. :P
02:48:37<gwern>has anyone successfully installed 'cedict-0.1.1'?
02:49:08<EvilTerran>runar, i just meant that as a demo of a simple type-parameterised-module -> typeclass transformation
02:49:46<EvilTerran>there's far better ways of achieving the same thing
02:50:54<runar>EvilTerran: Oh, I see. But say I have a module with several classes which declare functions for manipulating numbers. Any user of the module will want all the functions to manipulate the same type of number.
02:52:13<EvilTerran>why make the restriction?
02:52:44<EvilTerran>write all the functions to be independently polymorphic; it's not your business if people want to use it with more than one numeric type
02:53:48<MyCatVerbs>dcoutts_, dons: y'know how there was a lot of traffic on haskell-cafe about building up a library of programs to be able to test for performance regressions with GHC?
02:53:59<dcoutts_>MyCatVerbs: yep
02:54:05<dcoutts_>it's a good idea
02:54:15<EvilTerran>runar, if you have a *really* good reason to restrict 'em all to one type but let the user of the module choose which type, you can do that with fundeps
02:54:22<MyCatVerbs>Would it be a sane idea to, as well as all these nicely written and decently optimized things using all the fast APIs (bytestrings, etc)...
02:54:35<runar>EvilTerran: OK, thanks. I will look at that.
02:54:38<MyCatVerbs>...add in, oh, a large fistful of programs written in an extremely naive manner?
02:54:45<EvilTerran>class Foo a | -> a; foo :: Foo a => a -> a; bar :: Foo a => a -> Int -- etc
02:54:49<dcoutts_>MyCatVerbs: sure
02:55:05<EvilTerran>(nb i didn't give the class a where{} clause)
02:55:22<EvilTerran>runar, but do you *have* a *really* good reason? ;)
02:55:50<MyCatVerbs>dcoutts_: I ask because I'm quite capable of generating mountains of shite code, but so far useless at fast Haskell programs (I've never tried yet, to be honest). Also, I have some pretty godawful code hanging around on disk that I'm using for courseworks and the like.
02:56:19<MyCatVerbs>(Godawful from the POV of performance, I mean. It's not *totally* byzantine and crap, just largely so. ;)
02:56:21<dcoutts_>MyCatVerbs: :-) I think it's useful to have naive code so long as it's short and easily comprehensible
02:56:32<runar>EvilTerran: It's not really that good. Just wanted a shorthand for saying "use Float throughout and don't bother me"
02:57:00<EvilTerran>inference should mean you won't need that many type annotations
02:57:04<MyCatVerbs>dcoutts_: plus, some of what I have kinda works the shit out of Concurrent Haskell, or would if it didn't have a giant block-on-real-world sitting in the middle of one of the feedback loops. :)
02:57:49<EvilTerran>and you could make all your annotations of a type synonym so you can change 'em all from one place
02:57:49<MyCatVerbs>dcoutts_: (personally, I find CH to be something of a killer feature for Haskell. Not even Java seems to make concurrency this... easy.)
02:58:04<EvilTerran>"not even java"?! hah!
02:58:15<MyCatVerbs>EvilTerran: hey, it's heaven if you're used to C. :)
02:58:28<EvilTerran>thankfully, i am used to doing threading in neither :D
02:58:29<faxlore>truth
02:58:47<dcoutts_>Saizan: try pulling cabal-install again, should be fixed
02:59:09<runar>MyCatVerbs: Concurrency in Java is not easy.
02:59:17<MyCatVerbs>runar: chances are you want to use Doubles anyway, though. AFAIK, GHC does a better job of optimizing things when you use Doubles (I think there's a more complete set of rewrite rules in place). Only when you're dealing with large quantities of packed floats (and worried about fitting them inside your CPU's cache) would you want to use Floats.
02:59:32<EvilTerran>@where+ default http://haskell.org/onlinereport/decls.html#default-decls
02:59:33<lambdabot>I will remember.
02:59:35<diltsman>Threading isn't too bad in C++ if you use Boost.Thread
02:59:42<EvilTerran>runar, that ^^ link might be relevant to your interests
02:59:55<MyCatVerbs>runar: I haven't found an imperative language in which threading is easier than in Java.
03:00:04<Valodim>true dat
03:00:04<diltsman>What is the difference between type and newtype?
03:00:15<MyCatVerbs>diltsman: tiny tiny semantic difference.
03:00:39<EvilTerran>MyCatVerbs, actually, that one's pretty big
03:00:40<diltsman>MyCatVerbs: No doubt, but anybody know where I can find what that is? (I'm a glutton for punishment)
03:00:44<MyCatVerbs>diltsman: newtype can only be used where you have exactly one constructor. In many cases, it allows the constructor to be optimized away.
03:00:45<EvilTerran>you may be thinking of data/newtype
03:01:00<MyCatVerbs>EvilTerran: oh, whoops.
03:01:07<runar>MyCatVerbs: I'll agree with that. My not keeping up with Pascal notwithstanding.
03:01:10<monochrom>Threading isn't too bad in C++ if you use Haskell.
03:01:10<EvilTerran>diltsman, "type" creates two types that the typechecker can't tell apart
03:01:10<MyCatVerbs>diltsman: disregard that, I'm talking bullshite.
03:01:18<diltsman>So, type is like typedef in C, and newtype and data are similar, except newtype only allows for 1 constructor?
03:01:28<MyCatVerbs>diltsman: yes, right.
03:01:36<EvilTerran>diltsman, but "newtype" makes the two types distinct, using the constructor you give to disambiguat
03:01:40<MyCatVerbs>diltsman: *that* is right. What I said was bumf. :)
03:01:53<MyCatVerbs>monochrom: what do you mean by that?
03:01:58<EvilTerran>also newtype requires exactly one parameter for the constructor
03:02:11<Saizan>dcoutts_: yes, nice :)
03:02:13<monochrom>It means switch to Haskell. :)
03:02:32<gwern>wow. I'm half through the Es, and I've found 27 broken packages (excluding ones broken because a dependency is broken)
03:02:46<davidL>@remember monochrom Threading isn't too bad in C++ if you use Haskell.
03:02:46<lambdabot>Nice!
03:02:47<MyCatVerbs>monochrom: heh. I thought for a moment you meant "write some stuff in C++, then have Haskell call it through FFI to handle all the multithreading."
03:02:50<diltsman>monochrom: lol I just wish I could use Haskell for most things. I love C++, but I'm finding I like Haskell more.
03:02:56<gwern>(and EtherBunny is the next to bite the dust...)
03:03:10<dcoutts_>Saizan: you mean it's working for you now? btw, I also added a warning to try to get people to specify build-type:
03:03:12<EvilTerran>diltsman, newtype and type are similar in that they create an alias of an existing type
03:03:22<davidL>gwern: what is up with etherbunny?
03:03:33<MyCatVerbs>gwern: EtherBunny?
03:03:39<gwern>davidL: 'cabal install EtherBunny' fails
03:03:39<EvilTerran>diltsman, but data and newtype are similar in that they create a type that's distinct from any existing types at the type-checking stage
03:03:46<EvilTerran>(type doesn't)
03:03:50<gwern>(fenfire is next)
03:03:53<runar>Is that similar to a VorpalBunny?
03:04:10<MyCatVerbs>Ohhh, piece of software. Heh. Had me wondering, since I know someone who uses that nickname on IRC. :)
03:04:12<gwern>no idea
03:04:12<EvilTerran>diltsman, and data creates a type that can be structurally different from any existing type
03:04:23<EvilTerran>(unlike type and newtype)
03:04:35<diltsman>data I had figured out, and type, but newtype what what had me confused.
03:04:42<davidL>etherbunny is like a packet parser for the ethernet, tcp, and ip protocols
03:05:01<MyCatVerbs>EvilTerran: newtype's constructor can take more than one parameter though, right?
03:05:09<Saizan>dcoutts_: yeah it works, and i agree on encouraging build-type, and i've just noted that install is case-sensitive in package names, a bit surprising
03:05:09<EvilTerran>MyCatVerbs, no; not less than on3
03:05:14<EvilTerran>er, one
03:05:18<EvilTerran>also "nor"
03:05:29<dcoutts_>Saizan: there's a bug open about that if you want a small task :-)
03:05:49<gwern>dcoutts_: what does build-type do anyway? I use it, but I don't understand why
03:05:51<MyCatVerbs>EvilTerran: oh, it has to be exactly one? I presume that parameter can be a tuple, though?
03:05:56<EvilTerran>MyCatVerbs, seeing as it's a wrapper for a single type, it wouldn't really make sense
03:06:06<dcoutts_>gwern: it means we can avoid using Setup.hs at all in most cases
03:06:18<gwern>oh. that's good?
03:06:20<EvilTerran>other than by doing implicit tupling, and, yes, it's more in the spirit of haskell to just tuple explicitly
03:06:20<LoganCapaldo> newtype A = A Int Int, what type is Int Int ?
03:06:38<MyCatVerbs>EvilTerran: yes, it would be silly. But still, fun. :)
03:07:00<EvilTerran>if you were doing implicit tupling, you might as well go the whole hog and do implicit Either'ing as well, thus defeating the whole point :P
03:07:03<dcoutts_>gwern: which 1. is faster, 2. is less prone to breakage, 3. good for security of build bots as it means not executing unknown untrusted code
03:07:54<dcoutts_>gwern: it also means you don't need to supply a Setup.hs file which is a small bonus for developers
03:08:01<MyCatVerbs>EvilTerran: oooh, good idea.
03:08:38<MyCatVerbs>EvilTerran: newtype Foo = Fooonst (Either (Int,Int) (Int,Int -> Int)) -- ;)
03:08:46<gwern>dcoutts_: I do like that, yes. Setup.hs always struck me as redundant...
03:08:48<sjanssen>dcoutts_: you still need Setup.hs for backwards compat, right?
03:09:06<sjanssen>for all those people that aren't using the 'cabal' executable
03:09:08<EvilTerran>...
03:09:12<dcoutts_>sjanssen: for the moment, yes.
03:09:15<EvilTerran>I'm going to bed now.
03:09:27<MyCatVerbs>Eh? Setup.hs getting replaced? *peeks at the backscroll*
03:09:35<Saizan>ACTION still uses cabal-setup
03:10:27<MyCatVerbs>dcoutts_: I don't see the problem with executing untrusted code in Setup.hs. If you don't trust the person who wrote Setup.hs, how're you going to trust the person who wrote the damn *library* you're compiling? Since they're generally the same person or people...
03:10:48<faxlore>can't you just open it? :p
03:10:50<faxlore>and check
03:11:02<MyCatVerbs>faxlore: no, I'm lazy. :)
03:11:03<allbery_b>up to a point, yes
03:11:28<TomMD>Curiously - how does one determine the endianness of the current machine? I see you can abuse Data.Binary or parse the architecture string from System, but I can't find a preexisting value isBigEndian :: Bool
03:11:33<allbery_b>but it's easy to miss stuff, even when it's not hyper-obscure (cf. "Reflections on Trusting Trust")
03:12:00<MyCatVerbs>allbery_b: oh, that was quite an incredible feat of bastardry, heh.
03:12:17<dcoutts_>MyCatVerbs: I don't generally have to run your code to be able to compile it or to compile the docs
03:12:40<dcoutts_>MyCatVerbs: there are exceptions, like TemplateHaskell but it's possible to black-list that too
03:12:50<MyCatVerbs>dcoutts_: this is true.
03:12:57<gwern>in the Gs, more than 38 broken packages... I'm getting really sick of the 'package hidden' error :)
03:13:18<gwern>ACTION wonders what the heck a 'gopherbot' package would be good for
03:13:20<MyCatVerbs>dcoutts_: I presume the security of buildbots isn't the *only* reason to replace Setup.hs though, right?
03:13:40<dcoutts_>MyCatVerbs: not the only one
03:15:09<Saizan>MyCatVerbs: when using cabal or cabal-setup is quite annoying to compile another exec just to do the same work
03:15:49<MyCatVerbs>Saizan: eh? But one usually uses runghc/runhaskell anyway, not much pain aside from the (irrelevant) speed penalty.
03:16:32<dons>TomMD: you can use CPP
03:16:42<Saizan>s/is/it's/
03:16:53<dons>oh, maybe you can't, actually
03:17:15<Saizan>MyCatVerbs: "usually" because you've not installed those yet!
03:17:48<MyCatVerbs>Saizan: when have you not installed runghc? Se cometh with GHC...
03:20:04<Saizan>MyCatVerbs: by those i meant cabal-install or cabal-setup, sorry
03:20:50<sjanssen>there is so much FUD about laziness and space usage lately, it is quite sad
03:21:00<MyCatVerbs>Saizan: I think I'm out of sync with this conversation. :)
03:21:22<MyCatVerbs>sjanssen: mmmm, I'd say there's something of a point to it.
03:21:39<sjanssen>MyCatVerbs: yes and no
03:22:03<allbery_b>wasn't the main problem with Setup.hs that it was either (a) one-liner boilerplate or (b) complex and fragile (and better handled these days in the cabal file)?
03:22:17<MyCatVerbs>sjanssen: imagine that every single function you write gets transformed by "\x -> unsafePerformIO (putStr ".") >> return x"
03:22:40<MyCatVerbs>sjanssen: then attempt to work out exactly how many .'s will have been dumped onto stdout by the end of your program run. :)
03:22:43<sjanssen>what everyone has forgotten, it seems, is that lazy evaluation can also have asymptotically *better* space usage
03:23:08<sjanssen>MyCatVerbs: why does that matter? Also, that seems more to be about time than space
03:23:35<monochrom>Where is the FUD?
03:23:39<MyCatVerbs>sjanssen: indeed it is. I don't think space is anything like such an issue.
03:24:05<monochrom>Anyway the whole bloody computer industry is based on FUD.
03:24:30<sjanssen>monochrom: eg. slava's comment on http://programming.reddit.com/info/654xq/comments/
03:24:35<dons>sjanssen: 'laziness' 'space leaks' is the single-issue pigeon hole for haskell
03:24:48<dons>like 'slow' for ruby, or 'parenthesis' for lisp
03:24:49<MyCatVerbs>sjanssen: personally, I get the impression that it's fine in practice, since (using -Sstderr to look for memory leaks while the program runs) the last interesting program I wrote had no space leakage at all, without me putting any effort into worrying about its' space efficiency at all.
03:25:23<sjanssen>MyCatVerbs: this is my experience as well. I can't remember the last time I fixed a space leak in my own code
03:25:42<dons>yeah. the only space leaks i fix are on -cafe@ :)
03:26:13<monochrom>@remember dons the only space leaks i fix are on -cafe@ :)
03:26:13<lambdabot>Good to know.
03:26:14<MyCatVerbs>sjanssen: (well, except that I did use seq in one place, but that was only to assign unique ID numbers to each of a list of consecutive records).
03:26:49<dons>sjanssen: slava's used this 2 days in a row, btw
03:26:59<dons>and then it was raised as a red herring on the ocaml thread today
03:27:23<dons>talking about equational reasoning, someone throws in the "yeah, but ... space usage!" bomb
03:27:24<sjanssen>the thing is, there is some truth to this issue -- so I can't just say "you're wrong"
03:27:33<MyCatVerbs>sjanssen: (and yeah, that would've been an O(n^2) space waste, except that the program would pretty much immediately evaluate most of those thunks as soon as a single client connected to it to do anything useful, anyway. ¬_¬)
03:28:02<gwern>no, not you too hmp3!
03:28:57<monochrom>This reminds me of someone's quote. "The problem with fools is they're so sure of themselves. The problem with intelligent people is they're so doubful of themselves."
03:29:00<MyCatVerbs>dons: well, "slow" is true for Ruby, "parenthesis" is true for Lisp (though I do contend that anyone stupid enough to be incapable of, oh, I dunno, mashing on the % key in vim? Is too stupid to be trusted to write computer programs that actual people will end up having to use to do their jobs)...
03:29:29<gwern>monochrom: 'the best lack all conviction, while the worst are full of a fiery intensity'?
03:29:41<sjanssen>MyCatVerbs: I think the analogy is good, because the truth is that those issues aren't as problematic as you might think
03:29:44<MyCatVerbs>dons: "space leaks" is pretty much irrelevant for Haskell in practice, but "usually uses quite a bit of RAM" is true, what with things like [Char] being the norm.
03:30:05<MyCatVerbs>ACTION wonders how Haskell compares to Java for memory usage.
03:30:07<dons>5108K sleep/0 poll 0:00 0.05% xmonad
03:30:14<monochrom>Actually something like "The problem with the world is the fools are so sure of themselves and the intelligent people are so doubtful of themselves."
03:30:16<dons>101M sleep/0 poll 1:14 0.00% firefox
03:30:18<dons>:)
03:30:28<MyCatVerbs>sjanssen: well... I'd agree with you except for Ruby.
03:30:34<dons>7576K sleep/0 select 0:00 0.05% urxvt
03:30:39<monochrom>It definitely leads to the fools dominating all issues.
03:30:46<sjanssen>MyCatVerbs: nobody uses Ruby to write speed-intensive code, all lisp users use good editors, laziness only blows up in rare cases, etc.
03:30:52<MyCatVerbs>sjanssen: the Ruby 'terp is, I am informed, slower than even fucking TCL.
03:31:32<MyCatVerbs>sjanssen: that is something special, dammit, considering that TCL is built on the "everything is a string" model.
03:31:41<sjanssen>MyCatVerbs: yes, but the argument is that it is usually fast enough -- and that's true
03:32:31<dons>at least we dont' hear "haskell's slow" anymore.
03:32:34<dons>that used to be hte label
03:32:38<gwern>dunno. the TCL interpreter has had like almost 2 decades now. I'd be surprised if they hadn't added in quite a few optimizations
03:32:39<MyCatVerbs>sjanssen: dunno, I keep hearing bad things about its interpreter. And I hear, "well, you can always scale it horizontally," more often that I hear, "it's I/O bound anyway" or "it's database-bound anyway". :/
03:32:40<monochrom>hehehe
03:32:41<sjanssen>(last time you'll find me defending Ruby, I bet :) )
03:32:47<dons>guys who only remember the old news (like jdh30) still trot that one out
03:32:50<MyCatVerbs>gwern: nope, I'm informed.
03:32:51<dons>but it used to be ubiquitous
03:33:08<dons>so critics need a different label
03:33:09<MyCatVerbs>gwern: that flies in the face of their vision for the project, apparently.
03:33:19<monochrom>They are critics?
03:33:30<monochrom>Critics are actually rational.
03:33:30<dons>everyone's a critic
03:33:32<gwern>MyCatVerbs: really? they've deliberately kept it slow?
03:33:34<sjanssen>dons: I'm keeping this eta-expansion/pointfree example in my pocket for anti-jdh ammo :P
03:33:49<dons>heh :)
03:33:59<MyCatVerbs>gwern: no, they've deliberately not complicated the living shit out of the interpreter. But they have a number of reasonably clever things, like variables are cached.
03:34:14<monochrom>I'd call them haters.
03:34:43<MyCatVerbs>gwern: e.g. if you use a string as a number, the interpreter caches the integer conversion, so that you're not constantly re-reading the same string over and over again.
03:34:44<gwern>MyCatVerbs: I deny that a fast interpreter/compiler has to be complicated - I was impressed by the elegant design of the sausage scheme compiler, for example, which was fairly fast
03:35:06<MyCatVerbs>gwern: (and also, for obvious reasons, invalidates the cache if you alter it using string manipulation functions)
03:35:59<MyCatVerbs>gwern: it does if your language semantics revolve around everything being a string, and alterable at run-time using string manipulation functions.
03:36:31<MyCatVerbs>gwern: it also does require massive complication to make things fast in the face of having eval in the language - which TCL does.
03:37:19<gwern>scheme has eval
03:37:21<MyCatVerbs>gwern: e.g. you can concatenate, apply regexes to, paste together and split apart the strings that represent your program in TCL. I have a vague suspicion that that makes it one of few languages actually more expressive than Lisp. ;)
03:37:50<MyCatVerbs>gwern: yes, and it comes with huge dire warnings about it being blastedly slow.
03:37:58<gwern>'setup: The pkg-config package hyperestraier version >=1.4.9 is required but it could not be found.' <-- wow, what on earth does that mean?
03:38:19<faxlore>you can do that in lisp too
03:38:21<faxlore>though
03:38:27<sjanssen>gwern: it means install hyperestraier
03:39:02<gwern>sjanssen: yeah, but that's what I was doing!
03:39:16<LoganCapaldo>ACTION wonders idly if jruby or 1.9 are "faster" than tcl
03:39:17<MyCatVerbs>faxlore: this is true, but doesn't everybody use macros instead, since they're always faster?
03:39:28<sjanssen>gwern: the C library called hyperestraier (pkg-config is something like a package manager for C)
03:39:46<gwern>oh. that makes sense then
03:39:57<MyCatVerbs>LoganCapaldo: dunno. Perhaps they are.
03:40:20<MyCatVerbs>LoganCapaldo: but a good dynamic language implementation ought to be able to smoke TCL. AFAIK, Python and Perl both do so easily.
03:41:26<LoganCapaldo>who says ruby's impl. is good?
03:41:35<dons>we really need to get haskell running on lego, http://jpbrown.i8.com/cubesolver.html
03:41:35<lambdabot>Title: JP Brown's Serious LEGO - CubeSolver
03:41:38<faxlore>I don't like it much
03:41:41<faxlore>there's a lot of code though..
03:41:46<LoganCapaldo>yes
03:41:53<dons>lego haskell seems like a killer app -- clean language, high level algos, low level robot fun
03:41:57<LoganCapaldo>haskell/lego is essential
03:41:58<MyCatVerbs>LoganCapaldo: http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=tcl&lang2=ruby -- ever so slightly in TCL's favour there, I think. Compare and contrast with http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=tcl&lang2=python -- where Python totally smokes TCL.
03:42:03<lambdabot>Title: Tcl benchmarks | Gentoo : Intel&#174; Pentium&#174;&nbsp;4 Computer Language Ben ..., http://tinyurl.com/3ye9og
03:42:18<LoganCapaldo>MyCatVerbs: err I ddin't doubt you
03:42:22<MyCatVerbs>LoganCapaldo: no, it isn't. That precisely the thing. Ruby may be an awesome language but it has a terrible implementation.
03:42:43<MyCatVerbs>LoganCapaldo: oh, my bad.
03:43:00<dons>so there's just some C/C++ interface to the lego kit?
03:43:14<MyCatVerbs>ACTION is curious...
03:43:27<MyCatVerbs>Oh wow, Perl and Python are pretty evenly matched there.
03:43:53<dons>can everyone click on the ruby/ghc comparison, and feel good about the world.
03:43:53<phobes>lego doesn't qualify as "killer app" until more people rush to program robots :)
03:44:03<dons>20 years of research in one graph :)
03:44:59<skew>Not until the gcc/ghc one looks the same way :)
03:45:57<monochrom>Let's write an optimizing Ruby compiler in Haskell.
03:46:00<dons>the hcar this month gave me some hope -- there's serious backend research happening now.
03:46:09<MyCatVerbs>monochrom: ...why?
03:46:17<gwern>'cabal: user error (Unresolved dependencies: ghc >=6.6&&<6.8)' <-- interesting requirement :)
03:46:18<dons>yeah, i've been saying for 2 years -- if you want to get super famous, just do a simple ruby compiler in haskell, that wipes the floor
03:46:20<monochrom>Powerful static analyses to eliminate most dynamic dispatch.
03:46:22<gwern>must be using the GHC API
03:46:22<MyCatVerbs>monochrom: admittedly it wold be funny.
03:46:38<MyCatVerbs>monochrom: would a Ruby-to-Haskell compiler count?
03:46:43<dons>i better translating ruby to haskell, and compiling with ghc, would beat the current ruby interpreter :)
03:46:48<monochrom>dunno.
03:46:54<dons>MyCatVerbs: i reckon so. :)
03:47:01<MyCatVerbs>dons: brilliant idea.
03:47:03<dons>and you can use unboxed types and so on.
03:47:03<skew>Translating Python to OCaml doesn't seem to beat CPython
03:47:06<MyCatVerbs>ACTION wonders if Ruby has a spec.
03:47:08<Valodim>how come haskell is losing in most disciplines against most languages in gzip bytes in the shootout?
03:47:30<dons>Valodim: gzip is a floored benchmark, and the haskell code's not optimised for shortness -- but for speed
03:47:32<skew>One of Walid Taha's students has something like that, just implementing stuff with classes and so on
03:47:33<monochrom>Because gzip bytes is unfair IMO.
03:47:39<gwern>dons: hey, what's this 'fps' dependency for lambdabot?
03:47:40<MyCatVerbs>Valodim: gzip bytes measures what, the size of the generated executables?
03:47:43<dons>Valodim: think about it. gzip rewards repetition :)
03:47:49<Valodim>hah
03:47:50<dons>gwern: i think you've got old code.
03:47:50<Valodim>yeah
03:47:54<Valodim>yeah I just thought of that
03:47:58<Valodim>more repetition = better compression
03:48:02<Valodim>sweet
03:48:07<allbery_b>gwern: fps is what's now called bytestrings
03:48:07<monochrom>fps = fast packed string.
03:48:08<gwern>dons: Hackage package
03:48:16<dons>we could add a page of ;;;;;;;;;;;;;;;;;;;; to the end of every file, with no loss :)
03:48:24<gwern>ouch. how *old* is the lambdabot package on hackage?
03:48:24<dons>gwern: out of date by about 3 years.
03:48:34<dons>it was the first or second package uploaded to the demo version of hackage
03:48:58<gwern>ACTION thinks that should be fixed :)
03:49:05<dons>we'd have to do a release.
03:49:10<monochrom>gzip hides some boilerplate code.
03:49:10<dons>and to do that would require some QA on lambdabot
03:49:11<gwern>the horror
03:49:13<dons>which i can't do.
03:49:36<dons>gwern: btw, thanks for fixing all these :)
03:50:03<gwern>dons: I haven't even started. I'm just in the Ls and my list is 68 items long
03:50:21<gwern>and that's omitting everything broken by C library depdencies or other Haskell dependencies...
03:50:35<lambdabot>You're not QAing me, whatever that is.
03:50:35<gwern>ACTION adds lhs2tex to that list
03:50:45<phobes>What's wrong with gzip as a measure? That it doesn't much reward the common haskeller practice of using single letters and symbols for everything?
03:50:59<monochrom>It doesn't punish boilerplate code.
03:51:15<dons>oh man, look what being a commercial haskell developer is doing to me. i'm talking about "QA" all of a sudden
03:51:26<skew>phobes: that it doesn't punish you for hving to type a long identifier bazillions of tims
03:51:28<dons>corporate slave!
03:51:33<gwern>dons: srsly, just clean up some warnings, and release
03:51:41<dons>that would be ok :)
03:51:48<gwern>it's not like anyone who uses lambdabot really needs stability
03:52:08<gwern>or can't handle it
03:52:10<dons>i'm more concerned that it builds and install :)
03:52:13<phobes>monochrom, skew: Ya, that's the point. You dont want to reward a language like perl that has just as many "identifiers" but chooses obscure symbols for them
03:52:37<skew>phobes: it's not the lengths of identitifers, but the number of times you have to mention them
03:52:52<phobes>I agree "protected final static" should earn you two demerits tho
03:53:24<phobes>skew: mentioning them repeatedly will hurt your gzip score, though, right?
03:53:26<monochrom>Imagine a language that has no function call whatsoever.
03:53:32<skew>phobes: no, not really
03:53:41<faxlore>10 PRINT "HELLO WORLD"
03:53:42<skew>like, 1 byte for the reference to coppy the first occurence
03:53:44<faxlore>20 GOTO 10
03:53:49<faxlore>like this? :d
03:53:53<skew>so it's like you magically invented a java where you can write
03:53:56<sarehu>not hard to imagine, BF exists after all
03:54:06<faxlore>you can do functions in BF
03:54:07<skew>TypeName x = new _(args)
03:54:11<faxlore>takes a bit of trickery
03:54:22<sarehu>faxlore: what??
03:54:39<dons>has anyone ever attempted a full pointfree translator?
03:54:41<sarehu>assuming you don't first write an interpreter for another language and then fill memory with that language's code and call that...
03:54:50<faxlore>[ >[ {func1 code} ] >[ {func2 code} ] >[ {func3 code} ] ... <<<]
03:54:54<phobes>skew: If you had named your class with one letter instead of giving it a sensible name, you'd be able to do that
03:55:06<faxlore>or something along the lines
03:55:26<dons>? pl let map _ [] = [] ; map f (x:xs) = f x : map f xs in map
03:55:31<dons>?pl let map _ [] = [] ; map f (x:xs) = f x : map f xs in map
03:55:31<lambdabot>(line 1, column 11):
03:55:31<lambdabot>unexpected "["
03:55:31<lambdabot>expecting pattern or "="
03:55:35<gwern>ok! from A-L inclusive, there are at least 72 packages on Hackage which are broken with GHC 6.8.2 et al
03:55:41<gwern>this is not good people
03:55:42<sarehu>faxlore: I don't see the function call there... unless you're just referring to walking the stack
03:55:58<skew>phobes: yeah, gzip basically compares size of the code as if you had used one character replacements for everything
03:56:02<dons>?pl let map _ xs = if xs == [] then else f (head xx) : map f (tail xs) in map
03:56:02<lambdabot>(line 1, column 33):
03:56:02<lambdabot>unexpected reserved word "else"
03:56:02<lambdabot>expecting lambda abstraction or expression
03:56:05<dons>bah
03:56:48<phobes>skew: That seems pretty fair to me... you don't want to punish people for using sensible identifiers
03:57:20<Valodim>true
03:57:31<Valodim>but it also works with much repetition otherwise
03:57:49<monochrom>If you use token count, you will allow people to use good identifier names.
03:57:50<phobes>Valodim: Ya, that would be what I'd worry about
03:58:04<monochrom>If you use gzip, you do a lot more than that.
03:58:05<phobes>monochrom: That seems like a better metric, I agree
03:58:14<MyCatVerbs>? pl let map f x = if null xs then [] else f (head x) : map f (tail x) in map
03:58:21<MyCatVerbs>D'oh.
03:58:23<MyCatVerbs>?pl let map f x = if null xs then [] else f (head x) : map f (tail x) in map
03:58:23<lambdabot>fix (((if' (null xs) [] .) .) . ap (ap . ((:) .) . (. head)) . flip flip tail . ((.) .))
03:58:26<monochrom>gzip has side effects (in the medicine sense)
03:58:30<MyCatVerbs>HOLY SHIT
03:58:34<skew>phobes: the problem is that it fails to punish people for being forced to repeat the identifier lots of places
03:58:35<MyCatVerbs>ACTION runs and hides.
03:58:44<MyCatVerbs>Can't sleep, @pl will eat me, can't sleep, @pl will eat me...
03:58:58<monochrom>Imagine a language that allows no loops, no recursion. Imagine the task of printing "hello" five times.
03:59:03<LoganCapaldo>and it still needs if' :(
03:59:09<MyCatVerbs>:t if'
03:59:12<lambdabot>Not in scope: `if''
03:59:15<sarehu>hah, MyCat just got 'fixed'
03:59:16<monochrom>The imagined language forces you to write "print hello" 5 times.
03:59:23<MyCatVerbs>sarehu: ...dammit. :)
03:59:30<LoganCapaldo>when are we gonna get bool >
03:59:31<faxlore>print "hellohellohellohello"
03:59:31<MyCatVerbs>monochrom: that's not Turing complete, though.
03:59:32<phobes>skew: Every time they use it it increases the size of their program, right? Just not by an amount proportional to its size
03:59:32<LoganCapaldo>?
03:59:36<sarehu>he got his tail flipped too :)
03:59:44<LoganCapaldo>can I lobby for a bool function?
03:59:47<skew>phobes: there's also that, gzip can cut out sequences of symbols you can't actually abstract as a programmer
03:59:52<monochrom>gzip will tell you that's as good as Haskell's "replicateM 5 (print hello)".
03:59:56<skew>like }else{ => 1 char
04:00:08<monochrom>That is why gzip is a dumb measure.
04:00:09<skew>monochrom: better even, cause it's just the same thing,
04:00:15<LoganCapaldo>that could even be an excuse for a Data.Bool module
04:00:16<MyCatVerbs>sarehu: the amount of swinging around going on in there, I think I got pulverized against the room's walls, floor and ceiling.
04:00:18<LoganCapaldo>heh
04:01:01<phobes>monochrom: Agreed, but that's also kind of contrived. It seems plausible to me that gzip would produce fairish results in practice
04:01:04<skew>monochrom: haskell has a "replicateM 5" and a "print" and a "hello"
04:01:35<skew>phobes: what might be fair in practice is squishing all identifiers to a single character
04:02:01<LoganCapaldo>@type let bool True = const ; bool False = flip const in bool
04:02:02<lambdabot>forall a. Bool -> a -> a -> a
04:02:10<phobes>skew: That would be more fair in principle, I'm just wondering if you really have evidence that gzip isn't fair in practice
04:02:52<phobes>I suspect people aren't submitting many entries that use "copy and paste" looping
04:05:11<faxlore>ohh
04:05:20<faxlore>If you had lots and lots of processes you wanted to run at once..
04:05:28<faxlore>and some of them might never halt
04:05:35<faxlore>but you still want to get the output frmo those that do
04:05:37<monochrom>Buy lots and lots of computers.
04:05:45<glguy>chan
04:05:53<faxlore>well if you have only got one.. how would you do this?
04:06:06<monochrom>Write an OS.
04:06:12<monochrom>I'm just kidding :)
04:06:19<LoganCapaldo>mmm OS
04:06:22<faxlore>well someone already wrote an OS :P
04:06:24<faxlore>I can just use it
04:06:31<glguy>create a Chan, share it will all threads
04:06:34<faxlore>so I guess the best thing is, to run lots of GHC process
04:06:38<glguy>listen on the chan for the results
04:06:39<faxlore>oh.. ok I will check that out
04:08:08<ddarius>Define "process"
04:08:33<phobes>faxlore: If the processes can be killed and restarted, you can try running through the processes round robin, exponentially increasing the time you give each time you restart a process
04:08:58<faxlore>ohh nice iea
04:08:59<faxlore>idea
04:09:04<faxlore>I can do that, and save the state
04:09:04<phobes>Running 18 copies of GHC might not produce ideal results :)
04:09:21<MyCatVerbs>phobes: that doesn't really gain you anything over just -not- killing them round-robin, though.
04:09:30<phobes>faxlore: If you use an exponential time increase each time, you don't change the big-O by just restarting each time
04:09:42<MyCatVerbs>(And letting the preemptive scheduler alternate between them on your behalf.)
04:09:52<phobes>MyCatVerbs: Depending how many of them you have, it may be much better
04:10:21<sarehu>Depends on what they do, too.
04:10:38<ddarius>Depth first search with iterative deepening v. breadth-first search.
04:10:46<phobes>ya
04:10:48<MyCatVerbs>phobes: I could only see that being the case if your scheduler was so incredibly shite that the overhead from task switching massively exceeded the overhead from periodically murdering them part-way through their run.
04:11:03<phobes>MyCatVerbs: probably memory and resources are the issue
04:11:43<MyCatVerbs>phobes: memory, yes, I could see that at first, but not upon further reflection.
04:12:34<istarex>Is there a function like read in haskell with type String -> Maybe Int (so that it doesn't crash the program if the string doesn't turn into an int)?
04:12:41<MyCatVerbs>phobes: you'd be better off hacking the scheduler so that each process in turn gets a really huge-ass timeslice (on the order of at least ten minutes), then just use swap space for any processes that spill over from the RAM you have in the machine.
04:12:43<ddarius>MyCatVerbs: The analogy with breadth first search and depth first search with iterative deepening should be enough to clarify the memory behaviour of each.
04:12:52<skew>istarex: reads
04:13:47<phobes>MyCatVerbs: As ddarius says, this is known as iterative deepening, and it's definitely useful in some cases ... imagine you have 1000 processes to run
04:14:32<MyCatVerbs>phobes: since modern OSes are pretty good at virtual memory management, the only data that will actually be in core - as opposed to swapped out on the disk - should be the data your current running process is interested in. Pushing the task switching period up really high would then help make the overhead from swapping data for each process out in order to swap data for the next process in negligible.
04:15:22<Valodim_>nah, there's more than enough ram to have more than the currently running application use it :P
04:15:27<phobes>MyCatVerbs: I suppose you may be right ... until you run out of hard drive space :)
04:15:36<Valodim_>but which ones, that's the question. by cpu activity? by request?
04:15:37<MyCatVerbs>phobes: indeed. But I can totally afford enough disk space to keep 1000 processes in swap, no problem. And when you're talking about such a large volume of processes, the constants involved start to matter, not just the asymptotic complexity. :P
04:16:39<ddarius>The constants involved matter less, proportionally, with larger "input sizes"
04:16:53<MyCatVerbs>phobes: eh, hard disk space is *really* cheap. If I have the budget to run all those thousands of processes in a reasonable period (given how much CPUs cost) then I certainly have more than enough money on hand to buy disk space for all of them, ten times over.
04:16:54<phobes>MyCatVerbs: Use a multiple of 3x runtime with each iteration and your constant is now erm... 50% overhead I think. Now subtract the cost of all that caching and it's probably not so bad
04:17:47<MyCatVerbs>phobes: where does caching come into it?
04:18:05<phobes>MyCatVerbs: I mean the cost of caching out to disk
04:18:16<skew>what's the problem anyway? Usually iterative deepening means something like chess, where each configuration is branching
04:18:48<phobes>skew: I think it's applicable anytime you're getting huge numbers of options to explore
04:18:58<MyCatVerbs>phobes: swapping, you mean. And yes, swapping is expensive, that's why I say hack the OS scheduler for incredibly long timeslices.
04:19:22<skew>faxlore: what are these processes you want to explore anyway?
04:20:37<MyCatVerbs>ddarius: I'm not so sure about that. The cost difference between, say, running a slow and a fast regex over a few hundred megabytes of email might make the difference between, oh, one and two pennies, assuming a massively crap CPU and mind-bogglingly expensive electricity.
04:21:21<phobes>MyCatVerbs: Well, I'm pretty much agreeing with your analysis... I'm just saying that there is always going to be some problems for which iterative deeping doesn't exhaust your disk supply and parallel exploration does
04:21:25<MyCatVerbs>ddarius: for obvious reasons, I'm not going to sweat the difference.
04:21:54<faxlore>skew: check what ever brainfuck program prints out
04:22:07<faxlore>every*
04:22:21<MyCatVerbs>ddarius: whereas if you have a data set large enough that some fast algorithm costs, say ten of thousand quid to run, then you're not going to want to use a 10% slower algorithm because that'll cost you eleven grand, instead.
04:22:47<MyCatVerbs>faxlore: hee, sounds funny. :)
04:24:25<phobes>MyCatVerbs: And anyway, the idea still seems reasonable to me for faxlore, who may be more interested in a simple quick & dirty solution than in hacking his OS :)
04:24:26<skew>for that it's probably worth saving the state, and probably worth trying to detect looping programs after a while too
04:24:51<faxlore>detecting loops sounds tricky
04:25:03<MyCatVerbs>phobes: yesh, but if the individual programs take long enough to run that it's actually worth doing any interesting form of scheduling on them rather than just running them sequentially, and assuming that they fit into 4GB of RAM (fair enough, I think, since i386 only lets you address that much and most of the world is still on i386), then you have to spend so much on CPUs anyway that the disk costs are a tiny fraction of what you're spending anyw
04:25:17<skew>not if you just look for stupid ones, like [] or whatever
04:25:48<MyCatVerbs>phobes: admittedly hacking the scheduler would be a bit gratituously bastardly. Perhaps a better solution would be to find some language where a program could be frozen in mid-run?
04:26:02<faxlore>hey maybe can use CallCC?
04:26:09<skew>faxlore: I've heard that most short programs either break, or just go into stupid loops like that
04:26:19<faxlore>skew: sounds true
04:26:47<MyCatVerbs>phobes: heck, I'd say the ideal solution would be to do exactly what you suggest, but instead of murdering processes, you freeze them and then thaw them later. Though, that *is* mathematically identical to what the OS process scheduler does with your programs, heh.~~
04:26:48<phobes>MyCatVerbs: A modern processor can fill up 4 GB of RAM in what... 2-3 seconds? In practice it probably takes more like a minute or two at worst, but still... you can easily fill up a 400GB harddrive in half a day
04:26:54<skew>you could do something like run for a few hundred thousand cycles, then start recording the state every time you reach the end of a loop and see if you ever get there in the same state
04:28:06<MyCatVerbs>phobes: the other reason for giving 4GB as a reasonable ceiling is the fact that, eh, putting more than 4GB of RAM in a single box starts to get expensive.
04:28:28<faxlore>@hoogle [a] -> a -> Int
04:28:28<lambdabot>No matches, try a more general search
04:28:31<gwern>dunno. my 4gigs cost me about ~100$
04:28:40<skew>MyCatVerbs: oh, 8 isn't reasonable yet?
04:28:44<MyCatVerbs>phobes: 8GB is about the ceiling that any one process can reasonably go up to anyway, since above that you're going to hit the swap file with each *individual* process.
04:29:04<phobes>MyCatVerbs: What are we talking about
04:29:05<phobes>?
04:29:21<MyCatVerbs>phobes: I mean if you're building a cluster to run this on...
04:29:21<MyCatVerbs>skew: 2GB DIMMs are more expensive than 1GB DIMMs. Also, you
04:29:50<MyCatVerbs>phobes: ...then you're going to want to use consumer hardware, since it's cheap, and the cheaper it is the more of it you can fit in your budget. :)
04:30:09<skew>MyCatVerbs: I remember they were not absurdly more per byte than 1G at the start of the year, close enough I paid a bit extra for it
04:30:30<phobes>MyCatVerbs: I'm not disagreeing with you, but I'm not sure faxlore wanted to build a special system for this?
04:30:33<skew>hehe, newegg has 512MB DDR2 under $10
04:30:39<skew>maybe that's what I need to build with :)
04:30:44<MyCatVerbs>phobes: you *could* buy servers that take, say, 64GB each, but those would rapidly exhaust your budget. It's strongly preferrable to buy many consumer machines instead, as you'll get much more bang for your buck.
04:31:01<faxlore>eh I am just writing some code
04:31:02<faxlore>see what happens
04:31:05<MyCatVerbs>skew: *what*!? Bloody Hell that's cheap.
04:31:10<faxlore>gonna try using a Chan
04:31:23<MyCatVerbs>skew: okay, sure, I agree, 8GB would also be a reasonable limit. Probably a better one.
04:31:43<MyCatVerbs>But either way, 8GB of RAM costs, oh... *checks pricewatch*
04:32:00<MyCatVerbs>More than triple what 500GB of disk space costs, IIRC.
04:32:32<faxlore>is there a way to list every library that I have in ghc?
04:32:35<faxlore>like Data.List etc
04:32:39<phobes>MyCatVerbs: My claims are as follows: 1) In theory, for some very large number of processes, you'll be better off using iterative deeping 2) For a quick and dirty solution that doesn't thrash the harddisk, this may be the easiest approach to implement (and it's fairly performant)
04:32:39<MyCatVerbs>faxlore: ghc-pkg list
04:32:48<faxlore>ace thanks :D
04:32:51<allbery_b>that's packages
04:32:57<MyCatVerbs>faxlore: well, that tells you all the packages you have installed, not what modules each of those packages includes, sorry.
04:32:58<faxlore>well it shows regex which is what I waned
04:33:08<allbery_b>if you want the namespace, run a find on the ghc lib directory for .hi files
04:33:34<phobes>I must run - g'night all
04:33:47<MyCatVerbs>phobes: sleep well. And yeah, you're right.
04:34:05<MyCatVerbs>phobes: I'd just find it more fun to go completely overboard than to do things on a small scale. :)
04:34:54<skew>MyCatVerbs: $35 for 2G module vs. $18 for 1G. Wow
04:35:44<MyCatVerbs>skew: eh? *re-checks pricewatch*
04:37:19<hpaste> gwern pasted "List of broken Hackage packages" at http://hpaste.org/4915
04:37:20<MyCatVerbs>skew: oh, I have that wrong. 8GB of RAM is merely just under twice as expensive as 500GB of disk space.
04:37:32<gwern>105 packages in total
04:37:39<gwern>that's gonna be a lot of work :(
04:38:11<runar>How do I allow a module's user to set a "global value"? Like DPI for a drawing module?
04:38:22<MyCatVerbs>skew: (I'm looking at pricewatch.com, 800MHz DDR2 vs. 500GB sata disks. Where are you looking?)
04:39:12<runar>That's probably not what I want.
04:39:54<MyCatVerbs>skew: still, the point remains. If you can swing things cleverly enough that you aren't significantly affected by the cost of shunting data to and from the hard disk, you could happily support your RAM's capacity dozens of times over.
04:41:22<skew>irssi doesn't paste so well on windows, but newegg, "Desktop Memory"->Capacity="2G
04:43:37<MyCatVerbs>skew: transcend sticks? k.
04:44:14<MyCatVerbs>skew: ah, those're 667MHz sticks, rather than 800MHz.
04:44:38<ddarius>"Why is it that in so many different branches of physics, the introduction of antisymmetric bracket symbols, all with the same abstract algebraic properties, leads to the most succint and powerful methods of calculation?"
04:45:07<MyCatVerbs>skew: heck, if I check that spec on pricewatch, it comes up with... hrmn, dollar and a half cheaper. :)
04:45:24<MyCatVerbs>skew: well, no, actually that price is a lie. NVM.
04:45:28<runar>hmm... are implicit parameters what I want?
04:46:03<MyCatVerbs>skew: (though I'd tend to buy the faster sticks myself, since modern CPUs are so hungry for memory bandwidth)
04:46:20<faxlore>@undo do x <- a ; y <- b ; return (x,y)
04:46:20<lambdabot>a >>= \ x -> b >>= \ y -> return (x, y)
04:50:40<MyCatVerbs>ACTION wonders how nasty an expression @pl can be coerced into printing.
04:50:51<MyCatVerbs>@pl \(a,b) f q -> f (a b) : f (q (a b))
04:50:51<lambdabot>uncurry (liftM2 ap ((ap . (((.) . (:)) .) . flip id) .) ((flip (.) . flip id) .))
04:51:14<skew>@pl \a b c -> c b a
04:51:14<lambdabot>flip (flip . flip id)
04:51:21<nelhage>"How ugly do you want?"
04:51:25<skew>@pl \a b c -> c a b a
04:51:25<lambdabot>flip =<< (flip .) . flip . flip id
04:52:14<MyCatVerbs>@pl let y f = f (y f) in y (\rec a b c -> [a b,c] ++ (rec b a c))
04:52:15<lambdabot>fix (ap id) (ap (ap . (liftM2 (++) .) . flip flip return . (((.) . (:)) .)) . flip)
04:52:45<MyCatVerbs>@pl let rec a b c = [a b,c] ++ (rec b a c)) in rec
04:52:46<lambdabot>(line 1, column 39):
04:52:46<lambdabot>unexpected ")"
04:52:46<lambdabot>expecting variable, "(", operator, ":", "++", ";" or "in"
04:52:51<MyCatVerbs>@pl let rec a b c = [a b,c] ++ (rec b a c) in rec
04:52:52<lambdabot>fix (ap (ap . (liftM2 (++) .) . flip flip return . (((.) . (:)) .)) . flip)
04:53:18<MyCatVerbs>Oh, neato. Those two *ought* to be identical, but they aren't. :D
04:53:37<MyCatVerbs>:t let rec a b c = [a b,c] ++ (rec b a c) in rec
04:53:38<lambdabot> Occurs check: cannot construct the infinite type: t = t -> a
04:53:38<lambdabot> Expected type: t -> (t -> a) -> a -> [a]
04:53:38<lambdabot> Inferred type: (t -> a) -> t -> a -> t1
04:54:15<MyCatVerbs>Whoa, neat. @pl can interpret code which won't ever typecheck.
04:54:32<MyCatVerbs>@pl let y f = f (y f) in y (\rec a b c -> [a, b, c] ++ (rec b a c))
04:54:33<lambdabot>fix (ap id) (ap (ap . (liftM2 (++) .) . (. ((. return) . (:))) . (.) . (:)) . flip)
04:54:40<nelhage>It's not hard to construct code that has a recursive type
04:54:40<MyCatVerbs>:t let y f = f (y f) in y (\rec a b c -> [a, b, c] ++ (rec b a c))
04:54:41<lambdabot>forall a. a -> a -> a -> [a]
04:55:13<MyCatVerbs>nelhage: yes, but I has assumed that @pl would refuse to touch it. :)
04:55:25<skew>\a b x -> (a x) (b x)
04:55:27<skew>@pl \a b x -> (a x) (b x)
04:55:27<lambdabot>ap
04:56:31<MyCatVerbs>@pl \a b f p -> p (f a) (f b)
04:56:32<lambdabot>(. flip id) . ap . ((flip . flip id) .) . flip id
04:56:42<MyCatVerbs>@pl \a b f -> (f a) == (f b)
04:56:43<lambdabot>(. flip id) . ap . ((==) .) . flip id
04:56:52<runar>@pl (\flip -> (. flip id) . ap . ((flip . flip id) .) . flip id)
04:56:52<lambdabot>ap ((.) . ap ($ (.)) ($ id)) ((ap .) . ap ((.) . (.) . ap (.) ($ id)) ($ id))
04:57:08<skew>I think turning lambdas to combinators can be exponential
04:57:31<nelhage>The straightforward transformation is in fact exponential
04:57:39<faxlore>skew: I think so yeah
04:57:47<skew>but I'm not sure about what @pl does
04:58:03<nelhage>And I think it is in general, but I'm not sure.
04:58:30<nelhage>http://www.madore.org/~david/programs/unlambda/#lambda_elim
04:58:32<lambdabot>Title: The Unlambda Programming Language
04:58:39<skew>@pl \a b c d e -> (a (c b a)) (c d e)
04:58:39<lambdabot>flip flip id . (liftM2 ((.) . (.)) .) . liftM2 (.) (.) (flip (flip . flip id))
04:58:42<allbery_b>it's often possible to simplify the output of @pl; it has some simplification rules built in, but not many
04:58:59<nelhage>(that particular section details transforming lambda expressions into the SKI calculus)
04:59:12<skew>does it have something like B and C?
04:59:48<runar>OK, I win.
04:59:49<skew>@pl \f g x -> f (g x)
04:59:50<lambdabot>(.)
04:59:59<skew>@pl \f g x -> (f x) g
04:59:59<lambdabot>flip
05:00:02<runar>@pl (\x y z -> (x,y,z,y,x))
05:00:02<lambdabot>flip =<< (flip .) . join . (flip .) . (,,,,)
05:00:15<MyCatVerbs>skew: unlambda? Well, it was s, k, and call/cc, I think. Not sure if it has i or not. ;)
05:00:38<nelhage>I believe unlambda does have i
05:00:47<nelhage>Not that it matters
05:01:13<skew>pulling out one variable multiplies the length of the spine down to its occurences
05:02:23<skew>oh, except maybe you can pull it out like f(g(x) -> (f.g) $ x
05:02:27<runar>@unpl (.)
05:02:28<lambdabot>(\ a b c -> a (b c))
05:02:32<MyCatVerbs>:t ((.)$(.))
05:02:37<lambdabot>forall a b c a1. (a -> b -> c) -> a -> (a1 -> b) -> a1 -> c
05:02:57<runar>MyCatVerbs: That's a nice pair.
05:03:36<runar>@unpl ((.)$(.)
05:03:36<lambdabot>Unbalanced parentheses
05:03:38<runar>@unpl ((.)$(.))
05:03:38<lambdabot>(\ b c e f -> b c (e f))
05:03:39<MyCatVerbs>runar: saw that one on the haskell wiki, nicknamed the "owl combinator" :)
05:04:28<nanothief>I've recently upgreaded from ghc 6.6 to ghc 6.8. Now when using ghcii.sh, :b Prelude results in the message "module 'Prelude' is not interpreted". What does that mean?
05:04:35<MyCatVerbs>@pl \a b -> (gcd a b) /= 1
05:04:36<lambdabot>flip flip 1 . ((/=) .) . gcd
05:05:32<skew>nanothief: :b now stands for :breakpoint
05:05:52<MyCatVerbs>nanothief: you want to type :bro^I out instead. >>
05:05:53<skew>and the debugger only works on interpreted code
05:06:21<nanothief>skew, MyCatVerbs, thanks
05:06:41<nanothief>i didn't even think of testing with :browse
05:08:09<MyCatVerbs>nanothief: tab completion helps. If it's possibly that you're getting the wrong abbreviation, hit tab a few times to get ghci to give you the full list of commands that what you've typed is a prefix of.
05:08:52<nanothief>MyCatVerbs: unfortunately tab completion doesn't seem to work for me (I'm using ghcii.sh through mingw bash)
05:09:05<nanothief>it just inserts a tab character
05:10:22<MyCatVerbs>nanothief: oh, that sucks.
05:11:25<nanothief>MyCatVerbs: yeah it is quite annoying. Luckily :br Prelude works too, so its not too much more typing now
05:11:57<nanothief>(i mean :bro)
05:16:20<MyCatVerbs>Heehee.
05:16:53<MyCatVerbs>DOOM3 has to be the most expensive way in the history of human kind to render (in real-time, no less!) a series of black cats in coal cellars. :D
05:24:58<gwern>MyCatVerbs: I heard in some parts you can actually see things! using a 'flashlight' thingy supposedly
05:25:06<dons>?users
05:25:07<lambdabot>Maximum users seen in #haskell: 444, currently: 390 (87.8%), active: 16 (4.1%)
05:28:05<MyCatVerbs>gwern: personally I hate dark games.
05:28:30<MyCatVerbs>gwern: I'm more interested in being able to see stuff and violently blast it into pink mist than in searching for it in corners.
05:29:16<MyCatVerbs>gwern: I play mostly Operation Flashpoint, Team Fortress Classic, DOOM2.
05:30:11<MyCatVerbs>gwern: admittedly DOOM 1&2 have dark rooms, but they don't make up a particularly significant proportion of the game and they're reasonably well presented. Even if you do feel the need to chicken out, there's usually nothing stopping you from hanging back by the door and blasting whatever comes out. :)
05:32:30<MyCatVerbs>gwern: oh and deathmatch variants of CounterStrike, too, though I really can't stand the vanilla game.
05:33:22<Korollary>I should play some deathmatch CSS then
05:35:14<kfish>ACTION prefers deathmatch darcs
05:35:32<Pseudonym>Unfortunately, that's no fun in a SCCS without commit wars.
05:35:54<MyCatVerbs>Pseudonym: ehhhhh...
05:36:05<MyCatVerbs>Pseudonym: you could submit deliberately conflicting patches? :)
05:37:20<dons>ok. this is scary, http://programming.reddit.com/info/6567d/comments/
05:37:30<dons>"The Marvels of Monads" (in C#)
05:38:10<Pseudonym>It's a marvel that you can even do it in C#.
05:38:11<dons>"> Monads enjoy tremendous success in Haskell, but like an actor who does well in a particular role, monads are now stereotyped in the minds of most programmers as useful only in pure lazy functional languages. This is unfortunate, because monads are more broadly applicable."
05:38:56<Pseudonym>OK, that's not an entirely unfair statement.
05:39:08<dons>sure. i thought it was entirely fair.
05:39:17<Pseudonym>Sp why is it scary?
05:39:24<sarah__>how do i put a polymorphic value into a type? ex: data Node = Node { last_action :: (Action a) => a, info :: Info } deriving Eq
05:39:38<dons>Pseudonym: oh, in the last 2 days we've seen posts on pragmatic monads for python, for ruby, and now C#
05:39:47<dons>that's in the last 48 hours
05:40:06<Korollary>It's just a toy exercise
05:40:17<Pseudonym>Ah, right.
05:40:29<Pseudonym>I question how useful they are in dynamically typed languages.
05:40:31<ddarius>The "unfairness" comes from the fact that this stereotyping is against what most pure lazy functional programmers say.
05:40:37<Pseudonym>I imagine they'd be slihgtly more useful in C#.
05:41:06<MyCatVerbs>sarah__: data Node a = Node { last_action :: a, info :: Into } deriving Eq
05:41:10<dons>they used LINQ for the syntax
05:41:16<dons>i.e. comprehension syntax
05:41:16<sarah__>thx
05:41:38<dons>from/select. quite weird.
05:41:54<dons>var r = Bind(Unit(5), x =>
05:41:54<dons> Bind(Unit(6), y =>
05:41:54<dons> Unit(x + y)));
05:41:56<dons>becomes
05:42:06<dons>var r = from x in 5.ToMaybe() from y in Maybe<int>.Nothing select x + y;
05:42:10<MyCatVerbs>sarah__: I can't remember how to enfore the "Actor a" type constraint. I think you usually do it by making a class which contains all the interesting functions on Nodes, and an instance Actor a => Nodethingies a where...
05:42:27<dons>oh, looks like he changed the example, actually
05:42:28<hpaste> mmorrow pasted "love ghc's pre-emption (or what a difference a -N2 makes)" at http://hpaste.org/4916
05:42:32<MyCatVerbs>That's how large quantities of the libraries seem to do it.
05:43:49<hpaste> mmorrow annotated "love ghc's pre-emption (or what a difference a -N2 makes)" with "(no title)" at http://hpaste.org/4916#a1
05:46:00<sjanssen>"bababababa" is a pretty good result!
05:46:17<kfish>"Adjoint triples are stereotyped as only useful in categories with U-contractible coequalizers, but you can use them to balance your Macy's store card! In Visual Basic!"
05:46:36<dons>you're so wacky, kfish :)
05:46:55<Syzygy->kfish: Hehe
05:47:06<MyCatVerbs>kfish: was that real, or are you stringing words together at random?
05:47:23<dons>he's translating from blogspeak
05:47:32<dons>or too blogspeak, i'm not sure
05:47:34<MyCatVerbs>The thing I really don't like about category theory is that it takes a minimum of half an hour to ascertain which in any specific instance. x_x
05:47:36<Syzygy->kfish: Where are you reading?
05:47:41<faxlore>Something like this yeah
05:47:42<faxlore>> let floggle x = if even x then last [1..] else 6 in map floggle [1..]
05:47:47<lambdabot>Terminated
05:48:07<faxlore>would you dup a chan infinite times?
05:48:09<MyCatVerbs>faxlore: last [1..] is never going to terminate :)
05:48:13<faxlore>Exactly
05:48:19<faxlore>I have a list with holes in it
05:48:38<faxlore>I'm not sure I can use chans
05:48:57<MyCatVerbs>dons: is it possible to put typeclass restrictions on the members of a data structure?
05:49:04<faxlore>but there is some way to do this? try to compute everything in the list and extract things which did work
05:49:29<bos>MyCatVerbs: yes, it is.
05:49:33<kfish>MyCatVerbs, Syzygy-, Toposes, Triples and Theories sec. 3.7, in the edition with "Barbie" annotations
05:49:57<MyCatVerbs>bos: ah, danke. What's the syntax for that, please?
05:50:19<MyCatVerbs>data Typeable a => Foo a = Fooconstructor a or something?
05:51:03<ddarius>When was this phase transition that made Haskell a buzzword in e.g. the C# community? and what caused it?
05:51:14<MyCatVerbs>ddarius: I have a rough guess.
05:51:30<bos>MyCatVerbs: yes, or data Foo = Bar a => Beable a
05:51:47<bos>MyCatVerbs: it's kind of bad for your karma to put type constraints on a constructor, though.
05:51:57<MyCatVerbs>ddarius: a few months back, I remember seeing an article on using immutable data structures in C# in order to benefit from their handy-dandy safety properties under shared-memory multiprocessing.
05:52:07<sarah__>if in my type class i have some_method _ = 1 defined, and an instance of it has some_method x:xs = x defined, what would calling the insance with something not matching x:xs do, fail or return 1?
05:52:09<bos>it severely limits what you can subsequently do with the type.
05:52:26<bos>it also forces you to splatter type constraints all over the functions that use that type.
05:52:33<MyCatVerbs>ddarius: I think that was on one of Microsoft's sites, though I'm not sure if it was an MSDN blog or an article published by the company itself or what.
05:52:56<ddarius>It was more than a few months back, but less than a year.
05:53:01<MyCatVerbs>ddarius: that did refer to Haskell at one or two points. Plus Microsoft went and implemented F#...
05:53:20<skew>MyCatVerbs: you might really want GADTs
05:53:27<MyCatVerbs>ddarius: so perhaps all the FP features that MS have been implementing for themselves and then promoting have started to sink in?
05:53:30<bos>sarah__: the instance's version completely replaces the typeclass's default, so it will fail.
05:53:33<sjanssen>sarah__: fail
05:54:26<sarah__>k
05:54:43<MyCatVerbs>bos: ah, bummer.
05:55:31<ddarius>MyCatVerbs: Stuff has been sinking in for a while. There just seemed to be an abrupt change not too too long ago. There probably isn't a particular cause.
05:55:52<MyCatVerbs>ddarius: heh, well, that is the usual characteristic of phase changes, isn't it now? :)
05:56:50<MyCatVerbs>"Buggery, when did this stuff get solid? It was liquid yestderday, and its temperature has only dropped one measly degree sine then."
05:58:02<glguy>What was that paper about SICP and how Miranda would have been better for teaching CS?
05:58:09<glguy>something about scheming and calculating
05:58:17<Korollary>Wadler's computing is better than scheming
05:58:22<glguy>thanks
05:58:25<MyCatVerbs>Browsing the Haskell Hierarchical Libraries source code is fun.
05:58:25<nelhage>@go computing is better than scheming
05:58:27<lambdabot>http://www.cs.kent.ac.uk/people/staff/dat/miranda/wadler87.pdf
05:59:11<BMeph>Whenever I try getting something with Cabal, it says:
05:59:17<BMeph>"cabal: Data.ByteString.Lazy.index: index too large: 0"
05:59:35<BMeph>Does someone recognize the problem?
05:59:55<faxlore>let compute ch [] = writeChan ch 0; compute ch (x:xs) = do writeChan ch x ; compute ch xs in do x <- newChan ; (compute x [3,5,last [1..],8,last [1..],4,6]) ; getChanContents x
06:00:38<faxlore>in something like this, can you change compute so that it works on the list in any order in parallel
06:01:56<solrize>hi, anyone know of ghc 6.8.2 causing linking problems?
06:03:01<MyCatVerbs>solrize: you don't have libraries compiled with ghc 6.6 being linked in to programs being compiled with 6.8 or anything crazy like that, do you? Other that that I couldn't hazard a guess.
06:03:05<tehgeekmeister>I just got an exception from head about an empty list, but i don't call head directly in any of my code -- how does one go about fixing this sort of a bug?
06:03:25<solrize>i don't think so. i had ghc 6.4.something and upgraded to 6.8.2 and now i can't link
06:03:31<solrize>seems to happen when i import data.map
06:04:31<hpaste> (anonymous) pasted "(no title)" at http://hpaste.org/4917
06:04:37<solrize>that was me
06:04:39<bos>tehgeekmeister: i usually do a dichotomic search using trace expressions.
06:04:39<faxlore>This is odd, let pr n = putStrLn (show n) in mapM (forkIO . pr) [1..10]
06:05:01<bos>tehgeekmeister: that's the pure programmer's way of saying "shove some printfs in there"
06:05:10<MyCatVerbs>tehgeekmeister: there are two ways, depending on your version of GHC. Three, even.
06:05:31<solrize>by the way is anyone here at POPL?
06:05:35<MyCatVerbs>tehgeekmeister: one is to use the "trace" function from the Debug.Trace module (which is usually the first thing to go for)
06:05:40<tehgeekmeister>MyCatVerbs: 6.6.1, sadly the newest available in macports
06:05:46<bos>solrize: i've popped in and out a few times
06:05:51<MyCatVerbs>tehgeekmeister: another (if you have ghc 6.8) is to use ghc's debugger.
06:06:06<MyCatVerbs>tehgeekmeister: the third isn't applicable in your case, I think. :/
06:07:01<tehgeekmeister>bos: just sprinkle them around in any suspect code? that'd require bringing IO into the Parsec monad, that scares me, being a noob.
06:07:06<bos>ghci doesn't have an obvious break-on-error.
06:07:15<bos>tehgeekmeister: no, use Debug.Trace.trace
06:07:24<tehgeekmeister>bos: okay.
06:08:33<bos>tehgeekmeister: also see http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html#ghci-debugger-exceptions
06:08:34<lambdabot>Title: 3.5. The GHCi Debugger, http://tinyurl.com/2orwlb
06:08:46<MyCatVerbs>tehgeekmeister: Debug.Trace.trace uses unsafePerformIO. Which is normally scary, but very handy for printlining.
06:09:16<tehgeekmeister>MyCatVerbs: i.e.: it allows the side effect of printing without any monadic goodness?
06:09:18<shachaf>faxlore: What is odd?
06:09:25<shachaf>faxlore: (And pr = print.)
06:09:48<shachaf>@src putStrLn
06:09:48<lambdabot>putStrLn s = do putStr s; putChar '\n'
06:09:58<faxlore>well it just works a bit strangly
06:11:19<tehgeekmeister>bos: that's not available in 6.6.1, it seems. i've not been daring enough to either manually compile or install a non-macports binary yet.
06:11:22<MyCatVerbs>tehgeekmeister: yes, unsafePerformIO lets you plant side effects in pure code. This is why it's called 'unsafe' :)
06:11:39<tehgeekmeister>MyCatVerbs: figured, but i also figured it was good to make sure.
06:11:46<MyCatVerbs>tehgeekmeister: hrmn? import Debug.Trace
06:12:02<tehgeekmeister>MyCatVerbs: no, that is. but the section of the manual he pointed me to isn't.
06:12:23<MyCatVerbs>tehgeekmeister: I have a copy of 6.6.1 over here, and I can load and use the Debug.Trace module at the ghci prompt just fine.
06:12:41<MyCatVerbs>tehgeekmeister: oh, right, my bad, I see.
06:15:56<tehgeekmeister>if i've got a bunch of infix appends, i should convert those to prefix sections that have a trace in them if they're the suspect region, right? or is there a sane way to use trace on infix operators?
06:16:23<faxlore>tehgeekmeister what are you tracing?
06:16:29<shachaf>tehgeekmeister: You could define a (+++) which uses trace.
06:17:29<roconnor>@unicode minimum
06:17:30<lambdabot>Unknown command, try @list
06:17:32<tehgeekmeister>faxlore: parsing of a negative float in Write Yourself a Scheme in 48 Hours
06:17:32<roconnor>er
06:17:37<roconnor>@go unicode minimum
06:17:40<lambdabot>http://www.joelonsoftware.com/articles/Unicode.html
06:17:40<lambdabot>Title: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know A ...
06:17:43<tehgeekmeister>shachaf: good idea.
06:17:47<roconnor>@go unicode maximum
06:17:49<lambdabot>http://www.snort.org/vrt/docs/ruleset_changelogs/2_1/changes-2007-06-19.html
06:17:49<lambdabot>Title: Snort - the de facto standard for intrusion detection/prevention
06:17:53<roconnor>@go unicode max
06:17:54<lambdabot>http://www.snort.org/archive-3-3149.html
06:17:54<lambdabot>Title: NETBIOS SMB-DS Trans unicode Max Param DOS attempt - Snort Forums Archive
06:17:57<roconnor>:(
06:18:39<sjanssen>> maxBound :: Char
06:18:41<lambdabot> '\1114111'
06:18:42<solrize>mycatverbs, any other theories about 6.8.2 lossage?
06:19:56<shachaf>solrize: How did you install 6.8.2?
06:21:44<solrize>built from the tarball
06:21:50<solrize>then "make install"
06:22:25<shachaf>solrize: Is containers in `ghc-pkg list`?
06:22:50<solrize> containers-0.1.0.1,
06:22:51<solrize>tes
06:22:53<solrize>yes
06:23:40<sclv>my simple debugging function for parsec: pTrace s = pt <|> return ()
06:23:40<sclv> where pt = try $ do { x <- try $ many1 anyChar; trace (s++": " ++x) $ try $ char 'z'; fail x;}
06:23:51<shachaf>solrize: That's odd.
06:23:54<shachaf>solrize: Which OS?
06:24:00<solrize>ubuntu 6.10 i think
06:24:36<goalieca>lol another tanenbaum classic "The RISC revolution in the 1980s was one such breakthrough; another one is in the air now. We will look at one example (the Intel IA-64) in Chap. 5)"
06:24:58<solrize>haha
06:25:13<goalieca>i can't wait for my microkernel running on ia64
06:25:41<MyCatVerbs>solrize: nope. That's my first, last and old guess so far. :)
06:26:08<dons>"We will look at one example (the nvidia 128 way gpgpu graphics chip) " :)
06:26:17<dons>how times change
06:26:41<tehgeekmeister>right associativity means that it groups like this, correct: a ++ (b ++ (c ++ d)), right?
06:26:49<ddarius>Yes
06:26:55<tehgeekmeister>okay
06:26:56<goalieca>Nvidia 98700.. return of the coprocessor
06:27:07<goalieca>eventually... i figure
06:27:40<solrize>the day will come when there will be no more cpu's and no more ram. just giant fpga's.
06:28:00<dons>they'll be just 5 fpgas on the planet
06:28:03<goalieca>you know.. i would love it if every computer had an fpga in it. :-)
06:28:05<dons>each the size of an office block
06:28:10<solrize>hehe
06:28:32<solrize>nobody will need more than 640,000 clb's
06:28:35<MyCatVerbs>dons: I thought that was really unfair, y'know.
06:28:53<MyCatVerbs>dons: the IBM guy's quote, I mean, that there will only be a market for five computers on the planet.
06:29:01<shachaf>solrize: I'd suggest upgrading.
06:29:18<solrize>upgrading from 6.8.2? i thought this was the latest
06:29:20<shachaf>solrize:If you can.
06:29:28<shachaf>solrize: No, Ubuntu 6.10.
06:29:32<MyCatVerbs>Sure, he was wrong, but he wasn't saying that only five people would *want* computers, he was saying that it'd only ever be worth building five gigantic computers and then time-sharing them.
06:30:12<MyCatVerbs>Heck, you could just imagine that now - one in London, one in Beijing, one in San Francisco...
06:30:24<Cale>I wouldn't put that idea past the DRM people.
06:30:28<dons>one huge cluster inside google
06:30:40<goalieca>Ironically... if google gets their "Webapp" ways we're talking the size of a few city blocks... one on each of the 5 continents
06:30:46<MyCatVerbs>(Except for the fact that, hey, it turns out clustering is the new black.)
06:30:48<tehgeekmeister>okay, so i've traced it down to the point at which the exception occurs, but now i have absolutely no idea why because neither my code nor the code called at that point uses head.
06:30:53<solrize>oh. yeah, i tried upgrading a while back and hit some snags and had to revert, but i should try again.
06:31:01<tehgeekmeister>where do i go from that?
06:31:17<MyCatVerbs>dons: I'm not sure whether or not it counts for there to be five *clusters* on the planet, each of which contains thousands of smaller computers. ;)
06:31:36<MyCatVerbs>dons: I'm pretty certain that's one of the things that the Plan 9 folks would've liked to see, though. ^_^
06:32:18<shachaf>tehgeekmeister: @paste, if it's small enough?
06:32:29<shachaf>tehgeekmeister: Try GHC 6.8? :-)
06:33:06<goalieca>ACTION wonders when 6.8 will be in language shootout
06:33:21<goalieca>gentoo is usually fast about this type of thing
06:33:32<sclv>tehgeekmeister: how many calls do head do you have in the entirety of your code?
06:34:13<tehgeekmeister>shachaf: i hate to admit my folly, but there was a call to head, i just hadn't considered it because it was beyond where my imperative programming mind thot the execution had gone.
06:34:36<tehgeekmeister>also, i learned that readFloat doesn't like signs.
06:35:15<Cale>tehgeekmeister: remember, outermost first :)
06:36:33<bos>ACTION went to phil wadler's talk last night in SF, at POPL. the room was packed!
06:36:56<Cale>bos: What was it about? Was it taped?
06:37:17<bos>it was "well-typed programs can't be blamed", and yes, it was taped.
06:37:19<solrize>yeah, i was gonna go to that and forgot about it til it was already on!! i coulda caught the tail end at best
06:37:21<bos>excellent talk.
06:37:28<tehgeekmeister>Cale: this was weirder than that -- the appends which were building up the input to readFloat hadn't finished entirely before it sent an empty list on to head. lazy evaluation is cool, i must admit, in not doing that unnecessary work, but man it makes you have to think about debugging differently.
06:37:37<solrize>was it about haskell types, or something fancier?
06:37:45<bos>solrize: less fancy, actually.
06:38:03<bos>solrize: it's based on work he's been doing in mixing static and dynamic types.
06:38:19<ddarius>tehgeekmeister: Indeed you do debug rather differently in Haskell as compared to most languages
06:38:26<solrize>hmm interesting
06:38:44<Cale>tehgeekmeister: hmm...
06:39:32<Cale>tehgeekmeister: I'm not entirely sure I understand what's happening from that description -- surely values are well defined, and the value you're passing to head is either nil or a cons, but it can't be both.
06:40:05<tehgeekmeister>Cale: head is getting []
06:40:18<bos>wow, awesome. people are starting to seed web sites with SIPs so that they can send valid google.com URLs out in spam messages. that's COOL.
06:40:24<tehgeekmeister>Cale: because i'm giving readFloat a signed float ("-1.2" in this case.)
06:40:30<jcreigh>SIPs?
06:40:49<bos>statistically improbable phrases.
06:40:58<Cale>tehgeekmeister: ah, okay, it doesn't seem to handle negative floats
06:40:59<solrize>hahaha! googlewhack spam
06:41:04<solrize>must be possible to hijack those things
06:41:31<BMeph>Does anyone recognize that error?
06:41:38<tehgeekmeister>Cale: the confusion was that before the float was completely constructed by the appends of the various parts of the parse, as determined by the traces, readFloat had already been fully evaluated and execution was elsewhere.
06:41:51<Cale>BMeph: sorry? Which error?
06:42:06<glguy>> readFloat ""
06:42:08<lambdabot> []
06:42:25<Cale>tehgeekmeister: ah, okay :)
06:42:51<Cale>tehgeekmeister: Debug.Trace can be confusing if you don't know how evaluation goes (even sometimes if you do)
06:43:10<BMeph>I downloaded and compiled Cabal 1.2.3, but whenever I try to get something, it just prints:
06:43:13<BMeph>"cabal: Data.ByteString.Lazy.index: index too large: 0"
06:43:26<Cale>BMeph: interesting
06:43:49<BMeph>Isn't it just...;/
06:44:06<Cale>tehgeekmeister: GHCi in 6.8 has a debugger which you might also like to try for that sort of thing
06:44:52<Cale>BMeph: 1.2.3.0 is the version which comes with 6.8.2, isn't it?
06:45:17<tehgeekmeister>Cale: yeah, i really should put out the effort and get 6.8, but i just don't like having anything installed that a package manager isn't taking care of, unless it's a native OSX app. certainly one thing i miss about linux/bsd.
06:45:32<BMeph>Yes, it is. I'm tempted to just wipe out 6.8.2 and re-install from scratch. :|
06:46:16<Cale>tehgeekmeister: I make an exception for GHC, even on Ubuntu.
06:46:39<Cale>For most other packages, I'm similar in that regard.
06:46:44<MagicDuck>is it possible to build .so shared libraries with ghc
06:46:55<tehgeekmeister>Cale: yeah, i probably should myself, because ghc is the program i use most, aside from firefox, but i haven't done it yet nonetheless.
06:47:05<Cale>MagicDuck: If it is, I'm not aware of how to do it.
06:47:19<tehgeekmeister>ACTION looks at options for ghc on osx
06:48:12<Cale>tehgeekmeister: You can get a binary from the GHC website.
06:50:58<Cale>MagicDuck: Currently on most platforms, GHC statically links all the Haskell libraries and runtime in. IIRC, there was some support for dynamically linking stuff on OSX, but I haven't used OSX for quite some time now.
06:51:28<glguy>Fedora has been great about being really up to date on ghc versions
06:51:31<glguy>(thanks bos)
06:53:20<solrize>i really like building from sources instead of installing opaque packages, does anyone know if something might be wrong with the 6.8.2 tarball?
06:53:41<MagicDuck>thanks Cale
06:53:54<tehgeekmeister>ACTION is glad that his scheme can handle signed floats now
06:54:11<bos>glguy: yw :)
06:54:24<bos>solrize: it's build fine for me
06:54:30<bos>s/d/t/
06:54:49<solrize>bos, it built and installed fine for me too, i just can't compile and link with it.
06:55:08<bos>solrize: wha happen?
06:55:13<MagicDuck>I am learning hakell in one of my university classes. This channel is very responsive compared to others I have visited. Just try #scons, all dead. I'll be sure to tell other people in the class about this great resource :)
06:55:39<solrize>bos, http://hpaste.org/4917
06:56:05<MyCatVerbs>MagicDuck: try #scheme too. Pretty comparable. :)
06:56:06<tehgeekmeister>MagicDuck: it really is great -- i've noticed a lot of people mentioning that in the past week or two.
06:56:54<MyCatVerbs>MagicDuck: I've no idea why, but channels saturated with academics seem to be unusually friendly. Compare and contrast with anything gratituously industrial like, oh, C or Java?
06:56:55<tehgeekmeister>anyone know why readFloat has type String -> [(Float,String)] ?
06:57:08<bos>solrize: that's your bad, not ghc.
06:57:08<MagicDuck>yeah, haskell is a whole new world to me, coming from the domain of imperative languages
06:57:14<MyCatVerbs>tehgeekmeister: yes. It's giving a list of possible parses.
06:57:20<bos>solrize: use "ghc --make"
06:57:31<solrize>hmm, ok. it used to work under 6.4.whatever
06:58:04<MyCatVerbs>tehgeekmeister: if there's more than one possible way to parse the input string as a float, it will give you a list back with more than one element in it. If the input string can't possibly parse as a float, you'll get an empty list.
06:58:31<solrize>bos, thanks, that works!
06:58:38<MyCatVerbs>tehgeekmeister: the String in those (Float,String) pairs is the rest of the string, that is, the bit left over after the bit that was parsed as a float.
06:58:52<solrize>hmm, ghc -O3 6.8.2 compiled code is slower than 6.4...
06:58:52<MyCatVerbs>> readFloat "3.14 eats bagels"
06:58:54<lambdabot> [(3.14," eats bagels")]
06:59:05<MyCatVerbs>solrize: use -O2, not -O3.
06:59:28<MagicDuck>ghc 6.8.2 seems to be a big improvement over 6.6
06:59:33<MyCatVerbs>solrize: for lots of weird reasons, -O3 is closer to -O0 than -O1 or -O2.
06:59:42<solrize>O2 is a tiny bit slower than O3
06:59:55<solrize>both are about 5x slower than python :(
06:59:59<MyCatVerbs>solrize: oh, try -fvia-C?
07:00:21<bos>solrize: use -O, not -O2
07:00:27<solrize>tiny slowdown from -fvia-C
07:01:18<bos>solrize: if you're manipulating String values, performance will always be bad.
07:01:23<solrize>-O and -via-C fundamentally don't change much. i think i'm losing big because i'm processing a big file as a lazy string. i upgraded to 6.8.2 to use data.bytestring
07:01:26<solrize>yeah
07:01:30<MyCatVerbs>Eh? If 6.8.2 compiled code comes out slower than 6.4, that's probably a bug.
07:01:52<sjanssen>what is the program?
07:01:59<bos>also, python's string code is all well-tuned C.
07:02:07<solrize>just a simple word counting program, i can paste it if you want
07:02:17<roconnor>> 805/256
07:02:19<lambdabot> 3.14453125
07:02:22<bos>whereas even ByteString doesn't drop into C for more than a few small things
07:02:40<sjanssen>solrize: sure
07:02:45<hpaste> solrize pasted "(no title)" at http://hpaste.org/4918
07:02:57<Korollary>There's a haskellwiki page dedicated to word counting and the performance was great iirc
07:03:13<solrize>this finds the 20 most frequently used words
07:03:16<dons>but you're using [Char] !
07:03:18<solrize>an exercise in using data.map
07:03:34<skew>that's not using ByteString at all
07:03:38<solrize>dons, yes, i just upgraded ghc in order to use bytestring
07:03:38<dons>and lazy insertWith
07:03:47<dons>ah ok.
07:03:52<solrize>i haven't actually converted it to use bytestring yet
07:04:09<solrize>should i call insertWith differently? does this code generally look (stylistically etc.)?
07:04:15<solrize><- newbee
07:04:33<sjanssen>insertWith may be leaking space here
07:04:38<skew>5x slower than Python string code is less than I'd expect from [Char]
07:05:24<solrize>hmm actually more than 10x slower
07:05:27<bos>solrize: use insertWith' instead
07:06:06<bos>solrize: you're building up a map full of thunks as values
07:06:16<bos>that's going to further slow you down
07:06:16<solrize>insertWith' sped it up by 20% or so
07:06:21<solrize>bos, i think i understand
07:06:24<nelhage>Why does http://haskell.org/hoogle/?q=Data.Map not return any of the right hits?
07:06:31<solrize>i did use foldl' once the thing crashed on a large file :0
07:06:39<bos>solrize: that's about as good as you'll get without switching representations, then.
07:06:43<nelhage>(But searching for `Map' does, so clearly it's in the database)
07:06:52<solrize>right it sounds like data.bytestring is a huge win
07:07:07<bos>solrize: oh, actually you could use Int instead of Integer, too, and that will further improve speed.
07:07:20<goalieca>Integer is a "bignum" no?
07:07:25<bos>yes.
07:07:37<goalieca>huge difference then
07:08:00<goalieca>I feel the need to write some haskell code tonight. haven't in a month ::(
07:08:03<bos>well, it's a clever bignum. but it also behaves pretty weirdly.
07:08:41<solrize>using int made almost no difference
07:08:55<solrize>i think it's really spending all its time on String
07:08:56<sjanssen>in this case, Integer shouldn't behave to badly (no opportunity for unboxing)
07:09:00<hpaste> keseldude pasted "lambdabot help" at http://hpaste.org/4920
07:09:03<keseldude>^ can somebody help me with that :P
07:09:28<bos>solrize: yeah.
07:09:47<goalieca>keseldude, do you need an else statement?
07:09:49<solrize>if i define a new type as an alias for Int (basically to paramatrize that type) will the compiler do the right thing?
07:09:50<sjanssen>solrize: switching this program to ByteString should be easy, simply "import qualified Data.ByteString as B" and stick "B." in front of a few function names
07:10:12<keseldude>maybe? =\
07:10:20<goalieca>keseldude, you need to return something in all cases
07:10:25<goalieca>if "maybe" then return Maybe
07:10:32<keseldude>oh ok
07:10:36<goalieca>return Just "H" or Nothing
07:10:40<bos>solrize: type aliases just introduce new names, nothing more.
07:11:04<dons>how big is your input file, solrize ?
07:11:20<bos>solrize: so "type Foo = Int" doesn't give you a new type, just a new name. you can pass Foo values to functions of Int.
07:11:31<hpaste> keseldude annotated "lambdabot help" with "thanks goalicea" at http://hpaste.org/4920#a1
07:11:35<solrize>dons, 3M
07:11:40<dons>oh, easy.
07:11:41<solrize>about 3 seconds with ghc
07:11:46<dons>but too big for [Char]
07:11:52<bos>it will be instantaneous with bytestring.
07:11:54<Korollary>goalieca: 3-1 baby
07:11:55<keseldude>damn i spelled your name wrong... sorry :(
07:12:00<goalieca>keseldude, this is probably what you want: if s == 'h' then 'H' else s
07:12:13<keseldude>i wrote that ^^
07:12:15<bos>is goalicea related to boadicea?
07:12:18<goalieca>Korollary, i sad :( it was a pay-per-view game anyways
07:12:27<goalieca>bos: goalieca = goalie + canada
07:12:29<goalieca>so no
07:12:57<bos>yes, i was just punning on keseldude's misspelling.
07:12:59<OceanSpray>@hpaste
07:12:59<lambdabot>Haskell pastebin: http://hpaste.org/new
07:13:01<tehgeekmeister>MyCatVerbs: oh, so that means that my just taking the first element by default isn't necessarily correct?
07:13:14<goalieca>ACTION didn't read that then
07:13:15<bos>@users
07:13:15<lambdabot>Maximum users seen in #haskell: 444, currently: 383 (86.3%), active: 23 (6.0%)
07:13:16<hpaste> OceanSpray pasted "(no title)" at http://hpaste.org/4921
07:13:22<bos>quiet night.
07:13:24<OceanSpray>see this parser.
07:13:39<dons>what's a good input file?
07:13:41<OceanSpray>I don't understand why I need the '"2" there at the end.
07:13:45<MyCatVerbs>tehgeekmeister: usually is, for bloody simple things like floating point numbers.
07:13:55<OceanSpray>*"- 2"
07:13:57<tehgeekmeister>MyCatVerbs: well, considering i've already parsed it as a float and constructed it properly before it's fed to readFloat, i suppose it should always be okay. but i can't be certain...
07:14:09<MyCatVerbs>tehgeekmeister: those kinds of read functions are very useful for parsing ambiguous grammars, y'see.
07:14:15<MyCatVerbs>:t readS
07:14:18<lambdabot>Not in scope: `readS'
07:14:24<OceanSpray>without it, parsing 0.1 resulted in 0.001
07:14:25<MyCatVerbs>Wait, no. *pokes the docs*
07:14:51<MyCatVerbs>Oh right.
07:14:52<tehgeekmeister>MyCatVerbs: yes, there was a good example of that in all about monads, gave the parses of a string as hexadecimal, binary, and alphabetic word
07:14:52<solrize>hmm i'm having trouble figuring out how to convert this thing, and also am now regretting putting in all those explicit annotations instead of leaving it up to type inference
07:14:53<MyCatVerbs>:t reads
07:14:54<lambdabot>forall a. (Read a) => String -> [(a, String)]
07:15:12<MyCatVerbs>tehgeekmeister: well, if your grammar doesn't contain any ambiguities, no need to worry, right? :)
07:15:37<bos>solrize: replace all of your String with B.ByteString, and readFile with B.readFile
07:15:56<tehgeekmeister>MyCatVerbs: no, not really. Parsec's gotten rid of any possible ambiguity long before readFloat sees it.
07:17:27<solrize>hmm, "words" wants a string arg
07:17:46<goalieca>Bytestring contains all those things
07:17:50<dons>B.words
07:17:51<goalieca>B.words probably
07:18:07<solrize>not there
07:18:10<hpaste> dons pasted "bytestring version" at http://hpaste.org/4922
07:18:35<solrize>wow!
07:18:41<dons>i'm not entirely happy with it. the word parsing is fine, but it took 4s to parse a 3M beowulf.txt (due to the Map), also, finding the top 20 keys isn't ideal.
07:18:59<dons>should be a queue or heap of some kind
07:19:24<dons>ghc -O2 --make
07:20:02<bos>dons: 4 seconds? ouch!
07:20:21<solrize>ugh, 5 seconds for me
07:20:26<solrize>String version was 3 seconds
07:20:26<dons>so what's going on. hmm
07:20:34<dons>yeah. something's amiss
07:20:52<bos>that's deeply wrong. it's about 50 times slower than it should be.
07:22:53<hpaste> solrize annotated "(no title)" with "my bytestring version" at http://hpaste.org/4918#a1
07:23:26<sjanssen>dons: slow ByteString Ord, I bet
07:24:39<goalieca>ya. if you put it in a map..
07:25:16<dons>well, it counts the number of words in 0.07s
07:25:21<dons>so its all in the Map
07:25:32<bos>that's weird.
07:25:46<sjanssen>dons: we've seen this issue before
07:25:54<sjanssen>memcmp FFI call is sloooow
07:26:14<dons>sjanssen: yep
07:26:20<bos>especially for small strings.
07:26:35<sjanssen>dons: you should rip it out :)
07:27:07<sjanssen>even a dumb "compare x y = compare (unpack x) (unpack y)" is faster in many cases
07:27:19<dons>i guess compare is mostly done on small strings, not 10G files
07:27:26<dons>which was what it was optimised for originally :)
07:28:03<goalieca>memcmp in c is just a few loc.
07:28:08<goalieca>can probably be translated
07:28:27<dons>oh, we've got pure haskell versions
07:28:39<hpaste> goalieca pasted "memcmp in c" at http://hpaste.org/4923
07:29:08<bos>goalieca: an efficient memcmp is much more hairy
07:29:17<skew>why don't you use them, if FFI is so slow?
07:29:25<skew>or use them on the first 100k?
07:29:43<goalieca>bos: let the compiler sort it out. too many architectures
07:29:50<bos>skew: the trick is finding a sensible cutoff point
07:29:55<solrize>why is FFI so slow, you can use an unsafe call since memcmp doesn't mutate anything right?
07:30:16<sjanssen>solrize: even unsafe calls have significant overhead
07:30:22<solrize>hmm
07:30:49<sjanssen>let's all poke dons till he changes it ;)
07:31:02<solrize>does harpy use ffi then?
07:31:28<bos>solrize: it would have to, yes.
07:31:38<diltsman>What would you guys suggest as the best tutorial to learning everythnig about Mondads?
07:32:03<sjanssen>solrize: when I say "significant" I mean when compared to the work done by comparing only a few characters
07:32:06<solrize>diltsman, there are a lot of them, they all use different angles
07:32:28<ddarius>Read Wadler's papers.
07:32:31<ddarius>@where wadler
07:32:31<lambdabot>http://homepages.inf.ed.ac.uk/wadler/
07:32:34<sarah__>@pl append_act g a = g ++ [Node a (currentPos g)]
07:32:34<lambdabot>append_act = liftM2 (.) (++) (flip flip [] . ((:) .) . flip Node . currentPos)
07:32:40<tehgeekmeister>i can't nest a (name <- expr) from a do block inside an if expression, can i?
07:32:44<ddarius>ACTION goes to bed like he should have hours ago.
07:32:46<sarah__>oh wow that didnt make it any easier to read :)
07:32:48<solrize>yeah, wadler's "monads in functional programming", and i like the haskell wikibook article on category theory
07:33:15<MyCatVerbs>ddarius: I've hit the point where I interpret dawn as a sign that it's time to go to bed, rather than time to wake up. x_x
07:33:19<bos>tehgeekmeister: you have to start a new do block.
07:33:27<solrize>diltsman what languages do you use now?
07:33:29<tehgeekmeister>bos: thanks
07:33:30<bos>tehgeekmeister: and the "assignment" won't be visible in the outer one.
07:33:37<solrize>there's a good one that explains monads in terms of python lists, that helped me a lot
07:33:59<tehgeekmeister>bos: okay, time for alternate solutions, then.
07:34:21<hpaste> dons annotated "bytestring version" with "only marginally faster using a different Ord" at http://hpaste.org/4922#a1
07:34:22<diltsman>solrize: I'm mostly a C/C++ programmer. I think I'm at the point where I understand the basics of Monads, but I have some code that works (how I think it should) but I'm not quite certain why.
07:34:39<solrize>diltsman, yeah i'm in about the same place as you
07:34:40<sarah__>diltsman: im new too, helped me to think of bind like a unix pipe
07:34:48<goalieca>diltsman, moi too
07:34:48<skew>diltsman: I think both of sigfpe's tutorials are good
07:35:59<diltsman>I guess what is throwing me off the most is when I go from functions in one monad to functions in another monad. I'm having trouble figuring out the correct way to do that.
07:36:04<bos>dons: how big is the map when you're done? probably 500k elements?
07:36:39<sjanssen>dons: what is "marginal"?
07:36:57<dons>43319.
07:37:06<dons>(size)
07:37:07<goalieca>dons: how good is the balancing...
07:37:38<Korollary>goalieca: Ovechkin got a 13 year/$124M contract lol.
07:38:06<dons>sjanssen: 3.267s with OrdString, 5.286 with ByteString (so a good margin)
07:38:08<tehgeekmeister>ACTION has epiphany that he can use if expressions to select which function to apply to values, instead of using if expressions to branch to the individual functions applied to the values.
07:38:08<goalieca>Korollary, putting diPietro to shame
07:38:17<dons>but String is faster still (i can't work that out)
07:39:04<goalieca>tehgeekmeister, mean pattern matching?
07:39:07<kfish>ACTION works out that Ovechkin is /not/ the name of an elite type-theory consultancy
07:39:11<dons>2.047 for String. hmm
07:39:38<MyCatVerbs>kfish: s/consultancy/conspiracy/
07:40:04<skew>MyCatVerbs: but Overkin could be!
07:40:11<tehgeekmeister>> (\a -> if a == "-" then (* (-1)) else (*1)) "-" $ 1
07:40:14<lambdabot> -1
07:40:16<tehgeekmeister>versus
07:40:24<sjanssen>how long is the average word? In the range where [Char] is more compact than ByteString?
07:40:51<MyCatVerbs>skew: that sounds more like a branch of an Overtly Evil Empire than a Shadowy Conspiracy Ruling From The Shadowy Shadows.
07:40:54<dons>5-7 letters
07:41:00<dons>maybe less
07:41:31<tehgeekmeister>>let f sign n = if sign == "-" then (n * (-1)) else n*1 in f "-" 1
07:41:38<solrize>is there a way to convert the B.words output to Strings before putting them into Data.Map ?
07:41:47<dons>count Main 78.3 67.6
07:41:47<dons>cmp Main 18.5 30.2
07:41:49<tehgeekmeister>goalieca: get what i mean now?
07:42:24<dons>solrize: heh. good idea. its faster stlil
07:42:26<dons>1.5s
07:42:29<tehgeekmeister>goalieca: it's more useful if you just return a section instead of using a lambda like i did, but you get the idea, i'm sure.
07:42:33<goalieca>tehgeekmeister, yeh. functions are first class
07:42:35<dons>main = do f <- head <$> getArgs x <- S.readFile f let t = foldl' count M.empty (S.words x) print . M.size $ t
07:42:39<dons>count counts word = M.insertWith' (+) (S.unpack word) 1 counts
07:42:41<dons>type Table = M.Map String Int
07:42:52<dons>solrize: see the (S.unpack word), or B.unpack if you import as B
07:43:29<solrize>ok. but basically the current situation is there's something broken that hopefully can be patched up somehow?
07:43:30<Korollary>how many words are there?
07:43:51<dons>solrize: it looks like comparing is more expensive than it should be. i'm investigating
07:43:55<tehgeekmeister>goalieca: of course, but the real beauty is that if expressions evaluate to a value -- this is not typical of the programming languages i'm used to, where they would branch flow of control, instead.
07:43:55<solrize>korollary about 500k maybe
07:44:07<solrize>dons and i aren't using the same file, and his machine may be faster than mine
07:44:31<Korollary>solrize: are you comparing against python? Python dicts could be using hashmaps as opposed to maps we're using here.
07:44:33<solrize>dons, cool
07:44:41<solrize>korollary, yes, i'm comparing with python defaultdict
07:45:03<sjanssen>dons: I think that the BS comparison is still slower than [Char] in the case where only the first character is checked
07:45:25<goalieca>populating a large (balanced) map is not a fast thing to do
07:45:26<dons>sjanssen: yeah, that sounds plausible
07:45:29<sjanssen>compare (head x) (head x) is really fast
07:45:34<dons>right
07:46:04<sjanssen>BS has to do several dereferences there (deref the offset, length, pointer, then dereference the pointer itself)
07:46:15<hpaste> dons annotated "bytestring version" with "String compare" at http://hpaste.org/4922#a2
07:46:28<dons>solrize: ^ so i think we're narrowing this down
07:46:34<solrize>dons, thanks
07:47:35<tehgeekmeister>ACTION goes to bed -- fixing numeric towers is too complicated past midnight.
07:48:23<bos>also, doing pointer arithmetic directly might save a bit of work, since ghc's optimiser isn't going to be as clever as a c compiler would be.
07:48:46<Korollary>Holy cow. Every increment is another tree-insert?
07:49:05<bos>iow, increment p1 and p2 directly with plusPtr
07:49:11<sjanssen>Korollary: how else would you do it?
07:49:27<dons>count . group . sort ? :)
07:49:57<sjanssen>quite probably slower
07:50:01<skew>fromListWith could run in ST
07:50:29<skew>why oh why didn't we get linear types in the Great Lazy Unification?
07:50:49<sjanssen>skew: hmm? quicksort an array or something?
07:51:02<solrize>Your search - "great lazy unification" - did not match any documents.
07:51:38<sarah__>is there a version of @pl that leaves some arguments intact?
07:51:40<dons>sjanssen: yes, slower, but its beautiful :) 8.376s :)
07:52:10<sjanssen>are we still in the realm of losing to Python?
07:52:17<bos>sjanssen: absolutely.
07:52:19<hpaste> dons annotated "bytestring version" with "pretty sort.group.sort" at http://hpaste.org/4922#a3
07:52:26<dons>what was python?
07:52:43<solrize>speed? 0.4 sec
07:52:45<dons>ok.
07:52:54<skew>solrize: Haskell was made to unify a whole bunch of lazy research languages, except clean was out for lunch so we didn't get to eat their brains
07:52:58<dons>so the two issues: Map and compare.
07:53:15<sarah__>a bunch? wow i thought haskell was the ONLY lazy lang
07:53:19<skew>sjanssen: I was thinking modifying the values in the nodes inplace, rather than rebuilding the path
07:53:47<sjanssen>skew: I'm not sure that is a major issue, with the generational GC and all
07:53:49<hpaste> solrize annotated "(no title)" with "python" at http://hpaste.org/4918#a2
07:54:37<skew>sarah__: there were all kinds of little research languages in the early 90s
07:54:50<bos>you people have to stop dangling these interesting performance baubles in front of dons. he can't resist them.
07:55:13<bos>it's like watching a cat with a piece of tinsel.
07:55:33<solrize>i think this is one of those situations where the functional map just inherently loses to the hash table
07:55:36<glguy>?remember bos you people have to stop dangling these interesting performance baubles in front of dons. he can't resist them. it's like watching a cat with a piece of tinsel.
07:55:37<lambdabot>I will never forget.
07:56:01<dons>solrize: i think that's part of it (we have HashTables up the sleeve if needed though)
07:56:03<bos>solrize: probably not, they're often comparable in performance.
07:58:09<solrize>maybe i'll try a version where the keys are integers generated by some function, instead of words from a file
07:59:40<dons>oh there was a bad inline.
07:59:42<dons>down to 1s
08:00:01<solrize>cool
08:03:32<goalieca>and you said it took 0.7 to just count
08:03:35<goalieca>so that's preetty good
08:03:49<dons>0.07 to break the words
08:04:04<dons>but there's a lot to improve in the memcmp
08:04:46<sjanssen>dons: should there be ! on len1 and len2?
08:05:10<dons>that's what i'm simplifying right now, actually
08:10:52<MyCatVerbs>sarah__: Haskell is more like "the only lazy language *left* in academia" than "the only lazy language in academia" :)
08:12:43<hpaste> bos pasted "Data.HashTable version" at http://hpaste.org/4924
08:12:55<solrize>speed of that?
08:13:20<bos>0.69 seconds on a 974KB file
08:13:43<bos>i'm using http://www.gutenberg.org/dirs/etext97/bwulf11.txt concatenated onto itself repeatedly as the test dataset
08:14:05<solrize>2.6 sec for my 3MB file, a tiny bit faster than the map version
08:14:14<solrize>but the results are in reverse order, i think
08:14:45<bos>oh, right. use flip in front of comparing.
08:14:46<solrize>need to flip the comparison
08:14:47<solrize>right
08:15:09<solrize>yeah, that looks right
08:15:12<bos>doesn't change the execution time.
08:15:33<solrize>yeah, it would be nice if there was a heap sort function that was lazy
08:15:39<bos>the hashtable API sucks compared to the rich broth of Data.Map
08:16:06<solrize>bos yeah if i ever figure out this language enough, i want to start using happs for web stuff, and it revolves around data.map
08:16:23<xpik2>@pl (\x-> x+(x*2))
08:16:23<lambdabot>ap (+) (2 *)
08:16:45<solrize>Prelude> :t ap
08:16:45<solrize><interactive>:1:0: Not in scope: `ap'
08:17:36<xpik2>@pl (\x-> (x/3)+(x*2))
08:17:36<lambdabot>liftM2 (+) (/ 3) (2 *)
08:19:21<bos>ap :: Monad m => m (a -> b) -> m a -> m b
08:19:29<bos>it's the monadic version of $
08:19:54<bos>also written as <*> quite often in the latest fashion.
08:20:40<solrize>eh? there's a monad for numeric functions?
08:20:47<bos>no, for functions in general.
08:20:56<xpik2>there's a monad for type (->)
08:20:59<bos>think of (->) as a type constructor.
08:21:34<Cale>(since it is)
08:22:01<hpaste> dons annotated "bytestring version" with "1sec Map + new Ord" at http://hpaste.org/4922#a4
08:22:09<Cale>For any type e, (->) e, that is, the type constructor for functions from the type e, is a monad.
08:22:10<solrize>so "return" pulls out the original parameter ?
08:22:12<dons>so that's the fastest I've got with a Map, solrize
08:22:12<bos>well, yes, but newbs don't think of it as such. it just looks like notation.
08:22:20<dons>solrize: twice as fast as with String+Map
08:22:33<xpik2>@pl (\x y -> fst 1 == fst )
08:22:33<lambdabot>const (const (fst 1 == fst))
08:22:38<Cale>> do { x <- id; y <- reverse; z <- map toUpper; return (x,y,z) }
08:22:40<bos>different ords for different fnords.
08:22:43<Cale>> (do { x <- id; y <- reverse; z <- map toUpper; return (x,y,z) }) "hello"
08:22:53<lambdabot> thread killed
08:22:59<lambdabot> thread killed
08:23:02<Cale>uhh...
08:23:06<solrize>dons, 4x speedup from the earlier bytestring version is pretty good
08:23:15<dons>you got a 4x speedup?
08:23:17<solrize>i mean, can you fold that into the library?
08:23:28<dons>solrize, in this case, yes.
08:23:31<solrize>using your original timing
08:23:38<xpik2>@pl (\x y -> fst x == fst y )
08:23:38<mbot>(. fst) . (==) . fst
08:23:38<lambdabot>(. fst) . (==) . fst
08:23:41<Cale>mbot: @run (do { x <- id; y <- reverse; z <- map toUpper; return (x,y,z) }) "hello"
08:23:44<mbot> ("hello","olleh","HELLO")
08:23:53<Cale>mbot: @part #haskell
08:24:00<bos>dons: what's different?
08:24:12<dons>bos, an inlining was messing things up.
08:24:26<Cale>^^ there's an example of the (->) e monad, in this case, with e = String
08:24:28<dons>i tried a couple of different versions of the compare, but couldn't get a faster one
08:24:35<dons>though i'm not convinced its optimal
08:24:39<bos>oh, you killed the inlining of cmp.
08:24:49<Cale>and yeah, return = const
08:24:49<dons>yeah
08:24:56<Cale>> return 5 6
08:24:59<lambdabot> 5
08:24:59<bos>and compare.
08:25:10<Cale>> (do { x <- id; y <- reverse; z <- map toUpper; return (x,y,z) }) "hello"
08:25:11<lambdabot> ("hello","olleh","HELLO")
08:25:19<Cale>okay good, that's working again :)
08:26:04<bos>so i don't think Map has any significant bearing on this, in terms of performance.
08:26:13<solrize>bos, probably right
08:26:20<Cale>Basically, to "run" each sub-computation, which is just a function of type e, you apply the function to the parameter which the computation as a whole has been applied to.
08:30:12<solrize>so (ducks flames) does the PL research community still think laziness by default is a good thing?
08:30:40<solrize>skew, i don't think clean had linear types
08:31:14<skew>course it does!
08:31:22<skew>maybe they say uniqueness
08:31:34<solrize>yeah, they do, but i thought linear types meant something different
08:31:35<dons>solrize: lazines isn't an issue here
08:31:47<solrize>dons, not an issue for this, i mean in general
08:31:56<dons>seems like a useful thing.
08:32:09<sphynx>hi all
08:32:49<sjanssen>dons: it is faster than memcmp for smallish strings, right? Will you add it to the repository soon?
08:33:11<sjanssen>ACTION likes nagging :)
08:33:18<sphynx>I thought that if 'newtype NT = NT Float' then NT _|_ = _|_, now I am testing this and it doesn't seem to work..
08:33:19<dons>sjanssen: yeah. it seems like a good thing to do.
08:33:36<xpik2>@pl (\x y -> [x,y] )
08:33:36<lambdabot>(. return) . (:)
08:33:39<skew>a program really shouldn't be doing lots of comparisions on strings with big common prefixes
08:34:25<solrize>hmm, data.map might do a lot of exactly that, since it's chasing down a tree to find where to put something
08:34:30<Korollary>skew: "a" program?
08:34:57<sphynx>bot = bot
08:34:57<sphynx>nt = NT bot
08:34:57<sphynx>instance Show NT where show (NT x) = "NT"
08:35:08<sjanssen>sphynx: yes, NT _|_ = _|_
08:35:14<sphynx>and then main = print nt works
08:35:36<sjanssen>sphynx: ah, there is the other difference -- pattern matching on NT essentially has no effect
08:35:43<bos>sphynx: that's an irrefutable pattern.
08:35:43<skew>Korollary: you should be using prefix trees or something if you expect it to come up
08:35:45<sphynx>but if use data NT' = NT' !Float, all works as I want (it is strict constructor)
08:36:13<sphynx>so the problem is in pattern matching, not in newtype strictness?
08:36:34<sjanssen>sphynx: I would say difference rather than problem, but yes
08:36:53<skew>hmm, well I guess if you are writting diff you do expect equality to come up...
08:36:55<bos>sphynx: no, there's no problem. a binding in an irrefutable pattern doesn't need to be evaluated, so _|_ is never forced.
08:37:25<sphynx>sjanssen: how should I change this? Add ~ to pattern?
08:37:30<skew>anyway, the character where the strings first differ is useful infromation, and I don't see that returned in the current API
08:37:45<sphynx>I need to show the difference between newtype and data somehow
08:37:46<bos>sphynx: no, that makes the pattern lazy, which makes no difference in this case.
08:37:48<sjanssen>sphynx: ~ on a newtype pattern changes nothing
08:38:18<sphynx>hm, so how should I show the difference?
08:38:52<sjanssen>NT undefined `seq` () vs. Data undefined `seq` ()
08:39:54<dons>yeah, i get identical timings with Hash and Map now
08:40:38<hpaste> dons annotated "bytestring version" with "Hash on ByteString" at http://hpaste.org/4922#a5
08:41:03<sphynx>and this is single difference between data and newtype? I mean (NT _|_ = _|_)
08:41:30<sphynx>also there are some intenal differences maybe...
08:41:35<sjanssen>it isn't the only one, because strict data types have the same behavior
08:41:35<sphynx>internal *
08:41:35<bos>that's a yucky hash :-)
08:41:44<dons>:)
08:42:03<sjanssen>sphynx: the Haskell report has some commentary on this issue
08:42:09<dons>since we only need Eq, we can do a bit better yet
08:42:23<sphynx>yeah, so what is the difference between data! and newtype?
08:42:34<sphynx>sjanssen: ok, I will try to look into it
08:42:42<bos>we should adapt this for bytestrings: http://www.burtleburtle.net/bob/c/lookup3.c
08:43:04<dons>looks like Eq on bytestring should be tuned to avoid the C call too.
08:43:20<bos>sphynx: newtype vanishes completely at runtime - there's no additional overhead.
08:43:34<bos>sphynx: data will add an extra level of indirection usually, even with !.
08:44:06<solrize>is type different from newtype?
08:44:12<bos>sphynx: hence ghc's -funboxed-strict-fields flag
08:44:14<bos>solrize: yes.
08:44:25<bos>solrize: type == alias, newtype == distinct type.
08:45:02<sphynx>bos: -funboxed-strict-fields makes data! works as newtype?
08:45:13<bos>no.
08:46:10<bos>but it means that the unboxed value will be present in the same piece of allocated heap as the rest of the value's book-keeping.
08:46:23<sphynx>bos: BTW, I like your Mercurial book, greatly written! :)
08:46:28<bos>thanks!
08:47:04<solrize>ACTION eagerly awaits the haskell book! :)
08:47:27<bos>ACTION goes to bed
08:47:44<dons>there we go, 0.915s :)
08:48:01<solrize>cool
08:48:03<dons>so its all in tuning the inner loops of the eq and comparison functions in the end
08:48:13<dons>which surely has been done for the python hashtable
08:48:15<solrize>this is stuff that can go into the next version?
08:48:21<dons>yeah.
08:48:39<dons>basically, the current Eq and Ord are optimised for larger strings than we typically use
08:48:49<solrize>yeah they have tuned the heck out of the python hash func. on the other hand i deliberately wrote that python code in sort of a pessimized way using generators, to be like idiomatic haskell
08:49:14<dons>its a surprising benchmark
08:50:07<solrize>yes if bytestring was originally tuned for bigger strings
08:50:19<C-Keen>@paste
08:50:20<lambdabot>Haskell pastebin: http://hpaste.org/new
08:50:43<solrize>i mean it's a pretty reasonable application, i hope ?
08:51:06<C-Keen>good morning, while I now know how to define monads I am feeling totally stupid that I am unable to use one...
08:51:57<dons>solrize: yeah. having lots of small strings broken up, and stored in a Map should be well tuned.
08:52:21<hpaste> c-keen pasted "What am I missing here?" at http://hpaste.org/4925
08:52:58<hpaste> dons annotated "bytestring version" with "fastest (0.9s) Hash+ByteString Eq" at http://hpaste.org/4922#a6
08:53:01<solrize>is there some chance that this stuff can be more completely integrated with the regular string type in future incarnations?
08:53:24<dons>solrize: there's a very high chance the bytestring library will use these versions of Eq and Ord that don't make calls into C
08:53:31<dons>since its faster to stay in Haskell, as we saw
08:53:42<dons>so i'll probably commit the changes tomorrow, in fact :)
08:53:46<skew>faster for all sizes, or just for small sizes?
08:53:56<solrize>oh this version uses mutable hashes
08:53:59<dons>small sizes much faster, larger ones a few percent slowdown.
08:54:05<dons>solrize: right. the Map was 5-10% behind
08:54:16<solrize>that seems worth it
08:54:20<dons>(it needs Ord rather than Eq, which is a bit more complex)
08:54:27<skew>we're planning to win eventually with dph vectorization, right?
08:54:27<solrize>hmm true
08:54:34<dons>you could definitely tune the hashtable data structure too
08:54:41<dons>its very unoptimised.
08:55:01<dons>skew, well, mostly we do. strings && hashtables == a little bit neglected
08:55:47<dons>solrize: interestingly, the naive hashtables i've used in the shootout are many times faster than Data.HashTable, and tries are better still (for this kind of frequency counting)
08:55:47<skew>solrize: String = [Char] is easy to write up algorithms with. It's a little harder to do pattern matching and stuff with bytestrings
08:55:50<solrize>wow, you can importa ll those different packages as the same symbol, i didn't know that
08:56:17<bos>views for pattern matching on bytestrings will be nice.
08:56:25<skew>dons: I meant specifically speed of the C vs. Haskell operations on long strings
08:56:30<solrize>skew, yeah, my fantasy would be the compiler actually treating strings more like bytestrings
08:56:56<dons>bos, what do you reckon? given its down to 0.9s versus 0.7s for python, for the hashtable version, probably the rest is just algorithmic stuff from using a naive hashtable?
08:57:09<dons>(our current hashtable type doesn't even inline)
08:57:14<solrize>dons, 0.7 is the python version i pasted?
08:57:17<bos>probably. i think that being within 20% of python for this is great.
08:57:40<dons>well, i think we could top it -- the Data.HashTable impl is unoptimised
08:57:46<skew>the python hashtable isn't going to inline either
08:57:59<bos>yeah. but it will probably swing to 20% faster, not a substantial difference.
08:58:16<dons>a fairly naive one in the shootout outperforms python fairly well,
08:58:17<dons> http://shootout.alioth.debian.org/gp4/benchmark.php?test=knucleotide&lang=all
08:58:19<lambdabot>Title: k-nucleotide benchmark | Gentoo : Intel&#174; Pentium&#174;&nbsp;4 Computer Lang ..., http://tinyurl.com/mnnkb
08:58:33<bos>ok, really to bed now :-)
08:58:36<dons>(the hashtable data structure is naive algorithmically, but hand optimised)
08:59:13<skew>that outperforms Data.Hashtable, otherwise we wouldn't bother bloating the entry with it, right?
08:59:21<dons>skew, yeah, by 5-10x
08:59:32<skew>so why has that not become Data.Hashtable?
08:59:41<dons>i always meant to port it back over, but never got around to it
08:59:43<solrize>nite bos :)
09:00:47<dons>its also quite a naive hash type. but its simple code that optimises well.
09:01:05<skew>ah, they are also specialized for Int
09:01:15<dons>yeah. and the strings don't store their length
09:01:23<dons>(its fixed at initialisation time or some such)
09:01:38<dons>so quite specialised
09:01:46<dons>but the basic type is pretty straightforward
09:02:09<dons>solrize: so the lessons here, fix up ByteString's Eq and Ords to avoid ccalls, and poke around Data.HashTable some more
09:02:12<Sizur>hsxml is beautiful. it needs to be packaged. and used!
09:02:37<inimino>for writing an HTTP server: Erlang or Haskell?
09:03:02<dons>inimino: well, you're in #haskell
09:03:19<inimino>dons: yes ;-)
09:03:38<inimino>but I am wondering about the concurrency features of erlang
09:03:50<inimino>and the built-in networking support
09:03:52<solrize>dons, great, that kind of hacking is way past my ability but i'm glad it's happening
09:03:52<dons>i'd argue since you don't tend to magically distribute web servers, and haskell has better large string support/multicore support, haskell makes more sense.
09:04:04<solrize>inimino check out www.happs.org
09:04:25<skew>It's not exactly concurrency that erlang is good at
09:04:28<inimino>dons: it doesn't need to be distributed
09:04:38<skew>- except their runtime uses epoll -
09:04:56<skew>but rather stuff like failure monitoring and restarting on top of those threads
09:04:57<dons>inimino: right. so that doesn't play to erlang's strength. multicore concurrency is certainly haskell's
09:05:15<solrize>does haskell have a parallel gc and all that?
09:05:22<inimino>dons: ok, good to know
09:05:50<skew>Haskell threads are just as cheap to make and all that
09:05:54<inimino>I don't know much about Erlang, but I did just read the whitepaper
09:06:34<dons>solrize: parallel gc is in the head branch of ghc, but still experimental/not on by default
09:06:38<inimino>skew: ok, I didn't know anything about thread in Haskell, are they directly correspond to OS threads?
09:06:55<solrize>skew, erlang seems geared towards applications with simple enough logic that if something fails you can just crash the whole process and restart it, like rebooting a windows box when an application gets an error
09:07:19<dons>inimino: since benchmarks are fun, here's the thread-ring benchmark, http://shootout.alioth.debian.org/gp4/benchmark.php?test=threadring&lang=all
09:07:19<lambdabot>Title: thread-ring (new) benchmark | Gentoo : Intel&#174; Pentium&#174;&nbsp;4 Computer ..., http://tinyurl.com/2lyngq
09:07:25<inimino>solrize: or restarting a daemon on Unix
09:07:28<dons>inimino: it measure the cost of starting many threads
09:07:44<inimino>ACTION looks
09:08:39<inimino>looks very nice :-)
09:08:42<Sizur>solrize: i wouldn't exactly call a t-online system a simple logic
09:08:55<solrize>t-online?
09:09:00<Sizur>eh, make that t-com
09:09:12<inimino>also from the Erlang white-paper, the Mnesia thing sounded cool, how would you do something that with Haskell?
09:09:45<Sizur>their whole system is on erlang
09:09:47<solrize>sizur, phone switches seem to mostly run the same code paths over and over
09:10:14<quicksilver>sphynx: the different between data! and newtype is more front-end than back-end
09:10:44<xpik2>@src (==)
09:10:44<lambdabot>x == y = not (x /= y)
09:10:56<skew>sphynx: the difference between type and newtype, rather
09:12:17<Sizur>wow for ruby on that benchmark
09:13:05<Sizur>they should have a date of the benchmark on each results page
09:13:37<skew>A for effort!
09:13:38<quicksilver>dons: it bugs me slightly that ffi has such an overhead, actually.
09:13:55<inimino>dons: thanks for the link, I think that resolves my concern about thread overhead
09:14:01<quicksilver>dons: couldn't we hope GHC to have some kind of 'FFI inlining' which just generates a direct memcmp call for something as simple as this.
09:15:36<solrize>maybe we want a typed assembler programmed completely as gadt's, so we can write inlined machine code directly and still have it type-safe
09:16:07<skew>quicksilver: the problem is to make sure the runtime system knows what to do if it tries to suspend or GC the thread
09:16:41<quicksilver>skew: haskell threads are not real threads in general.
09:16:42<bruno_d>Dear Haskellers, I have a question about arrays with a functional interface.
09:16:57<quicksilver>skew: FFI blocks a whole real thread anyway...
09:17:14<quicksilver>so the runtime system can't "try" to suspend anything during an FFI call.
09:17:49<solrize>yow, the ffi sets a lock on every call? that's like 100 cycles
09:18:05<bruno_d>For characters, there is Data.ByteString. It seems to be only implemented for the Word8 type. Would it be possible to do the same for Double and other numeric types?
09:18:42<bruno_d>I'd like to use foldl, foldr, map, zip and the like efficiently with Double arrays, as it is possible with Strings.
09:19:02<qweqwe>how i can ask if xs null ?
09:19:13<qweqwe>how it should be ?
09:19:16<solrize>null xs
09:19:18<quicksilver>if null xs then ...
09:19:27<quicksilver>solrize: I don't think I understand what you're saying.
09:19:29<solrize>Prelude> null []
09:19:29<solrize>True
09:19:49<quicksilver>solrize: there's no lockin involved, in the simple case. haskell threads are not real threads, so there is nothing to lock. the haskell RTS just makes the FFI call ...
09:20:20<qweqwe>ok thanks
09:20:41<solrize>i thought you were saying the ffi blocks a real thread. i guess that means it just stops the haskell scheduler with a per-thread flag or something, ok.
09:21:25<skew>quicksilver: I think there are still timer signals
09:21:42<skew>also other threads can be sending over messages
09:21:42<quicksilver>solrize: in the simple case, there is only one real thread.
09:22:08<quicksilver>solrize: the haskell scheduler is just a virtual, software thing.
09:22:14<quicksilver>I know that's a bit of a clumsy way to say it :)
09:22:18<quicksilver>because all threading is software.
09:22:39<quicksilver>but the haskell scheduler in the non-threaded RTS doesn't use pre-emption or interrupts, AFAIK.
09:22:49<quicksilver>it seizes control at allocation points
09:22:59<quicksilver>(which won't happen during an FFI call like memcmp..)
09:23:04<C-Keen>hm.. how do I declare an instance of a monad w/o changing any definitions?
09:23:22<quicksilver>C-Keen: sorry, I meant to answer you earlier. That doesn't work because Either a isn't a monad.
09:23:41<xpik2>is there a function (toMaybe odd) 4 => Nothing
09:23:53<quicksilver>C-Keen: there is a Monad instance for either in Control.Monad.Error. But only in the case that "a" is a member of class "Error"
09:24:00<bruno_d>Any comments on my Double ByteString question?
09:24:13<quicksilver>xpik2: to lift a Bool function into Maybe? no, I believe not.
09:24:33<quicksilver>xpik2: I'v missed some connections between Bool and Maybe before. The library lacks them for some reason.
09:24:35<skew>bruno_d: there's nothing like the lazy bytestrings
09:24:47<C-Keen>quicksilver: thanks. You are not a helpdesk service so I am not demanding help, just asking :)
09:25:01<bruno_d>skew: Could I write it?
09:25:03<quicksilver>bruno_d: foldr, foldl map and zip all work pretty efficiently on [Double], by the way.
09:25:12<bruno_d>skew: Or are there any fundamental problems.
09:25:22<quicksilver>bruno_d: ByteString does not improve the efficiency of these basic operations over List.
09:25:42<bruno_d>quicksilver: Aha.
09:25:46<quicksilver>what it improves is memory-usage / cache usage etc
09:25:48<C-Keen>quicksilver: ah ok, so when I like a monad like that I need to indeed write my own? From yesterday's discussion I assumed I could just use one that does things like this Left success | Right failure where failure is something else than error
09:25:51<bruno_d>I thought so.
09:26:03<skew>bruno_d: Data.Array.Unboxed is already something like strict bytestrings
09:26:13<quicksilver>C-Keen: conventionally you always use "Left" for failure.
09:26:20<quicksilver>C-Keen: mnemonic : Right = that went Right.
09:26:37<bruno_d>skew: Yes, but it doesn't have a functional interface.
09:26:40<quicksilver>C-Keen: I would suggest you use the built in instance for Either and switch left and right.
09:26:47<skew>bruno_d: and then the data parallel haskell project is working on nice arrays, among other things
09:27:07<skew>C-Keen: Left = sinister
09:27:19<quicksilver>bytestrings for other types have been discussed and one suggestion is to use the DPH stuff.
09:27:30<bruno_d>skew: Yes, I noticed that, but it's not complete, yet.
09:27:59<bruno_d>Ok, thanks.
09:29:38<xpik2>> let boolToMaybe t x = if t x then Just x else Nothing in boolToMaybe odd $ 3
09:29:47<lambdabot> Just 3
09:29:49<quicksilver>xpik2: yeah, I've defined that more than once :)
09:30:48<scook0>a.k.a. guard (t x) >> return x
09:30:48<xpik2>quicksilver: I wonder what library it would be in.
09:30:52<sebaseba_>newbie question here. The type of / is (Fractional a) => a -> a -> a. But if I do (0 / 0), I get a NaN. Doesn't this imply that NaN is a Fractional?
09:30:57<quicksilver>xpik2: probably Data.Maybe
09:31:13<quicksilver>xpik2: since in my mind Bool is "more basic", so it would make more sense there than in Data.Bool.
09:31:35<scook0>sebaseba_: NaN is a Double (in this case)
09:31:39<quicksilver>sebaseba_: it implies that NaN is a member of whatever specific type oyu had
09:31:44<C-Keen>quicksilver: alright
09:31:48<scook0>and the Double type belongs to the Fractional typeclass
09:31:49<quicksilver>sebaseba_: Double, I imagine, because that's what defaulting gives ou
09:32:26<C-Keen>:t Either
09:32:27<lambdabot>Not in scope: data constructor `Either'
09:32:35<sebaseba_>ah, I see
09:33:14<scook0>@kind Either
09:33:14<lambdabot>* -> * -> *
09:33:17<scook0>@type either
09:33:18<lambdabot>forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
09:33:26<C-Keen>quicksilver: what do you mean by 'using the builtin instance of Either'?
09:33:32<C-Keen>scook0: thanks
09:34:32<quicksilver>C-Keen: the built in instance of Monad for Either, I should say
09:34:38<quicksilver>C-Keen: which you will find in Control.Monad.Error
09:35:06<scook0>quicksilver: to be precise, the instance for Either e
09:35:22<quicksilver>no, to be *precise* the instance for Either [Char]
09:35:29<quicksilver>since that's what C-Keen apparently had :)
09:35:56<xpik2>there should be a class maybeable where [] -> Nothing and False goes to Nothing
09:35:59<scook0>heh, I shouldn't have tried to beat you at your own game :)
09:36:22<C-Keen>quicksilver: what do I need to tell ghc to find that class?
09:36:28<quicksilver>C-Keen: import Control.Monad.Error
09:37:05<scook0>xpik2: not a bad idea ... I know I've occasionally wanted a ToList class
09:37:25<quicksilver>xpik2: well, you could write boolToMZero t x = if t x then return x else mzero
09:37:30<quicksilver>scook0: you're in luck! there is one!
09:37:35<quicksilver>scook0: it's called Foldable
09:38:13<C-Keen>quicksilver: I did this: Could not find module `Control.Monad.Error': Use -v to see a list of the files searched for.
09:38:51<C-Keen>quicksilver: my ghc is version 6.6.1
09:39:05<scook0>oh, in that case you could do listToMaybe . Foldable.toList
09:39:17<xpik2>> toList Node 1 [Node 3 []]
09:39:18<lambdabot> Not in scope: `toList'
09:39:51<xpik2>@m + Data.Foldable
09:39:51<lambdabot>Maybe you meant: map messages messages? more msg . ? @ v
09:39:54<scook0>> Data.Foldable.toList (Just 3)
09:39:54<lambdabot> [3]
09:41:13<quicksilver>C-Keen: you probably haven't installed the mtl?
09:41:23<quicksilver>apt-get install ghc6-mtl-dev, I think, on debian
09:41:31<quicksilver>some similar incantation on less fortunate OSes
09:42:19<C-Keen>grml not on ubuntu obviously
09:42:46<C-Keen>quicksilver: thanks for the pointer I will deal with this
09:43:22<quicksilver>it's something similar on ubuntu
09:43:26<quicksilver>I may have got the name slightly wrong
09:43:48<quicksilver>libghc6-mtl-dev
09:43:51<quicksilver>it looks like
09:48:07<C-Keen>quicksilver: it was the right name
09:51:28<C-Keen>quicksilver: now I feel like I am back to square 1. Is there a Monad that let's me use an arbitrary type for Left?
09:51:42<quicksilver>not entirely arbitrary
09:51:47<quicksilver>it has to be an instance of "Error"
09:51:52<quicksilver>to use the Control.Monad instance
09:52:06<quicksilver>however, making an arbitrary type an instance of Error is easy enough
09:52:30<C-Keen>quicksilver: what exactly is Error?
09:52:50<doserj>@src Error
09:52:51<lambdabot>class Error a where
09:52:51<lambdabot> noMsg :: a
09:52:51<lambdabot> strMsg :: String -> a
09:53:30<quicksilver>http://www.haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-Error.html
09:53:31<lambdabot>http://tinyurl.com/2cvgfn
09:53:43<quicksilver>does not exactly explain everything but it has a couple of example at least
09:53:51<C-Keen>so I can say Instance Error foo where strMsg :: footype -> a ?
09:54:13<doserj>no
09:54:35<doserj>instance Error foo where strMsg :: String -> foo; strMsg s = ...
09:55:07<doserj>then Either foo a is a Monad
09:56:22<Mr_Awesome>i just wrote a function like so: (^&&^) f g x = f x && g x, but i feel like im reinventing the wheel. is there a better way?
09:56:34<C-Keen>doserj: doesn't this mean that I still have to give the Left of the monad a String to return?
09:56:48<Sizur>:t (&&&)
09:56:50<lambdabot>forall (a :: * -> * -> *) b c c'. (Arrow a) => a b c -> a b c' -> a b (c, c')
09:57:03<doserj>Mr_Awesome: liftM2 (&&) ?
09:57:10<Sizur>sec you need a Bool
09:57:25<doserj>C-Keen: ?
09:58:10<Sizur>:t (\a-> uncurry (&&) . (&&&) a)
09:58:11<lambdabot> Couldn't match expected type `Bool' against inferred type `(c, c')'
09:58:11<lambdabot> Expected type: (Bool, c') -> (Bool, Bool)
09:58:11<lambdabot> Inferred type: (Bool, c') -> (Bool, (c, c'))
09:58:37<quicksilver>Mr_Awesome: that is also (&&) `on` f, if you have 6.8
09:58:43<quicksilver>Mr_Awesome: not that that is any shorter :)
09:59:08<doserj>> liftM2 (&&) not id True
09:59:09<lambdabot> False
09:59:23<doserj>quicksilver: not exactly
09:59:41<quicksilver>doserj: oh, misread
09:59:46<quicksilver>Mr_Awesome: sorry, ignore me :)
10:00:28<Sizur>:t (\a b -> uncurry (&&) . (a (&&&) b))
10:00:29<lambdabot>forall t (a :: * -> * -> *) b c c' a1. (Arrow a) => ((a b c -> a b c' -> a b (c, c')) -> t -> a1 -> (Bool, Bool)) -> t -> a1 -> Bool
10:00:30<Mr_Awesome>so, from what i can tell, i have no real reason to change what i have :)
10:00:52<Mr_Awesome>Sizur: yeah, i see what youre doing, but thats sort of overkill
10:00:58<quicksilver>Mr_Awesome: no, I agree.
10:01:17<quicksilver>Mr_Awesome: what you're doing is a pattern many of us recognise but I don't have a way to write it more concisely :)
10:01:17<Mr_Awesome>quicksilver: you agree with what?
10:01:25<Mr_Awesome>ah, right
10:01:40<quicksilver>ACTION . o o O ( everything, just stop hitting me )
10:01:58<Mr_Awesome>heh
10:02:09<Mr_Awesome>well, ill just stick with what i have now, since it works :)
10:03:12<gio123>does somebody knows free faxing service?
10:03:28<Botje>:t on
10:03:30<lambdabot>Not in scope: `on'
10:03:33<Botje>ahh
10:03:43<Mr_Awesome>\msg lambdabot :t \f g x -> f x && g x
10:03:45<Botje>Mr_Awesome's combinator is often defined as `on` here
10:03:49<Mr_Awesome>whoops
10:04:01<Mr_Awesome>wrong slash
10:04:13<Botje>hmm
10:04:19<Botje>ACTION notices the f & g
10:04:23<Botje>not entirely :)
10:04:50<Sizur>@pl \f g x -> f x && g x
10:04:50<lambdabot>liftM2 (&&)
10:05:37<Vq^>@. type pl on (+) f x y = f x + f y
10:05:38<lambdabot>parse error (possibly incorrect indentation)
10:06:08<ertai>is there a function to make a regex from a string that match exactly this string?
10:06:08<Vq^>:/
10:06:16<Cin>i'm using Data.Map and i want to use both `map` from Data.Map and from Prelude. how can i do this?
10:06:40<Mr_Awesome>Botje: are you saying that `on` is equivalent to my (^&&^) ?
10:06:51<doserj>import qualified Data.Map as M
10:06:56<Botje>no, i'm still groggy and misread a y :)
10:07:06<Sizur>> liftM2 (&&) (==1) (>0) 2
10:07:07<lambdabot> False
10:07:13<Sizur>> liftM2 (&&) (==1) (>0) 1
10:07:14<lambdabot> True
10:07:28<Vq^>Cin: check out the import instructions on http://www.haskell.org/ghc/docs/latest/html/libraries/containers/Data-Map.html
10:07:29<lambdabot>http://tinyurl.com/34gle9
10:07:42<Cin>oh, thanks
10:07:58<Mr_Awesome>ah. well, i suppose liftM2 will do for now. thanks everyone :)
10:08:04<Vq^>Cin: it describes how Data.Map and some other packages is supposed to be imported
10:08:10<quicksilver>if you want to be really fancy you could overload 'map'
10:08:15<quicksilver>but it's probably not worth it :)
10:08:31<Vq^>map=fmap ?
10:09:07<quicksilver>Data.Map isn't really a Functor
10:09:09<quicksilver>afaik
10:09:31<quicksilver>hmm. maybe it is a functor on the value side.
10:09:40<quicksilver>:t Data.Map.map
10:09:40<C-Keen>hm Control.Monad.Error does not let me define my own type to get handed to Left.... the Error instance always expects a String, the examples on the Control.Monad.Error page show custom error strings but still strings
10:09:41<lambdabot>forall a b k. (a -> b) -> Data.Map.Map k a -> Data.Map.Map k b
10:09:51<quicksilver>C-Keen: that's not true :)
10:09:56<Cin>what on earth is a functor?
10:10:06<scook0>I don't see why it wouldn't be a functor on the value side
10:10:25<Vq^>Cin: a type on which you can "map"
10:10:26<C-Keen>quicksilver: hm, then I don't get it
10:10:35<quicksilver>C-Keen: calculateLengthOrFail [] = throwError EmptyString
10:10:43<quicksilver>C-Keen: that is an example from that page
10:10:49<quicksilver>C-Keen: the custom error is "EmptyString"
10:10:53<quicksilver>that's not a String.
10:10:59<quicksilver>it's a "LengthError"
10:19:16<C-Keen>quicksilver: this only works because LengthError has a function strMsg :: String -> LengthError. What I want is that I can return a B.ByteString on error. But the compiler expects strMsg to be of type String -> a
10:20:26<C-Keen>quicksilver: sorry to be that annoying but obviously I missed to grasp some essential concept here...
10:21:16<doserj>C-Keen: define a function strMsg :: String -> B.Bytestring
10:21:34<Sizur>is strMsg used in the context of fail?
10:22:02<quicksilver>C-Keen: OK. Well strMsg is not important.
10:22:06<doserj>@src Either fail
10:22:07<lambdabot>fail msg = Left (strMsg msg)
10:22:10<quicksilver>C-Keen: it's extremely annoying, and not important.
10:22:27<quicksilver>C-Keen: for the most part you can entirely ignore it and just use throwError.
10:23:06<C-Keen>what's a good value to return then? strMsg a = "idontcare" ?
10:23:21<quicksilver>C-Keen: the only point of strMsg, as doserj alludes, is to cope with the built-in "fail"
10:23:25<C-Keen>doserj: aaah :)
10:23:36<quicksilver>well, that's the wrong type
10:23:36<Sizur>problem is haskell is too popular now to change the monad interface
10:23:46<quicksilver>strMsg a needs to return a B.ByteString
10:24:02<quicksilver>what it should return is entirely up to you
10:24:10<quicksilver>I don't know what format constraints your ByteString has
10:24:20<quicksilver>if it really isn't appropriate for you, you could just do
10:24:26<C-Keen>now I got the idea
10:24:34<C-Keen>thanks for bearing with me
10:24:37<quicksilver>strMsg a = error "Please don't call strMsg on this Monad, kthxbyelol"
10:25:09<Mr_Awesome>:t liftM2 (&&)
10:25:10<lambdabot>forall (m :: * -> *). (Monad m) => m Bool -> m Bool -> m Bool
10:25:27<Sizur>Mr_Awesome: it must be in the (->) monad
10:25:47<Mr_Awesome>Sizur: right, how do i write that?
10:26:26<Sizur>:t liftM2 (&&) .(.id)
10:26:27<lambdabot>forall a. (a -> Bool) -> (a -> Bool) -> a -> Bool
10:26:42<Mr_Awesome>i get an error when i write the type like that
10:27:13<Sizur>just use the liftM in the functional context
10:28:23<Mr_Awesome>well, i wanted to write convenience operators like (^&&^) = liftM2 (&&)
10:28:49<Sizur>dont you want it to be more general than just for (->)?
10:28:54<Cin>(^__^)
10:29:10<Mr_Awesome>Sizur: touché
10:29:23<Sizur>plus with liftM you can use other functions too
10:29:27<Mr_Awesome>i dont know why i wanted to restrict it, heh
10:30:00<Mr_Awesome>what do you mean, other functions?
10:30:15<Mr_Awesome>isnt liftM for unary functions?
10:30:20<Sizur>liftM2 (||), etc...
10:30:33<Mr_Awesome>oh, right yeah. thats what i planned on doing :)
10:31:05<Mr_Awesome>Cin: haha, is that a legal operator?
10:31:07<Sizur>it just seems backward to me. from abstraction to the more concrete
10:31:31<Mr_Awesome>what seems backward, restricting the type, or writing these functions?
10:31:37<Sizur>the second
10:31:47<Sizur>and the first :P
10:31:47<Cin>mr_awesome: no :P
10:32:00<Cin>i've not seen it anyhoo
10:32:05<Mr_Awesome>Cin: darn
10:32:16<quicksilver>> let (^__^) = (+) in 3 ^__^ 3
10:32:17<lambdabot> Parse error at ")" (column 10)
10:32:21<quicksilver>Yeah, I think not
10:32:26<quicksilver>_ isn't an operator char
10:32:31<quicksilver>it's an identifier char
10:33:14<Mr_Awesome>Sizur: well, its for convenience and clarity. my code will have a lot of this pattern in it, and its easier to understand (f ^&&^ g) than (liftM2 (&&) f g)
10:34:08<Sizur>> let (&&^) = (+) in 3 &&^ 3
10:34:12<lambdabot> 6
10:34:33<Sizur>use that, where ^ stands for 'lifted'
10:35:16<Mr_Awesome>...i dont know what youre talking about
10:36:20<Sizur>> let (&&^) = liftM2 (&&) in ((==1) &&^ (<2)) 1
10:36:21<lambdabot> True
10:37:02<Mr_Awesome>&&^ makes it seem like only the right side is lifted though
10:37:18<Sizur>well, it should mean the && is lifted
10:37:53<Mr_Awesome>what does ^&&^ mean to you then?
10:38:06<Sizur>anime face? ;)
10:38:11<Mr_Awesome>haha
10:38:19<Cin>broken nose but happy anyway
10:38:46<Mr_Awesome>^||^ is a good one
10:39:08<Cin>so awesome. i've got this algorithm where i'm checking a set of columns. but i only want to do each one step at a time, so i'm returning a list of all the steps. because it's lazy i can just get the heads of the list ^_^
10:39:39<Cin>strange, i missed out a whole sentence in that message. nevermind
10:39:57<Mr_Awesome>hooray for lazyiness!
10:40:04<Mr_Awesome>*laziness
10:40:10<Cin>:D
10:43:49<xpik1>> (Just 3) * (Just 4)
10:43:51<lambdabot> add an instance declaration for (Num (Maybe t))
10:43:51<lambdabot> In the expression: (Jus...
10:44:06<Sizur>:t (<*>)
10:44:08<lambdabot>forall (f :: * -> *) a b. (Applicative f) => f (a -> b) -> f a -> f b
10:45:19<Sizur>> liftM2 (*) (Just 3) (Just 4)
10:45:20<lambdabot> Just 12
10:46:55<Sizur>> (*) <$> (Just 3) <*> (Just 4)
10:47:03<lambdabot> Just 12
10:48:05<Sizur>> (*) <$> [3] <*> [4,5]
10:48:06<lambdabot> [12,15]
10:50:18<Sizur>> (&&) <$> (==1) <*> (<2) <*> 1
10:50:21<lambdabot> Couldn't match expected type `a -> b' against inferred type `Bool'
10:50:34<Sizur>> ((&&) <$> (==1) <*> (<2)) 1
10:50:35<lambdabot> True
10:53:54<phlpp>:t <>
10:53:57<lambdabot>parse error on input `<>'
10:54:23<phlpp>> (*) $ (Just 3) (Just 4)
10:54:23<lambdabot> Couldn't match expected type `t -> a'
10:54:35<xpik1>> Just 3 >>= guard . (>4)
10:54:37<lambdabot> Nothing
10:54:48<phlpp>:t <$>
10:54:48<lambdabot>parse error on input `<$>'
10:54:55<phlpp>:t (<$>)
10:54:56<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
10:55:00<xpik1>> Just 3 >>= guard . (>2)
10:55:01<lambdabot> Just ()
10:55:08<xpik1>why coin?
10:55:10<phlpp>:t ap
10:55:11<lambdabot>forall (m :: * -> *) a b. (Monad m) => m (a -> b) -> m a -> m b
10:55:21<Sizur>:t guard
10:55:22<lambdabot>forall (m :: * -> *). (MonadPlus m) => Bool -> m ()
10:56:09<Sizur>xpik1: what do you want to do?
10:57:50<Sizur>guard will simply fail or not fail, that's why the ()
10:58:14<Sizur>@src guard
10:58:15<lambdabot>guard True = return ()
10:58:15<lambdabot>guard False = mzero
10:58:35<Sizur>@src mzero
10:58:35<lambdabot>Source not found. My brain just exploded
10:58:41<xpik1>> Just 3 >>= \x -> guard (x>4) >> return x
10:58:42<lambdabot> Nothing
10:58:50<xpik1>> Just 3 >>= \x -> guard (x>2) >> return x
10:58:50<lambdabot> Just 3
10:59:42<Sizur>> liftM (>2) (Just 3)
10:59:42<lambdabot> Just True
11:05:45<mux>> (>2) <$> Just 3
11:05:48<lambdabot> Just True
11:06:55<Sizur>> fmap (>2) (Just 3)
11:06:56<lambdabot> Just True
11:10:25<xpik1>for (1+1) == (1+1) will GHC calculate 1+1 twice?
11:10:39<Taejo>xpik1: probably
11:11:13<xpik1>let x = (1+1) in x == x better not
11:11:22<Taejo>that's better
11:11:28<Corun>That last one definitely doesn't.
11:11:51<Corun>(Graph reduction and stufF)
11:12:08<Taejo>as far as I remember, GHC doesn't do common sub-expression elimination
11:13:35<quicksilver>only in a limited number of cases
11:14:09<quicksilver>I believe let x = (1+1) in x == (1+1) will CSE
11:20:30<ndm>quicksilver: why? what reason is it using to CSE there?
11:21:01<quicksilver>ndm: it would eliminate the (1+1), I believe
11:21:11<quicksilver>going to let x = (1+1) in x == x
11:21:11<Japsu>http://kde.org/announcements/4.0/ \o/
11:21:18<lambdabot>Title: K Desktop Environment - KDE 4.0 Released
11:21:27<ndm>quicksilver: yep, but why? because 1+1 is an Int, or other reasons?
11:21:27<quicksilver>i.e. it will only CSE something if the thunk already exists
11:21:37<quicksilver>it will CSE an expression to a let binding
11:21:41<quicksilver>but not create a new let binding
11:21:42<quicksilver>AIUI
11:21:48<quicksilver>this is "less likely" to cause space leaks
11:21:53<ndm>hmm, i would have thought that could still space leak
11:22:14<ndm>let x = repeat 'x' in x `foo` repeat 'x'
11:22:28<ndm>now all you need to do is have foo iterate down one list for 10000000 elements, then the second
11:22:50<ndm>foo x y = x !! 100000 == y !! 1000000 -- should o
11:24:18<quicksilver>it can, yes
11:24:22<quicksilver>I only said "less likely"
11:24:59<quicksilver>it is reusing an existing thunk, but it may keep it live longer than it was going to be
11:26:27<ndm>ACTION thinks thats still quite dodgy
11:26:38<ndm>Supero performs no CSE, on the basis it can't know its safe
11:26:56<ndm>your original example is safe though, as Int takes a bounded amount of space
11:27:10<ndm>just wondering if your reason for saying that was CSE was the Int or something else
11:27:13<quicksilver>yes, I agree it's a bit dodgy.
11:27:20<quicksilver>my reason wasn't the Int.
11:27:21<qweqwe>what is wrong here ?
11:27:22<qweqwe>merge1::Eq a =>[a]->[a]->[a]
11:27:22<qweqwe>merge1 x [] = x
11:27:22<qweqwe>merge1 [] x = x
11:27:22<qweqwe>merge1 (x:xs) (y:ys) = if (x>y) then y:merge1((x:xs) ys)
11:27:22<qweqwe> else x:merge1(xs (y:ys))
11:27:27<quicksilver>I may be slightly wrong, myself, of course
11:27:36<quicksilver>the GHC FAQ explains it slightly differntly to the way I explained it.
11:27:46<quicksilver>qweqwe: (a) you pasted something too long in the channel
11:27:54<funktio>qweqwe: merge1 x [] = [x]
11:27:54<qweqwe>sorry
11:28:00<doserj>@type (>)
11:28:00<quicksilver>qweqwe: (b) you can't use > on x and y because they aren't Ord
11:28:07<lambdabot>forall a. (Ord a) => a -> a -> Bool
11:28:12<quicksilver>qweqwe: (c) what funktio said :)
11:28:19<qweqwe>thanks
11:28:55<doserj>erm, no (c)
11:29:10<quicksilver>ah, no
11:29:12<funktio>hmm, yes
11:29:13<quicksilver>quite
11:29:16<quicksilver>funktio was wrong ;)
11:29:18<funktio>qweqwe: merge1 [x] [] = [x]
11:29:20<quicksilver>ignore that bit
11:29:22<funktio>is that right?
11:29:28<quicksilver>what qweqwe had was right.
11:29:39<quicksilver>but he's not naming his variables very consistently
11:29:39<funktio>ok
11:29:45<quicksilver>which is confusing ;)
11:30:10<funktio>ah, I see now :)
11:30:11<qweqwe>i still have error there
11:30:13<funktio>I'm a beginenr
11:30:15<doserj>maybe -Wall should report it :)
11:30:17<funktio>beginner*
11:30:36<qweqwe>and i only changed to ord there
11:31:02<qweqwe>*** Expression : (x : xs) ys
11:31:02<qweqwe>*** Term : (:)
11:31:02<qweqwe>*** Type : e -> [e] -> [e]
11:31:02<qweqwe>*** Does not match : a -> b -> c -> d
11:31:32<doserj>fix the parantheses in the then and else clauses
11:32:27<qweqwe>ah yes
11:36:13<C-Keen>hm how can I convert Word8 to an Int?
11:37:01<doserj>@type fromEnum
11:37:02<lambdabot>forall a. (Enum a) => a -> Int
11:37:33<C-Keen>ah
11:38:49<quicksilver>no, I don't think so
11:38:51<quicksilver>fromIntegral
11:38:59<quicksilver>hmm
11:39:00<quicksilver>well
11:39:08<doserj>> fromEnum (5::Word8)
11:39:08<quicksilver>ok, you could use fromEnum but that just feels wrong :)
11:39:19<lambdabot> 5
11:39:34<quicksilver>fromEnum == fromIntegral for all the Integral types, I suppose.
11:39:40<Taejo>@type fromIntegral
11:39:41<lambdabot>forall a b. (Num b, Integral a) => a -> b
11:46:45<resiak>If I use the 'stick char *ghc_rts_opts = "-N2" into a C file and link it with the rest of the program' trick, should I be on the lookout for dragons?
11:48:14<quicksilver>resiak: I don't believe so, no. I think that one is guaranteed dragon-free
11:48:22<quicksilver>it might not actually be dragon-repellent, mind.
11:48:51<resiak>Heh!
11:49:02<resiak>Hrm, it's also not going to do anything if I omit -threaded :/
11:51:15<scook0>http://www.haskell.org/ghc/docs/latest/html/users_guide/runtime-control.html#rts-hooks
11:51:16<lambdabot>Title: 5.14. Running a compiled program, http://tinyurl.com/d7dj4
11:51:27<scook0>ghc_rts_options seems to be totally sanctioned
11:53:33<C-Keen>now when I want to use another Monad's function within my Monad I am supposed to lift it right?
11:56:21<scook0>C-Keen: generally speaking, yes -- assuming your monad is a transformation of that other monad
11:57:07<resiak>yeah, i didn't see any documented potential disasters
11:57:12<scook0>in the particular case of IO, you can use liftIO
11:57:28<C-Keen>scook0: ah ok
11:57:29<scook0>and for MonadReader/MonadWriter/MonadState et al. you shouldn't even need to lift
11:57:43<scook0>C-Keen: what are the two monads in question?
11:57:51<C-Keen>IO and Error
11:58:09<resiak>ACTION is reluctant to test whether -threaded has helped avoid terrifying deadlocked unkillable processes for fear of discovering that it has not :)
11:58:43<C-Keen>scook0: I am 'inside' the Error Monad and want to print something to IO
11:59:01<scook0>C-Keen: that may be tricky, depending on how you've defined Error
11:59:44<scook0>if you just want debugging messages, you can use trace
11:59:48<C-Keen>scook0: my last statement may be wrong, I am inside an Either type
12:01:20<Botje>:t parse
12:01:22<lambdabot>Not in scope: `parse'
12:01:28<Botje>:t parseFromFile
12:01:29<lambdabot>Not in scope: `parseFromFile'
12:01:34<Botje>arg.
12:03:16<resiak>so, who wants to write some magic haddock -> devhelp index transformation? :)
12:03:38<quicksilver>C-Keen: you can't do IO from instance an Either type
12:03:46<quicksilver>C-Keen: that is the great thing, and the pain, of the type system
12:03:58<quicksilver>C-Keen: you can only do IO from inside the IO monad. Anywhere else its pure
12:04:14<quicksilver>C-Keen: you choices are (a) work in the IO monad (perhaps using the 'ErrorT' transformer)
12:04:23<quicksilver>(b) save the IO until later and do it from some outer code
12:04:26<quicksilver>which is runnin the IO monad
12:06:46<C-Keen>quicksilver: as I understood Monad transformations are just wrappers of needed monads around the current one to make the outer monad's functions usable
12:08:27<quicksilver>yes
12:08:42<quicksilver>so (ErrorT foo IO) a
12:08:53<quicksilver>is like a "micture" of 'IO a' and 'Either foo a'
12:09:02<quicksilver>allowing you to do IO stuff and clever exceptions, both
12:09:51<Cin>hpaste: url
12:09:52<hpaste>Haskell paste bin: http://hpaste.org/
12:10:10<hpaste> Cin pasted "why does my isWin look so ugly? ;_;" at http://hpaste.org/4926
12:11:34<Cin>hmph
12:11:42<scook0>Cin: ugh
12:11:56<quicksilver>Cin: try = any (\m -> expand m 0 0 0 > 3)
12:11:59<quicksilver>Cin: I believe
12:12:07<quicksilver>>= rather
12:12:57<Cin>ah, good one
12:13:04<scook0>Cin: you can hoist let (xm,ym) into the LHS of expand
12:13:25<quicksilver>scook0: well, he does reuse 'm' in the recursive call
12:13:32<quicksilver>scook0: he could do m@(xm,ym)
12:13:37<quicksilver>I don't know if that's better
12:14:19<scook0>some of those functions should probably be pulled out into a where, or to toplevel
12:14:22<quicksilver>Cin: I would probably write mods as [ (x,y) | x <- [-1..1], y <- [-1..1]] \\ [(0,0)]
12:14:32<quicksilver>then it fits on one line
12:14:35<scook0>they get in the way of the isWin function's logic
12:14:41<quicksilver>fitting on one line is important to my simple brain :)
12:14:51<Cin>hehe, thanks for the tip
12:15:12<Cin>scook0: such as expand?
12:15:20<quicksilver>giving 'x+xo' and 'y+yo' names might make that code readable
12:15:22<Cin>it has a lot of arguments, too many imo
12:15:31<Cin>hm, i'll try that too
12:15:37<Cin>hang on, lemmie update what we have so far
12:15:58<scook0>Cin: perhaps it would help to define some more concrete datatypes
12:16:17<scook0>instead of using tuples and multiple-argument functions so much
12:16:39<quicksilver>I htink tuples for coordinates are pretty intuitive
12:16:46<Cin>oh, you mean for Grid and whatnot?
12:16:46<quicksilver>and since they seem to be coords on a grid, I don't mind that
12:16:57<quicksilver>the lx, ly, ux, uy stuff is presumably a bounds check
12:17:02<quicksilver>you could make that into a function
12:17:03<Cin>yeah
12:17:07<quicksilver>I bet you'll need it elsewhere
12:17:27<Cin>okay, good thinking
12:17:45<scook0>if you had an inBounds :: Bounds -> (Int, Int) -> Bool function, that might help
12:17:51<Cin>aye
12:17:55<quicksilver>inBounds :: Grid -> (Int,Int) -> Bool; inBounds ((lx,ly),(ux,uy)) (x,y) == lx <= x && x <= ux && ly <= y && y <= uy
12:17:59<quicksilver>I was just writing it ;)
12:18:03<Cin>hehe
12:18:08<Cin>slow down, guys! :P
12:18:13<quicksilver>well, you asked :)
12:18:17<Cin>hehe
12:18:30<scook0>(that's the sort of thing I meant by defining new datatypes -- abstract away some of the nitty-gritty value-passing & logic)
12:18:47<Cin>right!
12:18:53<Cin>this is beginning to look far nicer
12:19:25<Botje>why not use Data.Ix.inRange ?
12:19:29<Botje>:t inRange
12:19:29<Toxaris>> inRange ((2, 2), (5, 5)) (3, 7)
12:19:30<lambdabot>forall a. (Ix a) => (a, a) -> a -> Bool
12:19:31<lambdabot> False
12:19:34<Toxaris>> inRange ((2, 2), (5, 5)) (3, 3)
12:19:35<lambdabot> True
12:19:54<Cin>oh lord :P
12:19:59<yaxu>ok so i have a smallish amount of data to read in as XML
12:20:39<yaxu>is it going to be easier to learn a haskell xml library, or convert it to a simpler format in another language and read that in?
12:20:59<yaxu>perhaps convert it to xml straight into haskell with a quick perl script
12:21:22<fadec>yaxu: haxml is pretty easy. I'm new and I figured it out
12:21:46<yaxu>fadec: ok thanks i'll take a look
12:22:14<ndm>yaxu: depending on how complex it is, tagsoup might suit you
12:22:28<ndm>tagsoup is really easy to learn, but not nearly as powerful as something like haxml
12:23:10<yaxu>it is pretty simple
12:24:01<yaxu>tagsoup looks good, the author's name looks familiar too :)
12:24:21<hpaste> fadec pasted "for yaxu" at http://hpaste.org/4927
12:24:52<fadec>yaxu: check out the hpaste to help get started
12:25:04<yaxu>thanks fadec
12:25:14<longlivedeath>quit
12:25:16<yaxu>i guess i'll invest some time looking at both libraries
12:26:34<ndm>yaxu: tagsoup doesn't deal at all with the nesting of elements, its more like a lexer for tags, than a complete parse tree - haxml does everything
12:27:42<quicksilver>it's not very hard to write some weak nesting combinators for tagsoup though
12:27:45<Cin>okay. think i have all that. plus i realised i didn't have to do "x+xo" all the time when i could just start xo as being == x..
12:27:46<quicksilver>I know because I did it :)
12:28:15<hpaste> Cin annotated "why does my isWin look so ugly? ;_;" with "improvment" at http://hpaste.org/4926#a1
12:28:23<yaxu>http://hpaste.org/4928 # i just want to read in this kind of data
12:28:52<yaxu>hand drumming data
12:30:02<quicksilver>you could do that easily with tagsoup
12:30:06<quicksilver>since "nesting doesn't matter"
12:30:09<quicksilver>for that kind of file
12:30:09<Cin>i'm quite pleased with that code now
12:30:19<quicksilver>you just want all the matrixrows after a given frame, etc
12:30:26<yaxu>yep
12:32:56<ac>does anyone know of a library for mp3 encoding?
12:33:19<Zao>ac: I'd probably interop against lame.
12:33:30<ac>Zao: what does interop mean?
12:33:43<hpaste> Cin annotated "why does my isWin look so ugly? ;_;" with "is using guards in this instance a bit silly?" at http://hpaste.org/4926#a2
12:33:47<Zao>ac: Make a foreign call into a native library.
12:33:55<Cin>hard to tell when and when not to use guards
12:34:27<ac>Zao: ok. I figured that's what you meant. So you mean I'll have to write haskell bindings for it.
12:34:53<scook0>Cin: guards seem like a win there
12:35:00<ac>I know someone must have already done decoding, as there's a Haskell mp3 player in hackage
12:35:10<scook0>I think ifs tend to be ugly
12:35:13<Cin>scook0: ah, cool. what about the way i indented it?
12:35:39<scook0>looks fine to me
12:35:41<Cin>scook0: me too, i think. they seem kind of verbose, if that makes any sense
12:35:51<scook0>though I usually ad an extra () around the LHS of a guard
12:35:51<ac>I doubt Don is around though
12:35:59<scook0>since the = has such low visual weight
12:36:06<Cin>scook0: what is LHS?
12:36:13<ac>Cin: Left Hand Side, right?
12:36:16<scook0>left-hand side
12:36:17<Cin>ahh, okay
12:36:47<quicksilver>ac: no, not left hand side right. left hand side left!
12:37:04<ac>oh, yeah
12:37:08<scook0>see whether putting the = on the second line looks better or worse
12:37:17<Cin>okay
12:37:20<ac>ifs bug me too
12:37:48<ac>in some cases ifs can be designed away
12:37:48<scook0>left hand side, ね? ;)
12:38:28<ac>you just make your code more general, and the ifs disappear. That may or may not be a good thing.
12:38:32<hpaste> Cin annotated "why does my isWin look so ugly? ;_;" with "next line. added a bit of code that needed adding (hadn't compiled with the guard)" at http://hpaste.org/4926#a3
12:39:12<doserj>I would definitely use x@(xm,ym) there
12:39:22<Cin>hehe, okay
12:39:28<scook0>why not just use fst & snd?
12:39:29<doserj>m@(xm,ym), sorry
12:39:32<Cin>i wasn't sure of the @ syntax was "bad practise"
12:39:44<scook0>expand m (c+1) (xo+fst m) (yo+snd m)
12:39:57<scook0>seems more direct to me
12:40:08<Cin>hm
12:40:29<Cin>aye that looks quite nice
12:40:45<scook0>I hate let almost as much as I hate if ;)
12:40:57<hpaste> Cin annotated "why does my isWin look so ugly? ;_;" with "looks about complete now?" at http://hpaste.org/4926#a4
12:41:07<scook0>ACTION is a die-hard where fan
12:41:24<Cin>heh, i used where originally, but then i had to pass more things to the function?
12:41:41<Cin>specifically the 'y' i obtained from the case
12:41:56<scook0>Cin: you've messed up a little
12:42:10<scook0>change xm/ym to m
12:42:11<Cin>ah, yes
12:42:12<Cin>oops
12:42:45<ac>lets have never bothered me
12:43:25<scook0>perhaps it's just that I'm never quite sure how to indent them
12:43:30<doserj>lets feel so SML...
12:43:47<Cin>indeed. lets tend to make my code branch out across the screen..
12:43:58<scook0>Cin: another minor thing: in mods, consider changing x/y to x'/y'
12:44:15<Cin>ah, to distinguish?
12:44:19<scook0>to avoid shadowing the y parameter, yeah
12:44:39<scook0>y' makes it clear that you aren't using the param
12:44:56<Cin>aye
12:45:51<ac>you don't have to indent lets... or is that just in do notation?
12:46:12<scook0>I just never know where to put the let and in keywords in non-monadic let
12:46:43<Cin>what is this x@pattern notation called?
12:46:48<scook0>and whether to put newlines before/after them
12:46:48<ac>what's a monadic let?
12:46:52<scook0>Cin: as-patterns
12:46:57<Cin>ah, thanks
12:47:06<Cin>considering using one for b,g
12:47:20<scook0>ac: in a do-expression, you can write a let that doesn't have an in part
12:47:31<scook0>(the in is implicitly the rest of the do)
12:47:42<ac>scook0: and that's the only place? Wouldn't it be possible to do the same thing in any function?
12:48:02<scook0>ac: it's part of the desugaring of do
12:48:11<Toxaris>Cin: I would change expand m c x0 y0 to expand c x0 y0 and any (\m -> expand m 0 x y >= 3) mods to expand 0 x y `any` mods
12:48:17<ac>scook0: right, sugaring would be required, but it would be good sugaring
12:48:24<scook0>outside a do, a let without an in wouldn't make sense in general
12:48:31<Toxaris>Cin: ehm, adn add some . (>= 3) :)
12:48:42<ac>scook0: why not? Couldn't the in just be the rest of the block?
12:49:04<doserj>I would define mods at the top-level, and call it directions or sth
12:49:06<scook0>ac: "block"?
12:49:17<ac>er, function
12:49:36<ac>scook0: by block I meant the syntactic block defined by indentation
12:49:44<quicksilver>let isn't an indentation thing, though
12:49:50<quicksilver>the declarations part of it is
12:49:52<quicksilver>but not the whole thing
12:49:54<quicksilver>IYSWIM
12:50:01<ac>oh
12:50:04<scook0>ac: where declarations are similar to what you describe
12:50:08<ac>I thought that might be the case, but I never understood that
12:50:10<Cin>toxaris: how would expand get the 'm'?
12:50:15<scook0>though they're placed after the main part of the definition
12:50:40<doserj>Cin: define expand to take m as the last parameter
12:50:48<Cin>ahh
12:50:57<Toxaris>> let add x y = x + y in map (add 3) [1, 2, 3] -- Cin
12:51:01<lambdabot> [4,5,6]
12:51:15<Toxaris>Cin: like this
12:51:27<Cin>right
12:51:34<doserj>then \m -> expand 0 x y m >= 3 === ((>=3).expand 0 x y)
12:52:06<ac>I guess it makes sense, because everything after the in is just one function, so it's completely unambiguous
12:52:17<ac>er, I should say "one value"
12:52:31<Cin>doserj: i think i follow that
12:53:34<Toxaris>Cin: and I would define a toplevel function getLine :: Grid -> (Int, Int) -> (Int, Int) -> [Player]
12:54:03<yaxu>ok i just did this on the ghci prompt: text <- hGetContents file
12:54:10<Toxaris>Cin: with getLine g (x, y) (deltax, deltay) the line of cells beginning at (x, y) and progressing in direction (deltax, deltay)
12:54:20<ac>I think I spend 3x the time talking on #haskell than I do actually writing Haskell. I should break that habit.
12:54:21<yaxu>and it echoed the contents of the file to the screen, which was pretty big
12:54:27<quicksilver>ac: or perhaps "one expression"
12:54:31<quicksilver>ac: but yes, that is the point.
12:54:34<yaxu>how can i avoid that behaviour?
12:54:47<quicksilver>there is an option for it
12:54:52<quicksilver>I don't remember but I'm sure it's in the docs :P
12:55:05<Toxaris>Cin: then your isWin can use something like (>= 3) . length . filter (== p) . getLine g (x, y) $ mods
12:55:23<LoganCapaldo>text <- hContents file ; return () :p
12:56:01<Cin>toxaris: i don't follow the bit about deltax and deltay. can you explain that?
12:56:01<doserj>:set -fno-print-bind-result
12:56:13<Toxaris>Cin: you called them mx and my
12:56:32<Toxaris>Cin, ahm, xm and ym, whatever. the (-1, 0, +1) things
12:56:49<yaxu>ta
12:57:16<Toxaris>Cin: correctness question: does your function handles the placing of a mark between two existing marks of the same player correctly?
12:57:30<Toxaris>Cin: (It obviously doesnt. should it?)
12:57:54<gio123>what is deference between tree language and word language?
12:58:09<Cin>toxaris: yes it does...
12:58:15<quicksilver>trees don't speak, they just rustle their branches a bit
12:58:20<scook0>harumph!
12:58:45<Toxaris>but ents *can* speak, just very slowly
12:58:45<Cin>toxaris: or it would. my original one did
12:58:54<Cin>toxaris: humph
12:59:00<scook0>gio123: you may need to rephrase your question
12:59:06<ac>gio123: that is an odd question. I've never heard of such a distinction
12:59:11<doserj>you learn sth new on #haskell everyday: http://en.wikipedia.org/wiki/Deference
12:59:12<lambdabot>Title: Deference - Wikipedia, the free encyclopedia
12:59:38<Toxaris>wasn't tree vs. word *regular* languages discussed yesterday?
12:59:46<gio123>what is deference between regular tree language and regular word language?
13:00:30<ac>Toxaris: I wasn't here yesterday, and #haskell is not the kind of channel where you keep up on the back log :-P
13:00:56<Cin>toxaris: it's supposed to carry 'count' inbetween the 'expand' construct. so that if, say, i count 2 on the left, and one on the right, it will total to 3 and thus get three in a row. likewise for veritcal and the diagonals
13:01:36<ac>gio123: do you mean "regular" as "spoken"?
13:01:47<gio123>nooo
13:02:05<Toxaris>ac: just wanted to give all information I have about regular tree / word languagse
13:02:23<Toxaris>Cin: but c is initialized to 0 all over again
13:02:49<Cin>toxaris: indeed. it's wrong at the moment. trying to figure how to change it without making it look horrible again
13:03:06<ac>Does anybody here think it would be interesting to create a spoken version of Haskell that could be used with an audio interface?
13:03:10<scook0>I'm guessing the difference is that a word language generates strings, whereas a tree language generates trees
13:03:23<quicksilver>maybe a tree language is like an AST?
13:03:32<quicksilver>while a word language is, well, what language normally means?
13:03:35<ac>It would possibly useful for blind people
13:03:36<quicksilver>but the terms are not familiar to me
13:03:49<Toxaris>it's (word regular) language, and (tree regular) language
13:04:07<Toxaris>at least I think so
13:04:25<Toxaris>not regular (word language) and regular (tree language)
13:04:27<ac>the Show class could be renamed to Speak ;)
13:04:42<ac>er, type class I mean
13:04:49<quicksilver>http://citeseer.ist.psu.edu/255817.html
13:04:49<lambdabot>Title: Forest-regular Languages and Tree-regular Languages - Murata (ResearchIndex)
13:05:03<quicksilver>but I've never heard of that terminology
13:05:56<ac>ok, so nobody thinks it would be interesting :-/
13:06:21<gio123><Toxaris> yes
13:06:23<quicksilver>ac: I missed your initial comment
13:06:27<quicksilver>ac: blind people do use haskell
13:06:39<quicksilver>ac: they use it with a screen reader, like with any other textual application
13:06:49<quicksilver>The layout is a bit painful though...
13:07:07<ac>quicksilver: hmm. you mean navigating written code using a screen reader?
13:07:45<ac>quicksilver: perhaps simply creating a better audio interface for editing than a text editor plus a screen reader would be a lot more interesting
13:08:42<C-Keen>hm, I defined type StreamIOMonad = ErrorT ByteString IO; type Stream = StreamIOMonad (Either ByteString (Int, ByteString))
13:09:05<fons>hi all
13:09:20<C-Keen>now when having Stream as a parameter I need to strip off IO first right? How do I do this?
13:10:11<quicksilver>C-Keen: I don't think what you have defined is what you meant to define.
13:10:27<C-Keen>quicksilver: probably :)
13:10:39<ac>quicksilver: I still think it may be interesting to try to fashion a vocabulary and syntax that would be easy to speak and to listen to. It might not be very possible
13:10:40<scook0>hmm, I'm trying to compile a module that has some foreign bindings
13:10:53<scook0>and I keep getting "warning: implicit declaration of function ‘get_wch’"
13:10:54<quicksilver>C-Keen: that expands to Stream = (ErrorT ByteString IO) (Either ByteString (Int, ByteString))
13:11:02<fons>I downloaded ghc 6.8.2 for OSX/Leopard and works nicely but I'd like to get the haddock documentation of the libraries and I don't seem to find a premade package in GHC's page
13:11:02<scook0>which goes away if I use -fasm
13:11:10<quicksilver>C-Keen: which has two layers of 'Either' in it
13:11:20<scook0>anybody have any better suggestions for getting rid of the warning?
13:11:24<C-Keen>quicksilver: I see
13:11:25<fons>did anyone have the same problem?
13:12:19<scook0>@where documentation
13:12:19<lambdabot>I know nothing about documentation.
13:12:24<quicksilver>C-Keen: unfortunately, I"m not quite sure what you do want :)
13:12:56<scook0>fons: http://www.haskell.org/ghc/documentation.html perhaps?
13:12:57<lambdabot>Title: The Glasgow Haskell Compiler
13:13:21<fons>damn I'm totally blind
13:13:23<C-Keen>quicksilver: I want to wrap the IO around my error monad
13:13:34<fons>thanks scook0 and sorry for wasting your time
13:13:43<scook0>ah, no problem
13:13:51<quicksilver>C-Keen: probably type Stream = ErrorT ByteString IO is what you want
13:13:53<ac>I think the trick would be to unambigously eliminate as many parens as possible
13:14:11<ac>by adding vocabulary words like "$" except they would have speakable names of course
13:14:45<quicksilver>ac: yes, there is definitely clever stuff which could be done
13:14:54<quicksilver>ac: good screenreaders can do some of these things
13:14:58<C-Keen>quicksilver: when having functions of that type then how do I strip off the IO part so I can access the inner monad?
13:15:03<ac>quicksilver: question is, would it be useful in any way?
13:15:06<quicksilver>ac: (they can substitute and transform without reading)
13:15:11<quicksilver>before reading
13:15:25<quicksilver>C-Keen: technically IO is the inner monad and ErrorT is the outer one
13:15:34<quicksilver>C-Keen: to access the other one, you need do nothing
13:15:41<quicksilver>to access the inner, IO, you need to do liftIO
13:15:59<ac>quicksilver: I guess the obvious use would be code comprehension for blind people
13:16:16<C-Keen>quicksilver: I get an error for foo:: Stream -> Stream : `Stream' is not applied to enough type arguments Expected kind `??', but `Stream' has kind `* -> *'
13:17:27<quicksilver>C-Keen: yes, because Monads always have a type parameter
13:17:51<quicksilver>C-Keen: when you use "Either ByteString blah"
13:17:55<quicksilver>your "blah" was the parameter
13:18:00<quicksilver>it's the 'return value'
13:18:58<ac>quicksilver: you mean substitute and transform _while_ reading?
13:19:02<C-Keen>So I need to either have the right type in my definition: Stream bla -> Stream bla
13:20:04<ac>quicksilver: hm. what I'm thinking of would basically be like syntax highlighting for the blind
13:24:24<ac>quicksilver: you type something in, and if the syntax is correct, when your screen reader reads it back to you it would substitute all the punctuation for vocabulary
13:25:46<ac>and if it wasn't, it would just say "blah blah left paren left paren blah blah dolar sign blah right paren whack l dash greater than blah"
13:26:17<fadec>Which db libs should I use as a newbie? Hackage has a plethora.
13:28:02<ac>fadec: in the spirit of the blind leading the blind, I'd sugest haskelldb
13:28:24<Cin>lots of blind talk today, heh
13:29:50<fadec>Looks like a choice between haskelldb and hsql - but there's also a haskelldb-hsql, an hsql-sqlite3, and a haskelldb-hsql-sqlite3. . .
13:29:54<fadec>ACTION barfs
13:30:01<ac>what is the relation between hdbc and hsql?
13:30:18<fadec>ac: good question
13:30:54<hpaste> C-Keen pasted "thanks for helping the monad dummy" at http://hpaste.org/4929
13:31:00<ac>fadec: yeah, I think you should answer that before anything else. My totally uninformed guess is that they're both the same thing, but hsql is of course geared to SQL
13:31:01<hpaste> Toxaris annotated "why does my isWin look so ugly? ;_;" with "how I would go about it" at http://hpaste.org/4926#a5
13:31:59<fadec>ac: I guess I'll start with the least dependencies.
13:32:08<ac>fadec: that looks like haskelldb-flat
13:32:42<ac>fadec: or maybe BerkelyDB
13:32:55<ac>fadec: depending on your definition of dependencies
13:33:04<fadec>ac: I think hsql + hsql-sqlite3
13:33:10<litb>hello there
13:33:52<scook0>C-Keen: you can't use the Left constructor any more
13:34:07<scook0>because you're no longer using Either
13:34:12<Toxaris>Cin: the point of my code is: all uses of if and case are hidden in takeWhile and filter, all uses of recursion are hidden in takeWhile, filter, map, iterate and length. so there is no complexity left for the program, all complicated language features are delegated to the libraries
13:34:21<scook0>you may need to use throwError instead
13:35:06<quicksilver>C-Keen: instead of Left, use throwError
13:35:11<quicksilver>C-Keen: and instead of Right use return
13:35:15<quicksilver>which you are already doing
13:35:19<quicksilver>but I mention for completeness :)
13:35:28<Cin>toxaris: aye, i follow
13:35:54<ac>fadec: but it still depends on sqlite3, whereas haskelldb-flat doesn't depend on any external libraries
13:36:15<Toxaris>Cin: and with some hope, there is a vector / matrix lib providing move, scale and sclice :)
13:37:29<C-Keen>quicksilver: that was easy
13:37:40<C-Keen>quicksilver: thanks so much for all this
13:38:10<Toxaris>would it make sense to define [(0, 0), (1, 2) .. ] = [(0, 0), (1, 2), (3, 4), ...]?
13:38:52<ac>fadec: anyway, let me know what your experience is, because my second to next project that I have lined up will involve some sort of database
13:38:57<Toxaris>> take 5 $ zip [0, 1 ..] [1, 2 ..] -- maybe no need to do so
13:39:00<lambdabot> [(0,1),(1,2),(2,3),(3,4),(4,5)]
13:39:11<Toxaris>> take 5 $ zip [0, 1 ..] [0, 2 ..]
13:39:12<lambdabot> [(0,0),(1,2),(2,4),(3,6),(4,8)]
13:39:29<hpaste> Cin annotated "why does my isWin look so ugly? ;_;" with "says "True"" at http://hpaste.org/4926#a6
13:39:56<fadec>ac: right now hsql build fails from cabal errors. Do you use archlinux by chance?
13:39:57<ac>my next project involves sound synthesis and mp3 encoding. If you're doing really simple stuff, is it worth using the dsp library?
13:40:05<Cin>toxaris: i'm not sure your algorithm is completely correct
13:40:11<ac>fadec: Ubuntu
13:40:24<quicksilver>C-Keen: np
13:40:55<ac>simple stuff being averaging streams together and concatenating them. I can't imagine it would be worth using dsp
13:41:00<quicksilver>Toxaris: the reason that tuples are not Enum instances is, that that would be an enumeration
13:41:08<quicksilver>Toxaris: however, you could argue that something is broken.
13:41:20<quicksilver>namely, it's not clear that ".." really belongs in the enum class
13:41:33<ac>though I do want to be adding some sort of generated noise...
13:41:42<quicksilver>there is the 'Ix' class for another way of ordering tuples
13:43:23<Toxaris>quicksilver: oh I see. Enum is more then just enumFromTo & friends
13:43:23<Cin>toxaris: does it read whole lines across the grid, and validates at least >3 of 'You'? it doesn't appear to account for gaps
13:43:44<Toxaris>Cin: oh yes you're right
13:43:51<quicksilver>Toxaris: yeah. It's a bit of a mess.
13:44:04<quicksilver>Toxaris: I think it's an unwritten rule that Enum should be consistent with Ord.
13:44:12<Cin>toxaris: would you have to change your code much? mine now accounts for gaps but it doesn't look very good
13:44:17<quicksilver>Toxaris: and I don't think your suggestion would be. Or maybe it should.
13:44:25<Toxaris>Cin: change filter (== p) to takeWhile (== p) to stop at the first wrong mark
13:44:36<Cin>ah, good stuff
13:45:29<qebab>takeWhile and dropWhile are awesome
13:46:16<gio123>what is deference between regular tree language and regular word language?
13:47:24<MyCatVerbs>:t compare
13:47:28<lambdabot>forall a. (Ord a) => a -> a -> Ordering
13:47:38<ac>@src Ordering
13:47:39<lambdabot>data Ordering = LT | EQ | GT
13:48:54<MyCatVerbs>:t let { fum [a,b,c,ds] = (a,b,c):(fum ds); fum [a,b] = (a,b,[]); fum [a] = (a,[],[]); fum [] = ([],[],[]); } in (sortBy (\(a,_,_)(b,_,_)-> a `compare` b)) . fum . lines
13:48:55<lambdabot> Occurs check: cannot construct the infinite type: t = [t]
13:48:55<lambdabot> Expected type: t -> [(t, t, t)]
13:48:55<lambdabot> Inferred type: [t] -> t1
13:49:16<ac>the infamous infinite type
13:49:22<MyCatVerbs>:t let { fum [a,b,c,ds] = (a,b,c):(fum ds); fum [a,b] = (a,b,[]); fum [a] = (a,[],[]); fum [] = ([],[],[]); } in fum
13:49:23<lambdabot> Occurs check: cannot construct the infinite type: t = [t]
13:49:23<lambdabot> Expected type: t -> [(t, t, t)]
13:49:23<lambdabot> Inferred type: [t] -> t1
13:49:37<ac>that's got to be my most hated type error
13:49:54<ac>and no, I'm not arguing they should be allowed
13:50:01<MyCatVerbs>:t let { fum [a,b,c,ds] = (a,b,c):(fum ds); fum [a,b] = [(a,b,[])]; fum [a] = [(a,[],[])]; fum [] = [([],[],[])]; } in fum
13:50:02<lambdabot> Occurs check: cannot construct the infinite type: t = [t]
13:50:02<lambdabot> Expected type: t -> [(t, t, t)]
13:50:02<lambdabot> Inferred type: [t] -> t1
13:50:21<MyCatVerbs>:t let { fum [a,b,c,ds] = (a,b,c):(fum ds); fum [a,b] = [(a,b,[])]; fum [a] = [(a,[],[])]; fum [] = []; } in fum
13:50:23<lambdabot> Occurs check: cannot construct the infinite type: t = [t]
13:50:23<lambdabot> Expected type: t -> [(t, t, t)]
13:50:23<lambdabot> Inferred type: [t] -> t1
13:51:04<Toxaris>MyCatVerbs: fum (a:b:c:ds) = (a, b,c) : fum ds
13:51:10<MyCatVerbs>:t let { fum (a:b:c:ds) = (a,b,c):(fum ds); fum [a,b] = [(a,b,[])]; fum [a] = [(a,[],[])]; fum [] = []; } in fum
13:51:11<lambdabot>forall a. [[a]] -> [([a], [a], [a])]
13:51:15<MyCatVerbs>Ahhhh.
13:51:28<MyCatVerbs>Toxaris: danke, silly me.
13:51:48<MyCatVerbs>:t let { fum (a:b:c:ds) = (a,b,c):(fum ds); fum [a,b] = [(a,b,[])]; fum [a] = [(a,[],[])]; fum [] = []; } in (sortBy (\(a,_,_)(b,_,_)-> a `compare` b)) . fum . lines
13:51:49<lambdabot>String -> [([Char], [Char], [Char])]
13:51:56<ac>would you mind explaining what that does?
13:52:42<MyCatVerbs>ac: rips up an input string into blocks of three lines, sorts them based on the first line.
13:53:03<Toxaris>ac: fum ["1st", "2nd", "3th", "4th"] = [("1st", "2nd", "3th"), ("4th", "", "")]
13:53:03<ac>cool
13:53:38<quicksilver>grouping in that sense is useful
13:53:47<quicksilver>I'm surprised it's not in the standard libs
13:53:53<quicksilver>it's like the "opposite to concat"
13:54:02<MyCatVerbs>ac: except that it's somewhat incomplete.
13:54:07<quicksilver>although you need to tell it how to group (I'm thinking equal-sized chunks)
13:54:53<ac>I think it's come up on this channel several times than a "chunking type" function should be in the standard libs
13:55:10<Toxaris>chunks :: Int -> [a] -> [[a]]
13:55:17<ac>s/than/that/
13:55:28<ac>@index chunks
13:55:29<lambdabot>bzzt
13:55:41<ac>darn. not in there yet
13:55:44<Toxaris>sortBy (comparing head) . chunks 3
13:56:03<Toxaris>so much more haskellish
13:56:07<ac>Toxaris: yeah that's SO much more readable than MyCatVerb's ;)
13:56:22<Cin>toxaris: hm. i think i fully understand your code now. althouh i am a little distressed that i wouldn't have realised that scale, slice and move might be in a math library.
13:56:32<litb>it doesn'T find the chunks function here
13:56:48<Toxaris>litb: unfortunately, there isn't any.
13:56:57<ac>litb: it's easy enough to write. it's a one liner
13:57:07<Toxaris>litb: write it yourself using splitAt
13:57:07<Cin>don't really feel like coding anymore, heh
13:57:07<litb>what is it supposed to do?
13:57:09<ac>litb: I've defined it myself in at least two programs
13:57:11<quicksilver>ac: often you want the tuple version, of course, and that doesn't have a general type
13:57:17<Cin>i'll go read some terry pratchett
13:57:21<litb>split a list into sublists of size N ?
13:57:23<quicksilver>ac: although you can do zip3 . transpose
13:57:29<ac>litb: yeah
13:57:53<ac>:t transpose
13:57:56<lambdabot>forall a. [[a]] -> [[a]]
13:57:59<Toxaris>Cin: well, move and scale are vector addition and scalar multiplication, but slice is more special
13:58:09<ac>quicksilver: that's not exactly what I alway want
13:58:31<MyCatVerbs>:t let chunks n list = let (foo,bar) = splitAt n list in foo : (chunks n bar) in chunk
13:58:32<lambdabot>Not in scope: `chunk'
13:58:35<quicksilver>ac: yeah, and it's not quite what I meant, either
13:58:37<MyCatVerbs>:t let chunks n list = let (foo,bar) = splitAt n list in foo : (chunks n bar) in chunks
13:58:38<lambdabot>forall a. Int -> [a] -> [[a]]
13:58:41<quicksilver>ac: but what I meant isn't quite typeable :)
13:58:54<Toxaris>Cin: I don't even know how it's called in linear algebra :(
13:58:59<quicksilver>(\[a,b,c] -> zip3 a b c) . transpose
13:59:01<quicksilver>is closer
13:59:06<quicksilver>:t (\[a,b,c] -> zip3 a b c) . transpose
13:59:07<lambdabot>forall a. [[a]] -> [(a, a, a)]
13:59:08<MyCatVerbs>:t ap
13:59:09<lambdabot>forall (m :: * -> *) a b. (Monad m) => m (a -> b) -> m a -> m b
14:00:18<Toxaris>class HomTuple t where fromList :: [a] -> (t a, [a]);
14:00:25<MyCatVerbs>> let chunks n list = let (foo,bar) = splitAt n list in foo : (chunks n bar) in unlines . concat . (sortBy (\a b->(head a)`compare`(head b))) . (chunks 3 . lines)
14:00:27<lambdabot> <[Char] -> [Char]>
14:01:27<Toxaris>class HomTuple t a | t -> a where fromList :: [a] -> Maybe (t, [a]) because of (1) different kinds for different tuples and (2) too short input lists
14:01:38<Toxaris>chunks = unfoldr fromList
14:03:01<MyCatVerbs>:t transpose
14:03:07<lambdabot>forall a. [[a]] -> [[a]]
14:03:08<ac>:t unfoldr fromList
14:03:11<Toxaris>:t sortBy (comparing head) -- MyCatVerbs
14:03:11<lambdabot>Not in scope: `fromList'
14:03:12<lambdabot>forall a. (Ord a) => [[a]] -> [[a]]
14:03:25<MyCatVerbs>Toxaris: ohhhhh, oops.
14:03:33<Cin>toxaris: what do you reckon to the speed of that function?
14:03:42<Cin>toxaris: i was going to write a fairly stupid AI player
14:03:49<MyCatVerbs>:t compring
14:03:50<lambdabot>Not in scope: `compring'
14:03:52<C-Keen>:t liftIO
14:03:53<lambdabot>forall a (m :: * -> *). (MonadIO m) => IO a -> m a
14:03:56<MyCatVerbs>Toxaris: that saves a bit of typing, heh.
14:04:06<MyCatVerbs>:t comparing
14:04:07<lambdabot>forall b a. (Ord a) => (b -> a) -> b -> b -> Ordering
14:04:10<Toxaris>Cin: It should basically do the same computation steps as yours
14:04:17<Toxaris>Cin: it's the same algorithm :)
14:04:32<Cin>yours has a call to length :P O(n) operation!
14:04:50<Cin>aye it seems to be the same algoritm
14:04:53<Toxaris>Cin: oups. you're right
14:05:10<Toxaris>Cin: but n will never be more then 5 in a running game
14:05:25<Cin>hehe
14:05:28<Toxaris>Cin: better: it will never be more then 3 in a running game
14:05:36<MyCatVerbs>@index compring
14:05:36<lambdabot>bzzt
14:05:40<MyCatVerbs>@index comparing
14:05:40<lambdabot>bzzt
14:05:47<MyCatVerbs>Ahhhh, damn you.
14:06:05<Toxaris>Cin: but you're right to avoid ((>= n) . length) in favor of ((== n) . length . take n)
14:06:24<Toxaris>Cin: or (not . null . drop (n - 1))
14:06:29<Cin>toxaris: hm, indeed
14:06:58<Cin>nice and concise, that code
14:07:14<ac>My definition is:
14:07:16<ac>> let chunks n = takeWhile (not.null) . map (take n) . iterate (drop n) in chunks 4 "foobarbazblahaoeu"
14:07:18<lambdabot> ["foob","arba","zbla","haoe","u"]
14:07:28<Toxaris>Cin: my version may be slower due to (:) cells being created
14:07:35<MyCatVerbs>WTF. ghc -e keeps spitting "parse error on input ]" on an expression that does not contain the ] character anywhere within its body.
14:07:55<Cin>toxaris: i'm quite good at writing concise code in scheme, i use library functions and whatnot. i'm still learning how to do it in haskell
14:08:33<Toxaris>Cin: in that case, ask dons for better fusion :)
14:08:42<Cin>hm?
14:08:49<Cin>fusion?
14:08:55<EvilTerran>MyCatVerbs, might the shell be expanding something?
14:08:57<ac>Cin: talking about his list fusion library
14:09:00<EvilTerran>*, $, or something?
14:09:08<Cin>ahh
14:09:27<Cin>oh god i can't stop eating these pringles
14:09:33<Toxaris>Cin: fusion is the process of transforming a program wich operators over lazy data structures into a program with explicitly tail-recursive functions
14:09:48<Cin>interesting
14:09:48<Toxaris>Cin: in this case: automatically transform my version into your version
14:09:54<Cin>yeah
14:10:17<ac>Cin: My understanding was list fusion took a series of composed functions on infinite lists and made it more efficient
14:10:33<ac>though I guess they don't have to be infinite
14:10:41<Toxaris>ac: finite lists too
14:10:43<MyCatVerbs>EvilTerran: ah, thank you, that was precisely it.
14:10:57<hpaste> (anonymous) pasted "(no title)" at http://hpaste.org/4930
14:11:00<ac>Cin: I actually installed it and used it once and it did make things a little faster ;)
14:11:08<Cin>ac: cool!:D
14:11:09<EvilTerran>... but what was expanding to ']'? an environment variable?
14:11:11<ac>Something like 10 or 20 % IIRC
14:11:17<Toxaris>a simple fusion rule is something like map f . map g ~~> map (f . g)
14:11:51<ac>Cin: using it is simply a matter of importing it, and it redefines all the standard functions that operate on lists
14:11:52<Cin>ah. straight-forward
14:12:26<Cin>suave
14:12:31<Toxaris>ac, Cin: there is list fusion for the Prelude and Data.List functions too, but the new library can fuse more expressions
14:13:08<Cin>i'll have to try that out
14:13:16<ac>For me, this brings up the question of how easy it is to create a "library" that actually changes how ghc compiles something, rather than simply suplying a module you can import?
14:14:04<quicksilver>Toxaris: that's a funny definition of fusion
14:14:17<Toxaris>excellent paper about the "new" list fusion system, shortly explaining old system too: http://www.cse.unsw.edu.au/~dons/papers/stream-fusion.pdf
14:14:28<quicksilver>I think fusion is the elimination of intermediate datastructures
14:14:45<quicksilver>I don't really think fusion is about tail-recursion per se.
14:14:53<quicksilver>or, for that matter, laziness.
14:15:00<quicksilver>fusion applies just as muh to strict lists.
14:15:00<ac>Toxaris: thanks for the link
14:15:41<Cin>it would be cool if (length (map ... could be transformed to some operation that works out the length at the same time as mapping..
14:16:02<ac>interesting: " by transforming list func-
14:16:05<ac>tions to expose their structure, intermediate values are eliminated
14:16:08<ac>by general purpose compiler optimisations
14:16:08<Cin>thanks for the link
14:16:09<ac>oops. sorry for formatting
14:16:12<quicksilver>Cin: it can.
14:16:18<Cin>quicksilver: woo!
14:16:31<quicksilver>Cin: if length was defined as a "foldr" that would happen in GHC 6.6 even
14:16:51<Toxaris>length . map f == length
14:17:08<pejo>quicksilver, you wrote what I was thinking.
14:17:11<Cin>i'm sure i saw something like this as a talk about haskell
14:17:31<Cin>maybe it was by dons, i can't remember. i only had the slides
14:17:32<ac>I love it how my Haskell code gets more efficient with each new GHC release
14:17:49<quicksilver>Toxaris: true, but I assumed he was thinking of stuff like 'sum' as wel
14:17:54<quicksilver>Toxaris: and just using length as an example ;)
14:18:49<guenni>hello, is => a reserved string?
14:18:55<EvilTerran>yes
14:19:00<Cin>ohh
14:19:04<Cin>toxaris: good point
14:19:10<guenni>thx
14:19:22<EvilTerran>guenni, it's used to mark a class context
14:19:36<EvilTerran>context -> "Foo a => a -> a" <- type
14:19:48<EvilTerran> ^^
14:19:54<litb>that says "a is a instance of class Foo" , right?
14:20:08<guenni>EvilTerran: ah, right
14:20:20<Toxaris>=> is used for superclasses too: class Super => Sub where ...
14:20:27<EvilTerran>litb, "Foo a" means "a is of a type that instantiates class Foo", yes
14:20:33<EvilTerran>er, s/of//
14:20:35<guenni>zat is why it didn't work zen
14:20:35<Toxaris>=> is used for superclasses too: class Super a => Sub a where ...
14:20:50<ac>What's the difference between a super class and a type class?
14:20:52<quicksilver>that is also a class context
14:21:03<ac>(I've never heard of a super class)
14:21:03<quicksilver>ac: a superclass is a type class :)
14:21:12<quicksilver>type classes can have superclasses
14:21:23<EvilTerran>litb, the whole thing is the type of a function that takes a value of any type that instantiates Foo, and returns a value of the same type
14:21:25<quicksilver>just like in C++
14:21:28<quicksilver>well not really :)
14:21:29<ac>quicksilver: I will refrain from thinking about that for the time being.
14:21:41<ac>but that is good to know
14:21:55<litb>ah, i see
14:22:10<litb>EvilTerran: but the same type, not another type of class Foo ?
14:22:17<Toxaris>litb: yes
14:22:21<litb>alrite
14:22:35<Toxaris>litb: (Foo a, Foo b) => a -> b
14:23:25<ac>just out of curiosity, could somebody give an example of a type signature that uses a super class?
14:23:38<quicksilver>ac: no
14:23:48<quicksilver>ac: because it's class declarations that use superclasses
14:23:53<quicksilver>ac: not type signatures
14:23:56<quicksilver>;)
14:24:01<ac>ah
14:24:11<quicksilver>ac: as in the definition of Num: class (Eq a) => Num a where ....
14:24:12<Cin>is there a special notation for talking about infix operators in module import lists?
14:24:22<quicksilver>Cin: put () around then
14:24:24<quicksilver>them
14:24:25<Cin>i get syntax error when saying '!' for the Map library
14:24:27<Cin>i tried that
14:24:30<Cin>i get another error
14:24:43<Cin>hang on
14:24:44<Toxaris>Cin: import M (alphanumericName, (=!$%), anotherName )
14:25:06<quicksilver>or if it's just one
14:25:10<Cin>hm
14:25:12<quicksilver>import Data.Map((!))
14:25:32<Cin>ah
14:25:49<Cin>thanks
14:26:45<ac>it amuses me that you actually can have an operator named "=!%%"
14:27:18<Cin>ACTION has amibition for an ^_^ operator
14:27:21<litb>insane
14:27:26<ac>Cin: lol
14:27:33<ac>Cin: any speculation on what it would do?
14:27:36<quicksilver>you can do ^.^
14:27:36<litb>what about a <3 operator ?
14:27:50<funktio>or function: o_O
14:28:03<Cin>ac: something cheerful
14:28:05<notsmack>funktio: o_O
14:28:11<ac>Cin: obviously. But more specific than that
14:28:26<Cin>ac: perhaps uniting two data structures, with love
14:28:40<ac>Cin: sort of like union for Data.Map
14:29:12<ac>ok, somebody has to write a program with all of those defined
14:29:14<litb>how would i make a partial application of the binary op - where the second number is given?
14:29:24<litb>(-4) doesn't work
14:29:33<funktio>-4 is a special case
14:29:39<funktio>because it parses as a negative number
14:29:40<ac>litb: yes, (-) is ugly
14:29:48<Toxaris>> map (/ 2) [1..5]
14:29:52<lambdabot> [0.5,1.0,1.5,2.0,2.5]
14:29:57<litb>funktio: yeah, that is the problem
14:29:58<ac>litb: it's probably the most inconsistent part of Haskell syntax I've discovered
14:29:58<scook0>> map (subtract 1) [1..4]
14:29:58<Toxaris>> map (subtract 2) [1..5]
14:29:59<lambdabot> [0,1,2,3]
14:29:59<lambdabot> [-1,0,1,2,3]
14:30:00<notsmack>litb: subtract
14:30:05<litb>ah
14:30:55<daf>funktio: - is not just a number prefix, it's a unary function
14:31:17<funktio>daf: ah, ok
14:31:26<notsmack>daf: really?
14:31:31<quicksilver>tup
14:31:35<daf>> -(2 + 2)
14:31:35<quicksilver>which makes it even worse
14:31:36<lambdabot> -4
14:31:40<notsmack>gotcha.
14:31:43<shapr>hi daf
14:31:48<daf>shapr: hola
14:31:49<quicksilver>I could just about live with it if it was only a number prefix
14:31:52<shapr>daf: Will you be there tomorrow?
14:31:57<daf>shapr: wrong continent, sorry
14:32:01<shapr>Oh, too bad.
14:32:02<quicksilver>but unary function, defying all the lexical rules of haskell for no good reason
14:32:04<quicksilver>that's just horrible
14:32:08<Toxaris>> map (+ (- 2)) [1..5] -- another option
14:32:09<daf>shapr: wrong Cambridge, even :)
14:32:11<lambdabot> [-1,0,1,2,3]
14:32:14<ac>quicksilver: I totally agree
14:32:28<shapr>daf: Sucks.. and I bet I didn't meet you when I was in the other Cambridge.
14:32:49<daf>shapr: hmm, my memory is really bad
14:32:50<ac>is there anyway to have a non symbol character in an operator name other than `foo`?
14:33:04<ac>so you can define things like "4 <3 5"?
14:33:06<shapr>daf: Were you at AngloHaskell?
14:33:12<daf>shapr: nope
14:33:19<shapr>I probably didn't meet you then.
14:33:20<daf>shapr: I didn't even hear about that
14:33:27<daf>darn
14:33:30<shapr>Well, it was organized in very short notice.
14:33:53<quicksilver>ac: no.
14:34:10<quicksilver>ac: the rule is simple. And I quite like the simplicity if not for the fact than - breaks it
14:34:13<Toxaris>:t let (<³) = undefined in 4 <³ 3
14:34:15<lambdabot>parse error on input `)'
14:34:19<ac>too bad parens are out too. "foo :) bar" would be cool
14:34:41<quicksilver>ac: there is a lexical class for normal (prefix) functions and one for infix operators
14:34:44<oerjan>@version
14:34:44<ac>Toxaris: my term does not support unicode it seams
14:34:44<lambdabot>lambdabot 4p581, GHC 6.6 (Linux i686 2.40GHz)
14:34:44<lambdabot>darcs get http://code.haskell.org/lambdabot
14:34:54<daf>shapr: I'm actually in Cambridge MA fairly often
14:35:00<quicksilver>ac, Toxaris: lambdabot can't read UTF8
14:35:27<shapr>daf: Cool, let's meet up for food/drink/whatever.
14:35:45<daf>shapr: I'll let you know when I'm in town :)
14:35:52<shapr>I want to start a Haskell user group in Somerville.. HUGS.
14:35:54<shapr>Spiffy!
14:35:56<ac>When will you be able to write Haskell source in unicode, or can you already?
14:36:18<shapr>daf: Do I also know you from the Python community possibly?
14:36:37<ac>It would be fairly simple to implement... all you have to do is define "symbol character", and maybe a few other things I'm not thinking about
14:36:49<ac>"upper case" is already well defined by unicode libs
14:36:55<litb>have some of you taken part of the functional programming contest?
14:37:15<daf>shapr: hmm, unlikely
14:37:26<Toxaris>ac: my ghc accepts unicode
14:37:37<ac>Toxaris: which version is that?
14:37:45<shapr>daf: ok
14:37:47<daf>shapr: I haven't really hung out with Python people a lot
14:37:53<Toxaris>ac: The Glorious Glasgow Haskell Compilation System, version 6.8.1
14:38:02<Adis>greetings
14:38:06<daf>shapr: perhaps the most likely vector for my meeting you is Mako
14:38:06<shapr>bok Adis
14:38:06<ac>Toxaris: sweet. Is that new in 6.8?
14:38:15<shapr>daf: I haven't met Mako.
14:38:16<daf>shapr: or OLPC, if you've had anything to do with that
14:38:16<Toxaris>ac: i have no idea
14:38:25<daf>shapr: ok, we probably haven't met then
14:38:26<shapr>daf: But I do know cjb, though never met.
14:38:42<daf>shapr: ah, cjb is cool
14:39:29<Toxaris>ac: i don't use it :) what's the point of using characters not on my keyboard?
14:39:56<Adis>I was wondering, can anyone be kind enough to point me to a BNF grammar for Haskell?
14:40:07<quicksilver>ac: you've been able to write haskell in unicode for yonks
14:40:18<quicksilver>ac: it's lamdbabot that has the limitation, not ghc
14:40:40<quicksilver>6.6 accepted unicode source, I suspect much older versions too.
14:41:23<Toxaris>Adis: http://www.hck.sk/users/peter/HaskellEx.htm
14:41:42<ac>according to a blog I just stumbled accross, 6.6 is where unicode support for source was added
14:41:53<Toxaris>Adis: http://www.haskell.org/onlinereport/
14:41:54<lambdabot>Title: The Haskell 98 Language Report
14:42:17<quicksilver>ah, fair enough
14:42:24<ac>Toxaris: I just think it would be cool to write Hangul and Japanese function names
14:42:28<Adis>Toxaris: thanks, I've tried using those, but I need something suitable for YACC or happy
14:43:14<ac>Toxaris: I don't pay attention to the characters written on my keyboard anyway
14:43:25<quicksilver>Adis: is there a reason that Language.Haskell isn't good enough for you?
14:44:07<ac>Toxaris: I haven't used qwerty for well over a decade
14:44:31<Toxaris>ac: and what do you use instead?
14:44:35<ac>Toxaris: dvorak
14:44:41<shapr>Me too!
14:44:49<shapr>I've been using dvorak since 1992.
14:44:57<ac>shapr: you have me beat I think
14:45:04<shapr>ACTION shrugs
14:45:08<ac>shapr: I was 7 then :-P
14:45:13<shapr>bah
14:45:15<Cin>i got my first computer in 1997 >_>
14:45:29<shapr>My first computer was a Spectrum Sinclair :-/
14:45:40<Cin>old person is old
14:45:46<ricky_clarkson>shapr: A Sinclair Spectrum. Noob.
14:45:46<shapr>ACTION waves his cane
14:45:53<shapr>ricky_clarkson: What was your first computer?
14:45:59<ricky_clarkson>The same.
14:46:02<shapr>oh
14:46:05<shapr>noob!
14:46:15<ricky_clarkson>I was just being silly because you got its name the wrong way around.
14:46:25<shapr>Bah
14:46:36<shapr>ACTION throws spiky lambdas at ricky_clarkson
14:46:52<ricky_clarkson>GOTO 42
14:47:27<ac>ACTION speculates #haskell has the highest density of nerds in the Internet
14:47:41<ac>s/nerds/nerdiness/
14:47:43<Toxaris>higher order nerds
14:47:59<Toxaris>and even some co-nerds
14:48:09<shapr>So that's what she means when she says "Hi, HON"
14:50:07<shapr>hej bringert
14:50:09<myname>:pl \x -> a (b x) c
14:50:15<ac>ACTION aspires to become a co-nerd
14:50:15<shapr>bok gour
14:50:27<bringert>hej shapr
14:50:37<Toxaris>@pl \x -> a (b x) c
14:50:38<lambdabot>flip a c . b
14:51:10<gour>shapr: bok, what's new?
14:51:25<shapr>Code is good!
14:51:27<gour>shapr: still in use?
14:51:28<shapr>What's new with you?
14:51:34<shapr>gour: Sort of...
14:51:55<gour>shapr: i'm ill a bit, code is none, but we hope for a better
14:52:13<gour>shapr: i meant, still in usa?
14:52:14<shapr>Oh, I'm sorry to hear that. I hope you feel better soon.
14:52:18<shapr>Oh yes.
14:52:20<shapr>Permanently now.
14:52:26<gour>some dry coughing...
14:52:31<shapr>I moved from Alabama to Boston, MA.
14:52:39<gour>when will you visit eu?
14:53:08<shapr>Probably not for a long time. But Zagreb is my next EU destination :-)
14:53:18<gour>i moved to emacs (from vim), if this can be called improvement :-)
14:53:29<shapr>I think each choice has its benefits.
14:53:35<gour>shapr: good, good...still single?
14:53:51<shapr>Sadly, yes.
14:54:09<shapr>But I'm meeting lots of new people in Boston!
14:54:13<gour>shapr: ohh, then you should visit cro sooner ;)
14:54:14<shapr>Mostly male programmers though.
14:54:17<shapr>hah, yes!
14:54:29<gour>not for she-programmers though :-)
14:55:06<gour>shapr: you code haskell for living now?
14:56:04<shapr>Nah, I switched jobs, I code C# for a living now.
14:56:22<gour>is it tolerable?
14:56:34<shapr>Yeh, lots of smart people to work with.
14:56:37<gour>you were working on happs?
14:56:51<Lycurgus>shapr: you weren't with Galois?
14:57:22<Lycurgus>at a uni, no?
14:58:01<shapr>gour: Yeah
14:58:04<shapr>Lycurgus: No, neither.
14:58:38<shapr>Lycurgus: Are you at uni?
14:58:54<Lycurgus>no, I'm free. Completely.
14:59:01<shapr>Even I can afford that!
14:59:09<shapr>Do you have a programming job?
14:59:28<Lycurgus>yes, but I'm self-employed.
14:59:51<Lycurgus>I've never done anything else as an adult.
15:00:07<ac>Lycurgus: cool, does your self employment envolve writing Haskell?
15:00:57<Lycurgus>yes, but only for myself at this point. That's why I asked about Galois.
15:01:44<gour>realworld haskell blog says "We’ve completed the first draft of 13 of the book’s chapters". is it all, or how many chapters are supposed to be there?
15:02:23<ac>Lycurgus: I see. I was hoping to ask if you ever felt overwhelmed writing all that Haskell code...
15:02:53<myname>@pl \x y z -> f y (splitAt x z)
15:02:53<lambdabot>flip ((.) . f) . splitAt
15:04:24<Lycurgus>ac: I've been programming for more than 30 years. It's not that easy to overwhelm me at this point.
15:04:32<ac>my next job is either going to be another very small startup, or some sort of Haskell programming ;)
15:04:34<puusorsa>..so, you know cobol? :)
15:04:58<litb>> map (+$-2) [1..5] -- another option
15:05:00<lambdabot> Not in scope: `+$-'
15:05:09<ac>heh
15:05:17<litb>oops
15:06:13<ac>(and if I'm lucky, both)
15:06:43<oerjan>litb: (+ $ - 2) is not a legal section, because of precedence
15:07:18<Lycurgus>puuorsa: me? Yes, I have of course used COBOL, though never was anyplace where it was the only thing. Was systems programmer in Burroughs shop and the app programmer used COBOL ...
15:07:36<litb>@src $
15:07:37<lambdabot>f $ x = f x
15:07:54<ac>litb: it simply has a different precedence than " "
15:08:05<litb>hm that looks like it would be a definition of an infix op
15:08:11<Lycurgus>but I used Algol and only used COBOL to interface with the apps. Similar experiences other places including once parsing COBOL at Dunn and Bradstreet.
15:08:14<litb>since the $ is in the middle of f and x
15:08:20<oerjan>litb: correct
15:08:42<Toxaris>> map ((+) $ (- 2)) [1..5] -- litb: has to be written like this
15:08:45<lambdabot> [-1,0,1,2,3]
15:08:46<ac>:info ($)
15:08:59<litb>i tried doing so the other day and it complained "infinite definition of f " or the like
15:08:59<ac>@info ($)
15:08:59<lambdabot>($)
15:09:13<oerjan>ac: @info -> @undo
15:09:25<oerjan>deceptive spelling correction
15:09:35<litb>ah, Toxaris
15:09:40<ac>oerjan: huh? What's @undo do?
15:09:43<Toxaris>> let f $ x = "money money money" in 27 $ 42
15:09:44<lambdabot> "money money money"
15:10:08<Toxaris>litb: not problem to define infix ops. your "infinite definition" must be some other problem
15:10:09<oerjan>@undo do { x <- test; putStr x; return (x++"hi") }
15:10:09<lambdabot>test >>= \ x -> putStr x >> return (x ++ "hi")
15:10:19<litb>i did it like this:
15:10:34<ac>oerjan: cool! I was wanting that earlier today
15:10:35<litb>let f q x = "money money money" in 27 q 42
15:10:41<litb>> let f q x = "money money money" in 27 q 42
15:10:42<lambdabot> Not in scope: `q'
15:10:44<oerjan>also:
15:10:51<oerjan>@redo test >>= \ x -> putStr x >> return (x ++ "hi")
15:10:52<lambdabot>do { x <- test; putStr x; return (x ++ "hi")}
15:10:54<litb>now i get another error...
15:11:02<myname>@pl \c (a, b) -> a ++ c (head b) : tail b
15:11:03<lambdabot>(`ap` snd) . (. fst) . flip ((.) . (++)) . (`ap` tail) . ((:) .) . (. head)
15:11:12<ac>oerjan: man, lambdabot has all sorts of features that should simply come packaged with ghci
15:11:16<litb>or is a op only allowed to ne a nonalphanumeric character?
15:11:40<ac>litb: operators must be all symbol characters
15:12:10<oerjan>litb: not quite
15:12:26<ac>litb: or in the form of `foo` where foo is a normal prefix function
15:12:28<oerjan>> let f `q` x = "money money money" in 27 `q` 42
15:12:31<lambdabot> "money money money"
15:12:32<litb>ACTION wonders what a symbol character is
15:12:38<fadec>ac: the darcs version of haskelldb seems to work. Looks to me like most of the other hackages are included in it e.g. it exposes Database.HaskellDB.HSQL.MySQL. Hackage is WAY out of date here.
15:12:42<litb>oerjan: ah, nice workaround
15:13:11<ac>fadec: good to know
15:13:15<ac>fadec: thanks
15:13:34<oerjan>litb: and (+) for the opposite
15:13:57<ac>fadec: have you looked in to hsql yet?
15:14:34<fadec>ac: I only tried to compile the hackage version of hsql. No luck.
15:14:50<ac>fadec: ah ok, but not the darcs version yet
15:14:53<oerjan>ac: there's ghc-on-acid although it is hard to install
15:14:59<fadec>ac: but haskelldb exposes modules that have HSQL in the name
15:15:18<oerjan>don't know if it works with 6.8 yet
15:15:19<ac>oerjan: what else does ghc-on-acid come with other than an improved ghci?
15:15:26<oerjan>ac: lambdabot
15:15:26<fadec>ac: I think haskelldb might have eaten up the other projects from the looks of it.
15:15:47<fadec>s/eaten up/consolidated
15:15:57<ac>fadec: that would make sense, considering there's a haskeldb-hsql lib
15:16:33<fadec>ac: that and the fact that while the hackage haskelldb is on ver 0.1, the darcs version claims 0.9
15:17:02<ac>fadec: did you figure out what hdbc is?
15:17:17<fadec>ac: guess odbc??
15:17:18<fadec>no
15:17:45<fadec>ac: docs say it is an "HDBC interface for HaskellDB"
15:18:17<ac>fadec: huh. I guess when I get to my second to next project I'll probably use haskeldb-hsql-sqlite3 then
15:18:41<ac>fadec: but I assume the sqlite3 part will be simply configuration
15:19:03<fadec>ac: Just get the darcs version of haskelldb. It includes all that other stuff.
15:19:20<ac>fadec: ok. Are you using 6.6 or 6.8?
15:19:33<fadec>ac: 6.8
15:19:43<fadec>ac: haskelldb exposes Database.HaskellDB.HSQL.SQLite3, among others.
15:19:44<ac>fadec: I'll probably upgrade to 6.8 while I'm at it
15:21:05<litb>is ghc a gcc frontend?
15:21:23<daf>no
15:21:33<daf>it does its own code generation
15:21:47<fadec>ac: I'm just getting into haskell. Never used 6.6. All I know is that everything on hackage is broken and the script I initially made to make an archlinux build package from a hackage package is almost useless.
15:22:33<ac>fadec: huh. That MAY be because you're using 6.8. I've found little to be broken with 6.6
15:22:33<litb>fadec: beware that 6.8.1 has bugs on archlinux
15:23:15<ac>fadec: but I've largely stuck to common libraries like OpenGL and whatnot
15:23:34<litb>are there games written in haskell?
15:23:41<ac>litb: a few
15:24:04<litb>more than lisp games?
15:24:15<Philippa>no, but lisp is decades older
15:24:16<ac>litb: I doubt it. lisp has been around longer
15:24:18<litb>anyway, stupid question =)
15:24:33<litb>lets seee what games there are for haskell...
15:24:47<Philippa>I'm not aware of any "mainstream" game industry use of haskell in code the player runs
15:24:55<fadec>litb: There was an opengl game engine which was pretty cool
15:25:02<Philippa>(I've a feeling I've heard of it being used for tools)
15:25:17<ac>litb: there's frag, and I saw a talk about an engine that looked interesting. not sure how complete it is
15:25:42<litb>i'm sure it wouldn't be easy to write a game with haskell?
15:25:47<ac>litb: there are simple games like xanqiboard
15:25:48<pejo>Philippa, holler if you figure out what tools it is. I share that feeling with you.
15:26:34<fadec>fadec: that's it. frag. http://www.haskell.org/haskellwiki/Frag
15:26:36<lambdabot>Title: Frag - HaskellWiki
15:27:13<fadec>Frag was cool but the demo was unstable for me. Froze after 3-5 minutes.
15:27:17<ac>litb: I've written a couple simple graphics programs that use OpenGL and it was pretty painless
15:27:57<ac>litb: but of course building a big virtual world is a whole different story. I wouldn't know what to say about the difficulty of that
15:29:16<litb>i've heard that the future is functional programming, since it allows for far more parallelism
15:29:36<cjb>litb: yes, that's what people said in 1960. :)
15:30:15<litb>oh =)
15:30:30<ac>litb: I read a blog of a guy whining about how it's a pain to write a virtual world of interacting objects in a purely functional language [Haskell]. He may or may not have been skilled at Haskell.
15:31:12<ac>can't remember who wrote it, and they may in fact be in this channel now
15:31:30<ac>(if so, I mean no offence by my use of "whining")
15:33:05<ac>His argument was that objects are a natural way to model such a thing. There is an OO library for Haskell, though I've never used it
15:33:29<litb>oh, nice: http://video.google.co.uk/videoplay?docid=9139666903029663537&hl=en-GB
15:33:33<lambdabot>Title: Games in Haskell, http://tinyurl.com/2bae7n
15:40:44<Philippa>ac: something object-like is natural, yes - you'll end up with things that smell like extensible records with "behaviour" fields
15:41:01<Philippa>but doing something akin to FRP is nice and much harder in other langs
15:41:06<Philippa>the combination is something fairly new
15:42:29<ac>Philippa: I was certainly not convinced that pure functionalism is discordant with simulation, and neither was the author actually. He just didn't know a good solution
15:43:32<ac>litb: do you have a cool idea for a game in mind?
15:44:17<litb>hm, no, ac
15:44:24<Philippa>OO isn't necessarily that great for continuous sims anyway
15:44:56<pejo>ac, that blog sounds like Erik Kidd (sp?). He had a presentation at CUFP or ICFP this year about what they do iirc. (Experience report thing).
15:45:06<shapr>Eric Kidd I think.
15:45:16<shapr>Hej pejo!
15:45:16<fadec>ac: there's a little more to it. http://haskelldb.sourceforge.net/getting-started.html
15:45:17<lambdabot>Title: HaskellDB - Getting Started
15:45:26<pejo>Ah. Sorry for butchering the spelling of your name Eric. :-)
15:45:29<pejo>Heya shapr!
15:45:34<shapr>@seen ekidd
15:45:35<lambdabot>I haven't seen ekidd.
15:45:36<shapr>bah
15:46:17<ac>shapr == Eric ?
15:46:44<shapr>Nah, I'm Shae Erisson.
15:46:54<shapr>I think Eric Kidd is ekidd on #haskell
15:47:21<shapr>ac: If you use /whois shapr (or other irc nickname) the Real Name is sometimes correct.
15:47:25<pejo>Philippa, for the record, I doubt he's advocating "Everything is an object". He's saying they would be useful to model some things.
15:48:35<ac>shapr: suppose I should've whoised you before I asked.
15:48:53<ac>fadec: thanks for the link
15:48:56<shapr>ac: Just a suggestion :-)
15:49:55<ac>ACTION thinks it would be fun to write a little script that whois's everybody in an irc channel and maps out their IPs to a google map
15:50:22<ac>well, writing the script would be a pain, but running it would be amusing
15:50:45<shapr>ac: You could do it in Haskell. Go for it!
15:50:53<shapr>There's a geoip library, yeah?
15:50:55<ac>shapr: too bad I have three other programs I want to write more
15:51:00<shapr>Heh, ok.
15:51:04<ac>shapr: I'm sure you could find a web service
15:51:13<shapr>Yeah, but I was thinking of how to do it as a quick hack.
15:51:39<ac>shapr: it should be a lambabot feature (somehow)
15:51:44<Botje>yeah
15:51:49<Botje>you could just group people by continent
15:52:05<Botje>I think that'd be pretty representative :)
15:52:12<ac>huh, does lambdabot have a web interface?
15:52:22<Botje>no(t yet)
15:52:26<ac>Botje: you can do way better than that. Why not by city?
15:52:45<Botje>because a list of cities wouldn't be very interesting
15:52:46<oerjan>Botje: i think that's no(t anymore)
15:52:55<oerjan>as in there's one which is broken
15:52:58<Botje>oerjan: no(t yet again) ? :)
15:53:05<ac>Botje: oh, I was imagining somehow rigging it to a google map
15:53:09<Botje>ac: a list of countries would be doable
15:53:19<quicksilver>I think the good geoip databases all cost money?
15:53:24<Botje>ac: .. while we wait for some kind soul to fix the webinterface ;)
15:53:29<quicksilver>unless you try to do something by screen-scraping google.
15:53:30<ac>Botje: yeah, than it would be much easier to implement in lambabot now
15:53:51<shapr>lispy wrote a web interface for lambdabot.
15:54:04<ac>quicksilver: huh. I know of several websites that do it to you for free with ads. You could just parse the crap away
15:54:04<Botje>quicksilver: you could do IP lookups to grab the ARIN / RIPE / whatever ID, and extract at least the country from that
15:54:26<quicksilver>ac: "good" geoip databases :)
15:54:32<ac>Botje: I had the whole ARIN database on my computer a while back from a contract job. I think I might still have it.
15:54:38<quicksilver>ac: I believe the free ones are mostly poor, except probably google.
15:55:26<ac>It's fun to dig up that database now and then and run queries against it
15:55:30<shapr>apt-cache search geoip shows several libs that would be easy to bind from the FFI
15:56:49<quicksilver>shapr: they're just "country" though
15:56:58<quicksilver>shapr: that's not good enough for a pretty map ;)
15:57:02<quicksilver>well, not a really pretty one.
15:57:05<shapr>Yeah, true.
15:57:20<ac>but good enough for Botje's country list
15:57:25<quicksilver>that library really shouldn't call itself libgeoip
15:57:25<shapr>But this is : http://www.haskell.org/haskellwiki/Haskell_user_locations
15:57:26<lambdabot>Title: Haskell user locations - HaskellWiki
15:57:30<quicksilver>it's libcountryip
15:58:08<ac>quicksilver: maybe it aspires to be more than it is
15:58:44<quicksilver>ac: everyone should!
15:59:49<ac>quicksilver: I think they're trying to save themselves a future name change
16:00:17<ac>shapr: looks like the coordinates on that wiki page were entered manually
16:03:09<ac>or from frappr
16:07:42<shapr>ac: Yeah, manually. But they're just fine for plotting a map.
16:08:50<notsmack>@oesis 4 8 15 16 23 42
16:08:50<lambdabot>The Lost Numbers.
16:08:50<lambdabot>[4,8,15,16,23,42,108]
16:09:32<quicksilver>lol
16:09:33<oerjan>@oasis 1,3,5,7
16:09:39<lambdabot>The odd numbers: a(n) = 2n+1.
16:09:39<lambdabot>[1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,...
16:10:11<oerjan>why are they lost, i wonder.
16:10:59<huamn>@oasis 1 7 13 19
16:11:00<lambdabot>6n+1.
16:11:00<lambdabot>[1,7,13,19,25,31,37,43,49,55,61,67,73,79,85,91,97,103,109,115,121,127,133,139...
16:11:20<quicksilver>oerjan: are you joking, or do you not know?
16:11:26<yaxu>oerjan: i think they were a plot device in a tv series called lost
16:11:34<oerjan>oh
16:11:47<quicksilver>yes, it's a tv series ;)
16:11:49<oerjan>i never watched that
16:12:06<quicksilver>http://en.wikipedia.org/wiki/4_8_15_16_23_42
16:12:07<lambdabot>Title: Mythology of Lost - Wikipedia, the free encyclopedia
16:12:07<oerjan>or much tv in general
16:12:27<notsmack>*spoiler alert*
16:13:22<ac>my friend watched it, and so I watched a few episodes with him. Silly and a little fun
16:13:32<yaxu>ACTION doesn't have a tv any more
16:13:45<ac>ACTION has never had a TV, but DLs TV once in a while
16:14:09<ac>(my parents were hippies)
16:14:48<yaxu>we'll wake conal up with all this talk of TVs
16:17:16<Nafai>ac: You're lucky to not have a TV.
16:17:29<Nafai>ac: I went without a TV for about 2 years when I lived alone and it was great
16:18:02<pejo>Nafai, so throw away your tv then? Exactly the advice Randy Pausch gives.
16:18:19<Nafai>Oh it's tempting
16:18:31<Nafai>Except my wife and I just bought a new TV after our old one went out :/
16:18:41<Nafai>I sure read a lot more back then
16:20:25<ac>Nafai: yeah I'd imagine it's somewhat of a bummer living with people who own a TV. I've never had to. My SO would kind of like one, but has abstained for the last two years :-P
16:22:48<Nafai>I've found our DVR to be absolutely essential. I'm not longer "controlled" by the TV. I watch what I want, when I want, and I can fast forward through commercials
16:24:07<ac>Nafai: yeah that's great. I torrent the TV I watch, or watch it on Veoh
16:24:13<Nafai>ACTION nods
16:24:23<shapr>I just don't watch TV, that solves the problem entirely.
16:24:35<ac>shapr: no it doesn't!
16:24:55<shapr>It doesn't?
16:25:00<shapr>Works for me.
16:25:07<ac>that's _avoiding_ the problem, not solving it
16:25:11<ac>;)
16:25:18<shapr>I dunno, books are faster.
16:25:37<noteventime>In what sense?
16:25:45<ac>noteventime: this guy reads like crazy
16:26:05<ac>it's a heck of a lot faster to read a short story than watch a movie of equivalent content
16:26:20<noteventime>ac: I generally enjoy the time I spend
16:26:29<ttt-->dont take about tv behind its back
16:26:32<ttt-->talk*
16:26:37<noteventime>So I want it to last for as long as possible :-)
16:26:56<ac>noteventime: yeah, I appreciate the media as well, but apparently shapr does not :-P
16:27:44<noteventime>There's some good TV
16:28:01<noteventime>:) Although very little compared to what's bad
16:29:58<ac>well, I even enjoy some "bad" TV once a year or so.
16:33:02<hexpuem>is it normal for GHC to generate 1mb+ binaries for a dynamically linked hello world?
16:34:21<ac>hexpuem: yes
16:34:35<ac>hexpuem: it's the haskell runtime. you can shrink that a good deal by running strip and gzexe on it
16:35:15<hexpuem>does putstrln have a lot of dependencies or is the linker just not stripping unused stuff from the runtime?
16:35:25<ac>hexpuem: er, I should say "GHC's runtime". It's not that GHC makes space inefficient code, there's just a 1mb lower limit
16:36:13<ac>hexpuem: AFAIU, the same chunk of code gets attached to every executable no matter what, and it's not attempted to optimize it. I really don't know that though
16:37:07<BMeph>@seen dcoutts
16:37:07<lambdabot>dcoutts is in #haskell-overflow, #ghc, #haskell and #gentoo-haskell. I last heard dcoutts speak 24m 31s ago.
16:37:49<dcoutts>hia BMeph
16:38:46<BMeph>Hi, dcoutts. I was just wondering - have there been any problems with Cabal building on Windows?
16:38:56<hexpuem>haha you werent kidding about gzexe
16:39:09<ac>hexpuem: go ahead and run strip too. It does not effect the program at all
16:39:26<hexpuem>most of the binary size isnt machine code then i assume?
16:39:33<hexpuem>for gzexe to get that good compression
16:39:56<dcoutts>BMeph: not that I know of, but I don't test it myself on Windows very often and few windows devs follow the darcs version of Cabal so I would not necessarily know about problems.
16:40:06<dcoutts>BMeph: are you having problems with it on Windows?
16:40:08<ac>hexpuem: gzip is pretty decent. it could easily be compressing machine code that well
16:40:38<conal>what does strip do?
16:40:49<ac>conal: read the man page. It removes all symbol names from an object file
16:40:51<hexpuem>removes symbol info
16:41:11<dcoutts>conal: standard binaries contain extra debugging information like symbol tables etc that are not necessary for running the code
16:41:14<hexpuem>theres utils that remove the Shdrs from elf too
16:41:20<conal>thanks.
16:41:23<hexpuem>OS only loads Phdrs
16:41:38<BMeph>Yes. I probably just messed something up, so I'm about to re-install GHC, but every time I try a "cabal update", I get an error out of zlib.
16:41:48<ac>hexpuem: I find it slightly annoying when really simple CGI scripts are that large
16:41:49<conal>so nothing about removing unused code from packages used. would it be difficult to do so?
16:41:58<dcoutts>conal: but are very useful for C coders using traditional low level debuggers as it allows them to match up addresses with names of C functions. It's almost useless for Haskell code.
16:42:15<hexpuem>yea i was trying to decide if i should try to learn haskell or Ocaml
16:42:17<conal>dcoutts: got it,thanks.
16:42:25<hexpuem>and was just comparing hello world size
16:42:31<ac>hexpuem: funny metric ;)
16:42:33<dcoutts>conal: linker do that automagically, to the best of their abilities
16:42:41<hexpuem>yea haha
16:42:48<hexpuem>think i might go with haskell anyway
16:42:50<conal>hexpuem: haskell will change your thinking more.
16:42:58<hexpuem>yea thats what i heard
16:43:09<hexpuem>cant cheat as much with mixed programming styles
16:43:17<ac>hexpuem: yeah, yay for Haskell. Even though it's the most recent language I've learned, it's probably taken me the longest and been the most rewarding
16:43:23<dcoutts>conal: the ghc "split objs" feature is to help linkers identify what bits of code are really needed so they can link in the minimum necessary
16:43:27<ac>s/learned/learning/
16:43:49<dcoutts>conal: which is why using split-objs on large libs can make such a difference to the size of final .exes
16:44:30<dcoutts>conal: eg, hello world with gtk2hs went from several MB to being just 30% bigger than a traditional text-only hello world when gtk2hs is built with split-objs
16:44:55<conal>dcoutts: neat. and how big is the text-only?
16:45:17<ac>1mb or so?
16:45:36<dcoutts>conal: can't remember off the top of my head, I can look it up, recall it being about 400k striped
16:46:41<ac>huh. 2.8 for my version of ghc, and 1.6 stripped
16:46:52<ac>that's more than I remember seeing last time
16:47:56<ac>400k after gzexe
16:48:52<ac>(that's 6.6.1)
16:51:55<pejo>ac, there's a mentioned bug about larger binaries with some recent ghc version. I can only find ticket 955 that mentions it though.
16:56:57<ac>pejo: it doesn't bother me extraordinarily. My only gripe is I typically web sites such that I have a lot of little cgi programs sprinkled around, which is a lot easier than writing some sort of fastcgi thingy. If the binaries are large than syncing them to the live server is slow, and I imagine loading them on a page request is slow
16:57:12<ac>s/typically/typically write/
17:03:49<ac>I guess the other option is just using Haskell for my web server, but the problem with that is all the servers I use have Apache... and I like how Apache's configuration works
17:04:45<hexpuem>you can have the runtime library as a shared object i think
17:04:54<BMeph>ACTION looks for a mod_haskell
17:05:00<ac>hexpuem: oh yeah?
17:05:02<ac>BMeph: I would love that
17:05:05<quicksilver>fastcgi is the right answer
17:05:09<quicksilver>mod_foo is a terrible answer
17:05:18<pejo>ac, modern operating systems perform some kind of read on demand for binaries, so it should only read what is necessary for executing it. If it is the same thing being loaded over and over it will remain in the memory cache.
17:05:19<ac>quicksilver: why not mod_haskell?
17:05:26<hexpuem>think i saw a -dynamic option in the ghc manpage but my install diddnt have the lib built so the link failed
17:05:27<quicksilver>the only reason to use mod_foo is if you actually want to modify the apache request sequence at all levels
17:05:34<quicksilver>if you do want to do that, it's the right answer
17:05:41<quicksilver>but assuming you don't, fastcgi is much cleaner
17:06:01<dons>?users
17:06:01<lambdabot>Maximum users seen in #haskell: 444, currently: 421 (94.8%), active: 12 (2.9%)
17:06:11<ac>quicksilver: ah I see. _sometimes_ I want to do that, but you're right that it's not typical
17:08:27<pejo>ac, and predicting the actual traffic patterns to websites (to determine load) is nearly impossible unless you have previously recorded data that you can 'replay' in some kind of test environment.
17:09:24<quicksilver>pejo: whilst your right about OS caching, there is still some kind of overhead to loading a large binary
17:09:34<quicksilver>pejo: even if the file is cached in memory
17:09:44<quicksilver>however, the situation is obviously much better for haskell than perl or python
17:10:12<quicksilver>since perl/python have to load all the dependent libraries and 'sort-of-compile' them each time.
17:10:51<jwprox>Once you learn and become proficient in Haskell... Does it actually make things easier?
17:11:29<Taejo>jwprox: some things
17:11:30<ac>I shouldn't be worrying about it too much because before I simply used #!/usr/bin/perl to make CGI scripts. I found mod_perl to be infuriating to develop with
17:11:34<puusorsa>google for quicksort in haskell. compare to c version.
17:11:39<puusorsa>jwprox
17:11:44<Taejo>jwprox: it doesn't make herding cats easier
17:11:51<puusorsa>i think that might answer your question
17:12:12<jwprox>Not that I'm bashing the language, but it seems that as a general purpose language it makes simple things more difficult to accomplish
17:12:16<Taejo>puusorsa: that's kind of cheating since the algorithms do different things (if you're referring to the list version)
17:12:25<Taejo>jwprox: does it?
17:12:33<ac>jwprox: it makes a lot of things more fun too, and I'd argue the Haskell style discourages a certain class of bugs
17:13:07<sjanssen>jwprox: what sort of things seem more difficult?
17:13:24<quicksilver>jwprox: I don't find it does. Not once you get into the swing.
17:13:41<quicksilver>jwprox: what I do find though, is it makes you face certain difficult problems at an earlier stage.
17:13:47<ac>jwprox: IMHO, there are many things that require a lot more knowledge than they do in other languages, but once you have that knowledge, those things are much easier
17:14:01<ac>jwprox: quicksilver says it more elegantly
17:14:03<dons>http://programming.reddit.com/info/657vx/comments/ "Partial application or currying?"
17:14:05<quicksilver>so, you end up being confronted by and forced to solve something which, in a more dynamic language, you wouldn't have even discovered until you had a working prototype
17:14:14<puusorsa>not sure about easier, but at least there's less typing which is nice as i'm lazy
17:14:28<quicksilver>effectively, the type system makes you aware of holes in your "mental model" of the problem you were trying to solve
17:14:35<quicksilver>this may feel like it's "harder"
17:14:53<quicksilver>but actually I think you're doing yourself a favour by solving that problem now rather than waiting to see the problems it produces
17:15:05<dons>i've just spent 3 months working on a commercial project, and we've had oh, maybe 5 bugs in that time. and lots of type errors that got removed before we demoed. :)
17:15:08<jwprox>Ok that makes sense, I guess my mind is still stubbornly clinging to an imperative outlook
17:15:10<puusorsa>often when haskell compiles, it works too. same can't be said of c
17:15:23<dons>i really really don't think that would have happened without the type system -- which we use moderately heavily
17:15:42<ac>puusorsa: and when it doesn't work, it's a semantic.. er higher level error rather than some stupid pointer bullshit
17:16:27<quicksilver>of course, occasionally you a real dozie of a type error and your head explodes
17:16:29<dons>right. you simply don't spend time tracking down low level bugs where you put the wrong data in the wrong place
17:16:30<ac>and when I say "stupid pointer bullshit" I'm not comparing it to just C. That also applies to JavaScript, PHP, and Perl
17:16:34<quicksilver>but that is just part of the experience
17:17:36<quicksilver>ac: different flavours of pointer bullshit in the different languages though :)
17:17:43<ac>quicksilver: exactly
17:17:55<quicksilver>the perl situation feels a lot more like "error: Prelude.fromJust"
17:17:59<ac>quicksilver: the C flavor is particularly nasty
17:18:01<quicksilver>than it does like "segmentation fault"
17:18:15<ac>heh
17:18:26<dons>its eerie sometimes how much could you can write (i.e. several hours), without anything going wrong.
17:18:38<pejo>quicksilver, what is the overhead of loading a large binary compared to a small one if all the code that gets executed fits in one page?
17:18:43<puusorsa>ac, right. doing the wrong thing instead of doing it wrong
17:18:46<dons>it type checks, it runs, it does the right thing, you go and play guitar hero instead of debugging
17:18:50<ac>dons: yeah, in all other languages prior to Haskell that SCARED me, but in Haskell it makes me happy
17:18:57<quicksilver>pejo: my understanding is that there is a certain amount of parsing of the executable file
17:19:11<quicksilver>pejo: mapping of data sections into areas with appropriate page permissions
17:19:23<quicksilver>pejo: but, I'm not a kernel guy so I could be overplaying it
17:19:32<quicksilver>dynamic linker time too?
17:20:08<ac>quicksilver: certainly seems intuitive to me that larger executable means longer load time, but it's definitely news to me that the whole thing isn't necessarily loaded before it's executed
17:20:20<pejo>dons, you're well beyond the average programmer, which is another reason for the lack of bugs, too.
17:20:47<quicksilver>pejo: before dons discovered haskell, he was a lesser man!
17:20:53<quicksilver>haskell embiggened him!
17:20:56<quicksilver>cromulently!
17:21:21<ac>jwprox is probably running about now
17:21:24<dons>definitely :) i haven't had to do serious debugging in 5 years
17:21:56<dons>i still find that most of the bugs are to do with ffi bindings.
17:22:02<dons>we need more robust tools there.
17:22:30<quicksilver>I worry about RULES and unsafe/inline
17:22:40<quicksilver>and subtle bugs in librarys like ByteString and Binary
17:22:45<quicksilver>my worries may be FUD though.
17:22:45<dons>there was an interesting rules issue yesterday
17:22:48<quicksilver>Or paranoia.
17:22:59<sjanssen>dons: oh?
17:23:01<dons>the side condition that made it correct was a subtle ghc compilation technique for ascii strings
17:23:18<dons>sjanssen: strings with embedded \0 have a packAddress rule that calls strlen.
17:23:32<Saul_>I just got back from an fp-day :)
17:23:35<dons>however, ghc utf8 encodes strings with \0 in them, so the strlen is ok (and the rule never files)
17:23:39<pejo>quicksilver, I don't disagree on the technical stuff there, I'm merely saying that it's not *that* expensive compared to the other stuff your webserver does.
17:23:40<dons>s/fires/
17:23:44<dons>Saul_: woot!
17:23:51<dons>i hope there's videos/blogs?
17:24:33<dcoutts>dons: what do you find the most common FFI bugs are? and would c2hs or an improvement on c2hs help?
17:24:37<Saul_>It was pretty cool, although most stuff was more advanced than what I can really use
17:24:50<Saul_>roconner did a presentation :)
17:25:01<dons>dcoutts: i think c2hs would help -- they're type errors in ffi imports
17:25:19<dcoutts>dons: right, that's c2hs's strong point
17:25:20<dons>and mistakes in structure definitions for peek/poke
17:25:30<dcoutts>that's c2hs's weak point :-)
17:25:30<ac>pejo: stupid premature optimization on my part... I mean I was at least thinking about it
17:25:46<quicksilver>pejo: ah yes. I was just being pedantic / making conversation I guess.
17:25:48<quicksilver>pejo: ;)
17:26:00<dons>dcoutts: after you do your thesis, you could come out and do an internship, and we could work on a safer ffi tools
17:26:03<dcoutts>dons: if only I had more time I'm sure I could improve c2hs's structure support
17:26:24<dcoutts>dons: aye, that's be a good project, c2hs needs some cleanup and extension and massive testing
17:27:16<dons>and i've had this idea for effect inference-based unsafePerformIO checking for a while
17:27:24<dons>that's probably an ICFP paper waiting to happen
17:27:25<dcoutts>dons: I was very pleased with the testing I was able to do with the parser, just parse everything in a gentoo system, the same massive testing technique could be applied to check that c2hs calculates structure field sizes, offsets, alignments correctly
17:27:44<dons>mm. that's good.
17:27:59<quicksilver>dons: that sounds interesting.
17:28:01<dcoutts>dons: there's been previous work on effect inference that might be applicable
17:28:10<sjanssen>dcoutts: I've also tripped on lots of bugs dealing with C library error conventions
17:28:16<dons>dcoutts: right. BenL's thesis was what got my interest there.
17:28:31<dcoutts>dons: so you mean trying to work out if a particular use of unsafePerformIO is actually safe
17:28:34<dons>quicksilver: yeah, imagine having it tell you 'yes, this use of unsafe stuff *is* referentially transparent'
17:28:37<dcoutts>sjanssen: mmm
17:31:35<quicksilver>dons: I'm also interested in the question of whether or not we can construct a set of referentially transparent primitives which are enough to rewrite Data.ByteString and other librarys which use unsafePerform
17:31:49<quicksilver>dons: so we just have one set of primitives to prove safe.
17:31:55<quicksilver>but, the answer is not obviously yes :)
17:32:17<dcoutts>quicksilver: I think bytestring could be rewritten using ST/runST and not IO/unsafePerformIO
17:32:26<jwprox>If there was one open source project written in Haskell that would be a good example code to browse through, which would it project would it be?
17:32:37<sjanssen>jwprox: xmonad is pretty nice
17:32:40<dcoutts>jwprox: try xmonad, it's small
17:33:00<quicksilver>dcoutts: ...and still expect similar performance?
17:33:06<dcoutts>quicksilver: yes.
17:33:07<Tac-Tics>Does ST typically use mutable containers for its implementation?
17:33:10<dcoutts>quicksilver: no, better.
17:33:12<quicksilver>dcoutts: that's very interesting.
17:33:17<jwprox>Thanks guys
17:33:19<quicksilver>dcoutts: why isn't it, then? ;)
17:33:23<sjanssen>dcoutts: ooh, better how?
17:33:28<oerjan>@src STRef
17:33:28<lambdabot>data STRef s a = STRef (MutVar# s a)
17:33:34<dons>sjanssen: btw, looks like there might be a PSU project to do proofs in isabelle for some bits of xmonad
17:33:44<dcoutts>sjanssen: heap allocated unpinned bytestrings
17:33:49<Tac-Tics>The # means a primitive function, right?
17:33:52<oerjan>@src IORef
17:33:52<lambdabot>newtype IORef a = IORef (STRef RealWorld a)
17:33:54<dons>dcoutts: yeah, we should look at this.
17:33:58<dcoutts>sjanssen: heap allocation for small strings should be a big win
17:34:08<dcoutts>dons: the only concern is loosing mmap
17:34:21<quicksilver>Tac-Tics: the # means ghc-internal, really
17:34:23<dons>what about other FFI calls?
17:34:27<dcoutts>dons: but if it's just that one I wonder if we couldn't handle it specially in the rts
17:34:29<quicksilver>Tac-Tics: I don't think everything with # is necessarily primitive.
17:34:33<dons>we can pin them for the duratoin of the ccall ?
17:34:41<sjanssen>dcoutts: isn't there a way to allocated pinned ByteArray#?
17:34:47<dons>dcoutts: but it should be possible to provide Pinned / Unpinned variants
17:34:49<dcoutts>sjanssen: yes, but it's slow
17:35:04<ac>anybody used the gd lib?
17:35:05<dcoutts>dons: yes, large ones are pinned, small ones are not
17:35:07<sjanssen>dcoutts: slower even than ForeignPtr+malloc?
17:35:08<dons>dcoutts: oh, you should look at the long thread last night tuning Ord for small bytestrings
17:35:22<dons>i got some numbers (we're way to slow for small strings currently)
17:35:23<dcoutts>dons: oh, yes I should
17:35:34<dcoutts>dons: comparing or allocating?
17:35:36<dons>this was the thread, http://hpaste.org/4922
17:35:38<dons>comparing.
17:35:47<quicksilver>so why does it not currently work this way? Because the ST/ ByteArray# wasn't good enough when the foreignptr rewrite happened?
17:35:50<dons>the problem was to take a 3M text file, and find the 20 most frequent words
17:36:06<dons>Map + ByteString or ?Hash + ByteString were find in the end, but needed non-FFI Ord
17:36:18<dcoutts>quicksilver: yes, mostly that
17:36:22<ac>I'm wondering if there's some way to retrieve a Ptr type from the Image type (doesn't mention it in the docs) so I can create arbitrary images and then do a gd operation on them
17:36:28<yav>having a version of bytestrings with ST would be useful
17:36:44<quicksilver>dons: oh, it was 20 most frequent?
17:36:48<dcoutts>yav: useful? it should not change the external api at all
17:37:10<quicksilver>dons: that's interesting. were you discarding things not in the top 20 constantly?
17:37:14<quicksilver>ah, can't do that
17:37:17<quicksilver>stupid quicksilver
17:37:23<quicksilver>ACTION fails algorithmically
17:37:28<yav>yes, but one can trust the implementation more, because it would presumable use less unsafe stuff
17:37:28<sjanssen>@slap quicksilver
17:37:29<lambdabot>ACTION places her fist firmely on quicksilver's jaw
17:37:29<dons>got to calculate the whole table, then do some fun stuff.
17:37:51<dcoutts>dons: so, the point is, there is no way at the moment to temporarily pin a bytearray# that was allocated as unpinned, however we can take advantage of the size heuristic, large ones do get pinned and small ones should be relatively cheap to copy
17:37:57<ac>there's a spurious 'e' in that slap
17:38:27<dons>dcoutts: i'd also say we need to move to non-ffi for small strings
17:38:32<byorgey>ac: good spot. submit a patch! =)
17:38:43<ac>byorgey: don't know how
17:38:51<dcoutts>dons: and all decent C libs provide a way to let the client manage memory, so accepting incoming data should not be a problem and for outgoing we can deal with large strings without copying and small strings with copying.
17:38:57<quicksilver>dcoutts: one of the interesting points made was that 99% of compares complete after comparing the first char.
17:39:04<dcoutts>quicksilver: mmm
17:39:09<quicksilver>dcoutts: and an FFI overhead to just compare the heads is painful
17:39:15<dcoutts>aye
17:39:21<quicksilver>compare (head a) (head b) is a whole lot faster
17:39:24<byorgey>ac: would you like to know how?
17:39:25<dons>i reckon it'd be safe to only do the memcmp when size>1k or so :)
17:39:31<quicksilver>99% is an informal number but I imagine you can guess what I mean
17:39:34<dons>since we can also bet on ghc getting faster
17:39:38<ac>byorgey: is slap actually built in? I figured you could change it with an @foo command or something.
17:39:52<sjanssen>dons: at that point, is it even worth the memcmp special case at all?
17:40:05<dons>sjanssen: so it definitely used to be, but we need the numbers
17:40:05<quicksilver>sjanssen: it is for 1G strings, yes :)
17:40:07<byorgey>ac: I think it's actually built in, it randomly chooses one of a number of different possible messages
17:40:13<dons>but people just don't Ord 1G strings very often!
17:40:18<quicksilver>indeed not
17:40:26<quicksilver>but they might do occasionally
17:40:31<sjanssen>quicksilver: the size of the string doesn't matter, the common prefixes do
17:40:38<quicksilver>very good point
17:40:42<quicksilver>damn I stupid this afternoon
17:40:48<quicksilver>I wonder how common a 1G common prefix is
17:40:50<sjanssen>quicksilver: how often do you compare strings with 1GB common prefixes? :P
17:40:52<quicksilver>rare, I would think.
17:40:53<dons>we need to get a better Map too. there are faster AVL trees around
17:41:09<dons>HashTable can be tuned easily, too, fwiw. and generalised tries have been toyed with
17:41:17<quicksilver>if you have 1G common prefixes you might want to consider comparing MD5 hashes instead.
17:41:21<dons>but even a specialised Trie ByteString a would be very useful
17:41:35<dcoutts>dons: indeed
17:41:37<ac>quicksilver: how could that possibly be faster?
17:41:53<ac>quicksilver: if it's just a one time thing, a simple compare would have to be faster
17:41:57<quicksilver>ac: if you compare the same 1G block more than once :)
17:42:04<quicksilver>of course if you only do it once it's daft
17:42:25<sjanssen>is that necessarily so? What about cache effects?
17:42:39<quicksilver>but normally if you're comparing big blocks it's for things like checking uniqueness of media files
17:42:42<quicksilver>or some such
17:42:47<quicksilver>and I imagine you expect to do it multiple times
17:42:57<ac>indeed
17:43:02<quicksilver>and I suppose media files occasionally do have huge common prefixes
17:43:03<quicksilver>although...
17:43:11<quicksilver>I suspec they normally have different sizes :)
17:43:19<quicksilver>large common prefixes but the same sizes should be rare
17:43:41<quicksilver>sjanssen: yeah, I agree with your initial comment. It's really not a very common case at all :)
17:45:14<dcoutts>dons: yeah, looking at compareBytes we could make some improvements
17:45:33<dcoutts>dons: eg we've got two special cases there but it's not clear they're the most likely cases
17:45:56<dcoutts>dons: eg we incur two comparisons for the case that both strings are empty (!!?)
17:46:07<dcoutts>seems an unlikely case to optimise for
17:46:36<dcoutts>so we want some stats, in "ordinary" programs that use ord, what is the most common outcome
17:46:40<dcoutts>then we optimise for that
17:47:05<dcoutts>and as people have pointed out, it's probably that they end up not-equal after comparing one byte
17:47:48<nelhage>Might it make sense to, for long strings, compare some number of bytes in haskell and then call out to FFI if they're still equal after some point?
17:47:53<dcoutts>we might keep the short-cut for comparing the same string, but move it after the initial inequality test
17:48:07<dcoutts>nelhage: probably
17:49:15<quicksilver>sjanssen: Ah. There is of course one common case for long prefix.
17:49:20<quicksilver>sjanssen: comparing a long string to itself.
17:49:33<quicksilver>which certain problems or algorithms might well involve.
17:49:57<dons>dcoutts: yep. so i've got some tests, and some different versions. so should be able to do something here
17:50:21<ac>anybody know where the darcs repository is for the gd bindings? The hackage version is giving me some sort of C compile error when I build it
17:53:21<gwern>ACTION idly wonders how long until dons writes 'Hugs considered Harmful'
17:53:26<dcoutts>heh heh
17:53:32<pejo>ac, http://code.haskell.org/gd/ perhaps?
17:53:33<lambdabot>Title: Index of /gd
17:53:46<dcoutts>it's good to have a range of working implementations
17:54:17<dcoutts>cabal support for the other implementations is important, as is making it easy to test packages with them
17:54:59<dcoutts>dons: about that, the hard part I think with gathering lots of build reports is distilling useful information out of them
17:55:33<ac>pejo: thanks. couldn't find it with Google
17:56:04<dcoutts>dons: eg trying to find out if a package "works with ghc-6.8" is not easy since there may be several reports that say it doesn't work with 6.8, though only on windows, so in fact we might still be able to conclude that it works with ghc-6.8 but it does not work on windows
17:57:02<dcoutts>dons: so we end up with samples in a multi-dimensional space of platform/environment/dependencies and we have to try and infer (with some level of confidence) useful information
17:57:45<dcoutts>dons: it seems possible but I don't know the statistical methods
18:00:01<gio123>what is deference between regular tree language and regular word language?
18:01:05<ac>gio123: I admire your persistence
18:05:44<Botje>dcoutts: perhaps you could simply say "this package worked on 86% of the ghc 6.8 installations it was tested on"
18:06:50<dcoutts>Botje: but supposing it works on only 50%, but 95% of the cases where it failed were windows, then it's much more useful to say that it works on ghc-6.8 but not on windows
18:07:15<ac>bah. darcs version is same as hackage version
18:08:08<myname>@oasis 88 70 4 223
18:08:13<Botje>dcoutts: hmm. bayesian networks spring to mind
18:08:23<lambdabot>Plugin `oeis' failed with: thread killed
18:08:59<dcoutts>Botje: I'll google for it
18:09:11<myname>@oasis 1,1,2,3,5,8
18:09:11<lambdabot>Fibonacci numbers: F(n) = F(n-1) + F(n-2), F(0) = 0, F(1) = 1, F(2) = 1, ...
18:09:12<lambdabot>[0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,1...
18:09:31<Cale>What's with all these thread killed errors lately? Is the machine on which lambdabot runs particularly busy?
18:09:38<Botje>you might get more hits with "bayesian belief networks", but they're called bayesian networks as well
18:09:43<ski_>http://worrydream.com/AlligatorEggs/ !
18:09:44<lambdabot>Title: Alligator Eggs!
18:09:49<Cale>@oeis 88 70 4 223
18:09:49<lambdabot>Plugin `oeis' failed with: Prelude.init: empty list
18:10:06<Botje>ski_: 25% of you can be replaced by half of you!
18:10:15<Cale>@oeis 4 8 15 16 23 42
18:10:15<lambdabot>The Lost Numbers.
18:10:15<lambdabot>[4,8,15,16,23,42,108]
18:10:24<dcoutts>Botje: one of the good things is that we know how all the predicates are related, it's a simple || or
18:10:32<C-Keen>Cale: what is this :)
18:10:39<ski_>@help oasis
18:10:39<lambdabot>help <command>. Ask for help for <command>. Try 'list' for all commands
18:10:41<Cale>C-Keen: those are from a TV show :)
18:10:42<dcoutts>Botje: ie if a build fails for any reason then it fails
18:10:44<ski_>@help oeis
18:10:45<lambdabot>oeis <sequence>. Look up a sequence in the Online Encyclopedia of Integer Sequences
18:11:04<Cale>@sloane 1 1 2 3 5 8
18:11:04<lambdabot>Unknown command, try @list
18:11:08<ski_>Botje : ?
18:11:11<Cale>hehe, no alias there :)
18:11:23<C-Keen>@oeis 2 5 0 1
18:11:24<lambdabot>Number of steps to reach an integer starting with n/3 and iterating the map x...
18:11:24<lambdabot>[0,2,6,0,1,1,0,5,2,0,3,2,0,1,1,0,2,4,0,3,4,0,1,1,0,22,7,0,2,5,0,1,1,0,7,2,0,4...
18:11:26<Botje>dcoutts: with bayesian networks you wouldn't have the "windows-ghc-6.8 fails so ghc6.8 fails" problem
18:11:31<Botje>but i'm off, byebye!
18:11:32<Cale>@oeis 6,11,23,47
18:11:33<lambdabot>Number of trees with n unlabeled nodes.
18:11:33<lambdabot>[1,1,1,1,2,3,6,11,23,47,106,235,551,1301,3159,7741,19320,48629,123867,317955,...
18:11:37<ski_>@oeis
18:11:38<lambdabot>Plugin `oeis' failed with: Prelude.init: empty list
18:11:38<dcoutts>borism: ta for the pointer
18:11:41<dcoutts>oops
18:11:43<ski_>bah
18:11:45<dcoutts>Botje: ta for the pointer
18:12:03<Cale>@oeis 2,5,0,1
18:12:03<lambdabot>Number of steps to reach an integer starting with n/3 and iterating the map x...
18:12:03<lambdabot>[0,2,6,0,1,1,0,5,2,0,3,2,0,1,1,0,2,4,0,3,4,0,1,1,0,22,7,0,2,5,0,1,1,0,7,2,0,4...
18:12:10<Cale>huh
18:12:17<Cale>I suppose it does occur there :)
18:12:50<ndm>@seen dcoutts
18:12:50<lambdabot>dcoutts is in #haskell-overflow, #ghc, #haskell and #gentoo-haskell. I last heard dcoutts speak 1m 6s ago.
18:12:56<dcoutts>hia ndm
18:13:03<ski_>Cale : why can't it handle the empty list ?
18:13:03<notsmack>Cale: i checked for the lost numbers a couple hours upwards :-)
18:13:06<ndm>dcoutts: if i want to acknowledge someone in a .cabal file, what field should i use?
18:13:06<lambdabot>ndm: You have 1 new message. '/msg lambdabot @messages' to read it.
18:13:09<ndm>@messages
18:13:09<lambdabot>pejo said 9m 8s ago: http://ailev.livejournal.com/544965.html, some russian dude obviously keeps track of us.
18:13:16<Cale>notsmack: hehe :)
18:13:36<dcoutts>ndm: hmm I'm not sure there is space for that unless they are author, maintainer or copyright holder
18:13:45<Cale>> lookupSequence [2,5,0,1]
18:13:47<lambdabot> Not in scope: `lookupSequence'
18:13:52<Cale>> Math.OEIS.lookupSequence [2,5,0,1]
18:13:54<lambdabot> Not in scope: `Math.OEIS.lookupSequence'
18:13:55<dcoutts>ndm: if a contribution is significant then they can become a joint copyright holder
18:13:56<Cale>huh
18:14:03<Cale>We used to have that module.
18:14:24<Cale>It's more fun than the basic @oeis command :)
18:14:24<ndm>dcoutts: i just want to say "thanks" in a .cabal file, can i use X-Thanks or something?
18:14:27<dcoutts>ndm: similarly, if it's a significant contribution then authors
18:14:42<dcoutts>ndm: you can, yes x-fields are ignored
18:14:58<dcoutts>ndm: I might just use an AUTHORS file
18:15:13<ndm>dcoutts: they didn't write anything, they just "helped"
18:15:21<dcoutts>ndm: eg we do that for gtk2hs and distinguish regular contributers from occasional or one off helpers
18:15:48<dcoutts>ndm: AUTHORS files are unstructured, you can say what you like
18:16:31<jwprox>Is the HOC (Haskell Objective-C) project dead and unusable?
18:19:48<ac>ok, now compiling gd says "Could not find module `Data.ByteString.Internal': it is a member of package bytestring-0.9.0.4, which is hidden"
18:20:22<jedbrown>Isn't IntMap a trie? I would expect a small modification would make it work for ByteString (and hence Binary).
18:20:47<dcoutts>jedbrown: in a sense I guess it is, it's a trie on the binary digits of a number
18:21:17<dcoutts>hmm, actually maybe I'm confused about that
18:21:18<jedbrown>Oh, it's bitwise, rather than byte-wise.
18:21:30<sjanssen>a ByteString map would need to be quite a bit different
18:21:32<sjanssen>s/map/trie
18:21:56<dcoutts>yes, I don't think it'd bear much obvious resemblance to an IntMap
18:22:32<BMeph>@oeis 1 1 2 4 9
18:22:33<lambdabot>Motzkin numbers: number of ways of drawing any number of nonintersecting chor...
18:22:33<lambdabot>[1,1,2,4,9,21,51,127,323,835,2188,5798,15511,41835,113634,310572,853467,23567...
18:24:58<Toxaris>can I make ghc output error messages with windows path seperators "\" instead of "/"?
18:25:12<ndm>Toxaris: no
18:25:19<ac>Toxaris: don't both work in Windows these days?
18:25:43<Toxaris>ac: my editor's tool support doesn't like them :(
18:25:49<ndm>ac: depends exactly what you are doing, in most cases, yes, in some cases, certain command line programs bork on / (i think copy springs to mine)
18:26:04<ac>lol
18:26:43<ndm>filepaths are a bit of an embarassing mess on windows
18:29:13<BMeph>Does anyone know why "cabal update" would give me:
18:29:24<BMeph>"cabal: user error (Codec.Compression.Zlib: premature end of compressed stream)"
18:31:02<Cale>BMeph: Maybe something failed to completely download?
18:31:21<Toxaris>changed the working directory so that I have a good chance that error messages are given without paths. works good enough for now.
18:31:45<ndm>Tobsan: when GHC move to using System.FilePath, the paths should snap back to being \
18:32:13<BMeph>But this is right after a re-install of GHC 6.8.2
18:32:15<ac>So how do I unhide a module?
18:32:42<Toxaris>ndm: Toxaris :) good to know. so no need for a "real solution" at my side.
18:32:55<BMeph>ac: "expose" it.
18:32:56<Toxaris>ACTION hopes for EclipseFP to become usable anyway
18:33:44<ndm>Toxaris: i don't think that might happen in the next few years though...
18:34:46<ac>the docs say that ByteString.Internal are semi public
18:35:36<ac>but GHC says thay're entirely hidden :-|
18:36:29<dcoutts>ac: I think you'll find it's just that gd is missing a dependency on the bytestring package
18:36:44<dcoutts>and since cabal builds with all other packages hidden, then ghc reports it as hidden
18:37:42<ac>ah, that problem again
18:38:01<ac>like usual, solving a build error does not involve editing code
18:38:39<BMeph>ac: It depends on whether you consider build instructions to be "code" or not. ;)
18:43:54<ac>dcoutts: well, the problem is well damn. I think I'll just upgrade to 6.8 and hope that will fix this
18:44:03<Toxaris>types and type classes share a common namespace?
18:44:44<dcoutts>ac: oh, if you're using 6.6, then yes the ByteString.Internal module does not exist
18:44:48<ac>dcoutts: the package relies on the new bytestring package, but I can't install it while it's already defined in base
18:44:55<dcoutts>ac: exactly
18:45:14<dmhouse>Toxaris: don't think so.
18:45:25<dcoutts>ac: many packages that use bytestring's internals use cpp to work with both, but gd seems not to be such
18:45:29<ac>oh well, been meaning to upgrade for a month or two
18:45:59<ac>sudo apt-get remove --purge ghc6 #!
18:47:02<byorgey>ac: seems silly to delete 6.6 before you have 6.8 installed and working...?
18:47:19<byorgey>but maybe it's too late =)
18:47:27<ac>97MB of disk space will be freed....
18:47:36<hpaste> Toxaris pasted "types and type classes share a common namespace" at http://hpaste.org/4934
18:47:43<ac>byorgey: last time I tried to install both I fucked something up and disaster ensued. That's why I went back to 6.6
18:47:50<byorgey>ah.
18:48:01<ac>byorgey: I'm sure I did something stupid, but I'm not going to take chances
18:48:34<ac>both versions were trying to use the same lib I installed
18:49:19<dmhouse>Toxaris: oh, apparently so.
18:55:08<shapr>ACTION boings furiously, with much fervor
18:56:28<kaol>yay!
18:57:00<thetallguy>what up, shapr?
18:57:25<thetallguy>What energy source produces such boinging?
18:57:39<dons>the perpetual shapr
18:57:46<thetallguy>lol
18:57:48<dons>he's clean and green!
18:58:10<dons>the future of our planet depends on harnessing shapr!
18:58:14<shapr>Actually, cognitive dissonance is producing this fervor.
18:58:17<shapr>Hah!
18:58:39<thetallguy>dons: we'll have to get adipping bird and put his head on it.
18:58:49<shapr>:-P
18:58:54<thetallguy>shapr: say it ain't so!
18:58:56<shapr>ACTION throws sticky lambdas around the channel.
18:59:05<dons>?users
18:59:05<thetallguy>shapr: not the dreaded cognitive dissonance.
18:59:06<lambdabot>Maximum users seen in #haskell: 444, currently: 426 (95.9%), active: 17 (4.0%)
18:59:17<dons>444. i wonder if we'll get 500 by year's end
18:59:25<thetallguy>eww
18:59:26<dons>which seems insane :)
18:59:33<shapr>This is the boinging of frustration. While you may be able to write FORTRAN in any language, I cannot write Haskell in any language.
18:59:39<dons>heh
18:59:56<thetallguy>dons: why? out of all the math classes in all the world...
19:00:12<shapr>For one thing, you can't efficiently reverse a string char by char in a strict language.
19:00:19<thetallguy>shapr: what's the target of frustration?
19:00:22<shapr>C#
19:00:47<thetallguy>shapr: can you write to the cells of the string?
19:01:12<shapr>Oh, I'm figuring it out, it's just that my brain's current native languages are emacs + haskell.
19:01:28<thetallguy>swap i (length -i)
19:01:36<BMeph>Strict languages are inefficient, because they always eat up space and time on unneeded calculations... ;)
19:01:43<thetallguy>shapr: understood
19:02:06<thetallguy>shapr: there's a scene in RoboCop II that you would empathize with think
19:02:45<thetallguy>shapr: one cop/robot hybrid is so distraught it just rips it's own head off.
19:03:04<thetallguy>shapr:felt that way many times.
19:06:27<byorgey>shapr: don't rip your head off though.
19:07:38<ac>an interesting way to commit suicide I think... it would require a fair amount of preparation
19:07:59<byorgey>hm, wasn't there an xkcd about this?
19:08:39<ac>probably. I haven't read them all yet. Just the earliest and most recent ones
19:12:36<Saul_>I have this function of type Applicable f => (t -> f (a -> b)) -> (t1 -> f a) -> t -> t1 -> f b, but I was wondering if I could write it so that I can apply it more than once
19:14:09<Saul_>It basically combines to functions into a function that takes both inputs and applies the first to the second (and after lifting to applicative)
19:14:20<Saul_>s/to/two
19:15:32<Saul_>Do I make sense at all?
19:16:00<Toxaris>:t \f g x y -> f x <*> g y -- Saul_ are you talking about this one?
19:16:03<lambdabot>forall t t1 (f :: * -> *) a b. (Applicative f) => (t -> f (a -> b)) -> (t1 -> f a) -> t -> t1 -> f b
19:17:25<Saul_>Toxaris: Yes
19:17:44<Toxaris>Saul_: what do you mean by "apply it more then once"?
19:18:55<Saul_>Well if the first input is of type t -> f (a -> b -> c), I want to be able to get a f c at the end
19:20:00<Toxaris>so it should be \f g h x y z -> f x <*> g y <*> h z in this case?
19:20:16<Saul_>yes
19:20:52<Toxaris>i don't think this is easily possible in Haskell
19:21:24<ac>I think it's rather nifty how "darcs pull" simply pulls from the last repository you pulled from
19:21:35<Saul_>that's too bad
19:21:47<Toxaris>Saul_: it may be possible with some type hackery, but wouldn't it be easier just to use <*> and <$> and so on?
19:21:54<byorgey>@type \fs xs -> foldl (<*>) (pure id) (zipWith ($) fs xs)
19:21:56<lambdabot> Ambiguous occurrence `pure'
19:21:56<lambdabot> It could refer to either `pure', imported from Control.Applicative
19:21:56<lambdabot> or `pure', imported from Control.Arrow
19:22:07<byorgey>@type \fs xs -> foldl (<*>) (Control.Applicative.pure id) (zipWith ($) fs xs)
19:22:08<lambdabot> Occurs check: cannot construct the infinite type: b = a -> b
19:22:08<lambdabot> Expected type: f (a -> b) -> f a -> f (a -> b)
19:22:08<lambdabot> Inferred type: f (a -> b) -> f a -> f b
19:22:28<byorgey>oh, right, can't fold <*> since the intermediate types all have to be the same
19:23:01<Saul_>Toxaris: I'm not sure how
19:23:43<byorgey>i.e. write out f x <*> g y <*> h z explicitly instead of using a higher-order function
19:24:03<Toxaris>Saul_: well, just use (f x <*> g y) instead of (foo f g x y) and (f x <*> g y <*> h z) instead of (foo f g h x y z).
19:24:29<Toxaris>Saul_: I assume that at the caller of foo knows the type of f, g and h.
19:24:39<Toxaris>Saul_: (foo is the function you hope to define)
19:28:05<Saul_>The problem then is that I can't separate the construction of the function and using it
19:29:55<Toxaris>I don't understand what you mean?
19:30:07<Toxaris>construction of which function.
19:31:36<Toxaris>let foo = f x <*> g y in ... foo <*> h z ... should work fine
19:32:39<Saul_>Ok I'll try that
19:33:10<hpaste> visof pasted "help" at http://hpaste.org/4935
19:33:38<visof>what is the wrong for this code?
19:34:26<Toxaris>visof: no need to use map here
19:35:44<Toxaris>> let foo x | Char.isUpper x = Char.toLower x | otherwise = Char.toUpper x in map foo "abcABC"
19:35:48<lambdabot> "ABCabc"
19:35:59<Toxaris>visof: alternative formulation using Char.isUpper and guards :)
19:36:03<visof>oh thanks
19:36:12<Toxaris>visof: but your's should work too. try it!
19:37:02<ac>can darcs do file permissions? Like for example make certain files you checkout be executable?
19:37:17<ac>er, I should say "pull" instead of "checkout"
19:37:18<mauke>not really
19:37:46<ac>it would be nice if all the Setup.hs files were already executable :P
19:38:05<mauke>--set-scripts-executable
19:38:17<ac>ah, nice
19:38:43<BMeph>visof: you're trying to use x as both a Char and a [Char], in your example.
19:39:52<visof>BMeph so what should i do?
19:40:05<dons>?users
19:40:06<lambdabot>Maximum users seen in #haskell: 444, currently: 430 (96.8%), active: 14 (3.3%)
19:41:15<bringert>when do you want Hac in Gothenburg? http://www.haskell.org/haskellwiki/Hac_2008/Dates
19:41:17<lambdabot>Title: Hac 2008/Dates - HaskellWiki
19:41:55<gwern>wow, ContArrow is *broken*. the hackage package doesn't even have the source files in it
19:42:10<bringert>nominolo: I don't see your name on http://www.haskell.org/haskellwiki/Hac_2008/Dates
19:42:24<ac>why are Setup.hs scripts taking so much longer to run than I remember?
19:42:47<BMeph>ACTION waits to read the best-selling book, "Broken ContArrow"
19:45:04<BMeph>visof: Just be consistent with how you're using your function arguments. :)
19:45:50<gwern>ACTION emails the ContArrow author
19:47:19<opqdonut>contarrow?
19:47:24<opqdonut>@go contarrow
19:47:25<lambdabot>http://hackage.haskell.org/packages/archive/pkg-list.html
19:47:49<ac>seriously, Setup configure is taking several minutes
19:47:56<dcoutts>that's odd
19:48:13<dcoutts>ac: configuring what package?
19:48:49<dcoutts>(unless it's Cabal itself in which case it's expected since it'd be interpreting all the Cabal code)
19:49:02<ac>dcoutts: zlib
19:49:08<dcoutts>hmm
19:49:28<dcoutts>ac: if you run with -v where is it getting stuck?
19:50:24<ac>dcoutts: not seeing anything
19:50:27<BMeph>Hey, dcoutts, do you know why cabal wouldn't be able to read a package?
19:50:48<ac>doh
19:50:56<ac>dcoutts: there was no #! line
19:51:04<dcoutts>BMeph: you mean like some parse error?
19:51:06<dcoutts>ac: :-)
19:51:22<dcoutts>ac: most don't, use runghc Setup configure, or better yet install cabal-install
19:51:27<BMeph>Specifically, I downloaded alex, and did "cabal info" on it; where it should state the packages is blank.
19:51:43<ac>dcoutts: working on it! ;)
19:52:00<BMeph>"These packages would be installed:
19:52:02<ac>hence why zlib, and next http
19:52:06<BMeph>"
19:52:08<dcoutts>ac: ah :-)
19:52:47<dcoutts>BMeph: cabal info is a bit of a misnomer at the moment, it's like cabal install but just says what would be installed, and you specified no packages and it said it'd install none :-)
19:52:59<dcoutts>BMeph: it's a UI issue really, feel free to report a bug
19:54:46<BMeph>Okay, because if I do that in a directory without a dist subdir, it complains about that.
19:55:27<BMeph>Oh, good, it's doing the "cabal: Data.ByteString.Lazy.index: index too large: 0" thing again. :p
19:55:55<dcoutts>BMeph: the dist thing is a bug in an older version of Cabal, use 1.2.3
19:56:19<dcoutts>BMeph: when do you get that bug? is it if the index fails to download or something?
19:56:20<qweqwe>pref::[a]->Int->Int->[[a]]
19:56:20<qweqwe>pref [] _ _ = [[]]
19:56:20<qweqwe>pref xs i len = if(i<len) then (take i xs):(pref xs (i+1) len)
19:56:20<qweqwe> else [take i xs]
19:56:37<qweqwe>why at the else is should be [take]
19:56:38<qweqwe>?
19:56:40<BMeph>I just did "cabal info alex"
19:57:14<qweqwe>when i do take num xs i already get [numbers]
19:57:17<gwern>excellent. now MissingH and ConfigFile should be fixed on Hackage soon
19:57:59<dcoutts>BMeph: can you try: ls -l $HOME/.cabal/ and see if the index file is empty?
19:58:07<BMeph>qweqwe: pref returns a list of lists at the end.
19:58:28<qweqwe>yes
19:58:44<BMeph>Aha - "ls: $HOME/.cabal/: No such file or directory"
19:58:53<qweqwe>i am confused why at one place it with[] and after that without
19:59:07<mauke>qweqwe: look at the type of (:)
19:59:28<dcoutts>BMeph: hmm, I would have expected that it'd tell you that the index does not exist rather than that error message
19:59:32<Toxaris>qweqwe: you can write "else (take i xs) : []" instead of "[take i xs]", then the two cases look more similar
19:59:44<dcoutts>BMeph: I'd recommend using the latest version of cabal-install rather than the one from hackage
19:59:45<BMeph>qweqwe: when you use take without the [], you're cons-ing it to another list-of-lists.
19:59:59<dcoutts>BMeph: you can cabal update to download the package index
20:00:35<qweqwe>ahh now i got you
20:01:28<BMeph>dcoutts: No, I get "cabal: user error (Codec.Compression.Zlib: premature end of compressed stream)" when I try it.
20:01:57<dcoutts>BMeph: sounds like the index is not getting downloaded correctly
20:02:28<dcoutts>BMeph: does the $HOME/.cabal dir exist with the downloaded index in it yet? (under packages/)
20:02:42<dcoutts>BMeph: it downloads the index file then uncompresses it
20:02:43<ac>when will cabal-install automatically pull things out of VCSs? ;)
20:02:57<qweqwe>how i can check the type of ":" ?
20:03:04<int-e>@type (:)
20:03:05<ac>:t (:)
20:03:07<dcoutts>ac: when someone designs a spec for describing VCSs in the .cabal file
20:03:07<lambdabot>forall a. a -> [a] -> [a]
20:03:07<lambdabot>forall a. a -> [a] -> [a]
20:03:20<ac>dcoutts: yeah, I remember talking about that a while back
20:03:40<ac>qweqwe: you turn operators in to prefix functions by wrapping them in parens
20:04:12<ac>qweqwe: and the reverse (turning prefix functions in to binary operators by wrapping them in ticks, like "1 `add` 2"
20:04:37<BMeph>dcoutts: Hm, maybe it's just a Windows thing... :(
20:04:44<ac>qweqwe: excuse my bad example, as add is not in the std libs
20:05:01<dcoutts>BMeph: ah, you definitely need the latest version of cabal-install if you're working on windows
20:05:16<qweqwe>ac: how i can check the type of ":" ?
20:05:20<dcoutts>BMeph: since yes, there were some issues with windows line endings in earlier versions
20:05:25<notsmack>@type (:)
20:05:26<lambdabot>forall a. a -> [a] -> [a]
20:05:27<opqdonut>@hoogle a -> [a] -> [a]
20:05:28<lambdabot>Data.List.intersperse :: a -> [a] -> [a]
20:05:28<lambdabot>Prelude.scanl :: (a -> b -> a) -> a -> [b] -> [a]
20:05:28<lambdabot>Prelude.scanr :: (a -> b -> b) -> b -> [a] -> [b]
20:05:29<ac>qweqwe: that was answered twice a few lines above
20:05:52<ac>qweqwe: ":t (:)" in ghci, "@type (:)" in #haskell
20:06:04<dcoutts>BMeph: I fixed them and tested it on windows, but that's only in the development version
20:06:18<BMeph>dcoutts: So, where is the newest cabal-install, if it isn't on Hackage yet?
20:06:31<dcoutts>BMeph: darcs.haskell.org/cabal-install
20:06:44<dcoutts>it depends on the development version of Cabal too
20:06:51<BMeph>Well, the newest *working* version... ;)
20:06:55<dcoutts>which is in darcs.haskell.org/cabal
20:07:08<qweqwe>@type (:)
20:07:12<lambdabot>forall a. a -> [a] -> [a]
20:07:23<qweqwe>@type :
20:07:24<lambdabot>parse error on input `:'
20:07:45<dcoutts>BMeph: the reason it's not on hackage yet is because it depends on the dev version of the Cabal lib which we're not ready to release just yet
20:07:48<ac>qweqwe: it simply takes a head and a tail and returns the tail list with the head at the beginning. @type expects a function, not an operator
20:08:19<notsmack>> (:) 3 [4,5]
20:08:20<lambdabot> [3,4,5]
20:08:40<ac>> (:[4,5]) 3
20:08:41<lambdabot> [3,4,5]
20:09:03<ac>> (3:) [4,5] -- :P
20:09:04<lambdabot> [3,4,5]
20:09:11<BMeph>Okay, that makes sense. I guess this is similar to the problem with getting readline to work on Windows, too, eh?
20:09:34<ac>> flip (:3) [4,5] :-PP
20:09:35<lambdabot> Not in scope: data constructor `PP'
20:09:38<ac>> flip (:3) [4,5] -- :-PP
20:09:39<lambdabot> Couldn't match expected type `b -> c' against inferred type `[a]'
20:09:42<ac>damn.
20:10:05<ac>> flip (:3) $ [4,5]
20:10:06<lambdabot> Couldn't match expected type `a -> c' against inferred type `[a1]'
20:10:18<int-e>@type (:3)
20:10:18<lambdabot>forall a. (Num [a]) => a -> [a]
20:10:33<ac>guess you can't flip that can you
20:10:38<int-e>> flip (:) [4,5] 3
20:10:40<lambdabot> [3,4,5]
20:10:53<ac>ACTION feels silly
20:11:21<kaol>> (++[3]) [4,5]
20:11:21<lambdabot> [4,5,3]
20:11:25<int-e>ac, you can flip (:), but you can't retroactively flip the (:) inside the (:3) application (which is equivalent to (flip (:) 3) or (\x -> x:3))
20:11:36<ac>int-e: yeah I know, I'm just tired
20:13:12<ac>qweqwe: make sense?
20:14:17<amaron>anything similar to python's: random.shuffle(list)
20:14:32<wolverian>perldoc -q shuffle
20:15:03<mauke>haha
20:15:16<amaron>in haskell...
20:15:33<ac>amaron: how about "sortBy randomlist list"?
20:15:43<jsnx>amaron: you have to do the schwatzian transform yourself, i think
20:15:56<mauke>@where oleg
20:15:57<lambdabot>http://okmij.org/ftp/
20:16:06<ac>I bet everyone's going to tell me why that's bad now
20:16:18<mauke>http://okmij.org/ftp/Haskell/#perfect-shuffle
20:16:19<lambdabot>Title: Haskell Programming: Miscellanea
20:16:25<Toxaris>ac: there is a nice article showing why it is bad
20:16:41<ac>not to mention it doesn't fit the type signature
20:16:44<jsnx>knuth has a whole big thing about this
20:17:05<jsnx>in volume 1
20:17:05<jsnx>it is a nice algorithm, but imperative
20:17:08<jsnx>lolz, i am lagged
20:17:34<BMeph>jsnx: Heh-heh, lagged cat is lagged. ;)
20:18:52<ac>map snd (sortBy fst (zipWith randlist list))
20:18:58<ac>that's more like what I meant
20:19:09<ac>er, s/zipWith/zip/
20:19:17<Toxaris>ac: what is "randlist"?
20:19:25<ac>a list of random numbers ;)
20:19:32<Toxaris>ac: like [0, 0, 0]?
20:19:39<IvdSange1>isn;t that in a Monad?
20:20:38<ac>IvdSange1: randlist you mean?
20:21:09<hpaste> psykon pasted "ghc-pkg list" at http://hpaste.org/4937
20:21:15<ac>Toxaris: those don't look random to me ;)
20:21:25<Toxaris>ac: well they are as random as every other list :)
20:21:29<Toxaris>ac: but that's not the point.
20:21:40<Cale>IvdSange1: You just need a supply of "random" numbers which you can treat as a parameter. Alternately, you can explicitly pass around the state for a pseudorandom number generator.
20:21:58<Cale>IvdSangen: Of course, you can construct a monad to take care of that for you.
20:22:39<ac>Toxaris: please disregaurd my obtuseness
20:22:50<Toxaris>ac: ?
20:22:57<IvdSangen>ofcourse we could be in a monad without seeing it in the type of this function, as it can be composed with return
20:23:28<IvdSangen>so forgive my stupid remark ;)
20:24:10<Toxaris>ac: do you mean sortBy (comparing fst)?
20:25:30<ac>Toxaris: yeah
20:26:17<ac>Toxaris: I'm think I'm being obtuse by missing the entire point of amaron's question
20:27:07<Toxaris>ac: what does "obtuse" mean?
20:27:48<ac>Toxaris: "dull; stupid;" ... not pointed or acute, blunt
20:27:50<Toxaris>ACTION looked it up and feels like it for not doing that earlier
20:28:07<notsmack>@wn obtuse
20:28:07<lambdabot>*** "obtuse" wn "WordNet (r) 2.0"
20:28:08<lambdabot>obtuse
20:28:10<lambdabot> adj 1: of an angle; between 90 and 180 degrees [ant: {acute}]
20:28:12<lambdabot> 2: of a leaf shape; rounded at the apex
20:28:14<lambdabot> 3: lacking in insight or discernment; "too obtuse to grasp the
20:28:16<lambdabot>[11 @more lines]
20:29:09<Toxaris>nice. \bot knows everything :)
20:29:43<ac>blaaarg: $ cabal install gd ... "Could not find module `Data.ByteString.Base'"
20:30:08<ac>What's with this ByteString nonsense?
20:30:22<shachaf>ac: That's the old bytestring.
20:30:44<ac>bbbut gd requires the new bytestring
20:30:58<gwern>the hackage one apparently doesn't
20:30:59<shachaf>ac: Hmm, `cabal install gd` seems to work for me.
20:31:12<gwern>(ditto)
20:31:13<ac>I'm cursed
20:31:15<shachaf>GHC 6.9.20080101.
20:31:57<gwern>@where Util.Digraph
20:31:57<lambdabot>I know nothing about util.digraph.
20:32:46<shachaf>@go util.digraph
20:32:47<lambdabot>http://www.augustsson.net/Darcs/Djinn/Util/Digraph.hs
20:33:30<gwern>figures
20:33:33<reteP>Hello: I'm new to Haskell and need to implement the Robinson Unification Algorithm (puh). Does anyone know "resources" on how to do this with Haskell?
20:34:03<byorgey>ac: did you do a 'cabal update' first?
20:34:12<ac>for me the darcs version dies with "Graphics/GD.hsc:340:11: Not in scope: `B.toForeignPtr'" and the hackage version dies with the error above
20:34:25<byorgey>reteP: what's that?
20:34:54<reteP>Do you mean my nick? Or the Robinson Unification Algorithm? ;-)
20:35:14<ac>byorgey: no... thanks!
20:35:27<shachaf>> reverse "Robinson Unification Algorithm"
20:35:28<byorgey>reteP: I meant the Robinson Unification Algorithm =)
20:35:31<lambdabot> "mhtiroglA noitacifinU nosniboR"
20:35:35<reteP>:-)
20:35:45<byorgey>> sort "Robinson Unification Algorithm"
20:35:45<lambdabot> " ARUabcfghiiiiilmnnnnoooorstt"
20:36:03<byorgey>ac: dunno if that's the problem but it's worth a try =)
20:36:03<ac>lol
20:36:07<ac>byorgey: it worked
20:36:11<byorgey>=D
20:36:15<shachaf>> unify "Robinson Unification Algorithm"
20:36:16<lambdabot> "reteP"
20:36:16<ac>byorgey: hence my enthusiastic thanks
20:36:19<reteP>Well...do some Prolog with Haskell...
20:36:36<EvilTerran>use the type system! :D
20:36:45<jsnx>reteP: how?
20:36:56<EvilTerran>@go "Robinson Unification Algorithm"
20:36:56<lambdabot>http://www.cs.rpi.edu/~freems/proj3/Unification_and_Variables.htm
20:36:56<lambdabot>Title: Unification and Variables
20:37:22<reteP>Found tons of stuff that use monands...@lambdabot: thx, I'll check it out...
20:37:27<reteP>monads...
20:38:03<jsnx>EvilTerran: thank you
20:38:06<qweqwe>i have a problem writing the type of that function
20:38:20<qweqwe>map (\f->f.f)[(\x->x+1),(\x->x+2)]
20:38:32<mauke>:t map (\f->f.f)[(\x->x+1),(\x->x+2)]
20:38:32<lambdabot>forall c. (Num c) => [c -> c]
20:38:35<ac>qweqwe: gawd put some spaces in there
20:38:53<EvilTerran>:t map (join (.)) [(+1), (+2)]
20:38:54<lambdabot>forall b. (Num b) => [b -> b]
20:38:54<patperry>does anyone have any tips on debugging stack overflows? I'm not sure what to look for in the ghc profiler output
20:38:54<opqdonut>:D
20:39:12<EvilTerran>qweqwe, sections are rather handy here
20:39:38<reteP>@lambdabot: well, that's about Prolog...thx anyway
20:39:38<lambdabot>Unknown command, try @list
20:40:04<shachaf>> sequence (map (join (.) [(+1),(+2)]) 5
20:40:04<lambdabot>Unbalanced parentheses
20:40:12<qweqwe>@list
20:40:12<lambdabot>http://www.cse.unsw.edu.au/~dons/lambdabot/COMMANDS
20:40:36<EvilTerran>reteP, lambdabot is a bot...
20:40:37<shachaf>> sequence (map (join (.)) [(+1),(+2)]) 5
20:40:37<lambdabot> [7,9]
20:40:46<ddarius>She hides it well
20:40:49<EvilTerran>@vixen how are you today?
20:40:49<lambdabot>i'm good, you?
20:40:53<shachaf>ACTION is a bot.
20:40:55<byorgey>reteP: maybe this is useful? http://web.engr.oregonstate.edu/~erwig/HaskellRules/
20:40:55<lambdabot>Title: Haskell Rules: Embedding Rule Systems in Haskell
20:41:42<reteP>Thx byorgey..I'll look at that
20:41:46<Toxaris>lambdabot is a shachaf.
20:42:13<shachaf>@babel he en שחף
20:42:13<lambdabot>Plugin `babel' failed with: Error: Language he not supported
20:42:54<ac>@src Ptr
20:42:54<lambdabot>data Ptr a = Ptr Addr#
20:43:02<ac>what the heck does "Addr#" mean?
20:43:15<qweqwe>but (\f->f.f) doesn"t it mean envoke a function twice on the [] ?
20:43:23<qweqwe>map (\f->f.f)[(\x->x+1),(\x->x+2)]
20:43:30<shachaf>qweqwe: On its argument.
20:43:33<byorgey>patperry: maybe start here? http://haskell.org/haskellwiki/Stack_overflow
20:43:39<shachaf>> (\f -> f . f) (+1) 5
20:43:39<lambdabot> 7
20:44:01<byorgey>patperry: there's various info on various pages in the wiki, you might have to poke around a bit =)
20:44:01<shachaf>> (\f x -> f (f x)) (+1) 5
20:44:02<lambdabot> 7
20:44:44<ac>@pl (\f x -> f (f x)) (+1) 5
20:44:45<lambdabot>7
20:44:51<ac>@pl (\f x -> f (f x))
20:44:52<lambdabot>join (.)
20:45:03<ac>:t join
20:45:04<lambdabot>forall (m :: * -> *) a. (Monad m) => m (m a) -> m a
20:45:12<qweqwe>thanks
20:45:18<patperry>byorgey: thanks for the pointer. I'll look around
20:45:21<amaron>ac: your shuffle worked well, tnx
20:45:28<ac>> join (.) (+1) 5
20:45:29<lambdabot> 7
20:45:38<EvilTerran>?type join :: (a -> a -> b) -> a -> b
20:45:39<lambdabot>forall a b. (a -> a -> b) -> a -> b
20:45:42<shachaf>ac: join f x = f x x, in (r ->).
20:45:47<ac>amaron: oh, I thought I was missing the point of your question ;)
20:46:03<Toxaris>shachaf: my xchat has serious problems with hebrew text. שחף is reversed when selected :(
20:46:36<shachaf>Toxaris: It's reversed for me too, in irssi/urxvt. :-)
20:46:55<visof>@src (:)
20:46:55<lambdabot>Source not found. I've seen penguins that can type better than that.
20:47:01<visof>@src cons
20:47:01<lambdabot>Source not found. Where did you learn to type?
20:47:04<ac>amaron: just make sure that precision of your random list corresponds to the number of elements you're shuffling
20:47:24<ac>amaron: otherwise you end up with only a subset of possible shufflings
20:47:34<Toxaris>shachaf: and what does it mean?
20:47:44<shachaf>Toxaris: "Seagull".
20:47:46<EvilTerran>@erc []
20:47:46<lambdabot>Maybe you meant: rc src
20:47:59<EvilTerran>@src []
20:47:59<lambdabot>data [] a = [] | a : [a]
20:48:02<EvilTerran>@help rc
20:48:03<lambdabot>rc name. Read a file of commands (asynchonously). FIXME: better name.
20:49:34<visof>i have function and i want to simplify it, can anyone help me?
20:49:48<Toxaris>shachaf: nice name.
20:49:50<EvilTerran>@paste
20:49:51<lambdabot>Haskell pastebin: http://hpaste.org/new
20:49:54<opqdonut>paste it somewhere
20:49:55<opqdonut>yep
20:50:00<patperry>is that a way to get a stack trace prior to a stack overflow?
20:50:07<opqdonut>and use @pl, @undo and others
20:50:39<ddarius>There are two ways.
20:51:37<hpaste> visof pasted "simplify it" at http://hpaste.org/4938
20:52:26<shachaf>visof: Well, (,,) tuples are a little hard to do much with @pl-ly.
20:52:26<Cale>visof: I doubt you're going to find anything simpler than that.
20:52:33<shachaf>visof: Is that not simple enough?
20:52:35<patperry>typo; is *there* a way to get a stack trace prior to overflow?
20:52:37<opqdonut>yeh that's pretty nice
20:52:51<opqdonut>you can of course shorten and obfuscate it :P
20:53:03<Cale>If it was a function on lists, rather than a function of three parameters returning a tuple, then there would be a nice way to generalise it.
20:53:15<opqdonut>Cale: indeed
20:53:21<ac>amaron: meaning, if your randlist is a list of bools, and you have more than two in your list, it's not a random shuffling
20:53:46<Cale>foo [] = []; foo (x:xs) = map (x ++) (x:xs)
20:53:50<visof>Cale how can we generalise it for any number of arguments
20:54:01<visof>ok
20:54:07<Cale>You can't. But you can write what I just wrote.
20:55:25<Cale>> let foo [] = []; foo (x:xs) = map (x ++) (x:xs) in foo ["hello","there","world"]
20:55:27<lambdabot> ["hellohello","hellothere","helloworld"]
20:57:44<nominolo>bringert: k. seems like any date is fine for the great majority
20:58:07<shachaf>Cale: Is there a nice way to write that without the [] special-case?
20:58:20<sclv_>ac: even if you only have two it's a pretty awful shuffle.
20:58:49<Cale>shachaf: Well, you could use head.
20:59:02<Cale>> let foo xs = map (head xs ++) xs in foo []
20:59:04<lambdabot> []
20:59:26<Cale>I just don't like head and tail all that much :)
21:00:47<Toxaris>> liftM3 (,,) (++ a) (++ b) (++ c) a ("hello", "there", "world")
21:00:48<lambdabot> Not in scope: `a'
21:01:01<Toxaris>> \(a, b, c) -> liftM3 (,,) (++ a) (++ b) (++ c) a $ ("hello", "there", "world")
21:01:01<lambdabot> Couldn't match expected type `a -> b'
21:01:02<Cale>It's just slightly less obvious that it's safe.
21:01:18<Toxaris>> (\(a, b, c) -> liftM3 (,,) (++ a) (++ b) (++ c) a) ("hello", "there", "world")
21:01:19<lambdabot> ("hellohello","hellothere","helloworld")
21:01:25<ac>sclv_: no it's not... there are only two options... reverse it or not reverse the list. They're both equally likely
21:01:34<Toxaris>ACTION obfuscated it a bit
21:01:52<shachaf>Toxaris: The arguments weren't in a tuple.
21:01:55<visof>ok Cale can we do this for 3-case let me show you what is 3-case mean
21:02:07<qweqwe>i still get error on it
21:02:18<qweqwe>lfunc:: (Num a) => [a -> a]
21:02:18<qweqwe>lfunc f xs = map (\f->f.f)[(\x->x+1),(\x->x+2)]
21:02:20<shachaf>@pl \a b c -> liftM3 (,,) (++a) (++b) (++c) a
21:02:20<lambdabot>flip =<< (flip .) . flip flip (flip (++)) . ((.) .) . (. flip (++)) . liftM3 (,,) . flip (++)
21:02:28<visof>the arguments in the last example is a b c right
21:02:44<visof>then the result take the form aa , ab , ac
21:02:47<shachaf>@pl \a b c -> (a ++ a, a ++ b, a ++ c)
21:02:47<lambdabot>ap (flip . ((.) .) . ap ((.) . (,,) . join (++)) (++)) (++)
21:03:14<ac>sclv_: [0,0], [0,1], [1,0], [1,1]... nevermind you're right. It's a 3/4 it won't get reversed
21:03:17<visof>i want the result take this form abc , bca , ..........
21:03:39<ac>sclv_: depending on the sorting algorithm I guess
21:03:40<Cale>qweqwe: The type you've given appears wrong...
21:03:43<shachaf>qweqwe: lfunc is a function that takes f and xs.
21:03:57<visof>Cale do you understand what i mean?
21:03:57<qweqwe>ok
21:04:02<shachaf>@ty let lfunc :: (Num a) => (a -> a) -> [a] -> [a -> a]; lfunc f xs = map (\f->f.f)[(\x->x+1),(\x->x+2)] in lfunc
21:04:02<lambdabot>forall a. (Num a) => (a -> a) -> [a] -> [a -> a]
21:04:13<Cale>qweqwe: That says that lfunc is a list of functions [a -> a] where a is some numeric type.
21:04:32<ac>sclv_: is that what you meant?
21:04:52<Cale>visof: You want all permutations of a list?
21:05:01<visof>ya
21:05:06<sclv_>ac: yep
21:05:16<qweqwe>shachaf : i still have error there
21:05:42<Cale>visof: Okay. So probably the best way to start is to think recursively. It's easy to get the list of permutations of the empty list, it's just [[]]
21:05:58<sclv_>you need a range large enough that collisions are statistically very improbable.
21:06:06<Cale>visof: So if your list is (x:xs), what are the permutations of that, in terms of the permutations of xs?
21:06:30<ac>visof: is this a homework problem?
21:06:42<Cale>ac: no, he's learning Haskell on his own.
21:06:52<visof>ac yep
21:06:54<ac>ah, it sounded like a classic ;)
21:07:15<visof>Cale what do you mean?
21:07:28<visof>Cale simply
21:08:15<Cale>Well, one way is to take x and insert it in each possible place in each permutation of xs.
21:08:30<visof>ya
21:09:17<Cale>So you might start out by writing the function which takes a value x, and a list xs, and produces the list of lists resulting from inserting x into each place.
21:09:20<Cale>For example:
21:09:39<visof>x ++ fst (xs) ++ fst ( snd xs).........
21:09:42<Cale>insertions 'a' "xxx" = ["axxx","xaxx","xxax","xxxa"]
21:09:58<visof>ya
21:10:00<Cale>fst and snd apply to pairs, not lists
21:10:09<visof>ok
21:10:15<shachaf>Are you thinking of car and cdr? :-)
21:10:31<notsmack>(and ++ applies to lists, not the individual 'x')
21:10:36<ski_>(when i figured out how to systematically enumerate permutations (by hand), i used the selection method .. i wonder if that's more common ?)
21:10:55<Cale>Selection is actually probably better in Haskell.
21:12:14<Cale>visof: Another way you can break down the problem is to pick some element y from your nonempty list xs (in all possible ways), and then pick a permutation ys of the remaining elements, and the resulting permutation is y:ys
21:12:48<Cale>(you can use a list comprehension to do that nicely)
21:13:25<Cale>You'll need a function select, which takes a list, and returns a list of pairs consisting of an element of the list, together with the remainder of the elements:
21:14:04<Cale>select "abcd" = [('a',"bcd"), ('b',"acd"), ('c',"abd"), ('d',"abc")]
21:14:26<Cale>(it should be in the list library, but it is not)
21:14:39<Cale>select [] = []
21:15:24<Cale>select (x:xs) = (x,xs) : [(y,x:ys) | (y,ys) <- select xs]
21:16:17<visof>insertions way is good for me
21:16:46<Cale>Okay, take a shot at that and let us know if you need more help.
21:17:16<visof>Cale ok , thanks
21:20:02<qweqwe>what is wrong here ?
21:20:03<qweqwe>takefirsthalf::[a]->[a]
21:20:04<qweqwe>takefirsthalf [] = []
21:20:04<qweqwe>takefirsthalf xs = take ((length xs)/2) xs
21:20:17<qweqwe>Instance of Fractional Int required for definition of takefirsthalf
21:20:35<mauke>qweqwe: / doesn't work on ints
21:20:46<seydar>div to the rescue!
21:20:56<qweqwe>:)
21:21:00<mauke>you don't need the first equation
21:21:20<qweqwe>do you know any other elegant way to do it ?
21:21:32<opqdonut>not really
21:24:45<Cale>I can think of a semi-elegant way.
21:25:31<qweqwe>shoot
21:25:58<Cale>takeEveryOther [] = []; takeEveryOther [x] = []; takeEveryOther (x:y:xs) = x : takeEveryOther xs; takeFirstHalf xs = map fst (zip xs (takeEveryOther xs))
21:26:20<Cale>At least it doesn't involve computing the length, and it operates lazily.
21:26:39<Cale>Or if you prefer,
21:26:48<EvilTerran>ACTION tends to call that "evens", and the dual "odds"
21:26:55<Cale>takeFirstHalf xs = zipWith const xs (takeEveryOther xs)
21:27:11<EvilTerran>evens [] = []; evens (x:xs) = x : odds xs; odds [] = []; odds (x:xs) = evens xs
21:27:35<EvilTerran>Cale, ooh, cunning
21:28:04<roconnor>takeFirstHalf xs = let {helper [] _ = []; helper (_:_:ys) (z:zs) = z:(helper ys zs)} in helper xs xs
21:28:34<roconnor>hmm, not quite right
21:28:52<roconnor>needs helper [_] _ = [] as well
21:29:25<EvilTerran>and it works on infinite lists, unlike take.(`div`2)=<<length
21:30:38<qweqwe>any idea how i can take the secound half ?
21:31:17<EvilTerran>well, that'd be _|_ for infinite lists anyway, so the `div` version would work
21:31:25<EvilTerran>although there may be a better way of doing it
21:31:25<roconnor>now I'd be tempted to splitAt (length l `div` 2)
21:31:34<Toxaris>> let half xs = map fst . zip xs . takeWhile (not . null) . iterate (drop 2) $ xs in half "abcdef"
21:31:37<lambdabot> "abc"
21:31:54<EvilTerran>yeah, if you always want both, that (roconnor's)'s probably better
21:31:59<hpaste> (anonymous) annotated "no proxy" with "(no title)" at http://hpaste.org/4939#a1
21:33:10<EvilTerran>firstHalf xs = zipWith const xs (evens xs); secondHalf xs = foldr (const tail) xs (odds xs)
21:33:42<EvilTerran>(using evens in one and odds in the other so the middle element doesn't end up in both)
21:33:49<EvilTerran>(in the case of an odd-length list)
21:34:17<EvilTerran>@let evens [] = []; evens (x:xs) = x : odds xs; odds [] = []; odds (x:xs) = evens xs
21:34:21<lambdabot>Defined.
21:35:00<EvilTerran>@let firstHalf xs = zipWith const xs (odds xs); secondHalf xs = foldr (const tail) xs (evens xs)
21:35:01<lambdabot>Defined.
21:35:12<EvilTerran>> firstHalf &&& secondHalf $ "testing"
21:35:14<lambdabot> ("tes","ing")
21:35:21<EvilTerran>huh.
21:35:34<EvilTerran>> evens &&& odds $ "testing"
21:35:35<lambdabot> ("tsig","etn")
21:35:38<sarah__>&&&?
21:35:44<kmcallister>:t &&&
21:35:45<shachaf>sarah__: From Control.Arrow.
21:35:45<lambdabot>parse error on input `&&&'
21:35:47<kmcallister>:t (&&&)
21:35:48<lambdabot>forall (a :: * -> * -> *) b c c'. (Arrow a) => a b c -> a b c' -> a b (c, c')
21:35:57<resiak>\ a:b:c:d:... -> ([a,c,...],[b,d,...]) doesn't have a standard name, does it?
21:36:08<shachaf>(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
21:36:10<shachaf>In (->).
21:36:18<EvilTerran>(&&&) :: Arrow (~>) => (a ~> b) -> (a ~> c) -> (a ~> (b,c))
21:36:31<EvilTerran>resiak, no
21:36:48<EvilTerran>i call it halve, myself (and phrase it much like evens/odds above)
21:37:01<resiak>yeah, i was just writing a 'halve' funciton :)
21:37:33<EvilTerran>@let halve [] = []; halve (x:xs) = (x:zs,ys) where (ys,zs) = halve xs
21:37:46<lambdabot>Couldn't match expected type `[a]' against inferred type `(a1, b)'
21:37:54<EvilTerran>@let halve [] = ([],[]); halve (x:xs) = (x:zs,ys) where (ys,zs) = halve xs
21:37:55<lambdabot>Defined.
21:38:00<EvilTerran>> halve "testing"
21:38:00<lambdabot> ("tsig","etn")
21:38:17<EvilTerran>@check liftM2 (==) (evens &&& odds) halve
21:38:18<lambdabot> Add a type signature
21:38:23<EvilTerran>@check liftM2 (==) (evens &&& odds) halve :: [Int] -> Bool
21:38:23<lambdabot> OK, passed 500 tests.
21:38:39<Heffalump>(map fst *** map fst) . partition even . zip [0..]
21:38:56<Heffalump>IM map snd, not map fst. And even might need a definition or to be (==0) . (`mod` 2)
21:39:02<shachaf>Heffalump: Probably (cycle [0,1]) is better.
21:39:09<shachaf>Heffalump: The numbers would get big eventually. :-)
21:39:16<Heffalump>cycle [True, False] then
21:39:21<Heffalump>this isn't C, you know
21:39:43<shachaf>Heffalump: I was leaving the rest as it was. :-)
21:39:51<seydar>what does 'inferred type `m Float' ' mean?
21:40:01<resiak>hrm, d'oh, i actually want a list of pairs not a pair of lists
21:40:07<Toxaris>> (foldr (.) id . zipWith ($) (cycle [first, second]) . map (:)) "abcdefghijklm" ([], [])
21:40:08<lambdabot> ("acegikm","bdfhjl")
21:40:09<EvilTerran>join (***) (map snd) . partition (even.fst) . zip (cycle [True,False]) -- =]
21:40:09<shachaf>seydar: That the type that was inferred was "m Float"?
21:40:16<Heffalump>zip IYF...
21:40:17<shachaf>seydar: Perhaps you can give more context.
21:40:20<seydar>no, what is m float?
21:40:25<resiak>true.
21:40:41<shachaf>seydar: m is probably a Monad.
21:40:50<EvilTerran>resiak, what do you want exactly?
21:41:00<shachaf>seydar: So it's something like [Float], Maybe Float, IO Float.
21:41:07<EvilTerran>[1,2,3,4,5] -> [(1,2),(3,4)]?
21:41:08<Heffalump>how many Oxford students does it take to split a list?
21:41:11<seydar>ooh
21:41:17<resiak>heh
21:41:38<resiak>EvilTerran: yeah, thinking about it. it's obviously trivial to write, but i kind of hoped it had a name :)
21:42:07<EvilTerran>> evens . (zip `ap` drop 1) $ "testing"
21:42:08<lambdabot> [('t','e'),('s','t'),('i','n')]
21:42:16<EvilTerran>there you go :D
21:42:18<seydar>shachaf: if i have a recursive function, and use return as a base case, will it just drop out?
21:42:33<EvilTerran>... that's not what return means in haskell
21:42:35<EvilTerran>?type return
21:42:36<lambdabot>forall a (m :: * -> *). (Monad m) => a -> m a
21:42:37<shachaf>seydar: return doesn't do what you think it does.
21:42:52<Heffalump>seydar: no.
21:42:54<seydar>that would explain the funky error
21:43:01<resiak>I'm still amazed that whileM :: [m Bool] -> m (); whileM (a:as) = x <- a; when x $ whileM as doesn't have a name
21:43:02<mauke>seydar: return is a virtual constructor
21:43:18<seydar>im scared now
21:43:28<shachaf>seydar: It "wraps" a value in a monad.
21:43:28<EvilTerran>mauke, i'm sure a line like that'll make it much clearer ;P
21:43:30<shachaf>seydar: Why?
21:43:34<shachaf>> return 1 :: [Int]
21:43:34<lambdabot> [1]
21:43:36<shachaf>> return 1 :: Maybe Int
21:43:37<lambdabot> Just 1
21:43:43<shachaf>> return 1 :: IO Int
21:43:44<lambdabot> <IO Int>
21:43:45<idnar>@pl whileM (a:as) = x <- a; when x $ whileM as
21:43:46<lambdabot>(line 1, column 23):
21:43:46<lambdabot>unexpected ";"
21:43:46<lambdabot>expecting letter or digit, variable, "(", "`", "!!", ".", operator or end of input
21:43:59<EvilTerran>idnar, @pl can't do pattern-matching
21:44:01<EvilTerran>iirc
21:44:10<EvilTerran>er... multiple cases, i mean
21:44:15<seydar>hold me! I dont want to die!
21:44:20<EvilTerran>?type foldM
21:44:21<shachaf>@. pl undo whileM (a:as) = x <- a; when x $ whileM as
21:44:21<lambdabot>forall a b (m :: * -> *). (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
21:44:21<lambdabot>Parse error at "=" (column 15)
21:44:23<idnar>isn't that just one case?
21:44:30<resiak>@pl f (a:as) = a >>= flip when (f as)
21:44:30<lambdabot>f = fix ((`ap` tail) . (. head) . flip ((.) . (>>=)) . (flip when .))
21:44:33<resiak>aii
21:44:34<idnar>@pl f a = a
21:44:34<lambdabot>f = id
21:44:40<shachaf>@. pl undo whileM (a:as) = do { x <- a; when x $ whileM as }
21:44:40<lambdabot>whileM = fix ((`ap` tail) . (. head) . flip ((.) . (>>=)) . (flip when .))
21:44:53<EvilTerran>idnar, ah, ignore me. sorry, the missing "do" made me think the bit after the ; was another case
21:44:55<EvilTerran>DO NOT WANT
21:44:58<idnar>heh
21:45:04<idnar>I didn't even know you could do that
21:45:13<shachaf>idnar: Do what?
21:45:13<EvilTerran>?type let whileM (a:as) = x <- a; when x $ whileM as in whileM
21:45:18<lambdabot>parse error on input `<-'
21:45:22<EvilTerran>?type let whileM (a:as) = do x <- a; when x $ whileM as in whileM
21:45:23<lambdabot>forall (m :: * -> *). (Monad m) => [m Bool] -> m ()
21:45:36<idnar>shachaf: well, wouldn't there normally be a do {} around that?
21:45:42<shachaf>idnar: Yes.
21:45:46<r3m0t>@unpl \x -> x
21:45:46<lambdabot>\ x -> x
21:45:53<r3m0t>@unpl \x y -> y
21:45:54<lambdabot>\ x y -> y
21:46:07<EvilTerran>?src when
21:46:07<lambdabot>when p s = if p then s else return ()
21:46:11<shachaf>idnar: resiak also didn't include the (Monad m) =>; that was meant for humans to parse.
21:46:16<r3m0t>@pl \x y -> y
21:46:16<lambdabot>const id
21:46:27<r3m0t>@pl \x y -> (==x).(!!y)
21:46:27<lambdabot>(. flip (!!)) . (.) . (==)
21:46:29<idnar>shachaf: oh, right, I see
21:46:33<EvilTerran>?type foldM when (return ())
21:46:34<lambdabot> Couldn't match expected type `Bool' against inferred type `()'
21:46:34<lambdabot> Expected type: Bool -> m () -> m Bool
21:46:34<lambdabot> Inferred type: Bool -> m () -> m ()
21:46:40<EvilTerran>?type foldM when
21:46:41<lambdabot> Couldn't match expected type `Bool' against inferred type `()'
21:46:41<lambdabot> Expected type: Bool -> m () -> m Bool
21:46:41<lambdabot> Inferred type: Bool -> m () -> m ()
21:46:45<EvilTerran>?type foldM (flip when)
21:46:46<lambdabot> Couldn't match expected type `m ()' against inferred type `()'
21:46:46<lambdabot> Expected type: m () -> Bool -> m (m ())
21:46:46<lambdabot> Inferred type: m () -> Bool -> m ()
21:46:50<EvilTerran>...
21:46:50<idnar>@src foldM
21:46:51<lambdabot>foldM _ a [] = return a
21:46:51<lambdabot>foldM f a (x:xs) = f a x >>= \fax -> foldM f fax xs
21:46:58<shachaf>@ty foldM
21:46:58<lambdabot>forall a b (m :: * -> *). (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
21:46:59<shachaf>@ty when
21:47:00<lambdabot>forall (m :: * -> *). (Monad m) => Bool -> m () -> m ()
21:47:11<idnar>@undo whileM (a:as) = do { x <- a; when x $ whileM as }
21:47:12<lambdabot>whileM (a : as) = a >>= \ x -> when x $ whileM as
21:47:43<r3m0t>@pl \y -> (==x).(!!y)
21:47:44<lambdabot>((x ==) .) . flip (!!)
21:49:09<idnar>hmm
21:49:21<resiak>hrm, or i can just do the termination before monadifying the list :)
21:49:31<idnar>@type foldM
21:49:31<lambdabot>forall a b (m :: * -> *). (Monad m) => (a -> b -> m a) -> a -> [b] -> m a
21:49:40<idnar>@type when
21:49:40<lambdabot>forall (m :: * -> *). (Monad m) => Bool -> m () -> m ()
21:51:10<EvilTerran>ACTION determines that foldM isn't suitable
21:52:13<idnar>oh, shachaf just did those two
21:52:17<idnar>man, I can't read tonight
21:53:08<idnar>@type foldr
21:53:08<lambdabot>forall a b. (a -> b -> b) -> b -> [a] -> b
21:53:20<Saizan>we lack a lot of truly monadic combinators, most of Control.Monad is applicative..
21:53:39<idnar>@type foldr1
21:53:40<lambdabot>forall a. (a -> a -> a) -> [a] -> a
21:54:04<idnar>@type foldr when (return ())
21:54:05<lambdabot>forall (m :: * -> *). (Monad m) => [Bool] -> m ()
21:54:27<idnar>@type liftM when
21:54:27<lambdabot>forall (m :: * -> *) (m1 :: * -> *). (Monad m, Monad m1) => m1 Bool -> m1 (m () -> m ())
21:55:33<idnar>@. pl undo \mx a b -> { x <- mx; when x a b }
21:55:34<lambdabot>Parse error at "{" (column 12)
21:55:45<EvilTerran>do
21:55:51<idnar>@. pl undo \mx a b -> do { x <- mx; when x a b }
21:55:51<lambdabot>(. (flip . flip when)) . (.) . (>>=)
21:55:53<EvilTerran>?type foldr (\m x -> do p <- m; when p x) (return ())
21:55:55<lambdabot>forall (t :: * -> *). (Monad t) => [t Bool] -> t ()
21:56:07<idnar>success?
21:56:13<hpaste> patperry pasted "memory leak" at http://hpaste.org/4940
21:56:15<EvilTerran>ugly success, but i think so
21:56:28<patperry>can someone tell me why this leaks memory, and how to fix it?
21:56:31<resiak>a-ha!
21:56:34<idnar>@undo \mx a b -> do { x <- mx; when x a b }
21:56:34<lambdabot>\ mx a b -> mx >>= \ x -> when x a b
21:56:56<idnar>it seems like there should be some nicer way to do that
21:57:11<resiak>it does
21:57:19<EvilTerran>the difficulty is when's first parameter not being monadic
21:57:21<resiak>it's only meant to model C's 'break' statement
21:57:23<trofimovich>@q how to build you with GHC-6.8.2?
21:57:23<lambdabot>Maybe you meant: quit quote . ? @ v
21:57:42<EvilTerran>if that weren't the case, it'd just be foldr when (return ()), i think
21:57:59<idnar>hmm
21:58:10<EvilTerran>?type (\m x -> do p <- m; when p x)
21:58:11<lambdabot>forall (t :: * -> *). (Monad t) => t Bool -> t () -> t ()
21:58:19<EvilTerran>?type liftM2 when
21:58:19<lambdabot>forall (m :: * -> *) (m1 :: * -> *). (Monad m, Monad m1) => m1 Bool -> m1 (m ()) -> m1 (m ())
21:58:30<EvilTerran>?type join . liftM2 when
21:58:30<lambdabot> Occurs check: cannot construct the infinite type:
21:58:30<lambdabot> m = (->) (m (m1 ()))
21:58:30<lambdabot> Probable cause: `liftM2' is applied to too many arguments
21:58:33<EvilTerran>hm
21:58:40<EvilTerran>?type (join .) . liftM2 when
21:58:41<lambdabot>forall (m :: * -> *). (Monad m) => m Bool -> m (m ()) -> m ()
21:58:52<EvilTerran>?type (join .) . liftM when
21:58:53<lambdabot> Occurs check: cannot construct the infinite type: m = (->) (m ())
21:58:53<lambdabot> Probable cause: `liftM' is applied to too many arguments
21:58:53<lambdabot> In the second argument of `(.)', namely `liftM when'
21:59:09<EvilTerran>?type (join .) . liftM2 when . (. return)
21:59:09<lambdabot>forall a (m :: * -> *). (Monad m) => (m a -> Bool) -> (a -> a -> ()) -> a -> ()
21:59:13<EvilTerran>er
21:59:21<EvilTerran>?type (join .) . (. return) . liftM2 when
21:59:21<lambdabot>forall (m :: * -> *). (Monad m) => m Bool -> m () -> m ()
21:59:26<EvilTerran>hehe
22:00:42<seydar>how do I do do an if then statement and match an empty list?
22:00:52<seydar>ie, if x == []
22:00:55<trofimovich>can someone share patches for lambdabot and ghc-6.8.x? thanks!
22:01:26<Toxaris>> null []
22:01:28<lambdabot> True
22:01:53<Toxaris>> seydar: either use null, or (imho better) use case instead of if
22:01:53<lambdabot> Parse error at "case" (column 47)
22:01:58<idnar>@let whileM (a:as) = do { x <- a; when x $ whileM as } in runWriter $ whileM [tell '1' >> return True, tell '2' >> return False, tell '3' >> return True]
22:01:58<lambdabot> Parse error
22:02:02<idnar>> let whileM (a:as) = do { x <- a; when x $ whileM as } in runWriter $ whileM [tell '1' >> return True, tell '2' >> return False, tell '3' >> return True]
22:02:02<lambdabot> add an instance declaration for (Monoid Char)
22:02:07<idnar>oops
22:02:09<idnar>too much Python
22:02:32<seydar>Toxaris: but how do I do it in an if-then?
22:02:41<seydar>in ruby, I can use ===
22:03:17<idnar>> let whileM (a:as) = do { x <- a; when x $ whileM as } in runWriter $ whileM [tell [1] >> return True, tell [2] >> return False, tell [3] >> return True]
22:03:17<lambdabot> ((),[1,2])
22:03:25<Toxaris>> let x = [] in if null x then "seydar: as I said, use null" else "will not be choosen"
22:03:25<allbery_b>if null xs then ...
22:03:26<lambdabot> "seydar: as I said, use null"
22:03:37<idnar>> let whileM foldr (\m x -> do p <- m; when p x) (return ()) in runWriter $ whileM [tell [1] >> return True, tell [2] >> return False, tell [3] >> return True]
22:03:37<lambdabot> Parse error at "in" (column 60)
22:03:45<idnar>> let whileM = foldr (\m x -> do p <- m; when p x) (return ()) in runWriter $ whileM [tell [1] >> return True, tell [2] >> return False, tell [3] >> return True]
22:03:46<lambdabot> ((),[1,2])
22:04:00<idnar>(ok, I'm done)
22:04:06<seydar>lambdabot: but didn't it throw an error for you?
22:04:40<allbery_b>ACTION is confused
22:04:47<allbery_b>throw what error?
22:04:55<seydar>Parse error at "case" (column 47)
22:04:58<Toxaris>seydar: lambdabot is just a bot, I made her answer to you by the line starting with "> ". other people made her throw an error. unkind people they are.
22:05:07<Saizan>trofimovich: mux linked me this patch http://mu.org/~mux/lambdabot-ghc-6.8.2.patch
22:05:11<seydar>ok
22:05:17<EvilTerran>> let whileM = foldr ((join.) . (.return) . liftM2 when) (return ()) in runWriter . whileM . map (tell.return &&& return) $ [(1,True),(2,True),(3,False),(4,True)]
22:05:18<lambdabot> Couldn't match expected type `Bool' against inferred type `m a'
22:05:23<seydar> so its if null xs then ....
22:05:24<EvilTerran>oh, never mind
22:05:28<trofimovich>Saizan: thanks !
22:05:44<EvilTerran>> let whileM = foldr ((join.) . (.return) . liftM2 when) (return ()) in runWriter . whileM . map (uncurry(>>).(tell.return &&& return)) $ [(1,True),(2,True),(3,False),(4,True)]
22:05:44<lambdabot> Couldn't match expected type `Bool' against inferred type `(a, b)'
22:05:45<Saizan>trofimovich: you also need latest darcs version of hs-plugins
22:05:51<EvilTerran>arghblahblahblah
22:05:52<trofimovich>i know
22:05:56<EvilTerran>@src null
22:05:57<lambdabot>null [] = True
22:05:57<lambdabot>null (_:_) = False
22:06:04<trofimovich>i've already built them
22:06:31<Saizan>from this? http://code.haskell.org/~dons/code/hs-plugins
22:06:31<lambdabot>Title: Index of /~dons/code/hs-plugins
22:06:53<seydar>Toxaris: so how do I test if a function returns a [] ?
22:06:58<dmwit>null [] = True; null _ = False -- save 8 characters! collect the whole set
22:07:08<shachaf>seydar: With null?
22:07:26<trofimovich>i'm afraid no
22:07:29<idnar>dmwit: heehee
22:07:37<seydar>i tested it with ' if null (function)
22:07:46<Toxaris>seydar: if null (f 42) then ..., assuming f is a function from numbers to lists
22:08:22<r3m0t>@src null.tail
22:08:22<lambdabot>Source not found. This mission is too important for me to allow you to jeopardize it.
22:08:25<seydar>it is. but that throws me an error
22:08:32<r3m0t>> (null.tail) [5]
22:08:36<lambdabot> True
22:08:44<r3m0t>ACTION could have used that a while ago
22:09:11<trofimovich>Saizan: "http://www.cse.unsw.edu.au/~dons/code/hs-plugins" - used this stuff (a little patched to make it build)
22:09:12<dmwit>r3m0t: It's dangerous, though.
22:09:13<lambdabot>Title: Index of /~dons/code/hs-plugins
22:09:24<seydar>"if null (findMin (filter (< f) rest)) " throws me an error from the depths of hell
22:09:31<dmwit>> (null.tail) []
22:09:32<lambdabot> Exception: Prelude.tail: empty list
22:09:42<Toxaris>> (null . drop 1) []
22:09:43<lambdabot> True
22:09:59<seydar>what does the . do?
22:10:01<dmwit>seydar: You need some "then" and "else" clauses, at least. ;-)
22:10:02<r3m0t>dmwit: not in my case it wasn't
22:10:11<dmwit>seydar: function composition
22:10:27<seydar>dmwit: i have them, but didn't want to paste it all here
22:10:31<dmwit>:t findMin
22:10:33<seydar>if null (findMin (filter (< f) rest)) []
22:10:33<seydar> then f
22:10:33<seydar> else findMin (filter (< f) rest)
22:10:36<lambdabot>Not in scope: `findMin'
22:10:48<r3m0t>@src minimum
22:10:48<lambdabot>minimum [] = undefined
22:10:48<lambdabot>minimum xs = foldl1 min xs
22:10:57<seydar>NOOOOOO
22:10:57<dmwit>Oh, there's your problem, that's not well-typed!
22:10:59<seydar>don't tell me!
22:11:18<seydar>but where was my typing error?
22:11:38<dmwit>findMin doesn't return a list, probably
22:11:55<Toxaris>seydar: the parens are wrong?
22:12:01<dmwit>Also, null doesn't take two arguments.
22:12:09<Toxaris>seydar: if null (...) [] then :(
22:12:22<Toxaris>seydar: you want if null (... []) then instead
22:13:00<dmwit>But, this function has very strange semantics.
22:13:27<dmwit>if null rest then f else minimum rest -- simpler, and probably does the same thing
22:13:41<Toxaris>seydar: but what you really want is (findMin (f : rest))
22:14:19<dmwit>yes
22:14:36<dmwit>Toxaris: cute! =)
22:16:17<Toxaris>> let foo atLeast = minimum . (atLeast :) in foo 5 [27, 42]
22:16:18<lambdabot> 5
22:16:26<Toxaris>> let foo atLeast = minimum . (atLeast :) in foo 5 [3, 1, 4, 1, 5]
22:16:27<lambdabot> 1
22:17:35<dmwit>> let foo = (minimum .) . (:) in foo 5 []
22:17:36<lambdabot> 5
22:18:48<trofimovich>@version
22:18:49<lambdabot>lambdabot 4p581, GHC 6.6 (Linux i686 2.40GHz)
22:18:49<lambdabot>darcs get http://code.haskell.org/lambdabot
22:21:50<Toxaris>> let foo atLeast = foldl' min atLeast in (foo 5 [27, 42], foo 5 [3, 1, 4, 1]
22:21:51<lambdabot>Unbalanced parentheses
22:21:54<Toxaris>> let foo atLeast = foldl' min atLeast in (foo 5 [27, 42], foo 5 [3, 1, 4, 1])
22:21:55<lambdabot> (5,1)
22:22:46<Toxaris>dmwit, seydar: that's how you would do it in c, just initialize the result variable for the minimum loop with the lower bound
22:22:46<trofimovich>@karma+ Saizan
22:22:46<lambdabot>Saizan's karma raised to 8.
22:23:12<seydar>turns out foldl is very smart
22:23:18<seydar>and i fixed my problem!
22:26:35<hpaste> (anonymous) pasted "(no title)" at http://hpaste.org/4941
22:26:38<dmwit>> 252. / 228
22:26:39<lambdabot> Parse error at "/" (column 6)
22:26:46<dmwit>> 252.0 / 228
22:26:48<lambdabot> 1.105263157894737
22:26:51<Corun>Er, oops, didn't mean to paste that, sorry
22:27:57<dmwit>> 228 / 252
22:27:58<lambdabot> 0.9047619047619048
22:29:02<psykon>guys, an haskell-scriptable irc client?
22:29:31<dmwit>nope
22:29:59<psykon>is that "nope" for me and meaning one does not exist?
22:30:30<dmwit>The nope is for you, and it means I don't know of any such thing.
22:30:45<psykon>ok, thanks
22:31:28<dmwit>Although a quick search on haskell.org comes up with hircules.
22:31:41<psykon>i want a curses one
22:31:50<r3m0t>I want a haskell pony
22:32:01<psykon>:)
22:32:17<dmwit>Ponies poop.
22:32:58<psykon>so one of you write one, pretty please :)
22:33:05<Nafai>dmwit: But if it were a Haskell pony, that poop would have to be wrapped in a Monad...isn't poop a side effect?
22:33:13<Nafai>ACTION knows he is going to regret saying that
22:33:42<lucca>no, it's the output. the growing pony is the side effect
22:33:44<dmwit>pony :: Food -> (Transportation, Poop)
22:34:10<Nafai>Dang it. You guys are right. It's always a type error.
22:34:34<resiak>type Pony = WriterT [Poop] IO ?
22:34:55<Cin>ACTION pokes psykon
22:35:09<psykon>ACTION glances around nervously
22:35:13<Nafai>r3m0t, dmwit: Look what you started
22:35:53<psykon>Cin: so, you know they'll kill you if they find you here?
22:36:00<r3m0t>Nafai: apologies
22:36:07<Cin>psykon: the SS?
22:36:16<Cin>i better start a diary
22:36:39<psykon>if SS means Scheme Security or something
22:36:40<dmwit>:t lookup
22:36:42<lambdabot>forall a b. (Eq a) => a -> [(a, b)] -> Maybe b
22:36:49<dmwit>:t maybe
22:36:50<lambdabot>forall b a. b -> (a -> b) -> Maybe a -> b
22:37:20<Cin>psykon: i thought you were an agent. they're in the walls
22:37:21<dmwit>?hoogle a -> Maybe a -> a
22:37:22<lambdabot>Data.Maybe.fromMaybe :: a -> Maybe a -> a
22:37:22<lambdabot>Prelude.maybe :: b -> (a -> b) -> Maybe a -> b
22:37:22<lambdabot>Data.Maybe.maybe :: b -> (a -> b) -> Maybe a -> b
22:38:31<psykon>Cin: i'll just modify the source *BAM* no more wall
22:38:57<Cin>ghc --make kungFu -o neo
22:39:00<dmwit>> let f x = fromMaybe x . lookup x . zip "aeiou" $ "eeoua" in map f "ping"
22:39:03<lambdabot> "pong"
22:39:07<dmwit>> let f x = fromMaybe x . lookup x . zip "aeiou" $ "eeoua" in map f "poke"
22:39:08<lambdabot> "puke"
22:39:27<Cin>lol
22:41:20<dmwit>> let f x = fromMaybe x . lookup x $ zip "aiou" "ioua" in map f "poke" -- more readable
22:41:23<lambdabot> "puke"
22:41:30<r3m0t>@src lookup
22:41:31<lambdabot>lookup _key [] = Nothing
22:41:31<lambdabot>lookup key ((x,y):xys) | key == x = Just y
22:41:31<lambdabot> | otherwise = lookup key xys
22:41:46<r3m0t>ACTION could have used that today
22:42:03<dmwit>You seem to say that a lot. =P
22:42:22<dmwit>Maybe you should have a look through the Prelude.
22:42:49<r3m0t>I did, just before the exam ;-)
22:42:53<dmwit>heh
22:43:19<r3m0t>but we haven't even done Maybe... it could look a bit lame
22:46:21<EvilTerran>@index lookup
22:46:21<lambdabot>Data.HashTable, Data.IntMap, Data.Map, Data.List, Prelude
22:46:47<EvilTerran>r3m0t, are you sure you didn't do Maybe, at least in passing? i'm sure we did...
22:47:21<r3m0t>EvilTerran: we most certainly did not
22:47:26<EvilTerran>weird.
22:47:47<EvilTerran>do you have another course of FP next term?
22:47:48<r3m0t>woah, we did
22:47:52<dmwit>EvilTerran: He may mean Maybe the module, not Maybe the type constructor.
22:48:05<EvilTerran>r3m0t, changing your mind? :P
22:48:13<r3m0t>yes, I grepped the notes
22:48:42<dmwit>The notes... are in a greppable form?
22:48:50<dmwit>...you are doing a class in Haskell?
22:48:51<EvilTerran>hehe. ISTR it was at least mentioned as an example when we did Functors in my year
22:48:51<r3m0t>yes, postscript and .lhs
22:48:57<dmwit>ACTION is jealous
22:49:18<dmwit>ACTION is doing a class in Java D=
22:49:19<EvilTerran>dmwit, he's a first-year at ox.ac.uk; i'm a second-year, which is why i know what the heck he's on about ;)
22:49:29<dmwit>EvilTerran: hehe
22:49:49<r3m0t>but as dmwit said, we didn't see any of the functions such as fromJust
22:49:51<resiak>suddenly Heffalump's joke makes even more sense
22:50:01<EvilTerran>don't worry, he'll have to do java next year. and between now and then, there'll be oberon, too
22:50:05<dmwit>?quote
22:50:05<lambdabot>newsham says: over here in america we take people with all sorts of names (except mohammed)
22:50:12<r3m0t>yum (!)
22:50:16<dmwit>?quote Heffalump
22:50:17<lambdabot>Heffalump says: docs aren't all that useful, generally
22:50:19<EvilTerran>being the evil bastard child of pascal
22:50:21<dmwit>?quote Heffalump
22:50:22<lambdabot>Heffalump says: CPP leads to suffering
22:50:25<dmwit>?quote Heffalump
22:50:26<lambdabot>Heffalump says: CPP leads to suffering
22:50:39<dmwit>Suffer, mortals!
22:50:53<EvilTerran>(via Modula)
22:51:23<resiak>(namely "how many Oxford students does it take to split a list?")
22:51:40<EvilTerran>yeah, i figured that's what you were referring to. he's a research student here, iirc.
22:51:44<dmwit>resiak: aha =)
22:51:51<Toxaris>> fmap fmap fmap fmap fmap fmap fmap fmap Char.toUpper [(1, "hello"), (2, "world")] -- r3m0t what about that one (in the context of association lists...)?
22:51:53<lambdabot> [(1,"HELLO"),(2,"WORLD")]
22:52:05<EvilTerran>wow.
22:53:00<r3m0t>Toxaris: oh shit...
22:53:05<dmwit>:t fmap fmap fmap fmap fmap fmap fmap fmap
22:53:07<lambdabot>forall (f :: * -> *) (f1 :: * -> *) a b (f2 :: * -> *). (Functor f, Functor f1, Functor f2) => (a -> b) -> f (f1 (f2 a)) -> f (f1 (f2 b))
22:53:30<resiak>EvilTerran: not any more
22:53:38<r3m0t>ACTION made another mistake in the exam, probably
22:53:40<EvilTerran>okay
22:53:45<dmwit>ACTION tries to resist saying "fap fap fap fap fap"
22:53:55<r3m0t>dmwit--
22:53:56<Cale>dmwit: You fail it!
22:54:03<r3m0t>@karma dmwit--
22:54:03<lambdabot>dmwit-- has a karma of 0
22:54:16<dmwit>?karma
22:54:17<lambdabot>You have a karma of 0
22:54:18<EvilTerran>ACTION notes that some of those fmaps are (.)s - that's one of my favourite obfuscation tricks, too
22:54:36<r3m0t>why would anybody obfuscate haskell
22:54:45<r3m0t>lambdabot can do it himself
22:54:48<Toxaris>yep, these fmaps are (.), map and second
22:54:48<EvilTerran>?type foldr1 ($) (relicate 8 fmap)
22:54:49<lambdabot>Not in scope: `relicate'
22:54:52<EvilTerran>?type foldr1 ($) (replicate 8 fmap)
22:54:53<lambdabot> Occurs check: cannot construct the infinite type: a = a -> b
22:54:53<lambdabot> Probable cause: `$' is applied to too many arguments
22:54:53<lambdabot> In the first argument of `foldr1', namely `($)'
22:54:57<r3m0t>@src elem
22:54:58<lambdabot>elem x = any (== x)
22:55:00<dmwit>r3m0t: *herself*
22:55:04<EvilTerran>hm. needs moar higher-order types
22:55:15<r3m0t>@pl \x -> any (==x)
22:55:15<lambdabot>any . (==)
22:55:22<Toxaris>EvilTerran: lists doesn't work that way, you know, this isn't Java...
22:55:23<EvilTerran>s/order/rank/, or whatever.
22:55:28<r3m0t>@pl \x -> not.null.filter.(==x)
22:55:29<lambdabot>((not . null . filter) .) . (==)
22:55:49<r3m0t>dmwit: herself
22:55:50<EvilTerran>Toxaris, as i said, i think i could make it work with RankNTypes
22:56:13<EvilTerran>although i'd have to wrap the fmaps in a constructor
22:56:55<Toxaris>EvilTerran: I don't think so. can one occurence of fmap in an Haskell expression belong to multiple Functor instances?
22:57:57<monochrom>f x = fmap x
22:58:12<monochrom>That "one" occurrence of fmap belongs to multiple Functor instances. :)
22:58:29<monochrom>(OK OK! I'm just kidding!)
22:58:32<opqdonut>:D
22:58:33<Toxaris>monochrom: not at once :)
22:58:46<ddarius>Toxaris: Yes.
22:58:56<ddarius>Depending on what you mean by "at the same time"
22:59:38<monochrom>(Turn off monomorphism restriction in the following.) let f = fmap in (f id (Just True), f id [True]). Does that work?
22:59:49<dmwit>ddarius: Can a list of fmaps refer to different Functor instances?
23:00:17<monochrom>If that doesn't work, add a higher-rank signature to f.
23:01:40<monochrom>Oh! List. I'll think about it.
23:01:52<ddarius>dmwit: There might be a way (to do what you meant to say), but I'm not sure if it would work.
23:02:14<Toxaris>monochrom: it should work, but it's not what I meant
23:03:09<Toxaris>monochrom: but I'm not sure how to say exactly what I mean :(
23:05:38<ddarius>Jaynes being dead is rather inconvenient.
23:08:34<opqdonut>jaynes?
23:09:14<ddarius>@google e.t.jaynes
23:09:15<lambdabot>http://bayes.wustl.edu/etj/etj.html
23:09:15<lambdabot>Title: Edwin Thompson Jaynes - July 5, 1922 - April 30, 1998
23:11:44<grahamhutton>@users
23:11:44<lambdabot>Maximum users seen in #haskell: 444, currently: 415 (93.5%), active: 12 (2.9%)
23:15:32<thetallguy>@users
23:15:32<lambdabot>Maximum users seen in #haskell: 444, currently: 416 (93.7%), active: 14 (3.4%)
23:15:50<thetallguy>active increased by 2.
23:16:04<thetallguy>me and the bot, I suppose
23:17:25<EvilTerran>> 416 - 415
23:17:27<lambdabot> 1
23:17:59<grahamhutton>hi clifford!
23:18:06<opqdonut>:D:D
23:18:40<dmwit>> 14 - 12
23:18:41<lambdabot> 2
23:19:49<hpaste> monochrom pasted "a list of fmaps" at http://hpaste.org/4943
23:21:05<EvilTerran>monochrom, i thought [forall f a b. ...] wasn't allowed?
23:21:13<thetallguy>hi graham!
23:21:27<thetallguy>grahamhutton: how's it going?
23:21:50<monochrom>Everything is allowed. Only trouble is can you code up non-trivial values.
23:22:01<grahamhutton>it's getting late here, but going ok. (we had dinner at ICFP in Freiburg)
23:22:28<EvilTerran>monochrom, i mean, i thought you weren't allowed to use a forall.ed type as a parameter to a tycon
23:22:50<EvilTerran>what am I thinking of?
23:23:17<monochrom>I vaguely recall something like that. But I don't know either way. Anyway, the computer is happy with it now, and I'm happy too.
23:23:28<EvilTerran>indeed
23:24:16<thetallguy>grahamhutton: I remember. I can't say I remember vividly, what with all the wine...
23:24:32<grahamhutton>indeed; very nice hare too... :-)
23:24:50<monochrom>ghc 6.6.1 likes it too. would be a long time ago when it was rejected.
23:24:55<gwern>ET Jaynes, presumably
23:25:01<thetallguy>grahamhutton: yes, that was a good meal. I can't remember who it was who picked the restaurant
23:25:24<grahamhutton>peter thiemann - the local organiser
23:25:30<visof>> foo [] = 0; let foo (x:xs) = x in foo [1,2,3]
23:25:30<lambdabot> Parse error at "=" (column 8)
23:25:34<thetallguy>grahamhutton: apparently some FP/foodie came into town two weeks earlier and helped Peter identify some place
23:25:40<Cin>> concat $ transpose ["igttepio,igttermd"," o h osn o h eey"]
23:25:41<lambdabot> "i got the poison, i got the remedy"
23:25:56<thetallguy>grahamhutton: I think Jerzy told me that.
23:26:00<r3m0t>Cin: ...why?
23:26:20<thetallguy>grahamhutton: I'm enjoying the worker/wrapper stuff, by the way, a little bit at a time.
23:26:27<Cin>list practise
23:27:20<grahamhutton>that's great to hear -- we had a lot of fun working on this paper. the final version will be out soon, quite a bit revised from the version currently on the web.
23:27:23<visof>> foo [] = 0 ; let foo (x:xs) = x in foo [1,2,3]
23:27:24<lambdabot> Parse error at "=" (column 8)
23:27:38<visof>what's the wrong?
23:28:11<EvilTerran>"let"
23:28:16<dmwit>> let foo [] = 0; foo (x:xs) = x in foo [1,2,3]
23:28:17<allbery_b>visof: misplaced let
23:28:17<lambdabot> 1
23:28:30<visof>oh
23:28:34<visof>ok
23:29:27<grahamhutton>the whole w/w business has opened up a whole vista of new ideas...
23:32:45<gwern>by a funny coincidence, I received my copy of his Probability book yesterday
23:32:48<monochrom>EvilTerran: It is allowed due to impredicative polymorphism.
23:32:53<thetallguy>grahamhutton: nice to hear. It hasn't yet for me, but I've just started thinking about it.
23:32:59<EvilTerran>okay...
23:33:08<grahamhutton>hopefully there will be a talk on worker/wrapper at the next "fun in the afternoon", in London in Feb.
23:33:16<monochrom>The impredicative polymorphism example uses f :: Maybe (forall a. [a] -> [a]) -> Maybe ([Int], [Char])
23:33:43<Toxaris>monochrom: I'm looking at your "list of fmaps" and don't see if they realy relate to EvilTerran's and my discussion
23:33:44<grahamhutton>(given by Andy Gill, who is visiting the UK at this time)
23:34:13<monochrom>It likely doesn't relate.
23:34:46<Toxaris>monochrom: given that (funk [fmap, fmap] == funk [fmap] ++ funk [fmap]) holds for your code, the two fmaps in the list doesn't seem to be that different
23:34:57<ddarius>gwern: Probability Theory: The Logic of Science? If so, then you will shortly find one of the significant reasons his death was inconvenient.
23:35:32<Toxaris>monochrom: (that argument may be nonsense, what do i know)
23:37:10<monochrom>In a list I can't have two very different items. They have to be of the same type.
23:37:28<monochrom>I can't possibly have [ fmap for Maybe, fmap for List ]
23:38:04<monochrom>But I can have [ polymorphic fmap, polymorphic fmap ]. So now the two are the same.
23:38:37<monochrom>However, you can still use the first polymorphic fmap just for Maybe, and the second just for List.
23:38:50<Toxaris>monochrom: wich your code doesnt do
23:39:03<monochrom>You can edit my code to do that.
23:39:45<monochrom>My code does more, not less.
23:40:08<EvilTerran>can you then have (replicate 8 fmap :: [forall f a b. Functor f => (a -> b) -> f a -> f b]), and somehow fold it down into (fmap fmap fmap fmap fmap fmap fmap fmap)?
23:40:10<monochrom>If the first fmap can be used for both Maybe and List, then it can be used for just Maybe.
23:41:30<monochrom>First you have to be able to type-check the "fold" there.
23:47:59<visof>> foo [] = 0 ; let foo (x:xs) = xs in foo [1,2,3]
23:47:59<lambdabot> Parse error at "=" (column 8)
23:48:01<thetallguy>grahamhutton: those are videotaped and posted, right?
23:48:11<visof>>let foo [] = 0 ; foo (x:xs) = xs in foo [1,2,3]
23:48:16<visof>> let foo [] = 0 ; foo (x:xs) = xs in foo [1,2,3]
23:48:16<lambdabot> add an instance declaration for (Num [t])
23:48:16<lambdabot> In the expression:
23:48:16<lambdabot> le...
23:48:26<visof>oh my God
23:48:29<grahamhutton>not so far, but this is something i want to propose for the next one
23:48:40<visof>what is the wrong?
23:48:58<Toxaris>visof: should foo return a list or a number?
23:49:09<visof>list
23:49:13<grahamhutton>we've had 4 so far - average attendance around 70, so there is lot's of interest
23:49:25<Toxaris>visof: so foo [] = 0 is ill-typed because 0 is no list :(
23:49:37<visof>ok
23:49:38<ddarius>It could be.
23:49:42<visof>thanks
23:49:52<Toxaris>visof: this is what lambdabot returns. (actually, she returns "list is no num", what means the same thing here)
23:50:10<visof>> let foo [] = [] ; foo (x:xs) = xs in foo [1,2,3]
23:50:11<lambdabot> [2,3]
23:50:16<visof>hehe
23:50:29<visof>@yow!
23:50:29<lambdabot>A wide-eyed, innocent UNICORN, poised delicately in a MEADOW filled
23:50:29<lambdabot>with LILACS, LOLLIPOPS & small CHILDREN at the HUSH of twilight??
23:54:05<Cin>is there a function to split a list into a sublist of x elements? like f 2 [1,2,3,4,5,6] => [[1,2],[3,4],[6,7]]
23:54:50<r3m0t>Cin: I believe there is not
23:55:03<Cin>oh
23:55:29<monochrom>There is one splitting a list into the first x items and the rest.
23:55:38<monochrom>> splitAt 2 [1,2,3,4,5,6]
23:55:39<lambdabot> ([1,2],[3,4,5,6])
23:55:44<monochrom>You can loop over it.
23:58:16<Cin>suppose that'll have to do
23:58:21<dons>?usrs
23:58:22<lambdabot>Maximum users seen in #haskell: 444, currently: 410 (92.3%), active: 12 (2.9%)

Back to channel and daily index: content-negotiated html turtle