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® Pentium® 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® Pentium® 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® Pentium® 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