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:04:05 | <sm> | how do you make a form with Text.Xhtml ? |
| 00:04:19 | <sm> | http://hackage.haskell.org/packages/archive/xhtml/3000.2.0.1/doc/html/Text-XHtml-Transitional.html#16 is no help |
| 00:06:13 | <Cale> | sm: Is there something that you need which is missing from that? |
| 00:06:56 | <sm> | hi Cale. Yes, an example of defining a form. I expected to see a form function to get things rolling |
| 00:07:05 | <Cale> | There is one |
| 00:07:11 | <Cale> | http://hackage.haskell.org/packages/archive/xhtml/3000.2.0.1/doc/html/Text-XHtml-Transitional.html#v%3Aform |
| 00:07:30 | <sm> | huh. Thank you! |
| 00:07:47 | <Cale> | No problem. In-page search is awesome, btw :) |
| 00:07:58 | <sm> | indeed.. mine was too hasty |
| 00:08:48 | <sm> | I worked a bit on ledger performance, still tinkering around as time allows |
| 00:10:16 | <yurinotigor> | do you know of any hosted haskell provider? Ideally, something along the lines of AppEngine but at least a hosting specialized in haskell |
| 00:10:39 | <Cale> | yurinotigor: Anything which allows arbitrary executables will do. |
| 00:10:53 | <Cale> | yurinotigor: Since you can simply compile your program. |
| 00:11:06 | <mgsloan> | nearlyfreespeech.net doesn't host haskell specifically, but it supports it as a language (ghc is on their servers and such) |
| 00:12:12 | <sm> | ACTION started reimplementing my tree utilities using your trie-tree but found it tricky. Then I tried to force more strictness, and mean to try again. Then I looked at the app and decided it doesn't need to use a tree at all, and started building an abstract AccountTree data type that I could easily change the implementation of. |
| 00:12:22 | <yurinotigor> | I see. It would be great if there was a provider that would provide a infrastructure for haskell with some of the common services already taken care of such as web authentication, persistent storage in the cloud. Something along the lines of AppEngine for Haskell |
| 00:12:56 | <sm> | yurinotigor: good idea. I'm sure the #happs folks would be interested in that |
| 00:13:28 | <mmorrow> | yurinotigor: you just need to get a hosted account with ssh access and a decent linux distribution whose pkg manager has at least ghc-6.4, and you can boot from there. |
| 00:14:22 | <yurinotigor> | mmorrow: yes, but things like Amazons Simple DB or AppEngine bigtable make a big difference. But your point is still valid its just that I would have to build the infra myself |
| 00:15:17 | <Cale> | If you're starting from ghc 6.4, why not just download a newer binary? |
| 00:15:31 | <mmorrow> | yurinotigor: as far as i'm aware, you'll need your bootstrap shoes on to get a haskell setup on a hosted box :) |
| 00:15:41 | <Cale> | Compiling your way up seems like a waste of time :) |
| 00:15:43 | <mmorrow> | Cale: oh yeah, the newer the better |
| 00:16:15 | <mmorrow> | (one of my hosted accounts is on CentOS, and its yum had ghc-6.4 as the newest..) |
| 00:16:33 | <mmorrow> | it took ~4 hours to build 6.8.3 |
| 00:16:37 | <Cale> | It's usually easy enough, given the space, just to wget the ghc binary package and install it in your homedir |
| 00:16:55 | <mmorrow> | Cale: it wouldn't function on that CentOS setup |
| 00:17:07 | <mmorrow> | the libc wasn't compatible or something |
| 00:17:13 | <Cale> | ah |
| 00:17:36 | <mmorrow> | but yeah, if the bindist works you're sitting pretty |
| 00:19:14 | <yurinotigor> | Would Happs be the closest to an "container" like that for Haskell? |
| 00:20:31 | <Saizan> | in happs each application gets compiled to a standalone server |
| 00:20:41 | <Saizan> | but it does provide a nice base to start with |
| 00:20:45 | <mmorrow> | (and in the case that it *doesn't* work, and you have to build a ghc from an older version.... ghc needs alex+happy top build, and each of those needs itself to build (for the initial processing step of the .x and .y files that provide each with their parser/lexer), and chances are good that if you have no ghc bindist you won't have a binary alex or happy, so all you have to do is preproc the .x and .y files on another computer, then upl |
| 00:20:45 | <mmorrow> | oad the resulting .hs's to the hosted machine. |
| 00:21:07 | <mmorrow> | that was a huge pita to figure out the first time around.. |
| 00:21:54 | <mmorrow> | (then build alex and happy, and finally you can build the new ghc) |
| 00:22:32 | <Saizan> | why not build alex an happy with the old ghc? the hackage packages have the preprocessed files in them |
| 00:22:38 | <mmorrow> | maybe i've just had bad luck though and being in the situation where you need to build everything is rare |
| 00:23:07 | <mmorrow> | Saizan: ah sure, or that (i was building from darcs i think) |
| 00:23:20 | <mmorrow> | err, the hackage packages have the already processed .hs's? |
| 00:24:38 | <Saizan> | the .hs corresponding to the .x/.y , yes |
| 00:24:38 | <mmorrow> | the hackage happy package doesn't seem to |
| 00:24:51 | <Saizan> | under dist/build |
| 00:24:56 | <mmorrow> | i only see Parser.ly in the tarball |
| 00:25:11 | <mmorrow> | but you need happy to get it! |
| 00:25:14 | <mmorrow> | :) |
| 00:25:30 | <mmorrow> | oh |
| 00:25:30 | <Saizan> | saizan@astarte:~/trash/happy-1.18.4/dist/build/happy/happy-tmp$ ls |
| 00:25:31 | <Saizan> | AttrGrammarParser.hs Parser.hs |
| 00:25:33 | <mmorrow> | so it's there |
| 00:25:34 | <mmorrow> | :) |
| 00:25:43 | <mmorrow> | good to know.. |
| 00:26:05 | <mgsloan> | what would be the simplest representation / interface through which to analyze haskell source? |
| 00:26:23 | <mmorrow> | ACTION takes back his hacky happy build scheme |
| 00:26:37 | <mmorrow> | mgsloan: analyze it how? |
| 00:26:51 | <mmorrow> | mgsloan: (probably haskell-src-exts) |
| 00:27:24 | <mgsloan> | just view it as a simple graph basically, an easily traversable graph |
| 00:27:53 | <mmorrow> | mgsloan: a graph of calls/types/tycondeps//modules/.. ? |
| 00:28:32 | <mgsloan> | just a bunch of expression graphs would be good enough |
| 00:28:41 | <mmorrow> | mgsloan: you want haskell-src-exts |
| 00:28:45 | <mgsloan> | for every method or function definition |
| 00:29:40 | <mgsloan> | yeah I suppose you are right |
| 00:30:37 | <yurinotigor> | Saizan, Cale, mmorrow, mgsloan: thanks for the insights. |
| 00:54:40 | <mmorrow> | gah |
| 00:55:10 | <mmorrow> | @tell yurinotigor here're some useful haskell-src-exts functions http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5512 |
| 00:55:11 | <lambdabot> | Consider it noted. |
| 00:58:57 | <mmorrow> | arg, this `pExp' is better http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5512#a5513 |
| 00:59:11 | <mmorrow> | (the other one fails to parse package.conf, this one works) |
| 01:00:39 | <mmorrow> | look at how pretty package.conf is with a little prettyPrinting! http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5512#a5514 |
| 01:00:57 | <mmorrow> | (ppHs :: forall a. (Show a) => a -> Doc) |
| 01:01:33 | <mmorrow> | never have to look at jumbled show output again |
| 01:02:08 | <mmorrow> | ACTION is so adamant about this because he uses it so often and can't get over how much easier it makes inspecting data |
| 01:02:39 | <Adamant> | mmorrow: you are Adamant too? welcome to the collective of Adamant! |
| 01:02:44 | <Adamant> | :P |
| 01:02:47 | <pumpkin> | :o |
| 01:02:59 | <mmorrow> | :0 |
| 01:03:15 | <Adamant> | I iz kiddin' |
| 01:03:19 | <mmorrow> | :) |
| 01:03:24 | <pumpkin> | :I |
| 01:03:25 | <ray> | i'm adamant that people should stop talking about ray tracers on irc |
| 01:03:33 | <Adamant> | ray: me too |
| 01:03:41 | <mmorrow> | @hoogle trace |
| 01:03:42 | <lambdabot> | Debug.Trace trace :: String -> a -> a |
| 01:03:43 | <lambdabot> | module Debug.Trace |
| 01:03:43 | <lambdabot> | package traced |
| 01:03:49 | <pumpkin> | ACTION port rays himself in a picture |
| 01:04:08 | <mmorrow> | ACTION project pumpkin onto a nurb |
| 01:04:10 | <pumpkin> | I guess I'd need to separate the S too, to be really annoying |
| 01:04:18 | <Adamant> | pumpkin: are you adamant about this? |
| 01:04:23 | <ray> | maybe i highlight on my own plural |
| 01:04:28 | <pumpkin> | more adamant than a pumpkin |
| 01:04:44 | <pumpkin> | (yeah, I suck) |
| 01:05:01 | <Adamant> | pumpkin: copumpkin is funnier than thou |
| 01:05:06 | <pumpkin> | :( |
| 01:05:24 | <ray> | bring back copumpkin |
| 01:05:26 | <Adamant> | just kidding, you're doing fine :P |
| 01:05:32 | <pumpkin> | ACTION sobs |
| 01:06:01 | <mmorrow> | ACTION carves a smiley face into pumpkin |
| 01:07:22 | <mutjida> | @hoogle mapAccumL |
| 01:07:23 | <lambdabot> | Data.ByteString mapAccumL :: (acc -> Word8 -> (acc, Word8)) -> acc -> ByteString -> (acc, ByteString) |
| 01:07:23 | <lambdabot> | Data.List mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y]) |
| 01:07:23 | <lambdabot> | Data.ByteString.Char8 mapAccumL :: (acc -> Char -> (acc, Char)) -> acc -> ByteString -> (acc, ByteString) |
| 01:17:58 | <Chile`> | so I see GHC has a 'SPECIALIZE' pragma.. is it considered bad form to use this for anything other than optimizations? |
| 01:18:23 | <Hunner> | If I wanted to have a haskell program that didn't restart, but I could modify the "backend" which passed something back and forth as requests came in, what am I looking for? |
| 01:19:06 | <Hunner> | an irc bot where you could modify the functions and triggers is specifically what I'm looking at |
| 01:19:21 | <Hunner> | as long as the framework code for the bot doesn't change |
| 01:19:33 | <Hunner> | in ruby I just open a pipe to another ruby script |
| 01:21:09 | <aavogt> | Hunner: maybe something like what I think happs does, or plugins (formerly hs-plugins) would interest you |
| 01:22:19 | <Hunner> | so it would most likely be something heavy duty? I'm looking to build something from scratch if possible to learn more |
| 01:24:19 | <defun> | How would I test a value to tell if it is a string or an int? If I hand 'func x' I would like the 'func' to take different actions depending on the type of 'x'. Any ideas? |
| 01:24:33 | <Saizan> | defun: use a typeclass |
| 01:25:03 | <Saizan> | or an union type |
| 01:25:15 | <defun> | thanks. anything else? |
| 01:25:17 | <Saizan> | like data StringOrInt = S String | I Int |
| 01:25:56 | <Chile`> | if you use a type class, can you assign a function to 'any type not already listed'? |
| 01:26:15 | <aavogt> | Hunner: and you could communicate by pipes with haskell code too |
| 01:26:18 | <dino-> | Or pack it in (Either String Int) |
| 01:26:41 | <Saizan> | there's also Typeable/Dynamic, but those are generally the last option one considers |
| 01:26:58 | <Saizan> | Chile`: you can with OverlappingInstances |
| 01:27:24 | <Saizan> | but it's not considered good style |
| 01:27:56 | <Saizan> | mostly because importing another module which defines another instance can change the behaviour of your code |
| 01:28:01 | <Hunner> | aavogt: thanks for the help. Class is done so I'm heading out, and will look at hs-plugins and pipes later |
| 01:28:19 | <dino-> | I think Either when it comes up that something is "this or that" |
| 02:02:17 | <fracture> | is there an invalid Handle value, or do you have to use Maybe Handle ? |
| 02:02:32 | <monochrom> | Use Maybe Handle. |
| 02:03:23 | <Cale> | Even if there were, using Maybe Handle out of principle would probably still be a good idea :) |
| 02:03:24 | <dancor> | template haskell can really crank up compile time |
| 02:03:45 | <dancor> | do you guys put crazy deriving blocks in separate files so they might get recompiled less often, or other tricks |
| 02:03:47 | <byorgey> | fracture: Haskell style is to never include 'invalid values' in a type, leaving that up to 'Maybe' or 'Either e' (for some appropriate error type e), etc. |
| 02:04:04 | <FunctorSal> | dancor: are you sure it's th? |
| 02:04:18 | <Twey> | data Bool = True | False | FileNotFound -- had to |
| 02:04:20 | <FunctorSal> | it shouldn't be slower than executing the TH + compiling the resulting code |
| 02:04:30 | <dancor> | FunctorSal: only change is adding deriving (Data, Typeable) everywhere |
| 02:04:30 | <FunctorSal> | I guess the former is insignificant... |
| 02:04:40 | <gwern> | hm. I'm trying to think. has anyone here ever used information theoretical concepts in real life (non-programming)? I'm sure I've done so, but I can't seem to remember what I decided or di |
| 02:04:47 | <FunctorSal> | dancor: wouldn't call that TH |
| 02:04:59 | <dancor> | ok, SYB |
| 02:05:05 | <FunctorSal> | ah |
| 02:05:24 | <mmorrow> | dancor: i usually compilte a program that's sole purpose is touch output the (prettyprinted and cleaned) code it generates on stdout, then > Foo.hs |
| 02:05:30 | <mmorrow> | *compile |
| 02:05:43 | <mmorrow> | *.. is to output |
| 02:05:45 | <FunctorSal> | gwern: yes! put often-used items in the best places |
| 02:06:18 | <fracture> | Cale: don't think I agree re the Maybe Handle... if you can set up situations where it is a precondition that the Handle is valid, it would avoid some use of Maybe in the code |
| 02:06:27 | <gwern> | FunctorSal: hm. I'd say that's actually more data structure stuff |
| 02:06:42 | <Cale> | fracture: But if you know that the Handle is valid, then you don't need Maybe Handle |
| 02:06:43 | <dancor> | mmorrow: i can't tell if that's a joke or some haskell thing i don't know about (i never can) |
| 02:06:46 | <fracture> | (probably no different from normal Handle use... you're often assuming it hasn't be closed as a precondition) |
| 02:06:51 | <gwern> | I was thinking more like 'each question gets me less than a bit so I can't hope to do it any faster than n' |
| 02:07:15 | <FunctorSal> | gwern: it's "encoding theory" (can't think of the right name of the field ;)) I would call that information scienec |
| 02:07:16 | <fracture> | well you might have a data structure that contains a handle if a particular step has occured, after which it will always be valid |
| 02:07:52 | <fracture> | by the way, refactoring that data type didn't really fix the problem... the logical names for the members are the same as logical names for them in other locations in the code, which sucks |
| 02:07:58 | <fracture> | so you get name hiding |
| 02:08:17 | <MyCatVerbs> | > 3 `mappend` 4 |
| 02:08:18 | <lambdabot> | Add a type signature |
| 02:08:29 | <gwern> | FunctorSal: the context for my question is someone suggested a book covering the basic simple math of every important field for laymen, and I was thinking information theory is very important but it's not obvious witout examples - you can explain bits and uncertainty and the pigeonhole principle and it still looks like trivia |
| 02:08:39 | <Cale> | fracture: There are at least a couple benefits to using Maybe to explain failures. One is that you can tell from the type of a function that it might not give you a valid value. Secondly, there are lots of functions for manipulating and combining values of Maybe type. |
| 02:08:41 | <fracture> | (was worth merging them though) |
| 02:09:06 | <fracture> | yeah but this wouldn't be for a failure (I agree that the maybe manipulation utilities are pretty badass) |
| 02:09:14 | <FunctorSal> | gwern: I thought huffman coding was very similar to storing items you need often on the table, and rarely used items in boxes etc. |
| 02:09:29 | <gwern> | too close to common sense |
| 02:09:37 | <gwern> | ACTION keeps pondering |
| 02:09:37 | <sclv_> | gwern: I don't think with the exact maths of shannon, but like lots of folks, I often use signal/noise and information bandwidth type analogies about different forms of communication |
| 02:09:48 | <Twey> | fracture: Maybe is used for ‘optional’ arguments and return values in general |
| 02:09:49 | <FunctorSal> | gwern: isn't that a good thing? :) |
| 02:10:10 | <fracture> | Twey: yeah I grok that |
| 02:10:12 | <Twey> | Not just failures, although that's often the meaning when used as a return value |
| 02:10:13 | <gwern> | FunctorSal: no, if it's too obvious people will mentally go 'that's stupid' and forget the lessons |
| 02:10:45 | <Cale> | fracture: There's at least one library which makes explicit the notion of a future value -- one which becomes defined at some point and thereafter remains constant. |
| 02:10:54 | <gwern> | a good example will be a common situation where your intuitions are obviously muddled, and a bit of thinking about information and certainty will give you an obvious and clearly better answer |
| 02:10:56 | <pumpkin> | or will think, "oh wow, it's a fancy name on something I already knew *build mental association of fancy name to already known thing*" |
| 02:11:00 | <FunctorSal> | gwern: oh, right... shouldn't be too trivial |
| 02:11:07 | <pumpkin> | ah |
| 02:11:08 | <gwern> | ideally, it'll make the person think, 'how extremely stupid of me not to have thought of that!' |
| 02:11:10 | <Twey> | gwern: I disagree |
| 02:11:16 | <dancor> | what is the $(..) equivalent of: deriving (Data) |
| 02:11:25 | <SamB> | Cale: but the notion of time involved is a bit mind-boggling, isn't it? |
| 02:11:27 | <Twey> | Formal reformulations of concepts the reader already knows are the easiest to remember |
| 02:11:44 | <Twey> | Because they can relate them (and everything deriving from them) directly to their ‘common sense’ |
| 02:11:47 | <FunctorSal> | dancor: cabal install derive; $(derive makeData ''MyDatatype) |
| 02:11:52 | <Cale> | SamB: perhaps, yeah |
| 02:11:53 | <FunctorSal> | (or similar) |
| 02:11:58 | <dancor> | FunctorSal: thanks |
| 02:12:06 | <Cale> | It makes more sense in an explicitly concurrent setting than a pure one |
| 02:13:44 | <FunctorSal> | hmm is there a consensus that only the existing top-level branches in the module namespace should be used? Data.* seems a bit overworked... |
| 02:14:04 | <Cale> | FunctorSal: No, you can make up new stuff as you see fit. |
| 02:14:17 | <gwern> | consensus? not as such. but there seems to be a weak prejudice against it |
| 02:14:26 | <gwern> | kind of like adding new categories to hackage... |
| 02:14:34 | <fracture> | is there a way to get at names in the enclosing namespace if you have shadowed them? |
| 02:14:37 | <Cale> | The difference between Data and Control is hazy |
| 02:14:48 | <fracture> | like if you have a data Foo = Foo { bar :: Int } or something |
| 02:14:58 | <fracture> | and a local name is bound to bar |
| 02:14:59 | <Cale> | fracture: Don't shadow them :) |
| 02:15:01 | <fracture> | Foo.bar or something |
| 02:15:23 | <fracture> | Cale: that'd be my preference, but (much to my disappointment) the names from data structures are basically global |
| 02:15:26 | <Cale> | Well, you can refer to the module |
| 02:15:27 | <fracture> | (module-wide) |
| 02:15:30 | <fracture> | ahhh |
| 02:15:36 | <fracture> | so Main.bar would get it? |
| 02:15:48 | <Cale> | Basically, pick field labels which you are not going to want to reuse for something else. |
| 02:15:52 | <Twey> | fracture: Which is why I recommend putting records in their own namespaces |
| 02:15:59 | <fracture> | yeah... that's really disappointing though |
| 02:16:03 | <Cale> | At least, that's what I do. |
| 02:16:08 | <Twey> | It's not, when you think about it. |
| 02:16:10 | <fracture> | (having to mangle names in fields) |
| 02:16:17 | <Cale> | You don't have to mangle them. |
| 02:16:26 | <Twey> | Named data fields is the task of records. |
| 02:16:31 | <Twey> | Namespacing is the task of modules. |
| 02:16:36 | <Twey> | If you want both, combine the two. |
| 02:16:37 | <Cale> | Just make the name a bit more specific. |
| 02:17:00 | <fracture> | hrm |
| 02:17:02 | <Twey> | It's a Good Thing that we have this composable simplicity. |
| 02:17:10 | <Cale> | Like, attach the type name (or an abbreviation of it) to the beginning of the field name. |
| 02:17:12 | <FunctorSal> | or make a typeclass if it is a thing that many types could have |
| 02:17:18 | <fracture> | Cale: that's mangling... |
| 02:17:20 | <FunctorSal> | (fracture) |
| 02:17:25 | <fracture> | (that's like what we had to do back in C) |
| 02:17:27 | <Cale> | I don't see it as mangling... |
| 02:17:41 | <Cale> | It's just giving a specific name to the extractor function for that type and field. |
| 02:17:52 | <fracture> | well, whatever you call it |
| 02:18:01 | <fracture> | (the C++ guys call it "mangling") |
| 02:18:08 | <Twey> | That is technically the definition of mangling. |
| 02:18:18 | <FunctorSal> | class Bar a where bar :: a -> Int |
| 02:18:21 | <fracture> | ok so the alternative is to make a module just for the data definition, eh? |
| 02:18:25 | <fracture> | hrm |
| 02:18:25 | <Cale> | ACTION thinks of mangling as more the sort of thing which is done by the linker... |
| 02:18:29 | <Twey> | fracture: And related functions. |
| 02:18:38 | <fracture> | ahh... well that's not too bad |
| 02:18:40 | <pumpkin> | I've brought this up before, but can anyone think of some "theoretical" basis for functions that are efficient to calculate on a sliding window over a stream? |
| 02:18:44 | <fracture> | anything non-trivial is probably going to have related functions |
| 02:18:49 | <Twey> | fracture: No, it's not :) Right. |
| 02:18:49 | <SamB> | Cale: not just a linker ... |
| 02:19:12 | <aavogt> | @go evil mangler |
| 02:19:13 | <lambdabot> | http://hackage.haskell.org/trac/ghc/wiki/Commentary/EvilMangler |
| 02:19:13 | <lambdabot> | Title: Commentary/EvilMangler - GHC - Trac |
| 02:19:15 | <Twey> | What *would* be nice is to be able to put multiple modules in the same file. |
| 02:19:19 | <Cale> | pumpkin: It seems they fit into a particular comonadic view. |
| 02:19:25 | <fracture> | ah is that illegal? .. d'oh |
| 02:19:32 | <pumpkin> | Cale: how so? |
| 02:19:32 | <smorg> | is it possible (or sane) to represent the output function of a comprehension as a variable to use as a predicate within the same statement? |
| 02:19:52 | <Twey> | But, well, it's okay to have to use different files, especially since, as you say, most non-trivial records are going to have associated functions on them anyway. |
| 02:20:03 | <fracture> | true |
| 02:20:05 | <smorg> | let y = [ 2*x | x <- [0..9], y>10 ] or [ y = (2*x) | x <- [0..9], y>10 ] |
| 02:20:15 | <Cale> | pumpkin: Have you read the stuff about how cellular automata are easily expressed in a particular comonad? |
| 02:20:27 | <pumpkin> | Cale: I can think of good ways of computing mean, entropy, and a few other simple measurements over a sliding window in constant time per additional sample |
| 02:20:39 | <pumpkin> | nope, do you have a URL? |
| 02:20:46 | <Cale> | pumpkin: Oh, that's a little different... |
| 02:20:58 | <pumpkin> | ah, yeah, that's the kind of thing I was talking about |
| 02:21:04 | <FunctorSal> | > [ 2*x | x <- [0..9], y>10 ] -- smorg |
| 02:21:05 | <lambdabot> | [0,2,4,6,8,10,12,14,16,18] |
| 02:21:17 | <pumpkin> | but I'd still be interested in reading about that... I'm still pretty unfamiliar with comonads beyond the basic definition |
| 02:21:21 | <Cale> | http://blog.sigfpe.com/2006/12/evaluating-cellular-automata-is.html -- it was supposed to be here, but this is a 404 |
| 02:21:30 | <pumpkin> | worked for me |
| 02:21:31 | <FunctorSal> | hmm I thought it would make an infinite list of zeroes |
| 02:21:41 | <pumpkin> | maybe edwardk has a special rule for your IP :) |
| 02:21:42 | <FunctorSal> | oh, there's no generator for y... |
| 02:21:46 | <pumpkin> | I mean sigfpe :) |
| 02:21:51 | <FunctorSal> | nevermind :) |
| 02:21:52 | <pumpkin> | damn comonad confusion in my head |
| 02:21:54 | <Cale> | heh, that's strange if true |
| 02:22:12 | <smorg> | I'm thinking there must be some interesting application for doing something like that - akin to a recursive function |
| 02:22:13 | <Cale> | So, anyway, look at the type of =>> |
| 02:22:45 | <pumpkin> | do you still think it would be applicable to sliding window-type computations? |
| 02:22:46 | <dibblego> | @type (=>>) |
| 02:22:49 | <lambdabot> | Not in scope: `=>>' |
| 02:22:59 | <pumpkin> | sliding windows feel a bit like convolution, but not quite |
| 02:23:21 | <Cale> | pumpkin: Perhaps not in quite the efficient sense that you were describing, but for describing such computations in the first place, yes. |
| 02:23:36 | <Cale> | Stream a -> (Stream a -> b) -> Stream b |
| 02:23:42 | <FunctorSal> | pumpkin: they are a convolution with the "window weighting" function, no? |
| 02:24:09 | <pumpkin> | I guess, but I'm not sure how I'd express an entropy computation over a sliding window as a traditional convolution |
| 02:24:14 | <pumpkin> | it doesn't feel possible, but I'm no expert :) |
| 02:24:16 | <FunctorSal> | (something like f x = if x >= 0 && x < 1 then 1 else 0) |
| 02:24:31 | <Cale> | Where the function parameter gets some tail of the Stream as its input, and is expected to look at some initial window of it. |
| 02:24:41 | <pumpkin> | I see |
| 02:24:44 | <FunctorSal> | pumpkin: I meant for a single window it's a convolution |
| 02:24:49 | <pumpkin> | ah |
| 02:25:09 | <FunctorSal> | so you'd have the function you convolute with varying in time... |
| 02:25:50 | <Cale> | Or, if you need more, there are lots of other possible valid cojoin implementations -- you can enforce the window size/scope in your instance of Comonad as well. |
| 02:26:27 | <Cale> | (at the cost of a little prettiness) |
| 02:26:52 | <pumpkin> | hmm |
| 02:27:04 | <smorg> | I guess that seems more elegent than filter (>10) [ 2*x | x <- [0..9] ] |
| 02:27:11 | <pumpkin> | that's interesting |
| 02:27:24 | <pumpkin> | any thoughts on how I could bring my definition of "efficiency" into it all? |
| 02:27:43 | <pumpkin> | that is, constant or sub O(window size) complexity per additional sample |
| 02:27:51 | <Cale> | > [y | x <- [0..9], let y = 2*x, y > 10] |
| 02:27:52 | <lambdabot> | [12,14,16,18] |
| 02:27:53 | <sclv_> | heh. i was just talking about how to model windows in streaming computations today and i forgot all about comonads! |
| 02:29:14 | <sclv_> | zippers = best comonads evah |
| 02:29:17 | <smorg> | Cale: oh didn't think of that. neat. |
| 02:29:35 | <smorg> | heh very cool actually... |
| 02:29:39 | <Cale> | pumpkin: I suppose that if you want to go that way, perhaps the pure comonadic view isn't going to work out. The important thing is being able to reuse your previous result to compute your next one. (Along with perhaps the element before the sliding window and the element after) |
| 02:29:51 | <pumpkin> | yeah |
| 02:30:12 | <pumpkin> | being able to maintain who's "coming" and who's "going", basically |
| 02:30:18 | <BMeph> | ACTION still snickers a little every time he see's "Paul Potts" in a reference. |
| 02:31:28 | <monochrom> | Paul Potts is the best Haskell programmer ever! |
| 02:31:31 | <monochrom> | (like that?) |
| 02:32:02 | <monochrom> | Or is it like the following? |
| 02:32:53 | <monochrom> | 12. Paul Potts. How to sing and write Haskell at the same time. Journal of Functional Vocal Programming 4:16 2007 |
| 02:36:00 | <smorg> | So you can use let right in the middle of an expression to specify a function to use within the same expression (and it can be used anywhere at all inside the expression)? |
| 02:36:22 | <fracture> | say you have a function inside a StateT-transformed monad... is there any way to declare that the function can't modify the state? |
| 02:36:31 | <fracture> | (kinda like a const member function in a C++ class) |
| 02:37:44 | <sclv_> | fracture: you can write a wrapper that gets the state, runs the function, then replaces the state with the original one. |
| 02:37:55 | <sclv_> | so even if it does modify the state, it doesn't really |
| 02:38:11 | <fracture> | I see |
| 02:38:16 | <monochrom> | Yes smorg if I understand you correctly. |
| 02:38:59 | <sclv_> | if you want to do it with typesafety, wrap the StateT in a newtype with a phantom type parameter that is either ReadOnly or ReadWrite |
| 02:39:28 | <sclv_> | then have the modify functions require the parameter be ReadWrite |
| 02:39:45 | <sclv_> | and allow the user to step "down" with runReadOnly but not step up. |
| 02:40:00 | <fracture> | makes sense |
| 02:40:14 | <fracture> | maybe would be worth doing if I had a significant amount of code that shouldn't be allowed to modify it... probably not for my current case |
| 02:40:36 | <fracture> | although, that wouldn't quite be what is desired actually |
| 02:40:39 | <fracture> | now that I think about it |
| 02:40:44 | <fracture> | because internally it could still replace the state |
| 02:40:46 | <fracture> | while it does whatever it does |
| 02:40:55 | <fracture> | ideally you'd want a compile-time error for attempts to modify it |
| 02:40:58 | <gwern> | (sure, maybe now we can sing and write haskell at the same time, but can we debug it?) |
| 02:41:26 | <sclv_> | aha! you could also just have a readerToState that takes ReaderT m a -> StateT m a ! |
| 02:41:31 | <sclv_> | cleanest solution yet |
| 02:41:41 | <fracture> | ok sorry to jump to another question: if I'm in a function in the StateT Foo IO monad, and I want to forkIO to another function, how do I get the types to work? |
| 02:41:46 | <fracture> | tried various combos of liftIO to no avail |
| 02:41:50 | <BMeph> | gwern: And how will we ever be able to keep track of all those precious stack frames? >;p |
| 02:42:16 | <byorgey> | fracture: you should be able to liftIO any IO action to a StateT Foo IO action. |
| 02:42:33 | <byorgey> | i.e., it should just take wrapping the forkIO call in a call to liftIO. |
| 02:42:40 | <sclv_> | fracture: there's a technique for writing deep embeddings like that -- it involves un and rewrapping so you can get forkMyMonad |
| 02:42:40 | <gwern> | BMeph: we can only balance on so many |
| 02:43:05 | <sclv_> | see the code for catchIO on hackage for how its done with exceptions, which is v. similar |
| 02:43:20 | <byorgey> | the 'minesweeper' package on Hackage lists 'glade' as a requirement--anyone know where to get this mythical 'glade' package? |
| 02:43:22 | <fracture> | oh the problem is my guy is a Foo (), not an IO ()... I probably need to forkIO a new call to runStateT passing the current state, eh? |
| 02:43:47 | <sclv_> | fracture: right. but the states won't sync back up again, so the semantics might be wrong... |
| 02:43:53 | <fracture> | hmm |
| 02:43:56 | <fracture> | oh |
| 02:43:58 | <jeffwheelerPhone> | byorgey: Gtk2Hs |
| 02:44:01 | <fracture> | I am just doing this wrong :) |
| 02:44:06 | <fracture> | these threads can't share state anyway |
| 02:44:10 | <fracture> | I should fork before I go into my monad |
| 02:44:27 | <byorgey> | jeffwheelerPhone: I installed gtk2hs, and used the --enable-libglade flag, but it didn't install a package called 'glade' |
| 02:44:38 | <byorgey> | jeffwheelerPhone: is there some other magic incantation I have to give while building gtk2hs? |
| 02:44:53 | <sclv_> | with some cleverness you could make it work for reader and writer tho! |
| 02:45:21 | <sclv_> | (you'd have to specify an explicit join to merge back) |
| 02:45:37 | <byorgey> | oh wait! the second time when I used --enable-libglade I forgot to do 'make install' after 'make' |
| 02:45:42 | <byorgey> | duh, problem solved =) |
| 02:45:44 | <jeffwheelerPhone> | byorgey: I didn't even have to do that; is there a libglade package that you can install first on your OS |
| 02:46:12 | <jeffwheelerPhone> | byorgey: That works too :) |
| 02:46:37 | <byorgey> | jeffwheelerPhone: thanks for the help =) |
| 02:47:23 | <jeffwheelerPhone> | byorgey: No problem |
| 02:48:03 | <kw317> | quick question: does Haskell (an if you know ML, then ML as well) erase type information after compilation? |
| 02:48:11 | <monochrom> | Yes. |
| 02:48:15 | <monochrom> | Both of them. |
| 02:48:29 | <pumpkin> | the closest thing to type information it retains is dictionaries of methods for typeclasses |
| 02:48:49 | <aavogt> | there is Dynamic though |
| 02:49:00 | <pumpkin> | which works through dictionaries of typeclasses doesn't it? |
| 02:49:04 | <kw317> | cool, thanks |
| 02:49:19 | <kw317> | ACTION is having a compilers (among other things) exam tomorrow :-) |
| 02:49:42 | <pumpkin> | good luck :) |
| 02:49:49 | <sclv_> | as far as i recall ml and ocaml in particular don't retain dictionaries |
| 02:49:55 | <kw317> | thanks :-) |
| 02:49:57 | <pumpkin> | how do they get around it? |
| 02:50:15 | <sclv_> | no typeclasses. |
| 02:50:18 | <pumpkin> | oh :) |
| 02:50:24 | <pumpkin> | that'll do it |
| 02:50:29 | <pumpkin> | I guess they have their fancy modules to do the same thing |
| 02:50:50 | <sclv_> | the upshot tho, as i recall again, is that, e.g., syb style generics can't be done in ocaml |
| 02:55:03 | <hackagebot> | simgi 0.1.1 |
| 02:56:13 | <gwern> | @pl foo x = "quux" ++ x ++ "bar" |
| 02:56:13 | <lambdabot> | foo = ("quux" ++) . (++ "bar") |
| 03:01:31 | <BMeph> | So, is there a co-Kleisli operator, (w a -> b) -> (w a -> w b)? |
| 03:02:13 | <byorgey> | BMeph: sure, that's just cobind with the arguments switched |
| 03:04:14 | <pumpkin> | is there a comonadic equivalent to kleisli composition then? |
| 03:04:31 | <MyCatVerbs> | BMeph: category-extras has that exactly, under the name (extend). It's just cobind, as byorgey says. |
| 03:04:58 | <byorgey> | pumpkin: let's see... it would have type (w a -> b) -> (w b -> c) -> (w a -> c) ? |
| 03:04:59 | <sclv_> | ?hoogle (>=>) |
| 03:05:00 | <lambdabot> | Control.Monad (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c |
| 03:05:06 | <pumpkin> | yeah |
| 03:05:23 | <pumpkin> | I don't think hoogle does category-extras |
| 03:05:35 | <pumpkin> | @hoogle (Comonad w) => (w a -> b) -> (w b -> c) -> (w a -> c) |
| 03:05:36 | <lambdabot> | Warning: Unknown class Comonad |
| 03:05:36 | <lambdabot> | No results found |
| 03:05:53 | <sclv_> | extend :: w a -> w (w a) |
| 03:06:22 | <byorgey> | pumpkin: there's an instance (Comonad w) => Arrow (CoKleisli w) in category-extras, so yes |
| 03:06:24 | <sclv_> | oh wait that's duplicate i think |
| 03:06:39 | <byorgey> | sclv_: yeah, that's duplicate/cojoin |
| 03:12:04 | <BMeph> | Well, we have a symbol for "bind with the arguments switched" - is there one cobind, and is it used much? :) |
| 03:12:15 | <BMeph> | one *for |
| 03:13:30 | <pumpkin> | ACTION slaps BMeph |
| 03:15:59 | <MyCatVerbs> | |
| 03:16:02 | <pumpkin> | |
| 03:16:02 | <Badger> | |
| 03:16:32 | <MyCatVerbs> | BMeph: (=>>) in Control.Comonad. |
| 03:16:54 | <Badger> | What's a comonad? :) |
| 03:17:21 | <aavogt> | What's a copumpkin? |
| 03:17:30 | <pumpkin> | it's the opposite of a pumpkin, just like a comonad is the opposite of a monad |
| 03:17:40 | <gwern> | aavogt: it's a strawberry |
| 03:17:49 | <gwern> | seeds on the outside to te pumpkin's seeds on the inside, y'see |
| 03:17:58 | <FunctorSal> | and like the sum is the opposite of a product ;) |
| 03:18:06 | <FunctorSal> | *a sum |
| 03:18:19 | <pumpkin> | and a contrafunctorsteak is the opposite of a functorsalad? |
| 03:18:34 | <FunctorSal> | :O |
| 03:18:39 | <Badger> | > 1 * (-1) |
| 03:18:41 | <lambdabot> | -1 |
| 03:18:48 | <pumpkin> | that's wrong btw |
| 03:18:52 | <pumpkin> | according to mr timecube |
| 03:18:58 | <Badger> | > 1 + (-1) |
| 03:18:59 | <lambdabot> | 0 |
| 03:19:09 | <Badger> | damn |
| 03:19:18 | <pumpkin> | yeah, all of mathematics is wrong, sorry |
| 03:19:23 | <ray> | you are an educated stupid |
| 03:19:26 | <Badger> | if only we had comathematics |
| 03:19:28 | <FunctorSal> | pumpkin: (-1) * (-1) is stupid and evil. |
| 03:19:28 | <pumpkin> | also, the earth is a cube but has four faces |
| 03:19:37 | <pumpkin> | and they rotate independently |
| 03:19:38 | <ray> | four CORNERS |
| 03:19:38 | <Badger> | > (-1) * (-1) |
| 03:19:39 | <lambdabot> | 1 |
| 03:19:41 | <Badger> | WHAT |
| 03:19:44 | <aavogt> | ACTION reads up on coma thematics |
| 03:20:05 | <FunctorSal> | hmm I'm overtired. there was an "= 1" supposed to be tehre |
| 03:20:20 | <ray> | > let (-1)*(-1)=(-1) in (-1)*(-1) |
| 03:20:21 | <lambdabot> | -1 |
| 03:20:27 | <ray> | so many parentheses. damn you, unary minus |
| 03:20:38 | <FunctorSal> | it's intriguing how it's not just stupid, it's stupid *and* evil. |
| 03:20:42 | <ray> | unary minus is stupid and evil |
| 03:21:25 | <ray> | > let time = cubic in fourCornerDay |
| 03:21:26 | <lambdabot> | Not in scope: `cubic'Not in scope: `fourCornerDay' |
| 03:21:47 | <ray> | lambdabot is stupid and evil too, QED |
| 03:23:07 | <Badger> | @vixen are you stupid and evil? |
| 03:23:07 | <lambdabot> | yes, i am |
| 03:23:14 | <BMeph> | ACTION reads up on psycho the rapists |
| 03:24:11 | <aavogt> | @vixen are you wrong? |
| 03:24:11 | <lambdabot> | i truely am |
| 03:25:36 | <ray> | among my fellow rays, there are many cranks |
| 03:25:43 | <ray> | like gene ray |
| 03:25:46 | <pumpkin> | yeah |
| 03:25:48 | <ray> | or the even bigger crank, ray kurzweil |
| 03:26:05 | <pumpkin> | I don't think you can be a bigger crank than gene ray |
| 03:26:15 | <pumpkin> | he's the only one with >1 wolfram, after all |
| 03:26:26 | <ray> | wolfram number? |
| 03:26:39 | <ray> | or are wolframs now a unit of crankness |
| 03:26:55 | <pumpkin> | http://www.aleph.se/andart/archives/2009/04/monumental_egos.html :) |
| 03:27:11 | <ray> | similar to the farad in that picowolframs are the normal unit |
| 03:27:14 | <ray> | or something |
| 03:27:23 | <pumpkin> | yeah :) |
| 03:27:27 | <pumpkin> | well |
| 03:27:30 | <pumpkin> | not really in this case |
| 03:27:37 | <aavogt> | is it possible to tell cabal install to pass --hyperlink-source to the haddock stage? |
| 03:27:38 | <pumpkin> | because most people have relatively high opinions of themselves, as he explains |
| 03:28:48 | <QtPlaty[HireMe]> | pumpkin: That seems to be a very ethnocentric view. |
| 03:28:52 | <pumpkin> | true |
| 03:28:56 | <ray> | well, he's not measuring egos on a linear scale |
| 03:29:05 | <ray> | no picowolframs necessary |
| 03:29:33 | <ray> | not linear. once again the correct word evades me |
| 03:29:42 | <pumpkin> | log? |
| 03:29:50 | <QtPlaty[HireMe]> | You wouldn't get that in an "asian" culture, hell it would be looked down on in Australian and British cultures as well to diffrent extents. |
| 03:30:14 | <pumpkin> | this is just about how people actually evaluate themselves, not how they feel they should talk about it to other people |
| 03:30:26 | <pumpkin> | just because you don't admit to thinking you're better than I am |
| 03:30:28 | <pumpkin> | doesn't mean you don't |
| 03:30:35 | <aavogt> | I see the --PROG-option, but --haddock-option doesn't seem to be accepted |
| 03:31:40 | <pumpkin> | but I agree that isn't the case in all cultures :) |
| 03:34:58 | <aavogt> | hmm, --haddock-option="--hyperlink-source" is silently rejected if specified before the package to install |
| 03:36:17 | <ray> | hmm, i can't measure my own ego in wolframs per that guy's post |
| 03:38:06 | <gwern> | aw shucks. I put too much parallelism into my program |
| 03:38:08 | <gwern> | ' |
| 03:38:08 | <gwern> | 'wp-rc-archivebot: socket: resource exhausted (Too many open files) |
| 03:38:08 | <gwern> | "http://www.webcitation.org/archive?url=http://www.njpw.co.jp/result/index.php?COM=result_main&SRNO=76&TKNO=1&email=gwern0@gmail.com" |
| 03:39:31 | <sclv_> | gwern: depending on the os, you can raise the ulimit |
| 03:39:41 | <sclv_> | some kernels its hard compiled in. :-( |
| 03:40:25 | <gwern> | yeah, but open files is a root ulimit |
| 03:40:40 | <encryptio> | not really |
| 03:40:56 | <encryptio> | the hard limits are always root-only, but the soft limits might not be |
| 03:41:06 | <gwern> | ulimit -n 100000 certainly asks me for root privileges |
| 03:41:20 | <encryptio> | that won't work on any os |
| 03:41:42 | <encryptio> | no unix-like kernel i know of supports more than 32k systemwide |
| 03:42:05 | <gwern> | well, there's no point in asking for just 1k when I already have 1024 |
| 03:42:24 | <gwern> | and asking for 4k I just get 'bash: ulimit: open files: cannot modify limit: Operation not permitted |
| 03:42:30 | <encryptio> | personally, i think if you're using more than a thousand filehandles, something is wrong (probably architecture) |
| 03:42:37 | <MyCatVerbs> | ulimit for open files? Uh, I've blown past about... either seventy or a hundred and ten thousand before. |
| 03:42:52 | <bos> | you can easily set ulimit -n to a very high number |
| 03:43:04 | <gwern> | encryptio: I need to open a shitload of http connections, that is what this program *does* |
| 03:43:07 | <MyCatVerbs> | I think I had to poke something in /proc for that, and needed root privs to raise ulimit -n. |
| 03:43:19 | <gwern> | there's no architecte to design |
| 03:43:43 | <encryptio> | gwern: thousands? i do hope you have the oc12 for that |
| 03:43:56 | <gwern> | if I want to archive a couple thousand web addresses using the http web interface to webcitation.org, then I'm going to have to make a couple thousand connections |
| 03:44:06 | <sclv_> | gwern: you probably know this but it doesn't hurt to check that you're managing filehandles strictly enough vis a vis closing them |
| 03:44:27 | <MyCatVerbs> | Specifically, I've had one process open way north of 70k recieving sockets on Linux. (epoll() FTW). Trying to open more than 32k outgoing TCP sockets in Linux did not work for me, though. |
| 03:44:41 | <gwern> | sclv_: this is via Network.HTTP. I'm not sure how I could be strict about closing them? |
| 03:44:44 | <bos> | gwern: are you trying to get that many sockets open from haskell at once? |
| 03:44:53 | <bos> | gwern: that definitely won't work. |
| 03:45:11 | <sclv_> | you probably want no more than ~50 connections open at once |
| 03:45:29 | <MyCatVerbs> | gwern: Oh dear. I would recommend using the libcurl bindings instead. |
| 03:45:30 | <encryptio> | gwern: and if i were a web administrator, i'd be very unhappy with anyone using more than 50 or so connections. in fact, i might look into suing them. |
| 03:46:06 | <gwern> | encryptio: eh. the webcitation.org folks basically encouraged/dared me to do this in their FAQ |
| 03:46:07 | <bos> | Network.HTTP *should* work OK, but only up to about 1024 open files. |
| 03:46:18 | <gwern> | bos: yes, that does seem to be the limit |
| 03:46:20 | <MyCatVerbs> | gwern: to the best of my knowledge, Network.HTTP does not handle file descriptors in particularly beautiful ways. |
| 03:46:33 | <bos> | MyCatVerbs: it just handles them in the usual way |
| 03:46:39 | <bos> | via Network.Socket |
| 03:46:50 | <gwern> | (I base this '1024 sounds right' on just looking at how many webcite acknowledgement emails land in my trash) |
| 03:46:52 | <MyCatVerbs> | bos: I thought it was a bit crap about closing them? Not sure. |
| 03:47:12 | <MyCatVerbs> | Plus I think there's a file handle limit in the GHC RTS, I think, aside from your ulimit -n entirely. |
| 03:47:30 | <MyCatVerbs> | Don't quote me on that, though. |
| 03:47:38 | <bos> | i know there is. it's 1024. |
| 03:47:44 | <bos> | which is why i said 1024 :-) |
| 03:47:59 | <MyCatVerbs> | bos: can you kick it up with an RTS option? |
| 03:48:11 | <encryptio> | gwern: to be completely blunt, it's a stupid idea to have so many connections to a single site. you'd be better served limiting it to 10-50, and even that's a high number. |
| 03:48:14 | <bos> | nope, it's a built-in limitation imposed by the RTS's use of select. |
| 03:48:25 | <gwern> | encryptio: why is that? |
| 03:48:31 | <MyCatVerbs> | bos: oh, select(2) is made of ouchies. I can see why that limit is in there. |
| 03:48:35 | <encryptio> | because you won't gain anything from it |
| 03:48:57 | <gwern> | (incidentally, if you're wondering by what I mean by daring me to do it: '# develop a wikipedia bot which scans new wikipedia articles for cited URLs, submits an archiving request to WebCite®, and then adds a link to the archived URL behind the cited URL' |
| 03:49:01 | <sclv_> | when using Network.Socket directly tho, it is, and i speak from experience, very easy to accidently leave sockets open. |
| 03:49:12 | <ray> | someone should write a haskell interface to kqueues |
| 03:49:17 | <encryptio> | gwern: and what part of that says open THOUSANDS of simultaneous connections? |
| 03:49:33 | <sshc_> | what is the haskell equivelent of the C typedef? |
| 03:49:38 | <gwern> | encryptio: you appreciate the scale of WP? |
| 03:49:44 | <sclv_> | the precise circumstances under which they are closed in event of various sorts of errors are rather undocumented and tricky to manage. |
| 03:49:48 | <MyCatVerbs> | sshc_: type Foo = Bar; |
| 03:49:50 | <ray> | sclv_: type i suppose |
| 03:49:55 | <sshc_> | thanks |
| 03:50:09 | <MyCatVerbs> | e.g. there's type String = [Char] somewhere in the base. |
| 03:50:12 | <ray> | hrm |
| 03:50:13 | <gwern> | I mean, even assuming they're only talkign about en! |
| 03:50:19 | <ray> | i'm sure you guys are the same person anyway |
| 03:50:19 | <sclv_> | i have some specific code to deal with it, but it would be nice to wrap it up and add it to the library. |
| 03:50:26 | <sclv_> | my socket-fu is weaker than many however. |
| 03:50:28 | <encryptio> | gwern: yes, and i know, for a fact, it's doable with a hundred. less if you're willing to let some lag through |
| 03:50:39 | <encryptio> | and that's to WIKIPEDIA |
| 03:51:39 | <encryptio> | that "bot" isn't meant to have the job be done in seconds after every edit. it's meant to have the job be done within days of the edit. |
| 03:52:03 | <gwern> | within days? the article could be gone within minutes. its refs could be gone in days |
| 03:52:14 | <encryptio> | then it wasn't very worthy, was it? |
| 03:53:06 | <gwern> | as everyone knows, new page patrol is infallible |
| 03:54:06 | <encryptio> | i still stand by my reasoning that it's a stupid idea to even consider using so much parallelism. |
| 03:54:33 | <encryptio> | even without the very lenient time limitations i mentioned. |
| 03:54:48 | <sclv_> | the bottleneck isn't going to be something that more threads solve, is the point. |
| 03:55:01 | <sclv_> | they might just create a difft. bottleneck in fact. |
| 03:55:53 | <gwern> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5517 |
| 03:57:18 | <hackagebot> | HsOpenSSL 0.6.1 |
| 03:58:19 | <Cale> | or . map p = any p |
| 03:58:24 | <encryptio> | worker model. put jobs (requests to either wp or webcite) in a queue (Chan (IO ()), probably) and have a fixed number of workers pull a job and do it. |
| 03:59:56 | <gwern> | encryptio: and how much code would this cost me? |
| 04:00:09 | <encryptio> | does your code work? |
| 04:00:16 | <gwern> | seems to |
| 04:00:30 | <encryptio> | then why are you having problems? |
| 04:01:30 | <gwern> | my problem is that looking at the number of external links in articles, I think I should be seeing more reply messages from webcite |
| 04:01:58 | <gwern> | my working theory being that the program is too slow and is being left behind by RC |
| 04:14:01 | <sshc_> | what does this type signature mean? "(Num b) => [a] -> b" |
| 04:14:19 | <pumpkin> | it returns any instance of Num |
| 04:14:54 | <encryptio> | it takes a list of anything and returns some number type (specifically, an instance of Num) |
| 04:15:26 | <dmwit> | It also means, slightly less obviously, that the function cannot depend on any of the elements of the list; at most it depends on the length of the list. |
| 04:16:22 | <SamB_XP> | @type genericLength |
| 04:16:24 | <lambdabot> | forall b i. (Num i) => [b] -> i |
| 04:16:31 | <dmwit> | ;-) |
| 04:16:33 | <pumpkin> | that's different! |
| 04:16:51 | <SamB_XP> | pumpkin: say what ? |
| 04:17:06 | <SamB_XP> | ACTION invokes the color rule |
| 04:17:09 | <pumpkin> | (Num i) => [b] -> i vs. (Num b) => [a] -> b, can't you see they're different!!?!? |
| 04:17:50 | <aavogt> | @type const 0 . flip asTypeOf [] |
| 04:17:51 | <lambdabot> | forall t a. (Num t) => [a] -> t |
| 04:17:52 | <dmwit> | Of course, not all functions with that type are actually genericLength. |
| 04:18:30 | <SamB_XP> | http://worrydream.com/AlligatorEggs/#colorrule |
| 04:19:06 | <pumpkin> | @type \x -> snd (length x, 1) |
| 04:19:07 | <lambdabot> | forall a t. (Num t) => [a] -> t |
| 04:20:55 | <aavogt> | why the different order in the forall? |
| 04:21:11 | <dmwit> | There's nothing deep about it. |
| 04:21:31 | <aavogt> | just how the inference worked out? |
| 04:21:48 | <aavogt> | @type \x -> fst (1,length x) |
| 04:21:49 | <lambdabot> | forall t a. (Num t) => [a] -> t |
| 04:21:55 | <SamB_XP> | ACTION isn't sure why kids would mind *alligators* dying ... |
| 04:21:57 | <dmwit> | aavogt: right |
| 04:22:24 | <hackagebot> | Lucu 0.3 |
| 04:22:25 | <SamB_XP> | aavogt: there's no meaning to the order in a forall |
| 04:22:48 | <pumpkin> | @hackage Lucu |
| 04:22:49 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Lucu |
| 04:23:10 | <pumpkin> | demonic! |
| 04:23:24 | <hackagebot> | haskeem 0.6.10 |
| 04:23:55 | <pumpkin> | Network.HTTP.Lucu.Abortion o.O |
| 04:24:01 | <dmwit> | There's an Abortion module! |
| 04:24:04 | <dmwit> | damn, beat me to it |
| 04:24:15 | <sshc_> | what is the purpose of (Num b)? (before the <=) |
| 04:24:24 | <dmwit> | sshc_: It's a class constraint. |
| 04:24:25 | <pumpkin> | sshc_: it puts a constraint on the type variable b |
| 04:24:26 | <SamB_XP> | sshc_: you mean the => |
| 04:24:35 | <dmwit> | sshc_: It says that "b" has to be a type that implements the Num interface. |
| 04:24:52 | <dmwit> | sshc_: Num has methods like (*), (+), (/), negate, etc. |
| 04:25:02 | <aavogt> | @class |
| 04:25:02 | <lambdabot> | Unknown command, try @list |
| 04:25:07 | <dmwit> | ?src Num |
| 04:25:07 | <lambdabot> | class (Eq a, Show a) => Num a where |
| 04:25:07 | <lambdabot> | (+), (-), (*) :: a -> a -> a |
| 04:25:07 | <lambdabot> | negate, abs, signum :: a -> a |
| 04:25:07 | <lambdabot> | fromInteger :: Integer -> a |
| 04:25:22 | <sshc_> | thanks, guys. |
| 04:25:29 | <dmwit> | Okay, so (/) isn't in there, sorry for that bit of misinformation. |
| 04:25:46 | <dmwit> | "This site is surely hosted by Lucu." |
| 04:25:52 | <dmwit> | Glad we definitely know that! =) |
| 04:26:49 | <outchanter> | ?src Fractional |
| 04:26:49 | <lambdabot> | class (Num a) => Fractional a where |
| 04:26:49 | <lambdabot> | (/) :: a -> a -> a |
| 04:26:49 | <lambdabot> | recip :: a -> a |
| 04:26:49 | <lambdabot> | fromRational :: Rational -> a |
| 04:27:45 | <aavogt> | SamB_XP: yep. I was mostly wondering how type variable names are propagated |
| 04:28:11 | <SamB_XP> | aapole: well, I think they have to sacrifice a virgin once a month or so ... |
| 04:29:04 | <SamB_XP> | er. |
| 04:29:06 | <SamB_XP> | aavogt: |
| 04:29:12 | <dmwit> | :t genericLength :: [a] -> Num b => b -- this ought to confuse people |
| 04:29:13 | <lambdabot> | on the commandline: |
| 04:29:13 | <lambdabot> | Warning: -fno-th is deprecated: use -XNoTemplateHaskell or pragma {-# LANGUAGE NoTemplateHaskell#-} instead |
| 04:29:13 | <aavogt> | or rather, that the order in the forall depends on the order the expressions they represent occur (but clearly could be done differently) |
| 04:29:38 | <dmwit> | Damn, I only confused myself |
| 04:29:58 | <SamB_XP> | dmwit: no, I think Cale or gwern must have messed something up ...? |
| 04:30:08 | <SamB_XP> | :t genericLength |
| 04:30:10 | <lambdabot> | forall b i. (Num i) => [b] -> i |
| 04:30:16 | <Cale> | hmm... |
| 04:30:21 | <dmwit> | SamB_XP: Typing the same thing into ghci here makes ghc panic! |
| 04:30:23 | <SamB_XP> | :t genericLength :: [a] -> Num b => b -- this ought to confuse people |
| 04:30:24 | <lambdabot> | on the commandline: |
| 04:30:25 | <lambdabot> | Warning: -fno-th is deprecated: use -XNoTemplateHaskell or pragma {-# LANGUAGE NoTemplateHaskell#-} instead |
| 04:30:28 | <SamB_XP> | what the! |
| 04:30:37 | <Cale> | odd |
| 04:30:40 | <dmwit> | SamB_XP: But I know I've done this before... |
| 04:30:41 | <SamB_XP> | oh. |
| 04:30:55 | <SamB_XP> | that's unusual syntax ... |
| 04:31:02 | <dmwit> | Yes indeedy. |
| 04:31:06 | <aavogt> | dmwit: implicitly doing Rank2 polymorphism? |
| 04:31:13 | <dmwit> | aavogt: No rank-2 here. |
| 04:31:15 | <SamB_XP> | maybe it messes up HSX ? |
| 04:31:19 | <dmwit> | Plain old rank-1 polymorphism. |
| 04:31:37 | <SamB_XP> | :t genericLength :: [a] -> Num b => b |
| 04:31:37 | <dmwit> | The type should be totally equivalent to Num b => [a] -> b. |
| 04:31:38 | <lambdabot> | on the commandline: |
| 04:31:38 | <lambdabot> | Warning: -fno-th is deprecated: use -XNoTemplateHaskell or pragma {-# LANGUAGE NoTemplateHaskell#-} instead |
| 04:31:48 | <SamB_XP> | :t (genericLength :: [a] -> Num b => b) |
| 04:31:49 | <lambdabot> | on the commandline: |
| 04:31:50 | <lambdabot> | Warning: -fno-th is deprecated: use -XNoTemplateHaskell or pragma {-# LANGUAGE NoTemplateHaskell#-} instead |
| 04:31:54 | <aavogt> | [a] -> (forall b. Num b => b) -- isn't too far from what you put |
| 04:32:09 | <SamB_XP> | :t [a] -> (forall b. Num b => b) |
| 04:32:11 | <lambdabot> | parse error on input `->' |
| 04:32:15 | <aavogt> | or is that just normal? |
| 04:32:22 | <SamB_XP> | :t _ :: [a] -> (forall b. Num b => b) |
| 04:32:24 | <lambdabot> | Pattern syntax in expression context: _ |
| 04:32:28 | <QtPlaty[HireMe]> | I have a structure S x which I wish to interate over the elemetents within this structure to generate a second struture S y. |
| 04:32:31 | <SamB_XP> | :t undefined :: [a] -> (forall b. Num b => b) |
| 04:32:32 | <lambdabot> | forall a b. (Num b) => [a] -> b |
| 04:33:12 | <dibblego> | QtPlaty[HireMe], check out the (>>=) function |
| 04:33:22 | <QtPlaty[HireMe]> | However the elements that I use within the second structure depend on all the previous elements I've iterated over. What is the best abstraction for this? |
| 04:34:04 | <aavogt> | SamB_XP: that clears it up for me |
| 04:34:14 | <BMeph> | dibblego, QtPlaty[HireMe]: Perhaps, the (=>>) function is better? ;) |
| 04:34:27 | <dibblego> | heh yeah praps |
| 04:35:04 | <QtPlaty[HireMe]> | BMeph: Which libary is =>> in? |
| 04:35:13 | <BMeph> | I wrote a function like that - I just broke it down all nasty-like. I'll have to see what comonads get me. |
| 04:35:34 | <BMeph> | QtPlaty[HireMe]: That's in the category-extras lib. :) |
| 04:35:44 | <dmwit> | aavogt: Sorry, I was filing a bug report. Yeah, that's basically what I put, but it is still not rank-2 polymorphism. =) |
| 04:36:20 | <dmwit> | rank-2 has foralls to the left of arrows |
| 04:36:42 | <dmwit> | (rank-3 has a rank-2 type to the left of an arrow, rank-4 has a rank-3 type to the left of an arrow, etc.) |
| 04:38:16 | <aavogt> | ACTION wonders if rank-0 is not actually polymorphism, or something different... |
| 04:38:58 | <dmwit> | Well, rank-1 polymorphism would have rank-0 types to the left of arrows, so... rank-0 sounds like monomorphism to me. |
| 04:40:30 | <QtPlaty[HireMe]> | BMeph: Which module? |
| 04:45:39 | <BMeph> | QtPlaty[HireMe]: Control.Comonad |
| 04:47:10 | <dancor> | what is better x1:_ or x0:_ |
| 04:47:23 | <dmwit> | They look the same to me. |
| 04:47:25 | <dancor> | don't say x:_, you have to choose one |
| 04:47:31 | <dancor> | mm |
| 04:47:36 | <BMeph> | dancor: What'sa wrong with x:_? ;p |
| 04:47:37 | <dmwit> | 0-indexing is consistent with (!!) |
| 04:47:38 | <SamB_XP> | y:_ |
| 04:47:45 | <dancor> | dmwit: that's true |
| 04:47:59 | <dancor> | sold |
| 05:01:06 | <dmwit> | Amazing. I just found a book in my school's library via Google books that I couldn't find via our own catalog. |
| 05:07:21 | <pumpkin> | wow |
| 05:09:41 | <dons> | dmwit: google books knows what is in your library? |
| 05:09:48 | <dmwit> | ACTION nods |
| 05:09:52 | <dmwit> | Amazing, isn't it? |
| 05:10:09 | <dons> | is your library the library of congress? |
| 05:10:13 | <dmwit> | hehe |
| 05:10:46 | <dmwit> | Google apparently interfaces with worldcat.org. |
| 05:10:51 | <dmwit> | It is way cool. |
| 05:11:57 | <dons> | "Find this book in a library" <-- cool |
| 05:12:12 | <mmorrow> | dancor: haha. i was dead serious :) |
| 05:12:27 | <dons> | oh man, and it knows where i live. |
| 05:13:03 | <dons> | huh. that is cool. so yeah, it says RWH is in a nearby library. |
| 05:17:05 | <bos> | not bad. lazy text does "wc -w" on a 300MB UTF-8 file in 2.5x the time of the real "/usr/bin/wc -l". |
| 05:17:18 | <bos> | and that's without the slightest attempt at speeding it up. |
| 05:18:10 | <bos> | ACTION loves combining quickcheck with code optimisation |
| 05:18:12 | <dons> | hmm. its interesting how easy it is to beat wc. that was the first benchmark i used for strict bytestrings back in the day.http://haskell.org/haskellwiki/Wc |
| 05:18:28 | <dons> | very small buffer size, in wc, iirc |
| 05:19:47 | <bos> | my UTF-8 decoding code for chunked bytestrings is not in the slightest bit optimized :-) |
| 05:19:53 | <dons> | mmm |
| 05:20:02 | <dons> | chunked is a pain too, i bet. |
| 05:20:13 | <bos> | it can be, but doesn't have to be awful. |
| 05:20:29 | <dons> | so how far are we from recommending 'text' for the platform set? |
| 05:21:13 | <dmwit> | dons: Do you respect locale the way wc does? |
| 05:21:14 | <bos> | i'd really like people to start using it and reporting bugs and shortcomings for a few months. |
| 05:21:30 | <dmwit> | I seem to recall wc does something wackily slow in some locales... |
| 05:21:34 | <bos> | but in order to do that, it needs a little more performance tuning. |
| 05:21:59 | <bos> | if i can speed up UTF-8 decoding by say 50%, i'll start asking people to actively use it. |
| 05:27:21 | <ryant5000> | what would be a good datastructure for storing tags? I need to be able to do queries that accept any combination of "must have tag X" or "must not have tag Y" |
| 05:27:51 | <ryant5000> | i.e.: taking tags as predicates, i should be able to specify any conjunction of possibly-negated predicates |
| 05:28:32 | <sjanssen> | maybe Map Tag (Set object)? |
| 05:28:52 | <ryant5000> | sjanssen: well, then i have to do intersections all the time; aren't they slow? |
| 05:29:25 | <ryant5000> | (intersections and set-subtractions, i suppose) |
| 05:29:31 | <sjanssen> | hmm, linear I suppose |
| 05:30:02 | <ryant5000> | (if my analysis is correct, writing an efficient datastructure that allows *arbitrary* boolean expressions is equivalent to solving the binary satisfiability problem in P, so i'm not trying for that) |
| 05:30:09 | <mmorrow> | dancor: here's an example of a prog that uses TH to gen code, and spits it to stdout (experimenting with unrolling... this particular attempt was a failure (==> much slower because of the overhead of more function calls)) |
| 05:30:12 | <mmorrow> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5521 |
| 05:30:13 | <ryant5000> | linear in the size of the smallest set would be fine |
| 05:30:20 | <mmorrow> | it spits 5500 lines of this to stdout: |
| 05:30:30 | <mmorrow> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5521#a5522 |
| 05:30:31 | <ryant5000> | but linear in the largest set isn't so good |
| 05:30:55 | <outchanter1> | ryant: keep the sets in a heap? |
| 05:33:12 | <outchanter> | wait, that wouldn't help |
| 05:33:21 | <sjanssen> | ryant5000: it can be done in O(n log m) where n are the total number of objects in each tag an m is the number of tags |
| 05:34:07 | <ryant5000> | outchanter: yeah, i need fast intersection, not fast union (had to look up heaps, lol; it's been a while) |
| 05:34:13 | <mmorrow> | bos: re utf8 stuff, this is interesting http://www.daemonology.net/blog/2008-06-05-faster-utf8-strlen.html |
| 05:34:22 | <mmorrow> | bos: __builtin_prefetch ftw |
| 05:34:30 | <ryant5000> | sjanssen: how so? |
| 05:34:37 | <mmorrow> | (ft huge w) |
| 05:34:38 | <bos> | mmorrow: yeah |
| 05:34:47 | <bos> | mmorrow: but not of much practical relevance here |
| 05:34:55 | <dmwit> | ryant5000: How about Map Tag (Set object, Set object), where for each Tag, the union of the two sets is all of the objects? |
| 05:34:58 | <sjanssen> | ryant5000: using an n-way merge algorithm |
| 05:35:01 | <mmorrow> | bos: heh, true |
| 05:35:11 | <mmorrow> | (although i secretly hoped it might be ;) |
| 05:35:18 | <outchanter> | ryant5000: I meant to find the smallest set, but you'd only want the smallest out of the subset you're interested in, not all of them |
| 05:35:36 | <dmwit> | ryant5000: So selecting those with tag foo is (fst . (!foo)), and selecting those without tag foo is (snd . (!foo)). |
| 05:36:13 | <dmwit> | Adding or removing a tag from an object moves it from one Set to the other. |
| 05:36:20 | <mmorrow> | i wonder what an ffi wrapper for gcc's __builtin_prefetch would give |
| 05:36:29 | <pumpkin> | mmorrow: I don't think it's a function |
| 05:36:29 | <ryant5000> | outchanter: ah, i see |
| 05:36:34 | <dmwit> | Of course, you won't want to be adding tags that you've never seen before very often... |
| 05:36:36 | <mmorrow> | pumpkin: just wrap it |
| 05:36:46 | <pumpkin> | mmorrow: but ffi wrappers try to link to that symbol |
| 05:36:51 | <ryant5000> | dmwit: yeah, that makes adding new tags really expensive |
| 05:36:53 | <sjanssen> | ryant5000: basically you keep the sets in a min-heap, repeatedly popping the set with the smallest value, then putting it back with that value removed |
| 05:36:55 | <pumpkin> | and it's not an exported symbol |
| 05:37:00 | <pumpkin> | of anything |
| 05:37:03 | <mmorrow> | pumpkin: sure, so wrap it in another C function :) |
| 05:37:14 | <mmorrow> | and ffi import that |
| 05:37:18 | <pumpkin> | mmorrow: oh, lol |
| 05:37:33 | <pumpkin> | seems like we could make a primop for it though |
| 05:37:36 | <pumpkin> | just like gcc did :P |
| 05:37:39 | <ryant5000> | would it be helpful to think of this datastructure as a matrix of booleans with tags on one side and objects on another? |
| 05:37:49 | <mmorrow> | ACTION is wrapping it now |
| 05:37:54 | <pumpkin> | mmorrow: TMI |
| 05:38:03 | <dmwit> | > let merge ((x:xs):xss) = x : insert xs xss; merge ([]:xss) = merge xss; merge [] = [] in merge [[2,3,5], [4,6]] |
| 05:38:05 | <lambdabot> | Occurs check: cannot construct the infinite type: t = [t] |
| 05:38:06 | <ryant5000> | then it would be reminiscent of a Karnaugh (sp?) map |
| 05:38:06 | <sjanssen> | ryant5000: are the set of tags closed? |
| 05:38:16 | <mmorrow> | touch hs-prefetch.cabal |
| 05:38:18 | <dmwit> | > let merge ((x:xs):xss) = x : merge (insert xs xss); merge ([]:xss) = merge xss; merge [] = [] in merge [[2,3,5], [4,6]] |
| 05:38:18 | <lambdabot> | [2,3,4,5,6] |
| 05:38:39 | <dmwit> | n-way merge for ascending lists =) |
| 05:39:02 | <ryant5000> | sjanssen: hm; i'm not sure |
| 05:39:23 | <ryant5000> | sjanssen: (i'm willing to make compromises on the API of this datastructure if they help a lot) |
| 05:39:52 | <sjanssen> | ryant5000: anyway, I think n log m is pretty good, and the algorithm will be easy to write |
| 05:40:26 | <dmwit> | ryant5000: May I suggest pushing this into a database? |
| 05:40:39 | <dmwit> | Relations are what they're good at. |
| 05:40:52 | <ryant5000> | sjanssen: yeah, that's probably good enough |
| 05:40:57 | <dmwit> | And queries of the kind you're suggesting are definitely a one-liner in SQL. |
| 05:41:12 | <ryant5000> | dmwit: well, i've struggled with that issue for a long time |
| 05:41:27 | <ryant5000> | dmwit: there are lots of things i'd love to put in databases... but they're usually complicated Haskell datstructures |
| 05:41:37 | <dmwit> | ACTION nods |
| 05:41:37 | <ryant5000> | dmwit: i don't want to serialize/deserialize stuff all the time |
| 05:41:51 | <ryant5000> | i kind of want to build a haskell-native RDBMS |
| 05:41:57 | <outchanter> | what algorithm does the average database use for finding intersections? |
| 05:44:18 | <outchanter> | the fastest I can think of off the top of my head is (1) of the tags you're interested in, find the smallest set (assuming you have a map from tags to sets) (2) filter that set according to the other tags |
| 05:44:48 | <outchanter> | which is order (sum of tags on item i for i in smallest set) |
| 05:45:04 | <pumpkin> | if you already have an index (which many databases do) you can do it more efficiently |
| 05:46:49 | <outchanter> | doesn't the map from tags to sets count as an index? |
| 05:48:25 | <mathijs> | Hi all, I'm building a tree-like structure but I want some extra rules to apply, let's say that certain tupes of nodes can only 'grow' on top of some other nodes, but x..7 levels deep. ofcourse I can make a 'validate' function that checks if a tree plays by the rules, but I would like to put the typesystem to use somehow, since there aren't that many rules. |
| 05:49:00 | <mathijs> | s/7/y/ |
| 05:49:01 | <sjanssen> | outchanter: hmm, I like your idea better |
| 05:49:56 | <sjanssen> | O(n log m) where n is the smallest set, m are the number of tags you need to check |
| 05:51:29 | <sjanssen> | wait, no. O(n m log t), where t is the total number off tags. Not so nice when your query involves lots of tags |
| 05:51:52 | <ryant5000> | sjanssen: isn't it O(n t log m)? |
| 05:52:50 | <outchanter> | it depends how you do the filtering. If each item has very few tags, you just have to check that none of them are forbidden and that all the required ones are there. If each item has very few tags and there are lots of required tags, your query will return no items anyway |
| 05:53:15 | <ryant5000> | can we get any traction out of having a converse mapping? |
| 05:53:23 | <ryant5000> | Map Object (Set Tag)? |
| 05:53:40 | <ryant5000> | that might make filtering each object cheaper |
| 05:53:55 | <sjanssen> | ryant5000: yes, you'd have to have this mapping as well |
| 05:55:05 | <sjanssen> | the question is, given an object's tag set, the set of tags the object must have and must not have, what is the fastest way to determine whether the constraints are satisfied? |
| 05:55:30 | <sjanssen> | sum of the cardinality of each set, right? |
| 05:56:33 | <ryant5000> | sjanssen: yes, that's the question |
| 05:58:07 | <ryant5000> | sjanssen: i suppose it could be as bad as the sum of the cardinalities of all the sets referred to in the query |
| 05:58:58 | <outchanter> | actually I think you can do it in the smaller of the cardinalities |
| 05:59:15 | <outchanter> | if the item has fewer tags than the number of required tags, it's out by default |
| 06:00:21 | <tibbe> | does Haskell ship with a mutable array type equivalent of data Array a = Array { elems :: !(Ptr a), size :: !Int, capacity :: !Int } ? |
| 06:00:31 | <ryant5000> | outchanter: yeah, that's true |
| 06:00:46 | <tibbe> | for Storable a |
| 06:00:54 | <sjanssen> | tibbe: StorableArray |
| 06:01:26 | <ryant5000> | is there a tutorial on how to write your own rdbms? |
| 06:01:34 | <ryant5000> | i'd like to just skim some stuff on it |
| 06:01:46 | <ryant5000> | i guess that might be more of a "huge tome-like book" sort of thing |
| 06:02:17 | <ryant5000> | i think ideally i'd like to be have a pile of objects |
| 06:02:24 | <ryant5000> | and a bunch of projection functions |
| 06:02:39 | <ryant5000> | with an index corresponding to each projection function |
| 06:02:56 | <ryant5000> | and each index allows the objects to be looked up based on their projected values |
| 06:03:00 | <blackh> | ryant5000: I am online and saying hello. |
| 06:04:25 | <solrize> | is 6.10.3 the best ghc to use these days? or should non-bleeding-edge users stay with earlier versions? |
| 06:04:42 | <dons> | solrize: use whatever the haskell platform specifies |
| 06:05:14 | <solrize> | "Note: the source tarball requires that you already have ghc-6.10.3 (or 6.10.4) installed." |
| 06:05:22 | <tibbe> | sjanssen: does it used pinned memory or not? I only intend to pass it it "unsafe" FFI functions |
| 06:06:05 | <sjanssen> | tibbe: via ForeignPtr, so pinned |
| 06:06:18 | <Cale> | solrize: Yes, use the latest released GHC. |
| 06:06:26 | <solrize> | thanks |
| 06:06:44 | <solrize> | looks like that's 8.10.3 and not .4 ? |
| 06:06:49 | <solrize> | 6.10.3 |
| 06:06:51 | <Cale> | yeah |
| 06:07:01 | <sjanssen> | solrize: the only thing you generally want to wait on is the first minor release in a new major release series |
| 06:07:04 | <Cale> | solrize: There are a few bugs in 6.10.1 and 6.10.2 which made them somewhat unusable for me. |
| 06:07:15 | <MyCatVerbs> | I dunno, 6.6.2 had a nice, solid oaken feel to it. |
| 06:07:28 | <solrize> | yeah, i remember hearing something about the first 6.10's being for early adopters |
| 06:07:34 | <solrize> | downloading |
| 06:07:39 | <MyCatVerbs> | 6.8.* weren't that much of a step up or down. 6.10.3's good, though. |
| 06:07:41 | <sjanssen> | solrize: things tend to break, and it's usually a month or so before most of hackage catches up |
| 06:07:46 | <tibbe> | sjanssen: so if I want to pass it to the kevent system call on Mac OS X I want a StorableArray? Is it unboxed? |
| 06:08:04 | <solrize> | i can install 6.10.3 over top of the 6.8.2 that i'm already using? |
| 06:08:10 | <sjanssen> | tibbe: you should probably see the fine manual at this point |
| 06:08:24 | <tibbe> | sjanssen: the GHC manual you mean? |
| 06:08:31 | <Cale> | solrize: yes, though it won't overwrite it |
| 06:08:32 | <quicksilver> | tibbe: I'm not sure your question even makes sense. |
| 06:08:34 | <sjanssen> | tibbe: the docs for Data.Array.Storable |
| 06:08:38 | <solrize> | cool |
| 06:08:39 | <quicksilver> | tibbe: a Ptr is a Ptr. |
| 06:08:52 | <quicksilver> | tibbe: although Ptrs themselves are boxed, the data they point to is just data. |
| 06:09:02 | <MyCatVerbs> | solrize: yeah, they put everything into entirely seperate directories, except for the top-level invocation stuff in /usr/local/bin. |
| 06:09:03 | <tibbe> | quicksilver: I want to pack it together with the capacity and current number of used elements |
| 06:09:23 | <tibbe> | quicksilver: and I want a type that unpacks nicely like the one I gave above |
| 06:10:02 | <MyCatVerbs> | solrize: AFAIK most of the GHC devs have at least three forgotten but still working copies of GHC hanging around in various places in their filesystems. It's a pretty well-supported situation, all told. ;) |
| 06:10:06 | <Cale> | tibbe: The bounds of the array will already be available from getBounds |
| 06:10:49 | <Cale> | tibbe: A Storable array is unpacked, in fact, it's usable from C code, since it uses the Storable instance to write the elements into a continuous block of memory. |
| 06:10:57 | <sjanssen> | tibbe: the array infrastructure actually provides more than you want, you'd probably be better off with your own type |
| 06:11:05 | <tibbe> | Cale: right, that's what I want. I initially rolled my own array type which had fields for bounds and size. I was wondering if there's a predefined type I could use |
| 06:12:00 | <tibbe> | sjanssen: want I'm trying to do is to implement a growable array which I from time to time will pass to C |
| 06:12:05 | <bos> | tibbe: i wouldn't use StorableArray. it's pretty heavyweight. |
| 06:12:29 | <tibbe> | bos: :) |
| 06:12:32 | <tibbe> | bos: there you are |
| 06:12:47 | <tibbe> | bos: I need a growable array for kqueue |
| 06:12:51 | <roconnor> | tibbe: doesn't Edison implement containers such as that? |
| 06:12:53 | <tibbe> | bos: I rolled my own |
| 06:12:58 | <tibbe> | roconnor: dunno |
| 06:13:01 | <bos> | tibbe: seems like a reasonable thing to do. |
| 06:13:08 | <tibbe> | roconnor: I need a pretty barebones container |
| 06:13:11 | <tibbe> | bos: OK |
| 06:13:21 | <roconnor> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/EdisonCore |
| 06:13:29 | <tibbe> | roconnor: I'll have a look |
| 06:13:35 | <MyCatVerbs> | bos: it's perfectly cromulent for conversing with C code. And AIUI the only interesting slowdown it should have in current GHC is that they're much slower to allocate than IOU or STU arrays. |
| 06:13:37 | <sjanssen> | tibbe: StorableArray also isn't growable |
| 06:13:38 | <roconnor> | * Data.Edison.Seq.BankersQueue |
| 06:13:43 | <roconnor> | Data.Edison.Seq.MyersStack |
| 06:13:53 | <tibbe> | bos: I'm thinking about putting a Haskell function |
| 06:13:56 | <roconnor> | Data.Edison.Assoc.PatriciaLoMap |
| 06:14:03 | <tibbe> | bos: (pointer) in the Storable instance |
| 06:14:07 | <roconnor> | I don't even know what these are! |
| 06:14:13 | <roconnor> | it must be good! |
| 06:14:14 | <tibbe> | bos: so I can easily get hold of it once an event fires |
| 06:15:20 | <mmorrow> | pumpkin: hs-prefetch: http://moonpatio.com/repos/hs-prefetch/ |
| 06:15:23 | <bos> | tibbe: yep |
| 06:15:26 | <pumpkin> | mmorrow: zomg |
| 06:15:36 | <mmorrow> | it's got function to prefetch ByteString for either read or writes |
| 06:15:38 | <tibbe> | bos: would I use FunPtr for that? |
| 06:15:45 | <mmorrow> | and with 4 levels of temporal locality |
| 06:15:45 | <solrize> | GHCi, version 6.10.3: http://www.haskell.org/ghc/ :? for help |
| 06:15:45 | <solrize> | Loading package ghc-prim ... linking ... done. |
| 06:15:45 | <solrize> | Loading package integer ... linking ... done. |
| 06:15:45 | <solrize> | Loading package base ... linking ... done. |
| 06:15:45 | <solrize> | Prelude> |
| 06:15:47 | <solrize> | woo hoo |
| 06:15:49 | <solrize> | thanks |
| 06:15:55 | <mmorrow> | http://moonpatio.com/repos/hs-prefetch/haddocks/ |
| 06:15:58 | <pumpkin> | mmorrow: does it make any difference? |
| 06:16:03 | <bos> | tibbe: you want to be able to call it from C? i think so, then. |
| 06:16:17 | <tibbe> | bos: no, just from Haskell |
| 06:16:17 | <mmorrow> | pumpkin: i haven't even tried it yet :) |
| 06:16:24 | <bos> | ACTION does calls from C to Haskell once a year, maybe, so always has to RTFM then |
| 06:16:28 | <pumpkin> | mmorrow: but it compiles so it must be correct, right? :D |
| 06:16:33 | <bos> | tibbe: oh, then just store the function directly. |
| 06:16:37 | <pumpkin> | mmorrow: I'd be interested though |
| 06:16:46 | <mmorrow> | pumpkin: i'm definitely going to test it out |
| 06:16:48 | <MyCatVerbs> | pumpkin: I call your dangerous assumptions and raise you fix id. |
| 06:16:57 | <tibbe> | bos: it needs to be persisted on the C side though in a void * field |
| 06:17:07 | <bos> | tibbe: i see. |
| 06:17:09 | <pumpkin> | MyCatVerbs: you don't know my definition of correct :D |
| 06:17:21 | <tibbe> | bos: so some kind of stable pointer |
| 06:17:28 | <bos> | tibbe: right |
| 06:17:30 | <tibbe> | bos: so the GC won't move the closure |
| 06:17:50 | <tibbe> | bos: I'm a bit lost in the pletoria of *Ptrs in the FFI spec |
| 06:17:59 | <tibbe> | bos: I'll go rtfm again |
| 06:18:11 | <pumpkin> | mmorrow: maybe worth making a prefetch :: TemporalLocality -> a -> IO () ? |
| 06:18:12 | <MyCatVerbs> | pumpkin: so far I'm beginning to suspect that it comes to, "generates an executable file which matches the pattern B*, where B denotes a byte in the range 0-255." ;P |
| 06:18:19 | <pumpkin> | :P |
| 06:18:31 | <pumpkin> | what if it doesn't even do that |
| 06:19:10 | <MyCatVerbs> | tibbe: for throwing bare Ptrs around, Foreign.Storable and Foreign.Marshall.Alloc. |
| 06:19:39 | <tibbe> | MyCatVerbs: are Ptrs relocatable or not? |
| 06:19:48 | <bos> | tibbe: a Ptr is a C pointer |
| 06:19:51 | <MyCatVerbs> | tibbe: Christ no. |
| 06:20:08 | <tibbe> | bos: so then that won't work for the void* user data field |
| 06:20:11 | <pumpkin> | mmorrow: or even just a referentially transparent version, prefetch :: a -> a that acts a bit like a seq (maybe the form I'd like to see if it were a primop) |
| 06:20:13 | <bos> | right. |
| 06:20:43 | <bos> | tibbe: the magic needed for the ability to store a pointer to a haskell function in a C-compatible way is a bit involved. |
| 06:20:51 | <bos> | i think dons has an example of it in the FFI chapter of RWH. |
| 06:20:55 | <pumpkin> | mmorrow: since it should never affect the behavior of your program if you provide it a valid address |
| 06:21:10 | <bos> | it's nice to be able to read one's own book for examples of stuff one forgets how to do. |
| 06:21:45 | <mmorrow> | pumpkin: here're the opcodes it uses on x86_64: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2544 |
| 06:21:48 | <MyCatVerbs> | tibbe: generally, alloca (in Foreign.Marshal.Alloc) if you want to allocate space for a single temp variable, and usually use StorableArrays if you want to cons up arrays that are easy to access from both C and Haskell. |
| 06:21:58 | <mmorrow> | pumpkin: yeah, inlinePerformIO even |
| 06:22:35 | <tibbe> | bos: I tend to reread RWH for the FFI stuff often |
| 06:22:50 | <tibbe> | MyCatVerbs: ok |
| 06:22:51 | <MyCatVerbs> | tibbe: for passing structs around, you really ought to use hsc2hs or something, because doing it all by hand is no fun at all. |
| 06:22:54 | <mmorrow> | pumpkin: hmm, but prefetch :: TemporalLocality -> a -> IO () ... how do you get the ptr to `a'? |
| 06:23:03 | <tibbe> | MyCatVerbs: I use hsc2hs |
| 06:23:08 | <mmorrow> | (just saw that part) |
| 06:23:19 | <tibbe> | MyCatVerbs: the problem is that I want to store a pointer to a haskell function in a C struct |
| 06:23:31 | <pumpkin> | mmorrow: it's gotta be somewhere? :P GHC knows where to go look for the box |
| 06:23:33 | <mmorrow> | pumpkin: (or are you assuming here it's been made a |
| 06:23:36 | <mmorrow> | ok |
| 06:23:42 | <mmorrow> | .. made a primop) |
| 06:23:48 | <pumpkin> | unpackClosure maybe in the mean time? |
| 06:23:51 | <pumpkin> | # |
| 06:24:06 | <pumpkin> | not sure if that'd be meaningful unless you had a lot of unboxed values in your constructor though |
| 06:24:37 | <mmorrow> | oh, i know of a way that's steals an StgClosure* from a StablePtr, but that has the overhead of making a StablePtr.. |
| 06:24:45 | <MyCatVerbs> | tibbe: and my last bit of advice is that if you feel the need to use FunPtr... Christ, that's a pain in the neck, rethink a little ;) |
| 06:24:49 | <mmorrow> | (and the Ptr can move next GC) |
| 06:24:51 | <pumpkin> | mmorrow: it doesn't need to be stable though |
| 06:25:11 | <mmorrow> | but i need the StablePtr to get at the StgClosure* |
| 06:25:20 | <tibbe> | MyCatVerbs: heh |
| 06:25:24 | <mmorrow> | (there's literally no non-haX way) |
| 06:25:29 | <pumpkin> | doesn't unsafeCoercing any value to an Addr have that effect though? |
| 06:25:40 | <pumpkin> | any evaluated |
| 06:25:41 | <mmorrow> | pumpkin: possibly |
| 06:25:41 | <MyCatVerbs> | tibbe: oh, there's also Foreign.ForeignPtr if you want a slightly lighter-weight alternative to Data.Array.Storeable. |
| 06:25:41 | <solrize> | oh man, the platform has a bunch of ubuntu package dependencies that aren't so easy to figure out |
| 06:25:52 | <mmorrow> | pumpkin: try it! |
| 06:25:53 | <pumpkin> | mmorrow: I mean, it can't too indirect to get at the location in memory |
| 06:25:55 | <pumpkin> | lol |
| 06:26:08 | <mmorrow> | you'd probably want to seq it too |
| 06:26:13 | <mmorrow> | (or better, pseq it) |
| 06:26:31 | <tibbe> | MyCatVerbs: as I understand it it's safe to pass a Ptr to C if the C function is "unsafe" and doesn't hold on to the Ptr |
| 06:26:51 | <mmorrow> | ACTION gives it 5-7% chance of working, but that's > 0% ;) |
| 06:27:19 | <MyCatVerbs> | tibbe: er, the situation is not quite *that* bad. :) |
| 06:28:01 | <mmorrow> | pumpkin: hmm, you probably want to coerce it to an unboxed type (i don't think you're allowed though..) |
| 06:28:11 | <MyCatVerbs> | tibbe: it's safe to pass a Ptr to C if the C code won't attempt to use that Ptr after it's no longer being backed by memory. Different ways of getting ahold of Ptrs have different lifespans! |
| 06:28:13 | <pumpkin> | I was planning on doing Addr# |
| 06:28:19 | <mmorrow> | ooh nice |
| 06:28:37 | <MyCatVerbs> | tibbe: e.g. Ptrs from alloca become invalid as soon as the IO action passed to alloca returns. |
| 06:28:37 | <mmorrow> | can you coerce to unboxed types? |
| 06:28:48 | <pumpkin> | with unsafeCoerce# you can |
| 06:28:53 | <mmorrow> | woo |
| 06:29:08 | <tibbe> | MyCatVerbs: but if I mallocArray to get a pointer can I pass that to C? |
| 06:29:15 | <MyCatVerbs> | tibbe: Ptrs from malloc won't ever become invalid until you pass them to free, after which they're in crazytown. |
| 06:29:20 | <tibbe> | MyCatVerbs: is that malloc on the C side |
| 06:29:47 | <MyCatVerbs> | tibbe: I mean Foreign.Marshal.Alloc.malloc -- where's mallocArray? |
| 06:29:53 | <mmorrow> | grr Couldn't match kind `*' against `#' |
| 06:30:08 | <pumpkin> | ur doin it rong |
| 06:30:32 | <tibbe> | MyCatVerbs: Foreign.Marshal.Array |
| 06:30:37 | <Gracenotes> | ugh. I always forget what Russel's paradox is |
| 06:31:02 | <Gracenotes> | only that set containing itself is paradoxical |
| 06:31:07 | <MyCatVerbs> | tibbe: yeah, those are all implemented using malloc. You'll need to free them afterwards, of course. |
| 06:31:13 | <Gracenotes> | or something like that |
| 06:31:22 | <tibbe> | MyCatVerbs: so no free finalizer attached by default? |
| 06:31:38 | <MyCatVerbs> | No. ForeignPtrs have finalisers, but malloc and free work just like in C. |
| 06:31:58 | <solrize> | tons of "magic number mismatch" errors from depended packages |
| 06:32:19 | <mux> | mallocForeignPtr calls malloc and attaches a finalizer at the same time |
| 06:32:19 | <MyCatVerbs> | Most of the time you want to allocate with a ForeignPtrs. The Ptrs you get from ForeignPtrs stay alive until the final time that touchForeignPtr is called on the ForeignPtr. |
| 06:32:46 | <mux> | but if you can use alloca instead, it's even better/safer |
| 06:33:19 | <solrize> | compiler warnings |
| 06:33:40 | <MyCatVerbs> | The most common way to use ForeignPtrs is a combinator called (withForeignPtr), which unwraps the ForeignPtr to give you a Ptr, executes the IO action that you pass to it, and then calls touchForeignPtr afterwards. That way the lifetime never comes out wrong. |
| 06:33:40 | <smorg> | Gracenotes: sets that are not members of themselves. |
| 06:34:01 | <Gracenotes> | right |
| 06:34:11 | <Gracenotes> | also, hurray wikipedia |
| 06:34:21 | <tibbe> | MyCatVerbs: I'm rereading the ffi spec ;) |
| 06:34:35 | <MyCatVerbs> | The dude in Bristol who shaves the faces of the dudes in Bristol who do not shave their faces themselves. |
| 06:34:57 | <MyCatVerbs> | Does that dude shave his own face? Scary knives to the first person who figures it out. |
| 06:35:18 | <lindzeyn> | Russel's Paradox |
| 06:35:30 | <lindzeyn> | *Russell |
| 06:35:52 | <mmorrow> | pumpkin: dang, doesn't seem to work (the way i just tried at least) |
| 06:35:52 | <outchanter> | it works if you add a delay. He could shave himself on alternate days |
| 06:36:06 | <pumpkin> | isn't working for me either, but I haven't given up! |
| 06:36:27 | <MyCatVerbs> | tibbe: I think SPJ's "Tackling the Awkward Squad" notes had a whole thing on the FFI, and it's fun to read besides. Perhaps you might want to hit it at some point. |
| 06:36:49 | <tibbe> | MyCatVerbs: I'll put it on top of my reading stack |
| 06:36:53 | <smorg> | barber paradox woot |
| 06:37:05 | <tibbe> | > push readingStack "awkward squad" |
| 06:37:06 | <lambdabot> | Not in scope: `push'Not in scope: `readingStack' |
| 06:37:08 | <MyCatVerbs> | I would like to note that Russell's Paradox sort of slinks away if you refuse to work in naive sets, but instead exclusively in recursively enumerable sets. |
| 06:37:10 | <mmorrow> | pumpkin: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2544#a2545 fail |
| 06:37:35 | <MyCatVerbs> | Then the question of the dude's face-shavery becomes trivial. You just reject it, because it's not a computable set. ^^ |
| 06:37:58 | <smorg> | Doesn't haskell being strongly typed fix such problems? |
| 06:38:05 | <lindzeyn> | Yes it does smorg |
| 06:38:16 | <MyCatVerbs> | smorg: ahahahaahah. |
| 06:38:18 | <tibbe> | hmm, when should one use an array allocated on the Haskell heap vs. the C heap? |
| 06:38:19 | <MyCatVerbs> | smorg: it helps. :) |
| 06:39:00 | <MyCatVerbs> | tibbe: you pretty much always want to do your allocations in Haskell. Haskell's allocators are much faster than C malloc. |
| 06:39:07 | <pumpkin> | mmorrow: there's got to be a way! :P |
| 06:39:22 | <tibbe> | MyCatVerbs: but didn't we just conclude that mallocArray et al used C malloc? |
| 06:39:27 | <pumpkin> | the true address can't be far off from whatever gets passed around in GHC |
| 06:39:48 | <solrize> | crashed with "configuring the editline-0.2.1.0 package failed". i opened trac ticket #56 |
| 06:40:35 | <mmorrow> | pumpkin: i tried for a good week and came up with nothing but that StablePtr hack (which depends on the particular workings of Stable.c) |
| 06:40:58 | <MyCatVerbs> | tibbe: IIRC they do indeed. But ForeignPtrs are allocated from Haskell's heap, and alloca is allocated on the stack. |
| 06:41:08 | <mmorrow> | pumpkin: the best part of it too is that the true address is so close you don't even realize it's there |
| 06:41:20 | <lindzeyn> | Is the problem still paradoxical if you use classes as presented in PM |
| 06:41:32 | <mmorrow> | reallyUnsafePtrEquality# is implemented with cmp |
| 06:41:36 | <mmorrow> | (or something) |
| 06:41:53 | <mmorrow> | you literally have the ptrs but you can't touch them! |
| 06:42:08 | <pumpkin> | hmm |
| 06:42:10 | <pumpkin> | feels fishy |
| 06:42:17 | <MyCatVerbs> | tibbe: in terms of allocation speed, it goes (roughly): registers are fastest, then alloca, then Haskell values, then ForeignPtr, then malloc is way off in the corner feeling sorry for itself. |
| 06:42:53 | <tibbe> | MyCatVerbs: then ForeignPtr it is |
| 06:43:07 | <mmorrow> | pumpkin: emitPrimOp [res] ReallyUnsafePtrEqualityOp [arg1,arg2] _ = stmtC (CmmAssign (CmmLocal res) (CmmMachOp mo_wordEq [arg1,arg2])) |
| 06:43:38 | <MyCatVerbs> | (No, you don't get control over what values end up in registers. But hey, maybe if we're all really good boys and girls, Simon Claus will have made the optimizer even cleverer by the time next Christmas rolls past. |
| 06:44:29 | <mmorrow> | pumpkin: (one could of course add a primop that hands you a ptr to whatever it gets passed and then watches with amusement as you blow your abdomen in half :) |
| 06:45:12 | <pumpkin> | yeah :) |
| 06:45:17 | <mmorrow> | do it! |
| 06:45:35 | <MyCatVerbs> | mmorrow: aren't there already, like, three in GHC.Base alone? |
| 06:45:53 | <mmorrow> | MyCatVerbs: not to get the ptr itself |
| 06:46:17 | <mmorrow> | (they change every gc..) |
| 06:46:35 | <MyCatVerbs> | ACTION nods. The perils of compacting GC. |
| 06:46:50 | <tibbe> | MyCatVerbs: hmm, ForeignPtrs can't be realloced |
| 06:47:32 | <pumpkin> | bah, this is really pointless :P but it should be possible! |
| 06:47:41 | <pumpkin> | surely what we're passing around is the pointer to the closure |
| 06:47:55 | <pumpkin> | when it boils down to it |
| 06:48:40 | <MyCatVerbs> | tibbe: indeed they can't. I think the only thing that *does* let you realloc is plain old malloc. |
| 06:48:43 | <Gracenotes> | soooooo. |
| 06:48:47 | <dons> | solrize: the platform source for unix requires you to install C libraries |
| 06:49:02 | <dons> | it would be far better if it was just packaged for your distro. |
| 06:49:05 | <tibbe> | MyCatVerbs: ok |
| 06:49:29 | <tibbe> | dons: what data type would you use for a growable mutable array that needs to be passed to C? |
| 06:49:34 | <MyCatVerbs> | tibbe: On the bright side, that won't really hurt you interestingly badly unless you are allocating thousands of the things. And, hey, most C programmers seem to be just about happy with their malloc() implementations. |
| 06:49:37 | <mmorrow> | pumpkin: ly |
| 06:49:40 | <mmorrow> | exact |
| 06:49:49 | <pumpkin> | orrow |
| 06:49:55 | <dons> | tibbe: hmm. Foreign.Marshall.Array |
| 06:49:58 | <pumpkin> | mm: you feeling backwards? |
| 06:49:59 | <dons> | (supports realloc) |
| 06:50:23 | <tibbe> | dons: we were just discussing allocation speed of Ptrs vs ForeignPtrs |
| 06:50:26 | <mmorrow> | pumpkin: more inside outy |
| 06:50:28 | <solrize> | dons, i think it would help if it said exactly what packages to install. also it's not obvious that the editline configuration error is due to a C library installation issue |
| 06:50:45 | <tibbe> | dons: I want realloc that often (I expect the size to grow to some constant C and stop there) |
| 06:51:15 | <MyCatVerbs> | tibbe: trust me that that'll be fine. Just make sure you always grow by *doubling* the size of your array, not by adding a constant factor. |
| 06:51:48 | <tibbe> | MyCatVerbs: I'll give it a whirl |
| 06:53:18 | <sjanssen> | MyCatVerbs: I've read that increasing according the the Fibonacci sequence is typically better |
| 06:53:23 | <dons> | solrize: hmm, how can we find out what package they're called on each system? |
| 06:53:35 | <dons> | via a wiki? maybe we should just encourage distros *more* |
| 06:53:45 | <dons> | to solve it on the distro side, rather than on the ./configure side |
| 06:54:46 | <araujo> | hello |
| 06:54:47 | <MyCatVerbs> | sjanssen: asymptotically it's O(1) either way, and most malloc implementations work in powers of two until you get up to *really* big allocations, no? |
| 06:55:00 | <araujo> | anybody knows a good site with nice algorithms implemented in Haskell? |
| 06:55:36 | <sjanssen> | MyCatVerbs: I'm not sure what most mallocs do, just thought I'd share |
| 06:55:37 | <lindzeyn> | google quicksort,Haskell |
| 06:55:51 | <MyCatVerbs> | sjanssen: where did you *hear* that? oO |
| 06:56:00 | <sjanssen> | MyCatVerbs: don't remember |
| 06:56:26 | <MyCatVerbs> | araujo: there are a number of pretty good Haskell blogs around the place. That's how I usually get my fix. :) |
| 06:57:18 | <MyCatVerbs> | araujo: http://augustss.blogspot.com/ <- does some interesting things, twisting Haskell to make it look like languages that are not Haskell. |
| 06:57:18 | <araujo> | MyCatVerbs, I know, just asking if anybody knew a place specially dedicated on this |
| 06:57:57 | <solrize> | dons, distro maintainers tend to have their own views of things and be hard to convince, so a wiki seems like an ok approach. also it would be good to have a way to build the platform without the gui stuff. the gui stuff shouldn't be essential if the platform is supposed to be available in every ghc system. some of them (like embedded systems) may not have any gui at all. |
| 06:58:57 | <blackdog> | lindzeyn: argh, do we have to? that quicksort implementation quite rightly gets torn apart when people start counting the number of operations it does... |
| 06:59:12 | <MyCatVerbs> | araujo: Conal Elliott's blog is nifty - http://conal.net/blog/ and sigfpe's is generally e... |
| 07:00:02 | <MyCatVerbs> | Murr. Puny humans! Whatever happened to good old fashioned quivering mortal patience? |
| 07:01:19 | <sjanssen> | solrize: Ubuntu has a meta-package you should install before trying to build any piece of software |
| 07:01:28 | <MyCatVerbs> | build-essential, IIRC. |
| 07:01:34 | <solrize> | sjanssen, hmm, what's that? |
| 07:01:36 | <MyCatVerbs> | apt-get build-essential, even. |
| 07:01:40 | <solrize> | oh i have that i'm sure |
| 07:01:45 | <sjanssen> | solrize: yep, build-essential |
| 07:01:47 | <MyCatVerbs> | Double check. :) |
| 07:01:57 | <sjanssen> | solrize: if Unix couldn't find headers, I bet you don't |
| 07:02:10 | <solrize> | hmm, installing |
| 07:02:49 | <solrize> | i wasn't missing headers, i just get a lot of compiler warnings about allow-undecidable-instances and things like that |
| 07:03:02 | <solrize> | looks like i didn't have build-essential on this box, who'd a thunk it |
| 07:03:18 | <solrize> | platform make still hits same error, configuring editline failed |
| 07:03:28 | <solrize> | trying make -k |
| 07:03:38 | <sjanssen> | solrize: got a link to the build output? |
| 07:03:46 | <MyCatVerbs> | The allow-undecidable-instances warnings are mostly because the names of the options that turn language extensions on have changed. They're harmless. |
| 07:03:49 | <MyCatVerbs> | mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm |
| 07:03:52 | <MyCatVerbs> | mmmmmmmmmmmmmmm |
| 07:04:01 | <solrize> | sjanssen want me to save it and paste it? |
| 07:04:11 | <MyCatVerbs> | Agh. Sorry, m key sticking. Hitting control didn't do what I wanted at all. >> |
| 07:04:18 | <sjanssen> | solrize: sure |
| 07:04:24 | <sjanssen> | solrize: you didn't do that for your bug report? |
| 07:04:26 | <solrize> | re-running |
| 07:04:33 | <solrize> | sjanssen, no i just typed in a summary |
| 07:04:41 | <amckinley> | hey, could someone help me with a weird parsec problem? |
| 07:04:46 | <amckinley> | heres the code: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5524 |
| 07:04:58 | <amckinley> | and heres an example file: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5523 |
| 07:05:27 | <amckinley> | the problem is that i throw a parse error at line 12 of that input |
| 07:05:31 | <pumpkin> | we need the world's most gratuitous feature on haddock: each function should have a little plot next to it of the time elapsed on quickcheck tests vs. the test size |
| 07:05:32 | <solrize> | hmm, this is weird, now it crashes because it wants to run happy and can't |
| 07:05:43 | <pumpkin> | for "at a glance" complexity :P |
| 07:06:01 | <pumpkin> | with adaptive size changing |
| 07:06:10 | <amckinley> | which i dont understand: i thought that the failure of the parser would cause the many block that im calling nextToken in to end |
| 07:06:25 | <amckinley> | instead of having that failure bubble up to me |
| 07:07:37 | <MyCatVerbs> | amckinley: What's the error message that Parsec gives you, please? |
| 07:07:38 | <dons> | solrize: re. distros, we will just state that the distro "doesn't support haskell" if they don't do it right. |
| 07:07:51 | <amckinley> | MyCatVerbs: Left (line 12, column 41): |
| 07:07:52 | <amckinley> | unexpected "\n" |
| 07:07:52 | <amckinley> | expecting ";", letter or digit, "@", "-", ".", "$", "(" or ")" |
| 07:09:15 | <amckinley> | which makes sense: records in this file are newline-delimited. finding a newline unexpectedly means you've reached the end of the record |
| 07:09:28 | <MyCatVerbs> | Thanks. That is kind of strange. |
| 07:09:30 | <MyCatVerbs> | > " 86400 ) ; whatever |
| 07:09:30 | <lambdabot> | <no location info>: |
| 07:09:31 | <lambdabot> | lexical error in string/character literal at end o... |
| 07:09:32 | <solrize> | dons, for something as widespread as ubuntu, that's not so hot as advocacy |
| 07:09:40 | <MyCatVerbs> | Agh, dammit, got the newline too. Sorry. |
| 07:09:40 | <solrize> | anyway i just attached the typescript |
| 07:09:45 | <solrize> | http://trac.haskell.org/haskell-platform/attachment/ticket/56/typescript |
| 07:09:49 | <MyCatVerbs> | > drop 40 " 86400 ) ; whatever\n" |
| 07:09:50 | <lambdabot> | " ; whatever\n" |
| 07:10:07 | <sjanssen> | dons: Debian and Ubuntu are listed in the supported platforms, what does that mean? |
| 07:10:08 | <tibbe> | where exactly is MutableArray# defined? |
| 07:10:19 | <sjanssen> | tibbe: it's a primitive |
| 07:10:26 | <MyCatVerbs> | tibbe: OH DEAR GODS NO. It's in GHC.Base somewhere. |
| 07:10:28 | <ksf> | somewhere in the GHC.* hierarchy |
| 07:10:51 | <sjanssen> | tibbe: the preferred import for that stuff is GHC.Exts |
| 07:10:55 | <amckinley> | MyCatVerbs: the really weird thing is that it works in the "normal" case, where normal means all the pieces of the record fit on a single line |
| 07:11:04 | <tibbe> | sjanssen: how can I find out which functions it supports? |
| 07:11:12 | <pumpkin> | browse GHC.Prim |
| 07:11:20 | <MyCatVerbs> | amckinley: what's confusing me is that it apparently got the column number wrong. :) |
| 07:11:22 | <solrize> | i tried erasing the directory and re-unpacking the tarball and it's getting much further this time |
| 07:11:34 | <amckinley> | MyCatVerbs: and if i add a token after the rparen, everything works |
| 07:11:42 | <Baughn> | tibbe: Why do you *want* it? |
| 07:11:49 | <sjanssen> | tibbe: this is one of those "if you have to ask, it isn't for you" things, for the most part |
| 07:11:50 | <amckinley> | MyCatVerbs: whoops, that was my fault |
| 07:11:55 | <tibbe> | Baughn: out of curiosity |
| 07:12:00 | <amckinley> | Left (line 12, column 59): |
| 07:12:00 | <amckinley> | unexpected "\n" |
| 07:12:00 | <amckinley> | expecting ";", letter or digit, "@", "-", ".", "$", "(" or ")" |
| 07:12:02 | <ksf> | amckinley, tokenise before you parse? |
| 07:12:04 | <tibbe> | sjanssen: heh |
| 07:12:10 | <Baughn> | tibbe: It killed the cat. Are you feline? |
| 07:12:16 | <ksf> | usually straightens up the parser a fair bit. |
| 07:12:21 | <amckinley> | ksf: this is my attempt at tokenizing :) |
| 07:12:25 | <sjanssen> | tibbe: or perhaps "for Simons only" |
| 07:12:34 | <pumpkin> | ACTION feeds the cat |
| 07:12:35 | <pumpkin> | tibbe: http://www.haskell.org/ghc/docs/latest/html/libraries/ghc-prim/GHC-Prim.html#t%3AMutableArray%23 |
| 07:12:42 | <pumpkin> | tibbe: you probably don't want it though |
| 07:12:51 | <solrize> | ok, it crashes at editline again |
| 07:12:59 | <amckinley> | MyCatVerbs: sorry about that; i fiddled with the sample file after i grabbed the error message |
| 07:13:57 | <pumpkin> | tibbe: you'll notice the source links don't work :P |
| 07:14:11 | <solrize> | http://trac.haskell.org/haskell-platform/attachment/ticket/56/typescript.2 new typescript added |
| 07:14:14 | <amckinley> | MyCatVerbs: and if you remove the parenthesized record (lines 7-12), everything works fine as well |
| 07:14:45 | <tibbe> | so I have a function ensureCapacity :: Array a -> Int -> IO (Array a) but I'm considering changing it to ensureCapacity :: Array a -> Int -> IO () but I wanted to check how other mutable arrays work in GHC |
| 07:14:50 | <MyCatVerbs> | amckinley: er. Your rule for (RToken,True) is immediately recursing on nextToken after reading the close bracket. |
| 07:15:10 | <sjanssen> | tibbe: other arrays are fixed size |
| 07:15:28 | <amckinley> | MyCatVerbs: is that a problem? the paren isnt the token, its just syntax that im trying to get rid of |
| 07:15:41 | <pumpkin> | tibbe: you'd have to make your own growable array on top of this |
| 07:15:41 | <MyCatVerbs> | amckinley: but it'll never advance over a newline? |
| 07:15:43 | <tibbe> | sjanssen: since ensureCapacity invalidates the original array I thought I would stick an IORef in there and update it in place instead |
| 07:15:53 | <tibbe> | pumpkin: that's what I'm trying to do :) |
| 07:15:58 | <pumpkin> | ah |
| 07:16:22 | <pumpkin> | might as well use a MutVar# while you're down there :P |
| 07:16:27 | <amckinley> | MyCatVerbs: right. but the normal case relies on the same behavior and works fine. is there something magic about the recursion? |
| 07:17:21 | <MyCatVerbs> | amckinley: it's looking for another token after the right bracket, and there aren't any more tokens on the same line. |
| 07:17:41 | <MyCatVerbs> | amckinley: and the nextToken parser can't advance over the line boundary. So it has to fail. |
| 07:18:09 | <amckinley> | MyCatVerbs: yes. but why doesnt that break the "all items on the same line" case in the same way? |
| 07:18:53 | <amckinley> | on line 3, after nextToken returns "bar", it cleans up the line so that the next call to nextToken starts at the newline |
| 07:19:29 | <amckinley> | and then it presumably fails, which ends the many1 combinator at line 29 |
| 07:19:31 | <pumpkin> | tibbe: also, if you're going to do it, you might as well bind to memcpy so you can copy your array to the new location as quickly as possible when you grow |
| 07:19:40 | <MyCatVerbs> | amckinley: when yo uput everything on one line, are you putting the "bang bash" at the end there on the same line too? |
| 07:19:41 | <pumpkin> | (do an FFI binding to it, that is) |
| 07:20:00 | <MyCatVerbs> | *you put, argh. |
| 07:20:10 | <amckinley> | MyCatVerbs: no |
| 07:20:42 | <tibbe> | pumpkin: realloc already does that |
| 07:20:58 | <tibbe> | pumpkin: given that reallocArray actually calls realloc |
| 07:21:19 | <amckinley> | the whole point of the parens is to tell the parser "discard newlines until you see a closing paren" |
| 07:21:31 | <amckinley> | because normally dns zone files are completely line-oriented |
| 07:21:38 | <MyCatVerbs> | amckinley: you didn't perchance have a right paren on a line by itself at any point? Because if I'm reading this right, that case should always break. |
| 07:21:39 | <sjanssen> | pumpkin: there's already a binding to memcpy, copyArray IIRC |
| 07:21:49 | <pumpkin> | sjanssen: ah, I didn't know about that, cool :) |
| 07:22:23 | <amckinley> | MyCatVerbs: no, why? |
| 07:22:56 | <MyCatVerbs> | amckinley: because (RParen,True) will try to get another token out, and end up failing. |
| 07:23:31 | <MyCatVerbs> | Ah, just thought. I'm not sure what Parsec does in the case of failure in a choice branch where the state has been changed. |
| 07:23:33 | <amckinley> | but how is that different from the regular case trying to get a token out and failing? |
| 07:23:38 | <pumpkin> | tibbe: wait, so you'll be using memory outside the GC's jurisdiction? |
| 07:23:41 | <amckinley> | where the STATE has changed!!!!! |
| 07:23:43 | <amckinley> | thats IT! |
| 07:23:53 | <amckinley> | :D |
| 07:24:02 | <tibbe> | pumpkin: yes I will pass it to C |
| 07:24:06 | <pumpkin> | ah, ok :) |
| 07:24:28 | <MyCatVerbs> | amckinley: I have no idea whether it is or not. I'd have to ask dcoutts, myself. I don't know what behavoir happens in crazytown o'er thar. |
| 07:24:32 | <amckinley> | i bet parsec is failing hard because ive changed the state without successfully exiting the parser |
| 07:25:03 | <MyCatVerbs> | amckinley: anyways. You probably do *not* want LParen and RParen to recurse on nextToken. |
| 07:25:37 | <MyCatVerbs> | amckinley: instead, just return a meaningless symbol which the consuming parser will filter out afterwards and let the outer many1 handle getting the next token. |
| 07:25:38 | <amckinley> | MyCatVerbs: im open to suggestions :) i thought i was being clever by putting the paren status in the parser state |
| 07:26:44 | <MyCatVerbs> | It's pretty rare, AFAIK, to use the parser state for nesting like that. More common is to have different Parsec actions for different parsing states. |
| 07:27:23 | <amckinley> | MyCatVerbs: but if the parser just returns a bogus DnsToken instead of failing, how do i ever exit the many1? |
| 07:27:43 | <amckinley> | oh wait |
| 07:27:52 | <MyCatVerbs> | amckinley: it doens't emit a bogus DnsToken on failing, it emits a bogus DnsToken on seeing a paren. |
| 07:27:57 | <amckinley> | right :) |
| 07:28:06 | <MyCatVerbs> | Then you just filter (/=Bogus) the result. |
| 07:28:10 | <amckinley> | right right right |
| 07:28:15 | <amckinley> | one sec, let me try that |
| 07:28:22 | <pumpkin> | tibbe: you could also use a PinnedByteArray and let the GC manage it |
| 07:28:52 | <MyCatVerbs> | Haaaaaouw much allocation are you actually doing, tibbe? |
| 07:28:58 | <tibbe> | pumpkin: there are so many options! I wish there was a good guide for all the tradeoffs |
| 07:29:06 | <tibbe> | MyCatVerbs: not that much |
| 07:29:12 | <MyCatVerbs> | ACTION facepalms. |
| 07:29:44 | <tibbe> | MyCatVerbs: avoiding indirections is more important than having slightly slower allocations in my case |
| 07:29:54 | <MyCatVerbs> | If you aren't doing much then it will not matter much if you use a suboptimal allocation method. |
| 07:30:45 | <pumpkin> | but if you're going to make a library, you might as well do it cheaply |
| 07:30:50 | <tibbe> | MyCatVerbs: sure, but if there are two equal choices but one is faster I will go with that |
| 07:30:54 | <pumpkin> | since you don't get much benefit doing it the other way |
| 07:31:11 | <MyCatVerbs> | In particular, I would advise you to stick to Foreign.* for things that need to talk to C, because for starters they're well supported by all of the current crop of Haskell compilers. |
| 07:31:12 | <tibbe> | this is an event loop library that I'd like to replace GHC's event loop so it better be fast |
| 07:31:26 | <tibbe> | MyCatVerbs: I'm using a plain Ptr now |
| 07:31:39 | <tibbe> | MyCatVerbs: since it supports realloc |
| 07:31:40 | <fynn> | Anyone here used qtHaskell? |
| 07:31:54 | <fynn> | Trying to get a sense of how mature it is. |
| 07:31:54 | <amckinley> | MyCatVerbs: it works! :D |
| 07:31:58 | <tibbe> | MyCatVerbs: I could change to ForeignPtr and FFI import memcpy |
| 07:32:12 | <MyCatVerbs> | amckinley: thank goodness. I was worried for a minute there. |
| 07:32:23 | <pumpkin> | sjanssen: I can't find the fast array copy op |
| 07:32:44 | <MyCatVerbs> | tibbe: y'know what? Profile, benchmark. |
| 07:32:52 | <tibbe> | MyCatVerbs: Sure |
| 07:32:55 | <amckinley> | MyCatVerbs: thank you so much :) on further reflection, the state changing + recursion was definitely what was biting me |
| 07:33:04 | <tibbe> | MyCatVerbs: although these things are a bit harder to benchmark |
| 07:33:16 | <hackagebot> | serial 0.1 |
| 07:33:25 | <tibbe> | MyCatVerbs: and you can easily end up with something where no part is really slow but together you get a factor of 2-3 slowdown |
| 07:33:42 | <MyCatVerbs> | tibbe: just use bare Ptrs (no indirection whatsoever yo, they'll practically always get put into registers, they'll get all but buggerin' well strength-reduced.) |
| 07:33:47 | <fynn> | I wish the Haskell logo was more awesome :( |
| 07:33:50 | <MyCatVerbs> | Er, for the moment. |
| 07:34:05 | <tibbe> | MyCatVerbs: I |
| 07:34:09 | <MyCatVerbs> | fynn: trust me that it is an enormous improvement on the previous one. That one was just confusing. |
| 07:34:10 | <tibbe> | MyCatVerbs: I'll do that |
| 07:34:16 | <amckinley> | MyCatVerbs: while you're looking at it, is there anything you see thats stylistically weird or just plain bad? this is my first project in haskell, so any feedback you could give would be helpful |
| 07:34:22 | <sjanssen> | pumpkin: maybe called copyBytes? |
| 07:34:25 | <sjanssen> | @hoogle copyBytes |
| 07:34:26 | <lambdabot> | Foreign.Marshal.Utils copyBytes :: Ptr a -> Ptr a -> Int -> IO () |
| 07:34:35 | <sjanssen> | pumpkin: that's the ticket |
| 07:34:55 | <fynn> | MyCatVerbs: the old one was a magical lambda, the new one is an airline logo :/ |
| 07:35:03 | <MyCatVerbs> | amckinley: nothing interesting. I haven't written all that much Haskell code under fire though, so eh. |
| 07:35:42 | <MyCatVerbs> | fynn: y'know what? I bet if you took the airline haskellogo and struck transparent lines through it (like IBM's logo), it'd look rawkin'. |
| 07:35:47 | <sjanssen> | MyCatVerbs, tibbe: ForeignPtr really doesn't have much overhead, and will help correctness and memory safety very much |
| 07:36:12 | <tibbe> | sjanssen: you're probably right |
| 07:36:37 | <tibbe> | sjanssen: I'm still unsure if I should use IORefs or not |
| 07:36:54 | <tibbe> | sjanssen: for ensureCapacity |
| 07:37:01 | <MyCatVerbs> | tibbe: do. They're fine, and you need to if you're re-allocating. |
| 07:37:09 | <sjanssen> | tibbe: now IORefs do have some overhead |
| 07:37:23 | <tibbe> | sjanssen: that's what I'm afraid of |
| 07:37:32 | <tibbe> | sjanssen: most of the time I won't realloc |
| 07:37:38 | <MyCatVerbs> | IORefs are boxed. If you're desperate, use Ptrs to Ptrs. |
| 07:37:41 | <sjanssen> | tibbe: perhaps you can use the arrays in a more persistent fashion? |
| 07:37:44 | <tibbe> | sjanssen: but I will read the content of the Ptr often |
| 07:38:11 | <tibbe> | sjanssen: it's for passing to kqueue which will fill it with event structs |
| 07:38:29 | <sjanssen> | tibbe: will multiple threads/calling contexts need to call it? |
| 07:38:46 | <tibbe> | sjanssen: potentially yes |
| 07:39:02 | <amckinley> | MyCatVerbs: good deal. thanks so much; have a great night! :) |
| 07:39:04 | <tibbe> | sjanssen: since other threads might need to add events they want to monitor |
| 07:39:13 | <solrize> | any idea how to get editline out of the platform dependencies? i removed it from the package list and the rest of the platform built ok |
| 07:39:19 | <sjanssen> | tibbe: okay, I'd go with type Array = IORef ArrayContents; data ArrayContents = AC ForeignPtr Int, etc. |
| 07:39:27 | <solrize> | but now the build won't compelte because editline is a dependency and is missing. |
| 07:39:31 | <tibbe> | sjanssen: ok |
| 07:39:37 | <MyCatVerbs> | amckinley: Thank you. Have a good morning. :) |
| 07:39:49 | <sjanssen> | tibbe: because the pointer is going to change too when you fill capacity |
| 07:40:03 | <tibbe> | sjanssen: yes |
| 07:40:30 | <sjanssen> | tibbe: you need to think about race conditions too |
| 07:40:54 | <sjanssen> | tibbe: so that IORef should probably be an MVar if you're really going to use it concurrently |
| 07:40:58 | <tibbe> | sjanssen: yes |
| 07:41:06 | <tibbe> | sjanssen: I can atomicallyModifyIORef |
| 07:42:21 | <sjanssen> | tibbe: that only takes pure functions, which probably isn't going to cut it |
| 07:42:31 | <tibbe> | sjanssen: ah right |
| 07:47:11 | <MyCatVerbs> | Probably you need to strictly serialise access to the structs you're passing around anyway, to stop threads from accidentally trampling on each other (iff there is the possibility of two different threads trying to modify the same structure at once.) |
| 07:48:18 | <tibbe> | yes |
| 07:48:53 | <tibbe> | what I'm trying to do is similar to what libev does with the difference that GHC uses its event loop differently |
| 07:49:23 | <MyCatVerbs> | GHC's current IO scheme (in the threaded RTS) has all IO handled by a single thread. So you could just keep the kqueue entries in an ordinary IORef, or even as parameters passed to a little infinitely looping function - provided no more than one thread can see them, you avoid concurrency issues pretty much by definition. |
| 07:49:50 | <MyCatVerbs> | (If you're planning to have your kqueue implementation replace the current threaded IO implementation, I mean.) |
| 07:50:10 | <MyCatVerbs> | Er, all IO on Handles, I mean! Should be as specific as possible with this stuff. :3 |
| 07:51:06 | <MyCatVerbs> | The non-threaded RTS just has a syscall to select() somewhere in its C code, IIRC. Replacing that should not in theory be insurmountable. :) |
| 07:51:44 | <tibbe> | MyCatVerbs: the current (threaded) event loop have a few problems I need to solve |
| 07:51:53 | <tibbe> | MyCatVerbs: it's O(watched events) |
| 07:52:21 | <tibbe> | MyCatVerbs: because it scans a list of all pending events and compares it to what's returned by select |
| 07:52:43 | <tibbe> | MyCatVerbs: epoll, kqueue, et al are O(1) in the number of pending events |
| 07:52:51 | <tibbe> | MyCatVerbs: I of course want to keep it that way |
| 07:52:52 | <MyCatVerbs> | Heh. That's not O(watched events), that's O(watched events + open descriptors). |
| 07:53:14 | <lindzeyn> | It's been a while since I've worked with Haskell. I want to make a new type that is a natural number in the set [0..11]. I tried this: data Pitch = 0 | ... | 11 , but to no avail |
| 07:53:53 | <tibbe> | MyCatVerbs: there is some concurrent access as Read/Write constructors holding an MVar are enqueued in a global list |
| 07:54:13 | <MyCatVerbs> | Yes, I'm familiar with select(2)'s issues. It baffles me that POSIX.1-2001 defined poll(2) instead of a syscall which could give O(1) y |
| 07:54:18 | <MyCatVerbs> | s/y/behavoir. |
| 07:54:32 | <tibbe> | MyCatVerbs: my hope is to replace that scheme with every thread registering a closure that unblocks the MVar and put that in the void* user data section of the C struct |
| 07:55:04 | <tibbe> | MyCatVerbs: so once e.g. kqueue returns with the array of ready events we can immediately get to the callbacks to unlock the MVars |
| 07:55:06 | <MyCatVerbs> | lindzeyn: those are getting parsed as numbers. Data constructors have to begin with an uppercase letter. |
| 07:55:30 | <MyCatVerbs> | tibbe: out of curiosity, why kqueue specifically rather than libevent? |
| 07:55:48 | <tibbe> | MyCatVerbs: libevent would have us make callbacks from C |
| 07:55:57 | <tibbe> | MyCatVerbs: which is apparently rather slow |
| 07:55:59 | <lindzeyn> | MyCatVerbs: How do I create a type that is synonymous with the natural numbers % 12? |
| 07:56:08 | <tibbe> | MyCatVerbs: this way we can make the callbacks from Haskell |
| 07:56:15 | <tibbe> | MyCatVerbs: which would hopefully be faster |
| 07:57:10 | <doserj> | lindzeyn: data Pitch = Pitch0 | Pitch1 | ... | Pitch11 would work, you can also make a custom Num instance, if you really want. |
| 07:57:16 | <MyCatVerbs> | Yeah, letting C functions call IO actions as callbacks requires generating trampolines, which can be dirt slow. |
| 07:57:37 | <tibbe> | MyCatVerbs: so that's why |
| 07:58:07 | <MyCatVerbs> | lindzeyn: you either define a type with twelve constructors, like doserj says, or you could wrap an existing type in a newtype and give a new Num instance for it. |
| 07:58:16 | <lindzeyn> | Thanks |
| 07:59:06 | <MyCatVerbs> | e.g. newtype ModTwelve = MT Int; instance (Num ModTwelve) where { ... } |
| 07:59:55 | <MyCatVerbs> | abs = id; signum = 1; a + b = (a + b) `mod` 12, etc. |
| 08:00:05 | <MyCatVerbs> | Er, signum = const 1. |
| 08:00:38 | <MyCatVerbs> | Usually you wouldn't expose the constructor MT directly, but instead give a smart constructor, like: mkMT i = MT (i `mod` 12) |
| 08:00:55 | <fynn> | I have an infinite list; how do I get its 61st element? |
| 08:01:07 | <MyCatVerbs> | fynn: infiniteList !! 61 |
| 08:01:09 | <Twey> | fynn: list !! 61 |
| 08:01:24 | <Twey> | However, doing so probably indicates that your design is wrong |
| 08:01:45 | <MyCatVerbs> | Er, !! 60, even, if you count element zero as the first. :) |
| 08:01:45 | <fynn> | thanks |
| 08:01:46 | <fynn> | Twey: why is that? |
| 08:01:47 | <Twey> | Lists aren't really designed for random access. Perhaps some kind of lazy map? |
| 08:02:03 | <fynn> | Twey: it's for a project euler question :) |
| 08:02:08 | <Twey> | Oh, okay then |
| 08:02:10 | <Twey> | Do what you like :-P |
| 08:02:15 | <fynn> | I'm generating an infinite list of primes, and I need the Nth |
| 08:02:24 | <Twey> | Okay. |
| 08:02:26 | <MyCatVerbs> | (!! 0) = head; (!! 1) = head . tail; (!! 2) = head . tail . tail; -- etc. |
| 08:02:34 | <Twey> | That's a fair usage. |
| 08:03:37 | <mxc> | on the subject of infinite lists, does sequence :: [m a] -> m [a] for the evaluation of the spine of the list? as in, if I have a function readMsg :: IO String and a processing function proc :: String -> IO (), could I run something like mapM_ proc $ sequence $ repeat readMsg to process every message that gets read? |
| 08:04:16 | <MyCatVerbs> | mxc: sequence_ and sequence force the list spine as they go, but no sooner. |
| 08:05:15 | <MyCatVerbs> | e.g. sequence_ (cycle $ putStrLn "BASIC is not my favourite programming language.") -- works just fine, and is a pretty good antidote to that "10 PRINT YEAH AWESOME \n 20 GOTO 10" crap. |
| 08:06:00 | <mxc> | :t cycle |
| 08:06:02 | <MyCatVerbs> | Personally I prefer fix ((putStrLn "BASIC is not my favourite programming language.") >>) -- for my insulting needs, however. |
| 08:06:02 | <lambdabot> | forall a. [a] -> [a] |
| 08:06:12 | <MyCatVerbs> | Oh, repeat, not cycle. Sorry. |
| 08:06:17 | <MyCatVerbs> | mxc: thanks. |
| 08:06:20 | <dmwit> | forever (putStrLn ...)? |
| 08:06:23 | <mxc> | no worries |
| 08:06:50 | <MyCatVerbs> | dmwit: no. The point is that we're being deliberately byzantine, yo. |
| 08:07:01 | <dmwit> | Oh, well! |
| 08:07:27 | <dmwit> | fix ((mapM_ putChar "BASIC is not my language.\n") >>) |
| 08:08:16 | <mxc> | well, forever works instead of mapM, but if you need to thread a state with foldM, it wouldn't, rihgt? |
| 08:08:24 | <MyCatVerbs> | :t \x -> let knot = fmap ($knot) in knot x |
| 08:08:25 | <lambdabot> | Occurs check: cannot construct the infinite type: |
| 08:08:25 | <lambdabot> | a = f (a -> b) -> f b |
| 08:08:25 | <lambdabot> | Probable cause: `fmap' is applied to too few arguments |
| 08:09:26 | <dmwit> | :t \x -> let knot = fmap ($knot) x in knot x |
| 08:09:27 | <lambdabot> | Occurs check: cannot construct the infinite type: |
| 08:09:27 | <lambdabot> | f = (->) (f (f b -> b)) |
| 08:09:27 | <lambdabot> | Probable cause: `knot' is applied to too many arguments |
| 08:09:47 | <dmwit> | hehe |
| 08:09:53 | <dmwit> | :t \x -> let knot = fmap ($knot) x in knot |
| 08:09:54 | <lambdabot> | forall b (f :: * -> *). (Functor f) => f (f b -> b) -> f b |
| 08:09:57 | <dmwit> | yay! |
| 08:10:02 | <dmwit> | GHC's suggestions were right. =D |
| 08:10:27 | <MyCatVerbs> | Handy like that, innit? :) |
| 08:10:49 | <MyCatVerbs> | I just put x in the wrong place. Buuuu. |
| 08:11:57 | <MyCatVerbs> | What in the Nine Hells does: loeb (return unsafePerformIO) -- do? :) |
| 08:12:40 | <MyCatVerbs> | When I try it at GHCi, I just get a GHC.Prim.Any in return. Heh. |
| 08:20:29 | <MyCatVerbs> | Oh, of course. |
| 08:22:36 | <MyCatVerbs> | :t let k = ($k) <$> [((putStrLn "BASIC is not my favourite programming language.") >>) . head] in head k |
| 08:22:40 | <lambdabot> | forall b. IO b |
| 08:23:18 | <MyCatVerbs> | Actually, for brevity's sake, we should probably, er. |
| 08:23:34 | <MyCatVerbs> | @let badger = "BASIC is not my favourite programming language." |
| 08:23:35 | <lambdabot> | Defined. |
| 08:24:15 | <Beelsebob1> | @hoogle Monad m => m Bool -> m a -> m a -> m a |
| 08:24:17 | <lambdabot> | Control.Monad liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r |
| 08:24:17 | <lambdabot> | Control.Exception bracket_ :: IO a -> IO b -> IO c -> IO c |
| 08:24:17 | <lambdabot> | Text.ParserCombinators.ReadP between :: ReadP open -> ReadP close -> ReadP a -> ReadP a |
| 08:24:19 | <MyCatVerbs> | :t let k = ($k) <$> [(putStrLn badger >>) . head] in head k -- much better. |
| 08:24:20 | <lambdabot> | forall b. IO b |
| 08:25:23 | <MyCatVerbs> | :t (\mbool ma mb -> mbool >>= \r -> if r then ma else mb) |
| 08:25:24 | <lambdabot> | forall (m :: * -> *) b. (Monad m) => m Bool -> m b -> m b -> m b |
| 08:25:38 | <MyCatVerbs> | :t if' |
| 08:25:39 | <lambdabot> | Not in scope: `if'' |
| 08:27:52 | <MyCatVerbs> | :t let { if' True (x,_) = x; if' False (_,y) = y; } in (\cond ma mb -> cond >>= (`if'` (ma,mb))) -- I thnk I may be coming down with something horrible. |
| 08:27:54 | <lambdabot> | forall (m :: * -> *) b. (Monad m) => m Bool -> m b -> m b -> m b |
| 08:32:22 | <dmwit> | :t <+> |
| 08:32:23 | <lambdabot> | parse error on input `<+>' |
| 08:32:25 | <dmwit> | :t (<+>) |
| 08:32:26 | <lambdabot> | Ambiguous occurrence `<+>' |
| 08:32:27 | <lambdabot> | It could refer to either `Control.Arrow.<+>', imported from Control.Arrow at /home/cale/.lambdabot/State/L.hs:4:0-19 |
| 08:32:27 | <lambdabot> | or `Text.PrettyPrint.HughesPJ.<+>', imported from Text.PrettyPrint.HughesPJ at /home/cale/.lambdabot/State/L.hs:54:0-46 |
| 08:32:36 | <dmwit> | :t (Control.Arrow.<+>) |
| 08:32:37 | <lambdabot> | forall (a :: * -> * -> *) b c. (ArrowPlus a) => a b c -> a b c -> a b c |
| 08:32:49 | <dmwit> | not quite |
| 08:32:52 | <dmwit> | :t (|||) |
| 08:32:52 | <lambdabot> | forall (a :: * -> * -> *) b d c. (ArrowChoice a) => a b d -> a c d -> a (Either b c) d |
| 08:34:43 | <dmwit> | MyCatVerbs: Don't worry, if you had a case of something horrible, you would have written "if' True = fst; if' False = snd" instead of this wordy pattern-matching junk. ;-) |
| 08:35:36 | <dmwit> | if' b (x, y) = head $ [x | b] ++ [y] |
| 08:35:40 | <dmwit> | yuck |
| 08:36:05 | <dmwit> | :t \b x y -> head $ [x | b] ++ [y] |
| 08:36:06 | <lambdabot> | forall a. Bool -> a -> a -> a |
| 08:36:25 | <dmwit> | ?pl \b x y -> head $ [x | b] ++ [y] |
| 08:36:25 | <lambdabot> | ((head .) .) . flip flip return . (((.) . (++)) .) . flip flip [] . ((:) .) . flip (|) |
| 08:36:30 | <dmwit> | haha |
| 08:36:32 | <dmwit> | not likely |
| 08:36:42 | <dmwit> | ACTION keeps forgetting that ?pl doesn't do list comprehensions |
| 08:36:48 | <Twey> | ACTION raises a sign and marches back and forth |
| 08:37:02 | <Twey> | Down with if'! Down with if'! |
| 08:39:10 | <monn> | Just curious.. Why haskell doesn't support memoisation natively? |
| 08:39:37 | <dmwit> | space |
| 08:40:10 | <QtPlaty[HireMe]> | And its hard to work out what should be memoized. |
| 08:40:19 | <osfameron> | memoization seems surprisingly hard to do programmatically |
| 08:40:25 | <osfameron> | in haskell I mean |
| 08:40:28 | <MyCatVerbs> | monn: good question. The compiler can't memoize everything without running out of RAM, and nobody appears to have written a compiler clever enough to know which expressions are worth memoizing. :) |
| 08:40:57 | <MyCatVerbs> | monn: the good news is that there are a couple of very easy to use libraries for lazy memoization on Hackage. |
| 08:40:58 | <dmwit> | osfameron: Have you seen Okasaki's post about this? |
| 08:41:01 | <osfameron> | I mean, in Perl you can do. use Memoize; memoize \&foo; <-- sub foo is now memoized |
| 08:41:02 | <dmwit> | http://article.gmane.org/gmane.comp.lang.haskell.cafe/7737 |
| 08:41:04 | <osfameron> | dmwit: nope |
| 08:42:10 | <quicksilver> | I'm not sure what monn means by 'natively'. |
| 08:42:30 | <quicksilver> | if he meant 'automatically', then dmwit and QtPlaty[HireMe] are of course right. |
| 08:42:31 | <osfameron> | dmwit: yeah, I've come across the "rewrite as an array" technique, but I don't really understand it (it also seems like a lot of boilerplate compared to "memoize foo") |
| 08:43:00 | <Jedai> | osfameron: I'm not sure what you mean ? You can't change the meaning of an already written function, but it's pretty easy to add memoization in a function (see http://hackage.haskell.org/cgi-bin/hackage-scripts/package/MemoTrie-0.4.5 for instance) |
| 08:43:01 | <quicksilver> | osfameron: what's to understand? an array is a cache of values. |
| 08:43:17 | <quicksilver> | it would probably be more sophisticated to use a map or a trie. |
| 08:43:28 | <monn> | I see |
| 08:43:35 | <quicksilver> | "let foo = bar x in ... foo ... foo ... foo " |
| 08:43:40 | <quicksilver> | ^^ I mean, that's memoization in a sense. |
| 08:43:46 | <quicksilver> | it does rather depend what you mean. |
| 08:43:53 | <Jedai> | osfameron: with this library it's really easy to add memoization to a function |
| 08:44:09 | <osfameron> | Jedai: given that a memoized function would give exactly the same results as the non-memoized one, the fact that it would be theoretically unsafe would be encapsulated, even if the function was effectively modified inplace though, no? |
| 08:44:43 | <monn> | Is there a way too use memoisation without hackage? |
| 08:44:44 | <osfameron> | quicksilver: yeah, I should look at it again. It seemed surprisingly hard *to me* but maybe I wasn't concentrating last time I looked at it... |
| 08:44:58 | <quicksilver> | monn: Yes. Just do it. It's easy. |
| 08:45:06 | <quicksilver> | monn: cache the values in an appropriate structure. |
| 08:45:10 | <quicksilver> | like a map or an array. |
| 08:45:21 | <quicksilver> | or a trie ;) |
| 08:45:27 | <quicksilver> | tries are a bit more fiddly. |
| 08:45:34 | <monn> | What is lazy memoisation? |
| 08:45:47 | <quicksilver> | The hard part in conal's (sjanssen's) code is the fiddly details of tries. |
| 08:46:09 | <quicksilver> | monn: I have no idea. |
| 08:46:15 | <quicksilver> | sounds like a meaningless juxtaposition of two words, to me. |
| 08:46:16 | <quicksilver> | ;) |
| 08:46:30 | <MyCatVerbs> | monn: you have an infinite (or near-as-in-practice) trie which is generated on demand. |
| 08:46:31 | <quicksilver> | Perhaps what they mean is a caching structure where values are lazily computed the first time they are accessed, though. |
| 08:46:51 | <Jedai> | osfameron: True, you could add memoization without changing the meaning of a function... Well I guess we'll seea support for that in a future compiler version |
| 08:47:58 | <MyCatVerbs> | monn: the leaves of that trie contain the outputs of your memoized function, and the trie itself maps from the input to the outputs. |
| 08:49:25 | <MyCatVerbs> | Actually "trie" isn't necessarily the right term. Complete-n-ary tree would be more common for many data types, I think. |
| 08:52:00 | <Berengal> | ghc-pkg find-module can tell you which package a module belongs to, but is there an easy way to find what modules a package contains? |
| 08:52:15 | <Jedai> | monn: Lazy memoisation doesn't seem right to me, but maybe it was meant to speak of the fact that writing memoizing function with lazyness often avoid the boilerplate you could see in other languages (supposing you don't have a native support for memoisation or you can't use it in this particular case) |
| 08:52:57 | <quicksilver> | Berengal: ghc-pkg describe |
| 08:53:27 | <Berengal> | quicksilver: Thanks, must've overlooked it.. |
| 08:54:09 | <Jedai> | monn: For instance, you can easily use an array to do dynamic programming in Haskell because when you ask for the contents of an element of this array only it and its dependance will be evaluated, not the whole array |
| 08:55:11 | <Berengal> | See also the loeb function |
| 08:57:42 | <monn> | I think that's not belong to the definition of DP,where values should be computed in some kind of order. |
| 08:58:40 | <Jedai> | monn: Yes, and the order is dictated by the dependance between values, right ? |
| 09:00:20 | <Jedai> | monn: but in a lazy language, you won't have to code the computation in order, as long as they depend correctly on each others, you can just evaluate the one you want and its dependance will be evaluated in turn |
| 09:01:40 | <Jedai> | monn: I'll try to find a simple example for you |
| 09:04:12 | <Jedai> | monn: http://www.haskell.org/haskellwiki/Dynamic_programming_example |
| 09:04:27 | <monn> | Is that mean we can't trade space for time in lazy language? Since IMHO memoisation is requiring more time but less space than DP |
| 09:05:12 | <monn> | (in imperative language) |
| 09:05:43 | <lindzeyn> | Dynamic programming in Haskell must be intense |
| 09:05:58 | <Jedai> | monn: http://caffeinatedcode.wordpress.com/2009/03/26/laziness-and-dynamic-programming/ |
| 09:06:55 | <Jedai> | monn: in fact this second reference is clearer for me and the conclusion is clearly that Haskell makes DP far easier than in an imperative language (or a strict functional one) |
| 09:07:09 | <Berengal> | > let loeb x = let r = fmap (\f -> f r) x in r in loeb $ const 0:const 1:[(+1).(!!(if mod n 2 == 0 then div n 2 else n*3+1)) | n <- [2..]] |
| 09:07:11 | <lambdabot> | [0,1,2,8,3,6,9,17,4,20,7,15,10,10,18,18,5,13,21,21,8,8,16,16,11,24,11,112,1... |
| 09:07:13 | <Jedai> | lindzeyn: Well in fact it's very easy and clean |
| 09:09:23 | <monn> | I'll check the example later (can't go :80 now) |
| 09:09:41 | <Jedai> | monn: that's a strange description of DP and memoization |
| 09:10:36 | <Jedai> | monn: I would say that memoization can be used to simplify the writing of DP, I don't see them as concurrent techniques |
| 09:11:29 | <Jedai> | monn: DP is a design method for algorithms, memoization is a mechanism to trade space for time on the calls of a function that's often used with the same arguments |
| 09:13:51 | <monn> | CMIIW, I mean in the sense, memoisation needs recursion, but DP doesn't need it for the cost of more space and extra function calls |
| 09:14:26 | <Jedai> | monn: note that you can do memoization in Haskell (as I said, check the MemoTrie, it's a single pure Haskell module, so you don't really have an excuse not to use it), my argument was just that DP is made easy with lazy array, you don't need memoization as often |
| 09:14:45 | <Jedai> | monn: memoization doesn't need recursion |
| 09:15:20 | <monn> | Well, of course I need to check the links |
| 09:15:28 | <Jedai> | monn: You probably means that doing DP using memoization needs recursion |
| 09:18:03 | <monn> | I'll check it |
| 09:18:22 | <Berengal> | corecursion is a nice way to do simple memoization... |
| 09:18:54 | <monn> | Oh, I mean that |
| 09:19:09 | <Berengal> | Not neccessary though |
| 09:20:25 | <monn> | For example is calculating the 7th fibonacci number |
| 09:21:03 | <Jedai> | Berengal: note that it is possible to use TH to simply add memoization to the declaration of a function (even a recursive one), apparently that has already been done (though I didn't find the code), it would be nice to add that to Conal's library |
| 09:21:29 | <Jedai> | monn: what about it ? |
| 09:22:03 | <Berengal> | Jedai: Yes, using conals library requires a slightly different way of writing things |
| 09:22:35 | <Berengal> | usually just 'foo = memo go where go [...]' instead of just 'foo = [...]' |
| 09:22:51 | <Jedai> | let fib n = let fibs = 0 : 1 : zipWith (+) fibs (tail fibs) in fibs !! n in fib 7 |
| 09:22:58 | <Jedai> | > let fib n = let fibs = 0 : 1 : zipWith (+) fibs (tail fibs) in fibs !! n in fib 7 |
| 09:22:59 | <lambdabot> | 13 |
| 09:23:13 | <yaxu> | anyone know if the CLI for ghci in the new version of the haskell platform has improved? |
| 09:24:19 | <Jedai> | yaxu: it use haskeline now (or rather GHC6.10.3 use haskeline) instead of editline, so it's better (editline sucks) |
| 09:24:48 | <BONUS> | what's improved? |
| 09:25:16 | <Jedai> | BONUS: unicode support to begin with |
| 09:25:19 | <monn> | That's nice to know |
| 09:26:19 | <BONUS> | awesome |
| 09:27:12 | <yaxu> | Jedai: I'm really used to readline features, like ^T doing transliteration, and the kill ring |
| 09:27:21 | <Jedai> | BONUS: also haskeline is a Haskell library, that's more actively maintained than editline, we can hope for a really good library rivaling readline in all aspect in the future |
| 09:27:33 | <Jedai> | yaxu: add them to haskeline ! |
| 09:28:04 | <yaxu> | I'm not that good a haskell programmer, and the kill ring isn't trivial |
| 09:28:23 | <dqd> | Oh, that's a cool library. |
| 09:28:24 | <Jedai> | yaxu: If you really can't live without those features, I think there still is a way to compile GHCi to use Readline |
| 09:28:56 | <yaxu> | yep I might end up doing that, shame as the haskell platform is a very nice thing otherwise |
| 09:29:09 | <Jedai> | yaxu: a little search in the haskell-cafe archive (or other haskell mailing list) shoud find a procedure to do that |
| 09:29:24 | <yaxu> | ok thanks Jedai |
| 09:30:35 | <koala_man> | is 'sort' O(n^2)? |
| 09:31:15 | <quicksilver> | no |
| 09:31:19 | <quicksilver> | O(n log n) |
| 09:31:27 | <quicksilver> | GHC makes it a merge, I believe. |
| 09:31:35 | <quicksilver> | the standard doesn't specify. |
| 09:32:08 | <koala_man> | lambdabot's @src sort seems to say that it's insertion sort |
| 09:32:20 | <quicksilver> | lambdabot's @src is a work of fiction. |
| 09:32:29 | <quicksilver> | you should not believe anything you see there. |
| 09:32:32 | <koala_man> | it's just an example of how it could be implemented? |
| 09:32:35 | <quicksilver> | right. |
| 09:33:01 | <Berengal> | @src sort |
| 09:33:01 | <lambdabot> | sort = sortBy compare |
| 09:33:06 | <Berengal> | @src sortBy |
| 09:33:07 | <lambdabot> | sortBy cmp = foldr (insertBy cmp) [] |
| 09:33:33 | <koala_man> | is this because the actual implementation is huge and ugly? |
| 09:33:36 | <monn> | merge sort? |
| 09:33:43 | <Jedai> | koala_man: I think it's extracted from the Prelude of the report but it's only there to specify what's the behaviour must be like, not the real implementation |
| 09:33:58 | <koala_man> | ah |
| 09:34:03 | <quicksilver> | mostly I think @src is designed to be clear and concise. |
| 09:34:08 | <quicksilver> | it's a manually maintained thing. |
| 09:34:12 | <Jedai> | monn: it's either a merge sort or a quick sort, I think it's a merge sort now |
| 09:34:34 | <Berengal> | quick sort on linked lists isn't preferable... |
| 09:34:37 | <quicksilver> | ACTION belongs to the school of thought that you can't do a quicksort in haskell without using mutable arrays. |
| 09:34:57 | <Jedai> | Berengal: I agree, anyway I don't like quicksort |
| 09:35:35 | <Jedai> | quicksilver: Well it depends on what you call quicksort I guess |
| 09:35:43 | <Berengal> | I think sort was quicksort way back when, but don't quote me on that... |
| 09:35:47 | <quicksilver> | right. |
| 09:35:54 | <quicksilver> | that's why I said 'school of thought'. |
| 09:36:05 | <quicksilver> | In my book, half the point of quicksort is the clever swapping algorithm. |
| 09:36:16 | <quicksilver> | which requires a mutable array to faithfully implement. |
| 09:36:19 | <Jedai> | But the main problem was that quicksort without randomness degrade too fast on some pretty current input |
| 09:36:42 | <Jedai> | Berengal: You're right |
| 09:36:53 | <quicksilver> | the naive haskell quicksort only implements the recursion strategy of quicksort |
| 09:36:58 | <quicksilver> | not the clever swapping part. |
| 09:37:14 | <Berengal> | ACTION wants bitonic sort |
| 09:37:15 | <quicksilver> | Jedai: well, median-of-3 works fairly well, but you can't even do that in haskell ;) |
| 09:37:24 | <Gracenotes> | if you have (say) a pile of papers, the important part of quicksort would be to pick a pivot and sort less than/greater than. |
| 09:37:28 | <quicksilver> | Jedai: (because it's O(n) to pick out the 3 elements to median) |
| 09:37:44 | <ultrakrankerhamp> | @help pl |
| 09:37:44 | <lambdabot> | pointless <expr>. Play with pointfree code. |
| 09:38:18 | <quicksilver> | Gracenotes: and if you have no aviation fuel, the important thing about an aeroplane is that it keeps the rain off. |
| 09:38:18 | <koala_man> | is there a list somewhere of many/some of the cute optimizations that ghc can perform? |
| 09:38:19 | <Gracenotes> | hm. I wonder what the most efficient physical sorting method would be for human workers for a given size of pile of papers |
| 09:38:34 | <ultrakrankerhamp> | @pl (\ xs ys -> sum $ zipWith (*) xs ys) |
| 09:38:34 | <quicksilver> | Gracenotes: however, that doesn't mean that *is* the important thing about an aeroplane in general :) |
| 09:38:34 | <lambdabot> | (sum .) . zipWith (*) |
| 09:38:35 | <Gracenotes> | quicksilver: a useful tool |
| 09:38:36 | <maltem> | array /~ pile |
| 09:38:37 | <Berengal> | koala_man: You could take a look at the ghc user manual |
| 09:38:44 | <Gracenotes> | that's why I buy all my airplanes |
| 09:39:14 | <koala_man> | Berengal: I found a list of flags, but it wasn't very specific |
| 09:39:19 | <quicksilver> | maltem: I would say a pile is more like a list, in the sense that removing an element form the middle and letting everything else slop downwards feels more like O(1) than O(n). |
| 09:39:28 | <Gracenotes> | hm. there must be research into the area of physical sorting... but anyway, I digress |
| 09:39:29 | <quicksilver> | koala_man: there is some stuff scattered on the GHC wiki |
| 09:39:34 | <quicksilver> | 'compiler commentary' |
| 09:39:46 | <Berengal> | Gracenotes: Bucketsort, with insertion sort on the smaller piles |
| 09:39:48 | <Jedai> | Gracenotes: I think that depending on the size of the pile I would use a mix of quicksort and selection sort |
| 09:40:05 | <koala_man> | neat, thanks |
| 09:40:06 | <quicksilver> | koala_man: http://hackage.haskell.org/trac/ghc/wiki/Commentary |
| 09:40:20 | <QtPlaty[HireMe]> | Jedai: I recall sorting libary cards. We did a radix sort. |
| 09:40:22 | <quicksilver> | koala_man: it's pretty large and not comprehensive |
| 09:40:37 | <quicksilver> | certainly to sort a hand of cards I use selection sort. |
| 09:41:14 | <Jedai> | QtPlaty[HireMe]: That demands a certain structure on the sorting criteria |
| 09:41:25 | <Berengal> | quicksilver: Really? I use insertion sort, since I know the already sorted part better than the unsorted part |
| 09:41:45 | <Jedai> | QtPlaty[HireMe]: but I agree that if you can it's one of the best |
| 09:41:47 | <QtPlaty[HireMe]> | Jedai: Yeah, thats why I said libary cards, they each had an index. |
| 09:41:58 | <quicksilver> | Berengal: eh, your'e right. |
| 09:42:00 | <Gracenotes> | once my compsci teacher had us sort permission slips from the entire school, and we used a sort of mergesort, given that the teachers had been required to sort it for their individual classes |
| 09:42:03 | <quicksilver> | Berengal: just got confused :) |
| 09:42:22 | <Berengal> | quicksilver: I do too. I usually have to think for a few seconds to remember the difference |
| 09:42:40 | <quicksilver> | Gracenotes: a merge step makes sense if you share the work. |
| 09:42:42 | <Gracenotes> | (she was also the school 'administrator') |
| 09:42:49 | <quicksilver> | Gracenotes: that's how we used to merge exam papers after an exam |
| 09:42:57 | <Gracenotes> | admin in a tech sense |
| 09:43:00 | <quicksilver> | (they had to be sorted into student ID number order) |
| 09:43:10 | <Gracenotes> | quicksilver: yeah, the whole class was working on it :) |
| 09:49:13 | <ivanm> | quicksilver: I don't know if you got my msg about kuribas' indentation mode, but I tried it and couldn't stand how it worked (in part because whilst tab = 4 spaces, backspace = 1 space :s ) |
| 09:51:16 | <quicksilver> | ivanm: I don't understand what your'e saying |
| 09:51:32 | <quicksilver> | ivanm: backspace goes 'back' on indentation level, tab goes forward one level. |
| 09:51:38 | <quicksilver> | neither 4 nor 1 are relevant numbers. |
| 09:51:45 | <ivanm> | nope, here tab goes forward 4 spaces, backspace goes back one space |
| 09:51:53 | <quicksilver> | well then you're not using it. |
| 09:52:06 | <ivanm> | it might be because it's trying to insert/delete literal tabs, but I have tabs auto-replaced with 4 spaces... |
| 09:52:15 | <quicksilver> | no, it doesn't do that. |
| 09:52:16 | <quicksilver> | it rebinds TAB |
| 09:52:37 | <quicksilver> | if you had, for example "let foobar = case argle of Just x ->" |
| 09:52:57 | <quicksilver> | then if you hit TAB on the next line, your first option would be lining up under the 'f' of foobar |
| 09:53:07 | <quicksilver> | (possibility of introducing a new binding) |
| 09:53:11 | <ivanm> | quicksilver: IIRC, it does that |
| 09:53:17 | <quicksilver> | hit TAB again and it would line up with the J of Just |
| 09:53:25 | <quicksilver> | (possibility of introducing a new case statement) |
| 09:53:30 | <ivanm> | but when trying to un-indent, it doesn't go back a full tab length, just one space |
| 09:53:42 | <quicksilver> | then your install is broken. |
| 09:53:48 | <quicksilver> | because that is not how it is intended to behave. |
| 09:53:51 | <ivanm> | hmmm... >_> |
| 09:54:16 | <Jedai> | ivanm: How are you trying to unindent ? |
| 09:54:23 | <ivanm> | by pressing backspace |
| 09:54:46 | <Jedai> | I don't think backspace unindent in indentation-mode (on emacs right ?) |
| 09:55:06 | <ivanm> | Jedai: it's meant to using kuribas' indentation mode (and yes, for emacs) |
| 09:55:08 | <quicksilver> | backspace goes back one indentation possibility in kuribas's indentation mode |
| 09:55:15 | <quicksilver> | I'll paste an example hs file for concreteness |
| 09:55:22 | <Jedai> | you can just press <Tab> again so that it begins its cycle again |
| 09:55:31 | <ivanm> | quicksilver: only when the cursor is at the beginning of the line though, right? |
| 09:55:36 | <ivanm> | Jedai: wrong indentation mode ;-) |
| 09:55:46 | <quicksilver> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5525#a5525 |
| 09:56:01 | <ivanm> | quicksilver: could it be that it's complaining because it seems my version of haskell mode has it, and I then downloaded a different one straight off kuribas' site? |
| 09:56:14 | <quicksilver> | if you are on the line after the singe line in that file |
| 09:56:19 | <ketil> | Is there a way to get my URL from Network.(Fast)CGI? |
| 09:56:19 | <lambdabot> | ketil: You have 3 new messages. '/msg lambdabot @messages' to read them. |
| 09:56:23 | <Gracenotes> | eek |
| 09:56:33 | <quicksilver> | then there are 4 indent positions |
| 09:57:03 | <quicksilver> | left margin, under 'f' of foobar, under 'c' of case, under 'J' of Just, and under '0' |
| 09:57:05 | <ivanm> | quicksilver: an in, another let, another case or another function? |
| 09:57:06 | <quicksilver> | sorry, that's 5 ;) |
| 09:57:19 | <ivanm> | why under the 0 ? |
| 09:57:27 | <quicksilver> | because that might be an incomplete expression |
| 09:57:30 | <quicksilver> | (0 + 1) |
| 09:57:31 | <ivanm> | ahhh |
| 09:57:45 | <quicksilver> | TAB will go right between those 5 |
| 09:57:49 | <quicksilver> | BACKSPACE will get left |
| 09:57:57 | <ivanm> | quicksilver: but only at the start of the line? you can't tab mid-line? |
| 09:57:57 | <quicksilver> | if that's not what's happening, your mode isn't right ;) |
| 09:58:25 | <quicksilver> | "start" in the sense of, only whitespace to your left and nothing to your right |
| 09:58:36 | <quicksilver> | if you hit tab otherwise you'll jump to the current indent level |
| 09:58:42 | <quicksilver> | its first guess is the rightmost one, btw |
| 09:58:49 | <quicksilver> | but it's just one BACKSPACE to go back a level |
| 09:59:04 | <quicksilver> | ah no, it's first guess is the 'J' in Just. |
| 09:59:22 | <quicksilver> | if it's behaving like that and you don't liek it - well, fair enough |
| 09:59:29 | <quicksilver> | if it's not behaving like that, something is botched. |
| 09:59:30 | <ivanm> | quicksilver: so hitting tab mid-text, it should still indent? |
| 09:59:35 | <ivanm> | not insert spaces? |
| 09:59:42 | <ivanm> | in that case, it definitely isn't working right... >_> |
| 09:59:47 | <quicksilver> | definitely not insert spaces! |
| 10:00:01 | <quicksilver> | mid-text TAB does nothing, when I do it |
| 10:00:31 | <quicksilver> | check the bindings of TAB and BACKSPACE |
| 10:00:49 | <ivanm> | quicksilver: so unlike the standard mode, kuribas' indentation stuff only works before you start typing? |
| 10:00:56 | <ivanm> | i.e. you position where it should go, and then type? |
| 10:01:04 | <PhDP> | Newbie question; I was trying to write a function lastButOne with only the functions last, head, and tail. I tried lastButOne xs = if(tail xs == [last xs]) then head xs else lastButOne( tail xs ). But it seems rather inneficient... |
| 10:01:08 | <m3ga> | ketil: use getVars and look at SCRIPT_NAME variable |
| 10:01:24 | <quicksilver> | ivanm: yes. |
| 10:01:34 | <ivanm> | PhDP: well, you're traversing the whole list |
| 10:01:38 | <ivanm> | so of course it's inefficient |
| 10:01:41 | <ketil> | m3ga: thanks, will try. |
| 10:01:41 | <quicksilver> | ivanm: well not exactly. If you want to change it after , just go to the beginnig of the line. |
| 10:01:44 | <ivanm> | what do you want it to actually do? |
| 10:01:46 | <ivanm> | quicksilver: *nod* |
| 10:01:54 | <Tarrant> | Sorry for the stupid question but: '$' and '.' both do very similar things correct? Except that $ is for the actual application, while '.' is for creating new compound-functions. Correct? |
| 10:02:06 | <PhDP> | ivanm = is there a better way ? |
| 10:02:07 | <quicksilver> | ivanm: ^D is also rebound to forward-delete one level of indentation |
| 10:02:14 | <quicksilver> | if you type it at the beginning of the line. |
| 10:02:18 | <ivanm> | PhDP: what are you wanting to do? |
| 10:02:21 | <Saizan> | Tarrant: $ is function application, while . is composition |
| 10:02:27 | <ivanm> | quicksilver: ^D is C-D? |
| 10:02:29 | <Jedai> | PhDP: if you had more functions I would suggest "lastButOne = last . init" |
| 10:02:30 | <Saizan> | ?src ($) |
| 10:02:31 | <lambdabot> | f $ x = f x |
| 10:02:34 | <Saizan> | ?src (.) |
| 10:02:34 | <lambdabot> | (f . g) x = f (g x) |
| 10:02:36 | <PhDP> | get the element before the last element in a list |
| 10:02:50 | <ivanm> | and forward-delete is? |
| 10:02:54 | <ivanm> | PhDP: does it have to be a list? |
| 10:02:55 | <Jedai> | PhDP: I would suggest doing it with pattern matching otherwise |
| 10:03:02 | <ivanm> | because that kind of thing is exactly what lists are not for... |
| 10:03:19 | <quicksilver> | ivanm: right, C-d. |
| 10:03:33 | <quicksilver> | ivanm: if your keyboard has DEL key I expect that works too :) |
| 10:03:36 | <quicksilver> | ivanm: I don't have one to test. |
| 10:03:38 | <ivanm> | ahhh ;-) |
| 10:03:44 | <ivanm> | quicksilver: cut-down keyboard? |
| 10:03:47 | <quicksilver> | laptop. |
| 10:03:51 | <PhDP> | ivanm; yes it has to be a list, it's an exercise in RWH and I wondered if my method was the most effcient given the functions we already saw. |
| 10:03:52 | <ivanm> | ahhh |
| 10:03:55 | <quicksilver> | mac laptop, in particular. |
| 10:03:58 | <ivanm> | hmmm.... my laptop has a delete key... |
| 10:04:09 | <ivanm> | PhDP: then I would do pattern matching as Jedai suggested |
| 10:04:12 | <ivanm> | and recurse |
| 10:04:15 | <quicksilver> | ivanm: anyhow, it sounds like your mode install is broken. |
| 10:04:52 | <Gracenotes> | PhDP: also consider what to do if your list was empty, or contained only one element! |
| 10:04:54 | <ivanm> | quicksilver: yeah, either the version shipped with 2.4 is borked or else it's clashing with the one I have in ~/.emacs.d or something... |
| 10:05:02 | <Gracenotes> | but pattern matching can take of these |
| 10:05:28 | <quicksilver> | ivanm: haskell-indentation-mode isn't shipped |
| 10:05:30 | <quicksilver> | ivanm: or is it? |
| 10:05:38 | <quicksilver> | ivanm: are you saying haskell-mode 2.4 comes with kuribas' mode? |
| 10:05:44 | <ivanm> | quicksilver: there's one there for me... |
| 10:05:46 | <PhDP> | ah, pattern matching is in the chapter just after the exercise. |
| 10:05:53 | <ivanm> | but it's different from what kuribas' site has (outdated?) |
| 10:06:04 | <ivanm> | I note that its documentation is still wrong however... |
| 10:06:12 | <ivanm> | Gracenotes: though he should write better error messages... |
| 10:06:59 | <quicksilver> | ivanm: my version of 2.4 certainly didn't come wiht it :) |
| 10:08:01 | <ivanm> | quicksilver: ahhh, looks like I'm using a cvs snapshot (I asked the gentoo devs to get one to fix the .cabal file bug) |
| 10:08:13 | <quicksilver> | that is a damn annoying bug. |
| 10:08:21 | <quicksilver> | anyhow back to working out what's going on |
| 10:08:22 | <Gracenotes> | PhDP: well. This can be done without pattern matching: the base case you want is if (null . tail . tail $ xs), but not (null . tail $ xs) or (null xs) |
| 10:08:26 | <quicksilver> | check your backspace binding |
| 10:08:30 | <quicksilver> | (C-h k BACKSPACE) |
| 10:08:44 | <Gracenotes> | the latter two would be undefined for your function, because they would be true for [x] and [] respectively |
| 10:08:48 | <Jedai> | PhDP: well then, try to write a version that works, don't worry that it's innefficient, you'll see more efficient version later (maybe come back to it later and rewrite it better) |
| 10:09:05 | <Gracenotes> | but pattern matching can make this a bit easier; failure to match simply means not using a certain function definition |
| 10:09:11 | <ivanm> | quicksilver: well, I won't do it now because I've disabled kuribas' mode |
| 10:09:31 | <quicksilver> | my guess would be you failed to correctly disable the old haskell-indent-mode |
| 10:09:34 | <quicksilver> | and that was screwing it up |
| 10:09:37 | <quicksilver> | but that's only a guess |
| 10:09:38 | <ivanm> | but do you know how to force one version of an elisp file over another? |
| 10:09:40 | <quicksilver> | think I did something like that. |
| 10:09:55 | <ivanm> | quicksilver: I tried copying your technique of completely setting haskell-mode-hook (or whatever it's called) |
| 10:09:56 | <quicksilver> | well you can load it by full path if you want to be clear |
| 10:10:22 | <Saizan> | btw, instead of the .cabal hack one could parse the module header and move to such a directory at startup |
| 10:10:32 | <ivanm> | quicksilver: ahhh, looks like I wasn't loading it |
| 10:10:41 | <ivanm> | just using (autoload 'haskell-indentation-mode "haskell-indentation" ... |
| 10:10:46 | <ivanm> | which probably pulled up the other one |
| 10:11:01 | <ivanm> | so how would I use the full patch there? |
| 10:12:42 | <quicksilver> | well, that will look for "haskell-indentation.el" |
| 10:12:46 | <quicksilver> | are you saying you have two of those? |
| 10:13:45 | <ivanm> | yes, one in ~/.emacs.d and one in /usr/share/emacs/site-lisp/haskell-mode-2.4/ or something like that |
| 10:14:07 | <quicksilver> | if you add ~/.emacs.d to your load-path I believe it will take priority |
| 10:14:11 | <quicksilver> | since it will be first. |
| 10:14:21 | <ivanm> | hmmmm, it is... >_> |
| 10:14:51 | <quicksilver> | and have you actually turned the mode on? |
| 10:14:51 | <alexeevg> | @list |
| 10:14:51 | <lambdabot> | http://code.haskell.org/lambdabot/COMMANDS |
| 10:15:32 | <ivanm> | quicksilver: I copied your config settings (at least for the hook setup) |
| 10:16:25 | <quicksilver> | Well, is the mode on? |
| 10:16:38 | <alexeevg> | @pl \a b c -> AppT (AppT (AppT (TupleT 3) a) b) c |
| 10:16:38 | <lambdabot> | (AppT .) . AppT . AppT (TupleT 3) |
| 10:17:35 | <ivanm> | quicksilver: how can I tell? |
| 10:18:20 | <quicksilver> | ivanm: C-h m |
| 10:18:47 | <ivanm> | quicksilver: can you please paste up your config for it? |
| 10:18:54 | <ivanm> | *again |
| 10:19:27 | <quicksilver> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5374#a5374 |
| 10:23:19 | <ivanm> | thanks |
| 10:23:53 | <ivanm> | quicksilver: I think I asked you this last time, but why do you use custom-set-variables rather than just setq for haskell-mode-hook? |
| 10:24:00 | <ivanm> | or is that part of your custom-set-variables? |
| 10:29:08 | <ivanm> | quicksilver: OK, seems to be working now... |
| 10:29:17 | <ivanm> | strange that it didn't when I tried it last time >_> |
| 10:31:59 | <hackagebot> | modsplit 0.2 |
| 10:32:45 | <quicksilver> | ivanm: if you use custom-set-variables you can customise them with customize-viarblae |
| 10:33:01 | <ivanm> | *nod* |
| 10:33:02 | <quicksilver> | ivanm: which does type-checking, and lets you change things experimentally for one session before saving forever |
| 10:33:11 | <ivanm> | type-checking? :o |
| 10:33:20 | <quicksilver> | yes. |
| 10:33:32 | <quicksilver> | it knows that a variable is supposed to be a number, or a string, or a list, etc. |
| 10:33:37 | <quicksilver> | and it can run a validation function on it. |
| 10:33:41 | <ivanm> | ahhhhh |
| 10:33:45 | <quicksilver> | the interface can present a popup menu of choices, etc. |
| 10:34:04 | <ivanm> | ACTION has been trying to pull apart his custom-set-variables stuff and splitting the settings into the individual customisation files |
| 10:34:29 | <ivanm> | quicksilver: for you, if you have a -- | style haddock comment, does it wrap properly (e.g. using M-q)? |
| 10:34:40 | <ivanm> | for me, it works with just -- comments, but not haddock ones :s |
| 10:40:06 | <quicksilver> | ivanm: Ah, never tried that |
| 10:40:26 | <quicksilver> | ivanm: yes, works fine |
| 10:40:32 | <ivanm> | hmmm.... weird... |
| 10:40:45 | <ivanm> | doesn't work here either in kuribas' mode, or normal indentation mode... >_> |
| 10:41:23 | <ivanm> | in fact, if I have a multi-line -- comment and add a | to the first line to make it a haddock comment, after hitting mod-q it made it all one line >_> |
| 10:41:34 | <ivanm> | but if | isn't there, then it leaves it as multi-line |
| 10:41:59 | <quicksilver> | well that's probably because you're mixing up | and not-| |
| 10:42:07 | <quicksilver> | if I have a long -- | comment, it splits it corectly |
| 10:42:16 | <quicksilver> | and if I have two short -- | comments it joins them correctly |
| 10:42:33 | <quicksilver> | if I mix the two, it gets confused. |
| 10:43:41 | <ivanm> | that's weird... if I have a comment, then hit enter, kuribas' mode automatically indents to the _previous_ indentation level rather than starting a new top-level definition... |
| 10:43:53 | <ivanm> | in fact, it won't tab back to the left column... |
| 10:50:30 | <Saizan> | is it me or there are less cabal-related questions, lately? |
| 10:53:44 | <ivanm> | Saizan: since when? |
| 10:53:49 | <ivanm> | that reminds me... |
| 10:53:56 | <ivanm> | is there a good emacs mode for .cabal files? |
| 10:55:20 | <cogno> | Ivanm ithink yi has a good cabal mode |
| 10:55:33 | <ivanm> | yi /= emacs ;-) |
| 10:55:37 | <Saizan> | well, the last few months |
| 10:57:29 | <maltem> | Saizan, maybe that's because Google has been fed by cabal q/a in the meantime |
| 10:58:08 | <dcoutts> | or maybe it's because we fixed some of the most confusing ones |
| 10:58:15 | <dcoutts> | and added an FAQ |
| 11:00:37 | <Saizan> | yeah |
| 11:02:13 | <quicksilver> | or maybe it's because everyone is now so confused by base versions they can't even formulate their questions any more? ;) |
| 11:02:55 | <Saizan> | or they try cabal install --help, get flooded with the flags and run away screaming in terror? :) |
| 11:03:31 | <dcoutts> | quicksilver: we're going to start forcing them to think! |
| 11:04:08 | <dcoutts> | http://haskell.org/pipermail/haskell-cafe/2009-June/062297.html |
| 11:04:22 | <dcoutts> | build-depends: base |
| 11:04:25 | <dcoutts> | wrong!! |
| 11:04:27 | <dcoutts> | build-depends: base >= 3 |
| 11:04:29 | <dcoutts> | still wrong!! |
| 11:04:51 | <dcoutts> | build-depends: base >= 3 && < 5 |
| 11:04:54 | <dcoutts> | well done! have a biscuit |
| 11:04:59 | <ahnfelt> | Why does this give me a stack overflow? http://paste.disktree.net/29 |
| 11:05:22 | <ahnfelt> | Shouldn't it be eliminated by tail call optimization? |
| 11:05:35 | <Berengal> | ahnfelt: It's too lazy |
| 11:05:56 | <quicksilver> | dcoutts: I just read that message. |
| 11:05:59 | <Saizan> | TCO does eliminate the stack produced by the recursive call to benchmark |
| 11:05:59 | <quicksilver> | dcoutts: that's why I said it ;) |
| 11:06:01 | <ahnfelt> | Berengal: how so? |
| 11:06:19 | <quicksilver> | ahnfelt: TCO fires fine, but you're building up a huge thunk |
| 11:06:23 | <Berengal> | What happens is 's' is never evaluated until print is called. At that point it's just a huge bunch of 1+1+1+1+1+1+1+... |
| 11:06:27 | <quicksilver> | that thunk blows the stack when you try to evaluate it. |
| 11:06:43 | <Saizan> | @wiki Stack overflow |
| 11:06:44 | <lambdabot> | http://www.haskell.org/haskellwiki/Stack_overflow |
| 11:06:46 | <ahnfelt> | ah, thank you |
| 11:06:58 | <quicksilver> | change the second clause to "s `seq` benchmark (n-1) (s+1)" |
| 11:06:58 | <dcoutts> | quicksilver: right :-) |
| 11:07:08 | <quicksilver> | and you'll keep forcing s. |
| 11:07:13 | <ivanm> | dcoutts: why should you specify && < 5? since it _might_ work with 5, in which case you're being overly restrictive with your versioning |
| 11:07:19 | <Berengal> | Or use bag patterns |
| 11:07:22 | <Berengal> | bang* |
| 11:07:23 | <quicksilver> | ahnfelt: it's interesting to understand why you don't get a big thunk in 'n' |
| 11:07:33 | <quicksilver> | ahnfelt: that's because you pattern match on 'n' (to check if it is 0) |
| 11:07:39 | <quicksilver> | ahnfelt: that forces it - thunk doesn't build up. |
| 11:07:46 | <quicksilver> | well, I hope it's interesting :) |
| 11:08:00 | <dcoutts> | ivanm: depends if you think users will be happier with you because they happen to be able to use a package they didn't otherwise know they'd be able to use, or upset when a package fails with no good explanation |
| 11:08:08 | <ahnfelt> | quicksilver: It is, and it makes sense |
| 11:08:25 | <dcoutts> | ivanm: in the pessimistic case we get much better error messages |
| 11:08:26 | <ahnfelt> | (interesting, that is) |
| 11:08:47 | <Saizan> | ivanm: when base-5 comes out you can always release a new version |
| 11:08:49 | <ivanm> | dcoutts: so if you think you'll get a newer version out before ghc-6.14 comes out, then don't worry about an upper bound? :p |
| 11:08:54 | <ivanm> | Saizan: yeah |
| 11:09:03 | <Saizan> | ivanm: but there's no way to take back the broken package if it won't work |
| 11:09:09 | <Berengal> | ahnfelt: Take a look at foldl and map. foldl is tail-recursive but overflows the stack. map is not tail-recursive, but won't overflow ever (unless the mapped function does) |
| 11:09:17 | <ivanm> | dcoutts: I know I found it annoying when jyp had hgal use containers and arrays == 1, when they work perfectly well with 2 as well |
| 11:09:20 | <icqn> | ahnfelt, was it your homework? |
| 11:09:22 | <ivanm> | Saizan: *nod* |
| 11:09:51 | <dcoutts> | ivanm: but it's also annoying when ghc-6.8 is released and everything breaks with no explanation |
| 11:09:52 | <Berengal> | ahnfelt: Understand why gives you a decent understanding of how the stack works in haskell |
| 11:10:33 | <ivanm> | dcoutts: hasn't it already been released? :o |
| 11:10:47 | <dcoutts> | ivanm: ok, it was annoying when it was released and everything broke |
| 11:10:52 | <ivanm> | yeah |
| 11:10:58 | <dcoutts> | ivanm: the ghc/cabal hackers caught a lot of flak for that |
| 11:11:07 | <dcoutts> | ivanm: so these days we're more conservative |
| 11:11:26 | <dcoutts> | note how ghc-6.10 came out and most things worked? |
| 11:11:50 | <ivanm> | dcoutts: except for those packages that weren't pessimistic enough and didn't work with base-4? |
| 11:11:52 | <ivanm> | ;-) |
| 11:12:01 | <dcoutts> | ivanm: no, those worked too |
| 11:12:06 | <ahnfelt> | icqn: My homework is to use monads to build an interpreter and a compiler. This is just a test. |
| 11:12:15 | <dcoutts> | ivanm: because we continued to use base 3 for them |
| 11:12:25 | <ivanm> | dcoutts: not if they had base >= 3 ... |
| 11:12:47 | <dcoutts> | ivanm: yes, even then, since 3.0.3.0 >= 3 |
| 11:13:27 | <ivanm> | dcoutts: well, we had to hack some ebuilds to force usage of base-3.* because cabal-the-library was telling ghc to use base-4, which promptly failed to build in many cases |
| 11:13:35 | <dcoutts> | ivanm: before we added the shim, everything broke (to a first approximation) |
| 11:13:48 | <ivanm> | "shim"? I thought that app was dead... |
| 11:13:49 | <ivanm> | ;-) |
| 11:13:57 | <dcoutts> | ivanm: yes, the shim was added in cabal-install, not Cabal library |
| 11:14:00 | <ahnfelt> | icqn: I realize I should have checked the wiki first, I was just too surprised coming from an eager language |
| 11:14:02 | <ivanm> | ahhhh |
| 11:14:06 | <dcoutts> | ivanm: so it didn't help you |
| 11:14:20 | <ivanm> | then you should have specified cabal-install ;-) |
| 11:14:27 | <dcoutts> | @arr! |
| 11:14:27 | <lambdabot> | Ahoy mateys |
| 11:14:30 | <ivanm> | since generally, doesn't cabal == cabal-the-library |
| 11:14:31 | <ivanm> | ? |
| 11:14:43 | <dcoutts> | Cabal == Cabal-the-library, yes |
| 11:18:43 | <icqn> | ahnfelt, there is although a good book available, as the topic says: "Real World Haskell: out now", here http://book.realworldhaskell.org/read/ |
| 11:21:04 | <icqn> | it covers the question you was asking, but I do not have a chapter number in mind... |
| 11:21:51 | <ahnfelt> | icqn: I will check it out, thank you |
| 11:33:47 | <ahnfelt> | icqn: I will check it out, thank you |
| 11:33:56 | <ahnfelt> | (nevermind, that, hit the wrong key) |
| 11:34:18 | <ahnfelt> | (nevermind, that, hit the wrong key) |
| 11:34:32 | <ahnfelt> | ahh, I can't keep track of my terminals, cya later |
| 11:46:47 | <jeffersonheard> | what kind of thing would error out and give me a "Negative exponent" ? |
| 11:47:19 | <MyCatVerbs> | jeffersonheard: x ^ y, where y is negative. |
| 11:47:34 | <jeffersonheard> | MyCatVerbs, thanks |
| 11:47:42 | <jeffersonheard> | That makes sense as you say it |
| 11:47:52 | <MyCatVerbs> | In which case, only x ^^ y, or x ** y, would both be acceptable, depending on the types involved. |
| 11:48:11 | <MyCatVerbs> | Really? Wow, and that despite being totally incoherent. ;) |
| 11:50:57 | <ulfdoz> | vdb: unknown partition table |
| 11:51:01 | <ulfdoz> | ewin |
| 11:51:09 | <jeffersonheard> | sure enough. thanks. you just saved me an hour of scratching my head |
| 12:04:04 | <nibro> | @seen malcolmw |
| 12:04:04 | <lambdabot> | malcolmw is in #haskell-in-depth, #darcs, #haskell-soc, #ghc, #haskell-overflow, #haskell-blah and #haskell. I don't know when malcolmw last spoke. |
| 12:20:08 | <malcolmw> | nibro: pong |
| 12:24:54 | <nibro> | hey malcolmw |
| 12:25:25 | <nibro> | malcolmw: I was looking at cpphs, since I'm using it for haskell-src-exts |
| 12:25:38 | <malcolmw> | nibro: yep |
| 12:25:50 | <nibro> | malcolmw: and I was curious to find that it depended on a lot of old haskell98 modules |
| 12:26:10 | <nibro> | malcolmw: is there a reason for this extra dependency other than "haven't gotten round to fixing yet"? :-) |
| 12:26:11 | <ksf> | I want to write a TH function like "foo ident = [d| data Foo = Foo|]", what's the syntax to use ident inside the quote? |
| 12:27:17 | <malcolmw> | nibro: deliberately so. cpphs comes with nhc98, and in that context, the base library is full of CPP-isms, so cpphs needs to be built before the base library |
| 12:27:47 | <nibro> | malcolmw: I expected the answer would be something like that |
| 12:28:29 | <malcolmw> | nibro: nice bootstrapping behaviour is a property I am loathe to break |
| 12:28:35 | <nibro> | malcolmw: though the library depends on base as well, no? |
| 12:29:17 | <malcolmw> | nibro: haskell98 package depends on base package, only in ghc I think. certainly in nhc98, the H'98 libraries are more basic than "base" |
| 12:29:47 | <nibro> | malcolmw: I meant the cpphs library, it's listed as depending on base and haskell98 on hackage iirc |
| 12:30:04 | <malcolmw> | but since ghc does not distribute cpphs, that is not a problem |
| 12:30:17 | <malcolmw> | nibro: let me check... |
| 12:31:02 | <ksf> | meh I don't wanna work with the TH ADT. I want sexprs. |
| 12:31:06 | <malcolmw> | nibro: you are right, the cabal file does claim it needs base |
| 12:32:03 | <Berengal> | Is there a better way to write this: (thousands, (hundreds, (tens, ones))) = (second (second (divMod' 10) <<< divMod' 100) <<< divMod' 1000) n |
| 12:32:46 | <ksf> | map read . show |
| 12:33:08 | <malcolmw> | nibro: ah, the only module cpphs uses from base is System.IO.Unsafe |
| 12:33:36 | <Berengal> | ksf: Needs reverse before read, but it could work |
| 12:33:49 | <nibro> | malcolmw: so I take it this is not something slated for a "fix" with anything less than a major rewrite of nhc98? |
| 12:33:52 | <ksf> | > showIntAtBase 10 id 1234 "" |
| 12:33:53 | <lambdabot> | Couldn't match expected type `GHC.Types.Char' |
| 12:34:01 | <philipp_> | i'm using parMap to parallelise a program which works fine for half an hour but then uses only one core, here's the output of +RTS -s : http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5526#a5526 is there a problem with garbage collection? |
| 12:34:02 | <ksf> | :t showIntAtBase |
| 12:34:03 | <lambdabot> | forall a. (Integral a) => a -> (Int -> Char) -> a -> String -> String |
| 12:34:04 | <nibro> | malcolmw: ...which I presume is not in the pipeline any time soon? |
| 12:34:11 | <ksf> | ...now that's mean. |
| 12:34:43 | <malcolmw> | nibro: is it a problem for you? |
| 12:34:46 | <byorgey> | > showIntAtBase 10 (['0'..'9']!!) 1234 "" |
| 12:34:47 | <ksf> | @src showIntAtBase |
| 12:34:47 | <lambdabot> | "1234" |
| 12:34:47 | <lambdabot> | Source not found. Take a stress pill and think things over. |
| 12:35:04 | <nibro> | malcolmw: certainly not a problem except for my aesthetical sense |
| 12:35:07 | <byorgey> | ksf: the Int -> Char just tells it how to display the digits |
| 12:35:07 | <Berengal> | ksf: thousands also needs to hold the entire remaining sum, but that's not too hard... |
| 12:35:37 | <nibro> | malcolmw: I tend to think of the haskell98 package as deprecated, and was surprised to find the transitive dependency on it from haskell-src-exts |
| 12:35:47 | <ksf> | byorgey, sure, but Berengal wants it to be Int -> Int |
| 12:36:09 | <malcolmw> | nibro: my aesthetic sense must be opposite to yours :-) |
| 12:36:12 | <nibro> | malcolmw: but I'm sure I can live with that :-) |
| 12:36:21 | <byorgey> | ksf: oh, right, showIntAtBase won't be very useful for that =) |
| 12:36:27 | <nibro> | malcolmw: what does your aesthetic sense say regarding this? |
| 12:36:38 | <nibro> | malcolmw: that haskell98 is preferred over base? |
| 12:37:19 | <malcolmw> | nibro: for me, the haskell98 libraries are a standard that is well-defined, and unchanging. I can rely on them. Base does not have those properties. |
| 12:38:21 | <Berengal> | Going via lists also brings problems when it comes to pattern matching |
| 12:38:24 | <malcolmw> | nibro: my aesthetics prefer semantic consistency :-) |
| 12:38:36 | <nibro> | malcolmw: then we truly do have opposite senses - to me unchanging == stale, while change == progress |
| 12:39:01 | <Igloo> | malcolmw: So do you still import List etc rather than Data.List? |
| 12:39:05 | <nibro> | malcolmw: unchecked change is bad of course, but I think base is definitely a step up from haskell98 |
| 12:39:21 | <malcolmw> | Igloo: I always prefer that, yes |
| 12:41:01 | <malcolmw> | nibro: of course, there are some things that haskell98 lacks, so I'm not too bothered about using base if those features are absolutely necessary to my application |
| 12:42:38 | <nibro> | malcolmw: so you don't acknowledge that the changes that have been made to the haskell98 libraries as they now appear in base have been improvements? |
| 12:42:45 | <JaffaCake> | ACTION thinks we should deprecate haskell98 on the grounds that it doesn't use hierarchical names |
| 12:43:04 | <malcolmw> | but for instance, when hsc2hs switched from using the haskell98 libraries to using base, it caused the nhc98 bootstrapping process a huge amount of grief |
| 12:43:21 | <nibro> | JaffaCake: well, it does use hierarchical names, only the hierarchies are very short :) |
| 12:43:40 | <malcolmw> | nibro: I would be hard-pushed to name any actual changes between haskell98 and base, as opposed to additions |
| 12:44:13 | <JaffaCake> | nibro: that's one way to look at it (but not the right way, IMO) |
| 12:44:20 | <nibro> | malcolmw: I can certainly see pragmatic reasons for wanting to depend on haskell98 over base (such as bootstrapping), but I was surprised to hear you actually saw it as preferable :-) |
| 12:44:29 | <Igloo> | exceptions is the only change that comes to mind |
| 12:44:38 | <nibro> | JaffaCake: oh, I totally agree with you :) |
| 12:44:43 | <malcolmw> | Igloo: yes, that's the only one I can think of too |
| 12:44:57 | <nibro> | malcolmw: there's also the differences in the time package |
| 12:45:06 | <nibro> | malcolmw: which is what would affect cpphs the most |
| 12:45:07 | <Igloo> | That and the module hierarchisation, of course |
| 12:45:30 | <JaffaCake> | aren't System.IO exceptions the same as haskell98 IO? |
| 12:45:35 | <nibro> | malcolmw: this is not base per se obviously, but it's something that has been changed since haskell98 |
| 12:46:15 | <ksf> | ACTION still can't believe TH can't do unquoting |
| 12:46:18 | <Igloo> | System.IO.catch doesn't exist |
| 12:46:40 | <JaffaCake> | it's in System.IO.Error, isn't it? |
| 12:46:50 | <JaffaCake> | but it's the same one as haskell98's catch |
| 12:46:50 | <Igloo> | Ah, yes, OK |
| 12:47:03 | <malcolmw> | nibro: I'm no particular fan of Haskell'98's Time library, but both of the old-time and time packages are available, and I would have no problem using them if I needed them |
| 12:47:31 | <JaffaCake> | malcolmw: old-time == haskell98 Time |
| 12:47:45 | <Igloo> | malcolmw: So is CPP the main reason nhc has base on top of haskell98? |
| 12:47:46 | <malcolmw> | nibro: actually, since old-time just duplicates haskell98, I would not use that, you are right |
| 12:48:08 | <malcolmw> | Igloo: no, it is not the main reason |
| 12:49:34 | <JaffaCake> | malcolmw: so it's historical, right? |
| 12:49:46 | <malcolmw> | JaffaCake: yes, mainly it is just historical |
| 12:50:00 | <JaffaCake> | and it would be a lot of effort to change, I understand that |
| 12:51:02 | <malcolmw> | there is still a little part of me that wants to argue that since Haskell'98 is the only actual standard we possess right now, then all the newer things ought to be built on top of that |
| 12:52:01 | <JaffaCake> | I'd argue that since we moved to hierarchical libraries, we should be striving to avoid haskell98 |
| 12:52:11 | <JaffaCake> | also, haskell98 has some clearly wrong and deprecated stuff in it |
| 12:52:33 | <malcolmw> | If haskell-prime decides to bless a particular fixed set of libraries, then that would be the new standard to build everything else on. |
| 12:52:38 | <nibro> | malcolmw: I would counter-argue that what we really need is a new standard, or perhaps in particular a way to introduce better standards |
| 12:53:16 | <JaffaCake> | malcolmw: so I see the structure of the packages as moving towards that |
| 12:53:33 | <JaffaCake> | if/when haskell98 is really deprecated, it'll be an easy change to make |
| 12:54:03 | <malcolmw> | yep, I agree with all that |
| 12:54:10 | <Igloo> | I'm not sure that standardising libraries is the right thing to do. We've had 10 years of Exceptions pain, amongst other things, because of it |
| 12:54:41 | <quicksilver> | if the concern is bootstrapping, then it seems at least as sensible to target a particular distribution as a bootstrap. nhc98 will bootstrap from GHC 6.6, GHC 6.8 or NHC X.Y |
| 12:54:56 | <quicksilver> | that seems just as sensible as bootstrapping from a slightly-mythical "haskell98 platform" |
| 12:55:07 | <nibro> | Igloo: I think the idea to standardize the incremental standardization process rather than deciding on one single haskell-prime standard is the way to go |
| 12:55:12 | <malcolmw> | quicksilver: well, nhc98 likes to be able to bootstrap on a platform that has no haskell compiler at all |
| 12:55:24 | <ksf> | backward-compability layers are always better than freezes, up to breakage. |
| 12:55:36 | <quicksilver> | malcolmw: well for a true bootstrap I don't see how haskell98 vs base matters? |
| 12:55:45 | <saml> | > let f l@(x:xs) = x : zipWith (-) xs l in f [1,2,6,9] --what would you call f ?? |
| 12:55:46 | <lambdabot> | [1,1,4,3] |
| 12:56:09 | <quicksilver> | nibro: OMG we have to standardise the standardisation process before we can make a standard? |
| 12:56:12 | <quicksilver> | ouch. |
| 12:56:25 | <malcolmw> | quicksilver: base was a rapidly-changing entity until relatively recently, so being able to guarantee to bootstrap from it was not so easy |
| 12:56:25 | <ksf> | saml, delta |
| 12:56:34 | <saml> | ksf, thanks |
| 12:56:44 | <ksf> | reactive has a similar thing for events and calls it withPrevE |
| 12:56:49 | <JaffaCake> | malcolmw: that's why we have package versions :) |
| 12:57:24 | <nibro> | quicksilver: I believe that's where the haskell-prime committee is at right now, though there are several here who would know better :) |
| 12:57:34 | <JaffaCake> | ACTION hides |
| 12:57:47 | <malcolmw> | JaffaCake: but it would be a bit odd for a compiler to bootstrap itself using base-2.0, only to then go on to supply base-3.x to the user? |
| 12:58:05 | <JaffaCake> | not at all, that's what GHC does |
| 12:58:08 | <malcolmw> | JaffaCake: although that is certainly possible I guess. |
| 12:58:08 | <nibro> | quicksilver: the idea being that creating one huge standard would take waaaaay too much time, and we would still be stuck with something that would be obsolete soon after |
| 12:59:07 | <JaffaCake> | malcolmw: if you force the bootstrapper to be the same as the bootstrappee, then you have big bootstrapping problems |
| 12:59:16 | <ksf> | quicksilver, there are RFCs about how to write RFCs. |
| 12:59:50 | <JaffaCake> | quicksilver: we semi-decided to modularise the haskell prime process, though things have been quiet for a while |
| 12:59:57 | <quicksilver> | ksf: yes, but they didn't write them first. |
| 13:00:04 | <quicksilver> | JaffaCake: I recall the semi-decision. |
| 13:00:12 | <malcolmw> | JaffaCake: but that is essentially what nhc98 does - it bootstraps with its own current version, in order to avoid needing to distribute multiple diverging copies of source code |
| 13:00:12 | <JaffaCake> | I should really start prodding people again |
| 13:00:30 | <quicksilver> | JaffaCake: AIUI it was around the time you took a sabattical with the modest ambition of solving all the world's problems in 3 months ;) |
| 13:01:03 | <nibro> | JaffaCake: you really should :) |
| 13:01:19 | <JaffaCake> | malcolmw: you have to bootstrap using *something*, what if that is an older compiler? (ignore bootstrapping from C files for now) |
| 13:01:40 | <JaffaCake> | quicksilver: I made a start ;) |
| 13:02:08 | <ksf> | ...using nothing but your bootstraps to pull you out of the swamp is the _very_essence_ of bootstrapping. |
| 13:02:16 | <malcolmw> | JaffaCake: yeah, so booting with a different compiler (ghc, hbc, older nhc98) all works OK, but that is partly because we try not to depend on moving targets like the base package :-) |
| 13:02:47 | <JaffaCake> | ok, so it's entirely possible that you're bootstrapping from base-2.x and supplying base-3.x or whatever |
| 13:03:26 | <malcolmw> | JaffaCake: yes, sure, but when booting without a Haskell compiler, I don't want to be supplying multiple copies of the base library |
| 13:03:37 | <JaffaCake> | no, 'course not |
| 13:04:13 | <malcolmw> | JaffaCake: and as I already said, by avoiding as many dependencies on base as possible, it doesn't really matter which version the bootstrapping compiler has. |
| 13:04:53 | <JaffaCake> | so would you rather we didn't make any changes to libraries at all? |
| 13:05:10 | <malcolmw> | Now that base is more stable, it could certainly make sense for nhc98 to switch over to it instead of haskell98 |
| 13:05:26 | <malcolmw> | JaffaCake: I'm not saying that at all |
| 13:06:18 | <JaffaCake> | ok, good :) |
| 13:06:22 | <malcolmw> | bugfixes are good, API additions are often good, it is just that bootstrapping can be a pain if you are not extremely careful |
| 13:06:29 | <malcolmw> | that's all |
| 13:07:12 | <malcolmw> | and I've had my share of pain in that department |
| 13:08:28 | <JaffaCake> | it occurs to me that supplying base-3 with GHC 6.10 wasn't really a fix for anything |
| 13:08:47 | <JaffaCake> | packages that don't update themselves just get broken a bit later |
| 13:09:42 | <Igloo> | It does make it easier for packages to support "this release and the previous release" |
| 13:09:52 | <Igloo> | But I think that the extensible-exceptions package is a better way to do that |
| 13:09:55 | <JaffaCake> | yes, true |
| 13:10:30 | <JaffaCake> | packages still get broken once per year, unless we're willing to indefinitely keep old base versions around |
| 13:10:38 | <hackagebot> | heap 1.0.0 |
| 13:11:38 | <malcolmw> | JaffaCake: how about freezing base, and never changing it again? :-) |
| 13:11:47 | <JaffaCake> | yikes |
| 13:12:13 | <JaffaCake> | we'd just end up with a heap of cruft that we have to keep working for ever |
| 13:12:31 | <malcolmw> | JaffaCake: it would make sense, if base wasn't so full of unnecessary junk |
| 13:13:03 | <JaffaCake> | maybe when it really is stripped down a lot further, but even then I'd be very wary |
| 13:13:41 | <malcolmw> | the idea that all library packages will break every time there is a new release of GHC doesn't seem very friendly either |
| 13:13:43 | <JaffaCake> | if it was basically just Prelude minus IO stuff, then maybe |
| 13:14:50 | <quicksilver> | one of the benefits of splitting base, though, is that packages only depend on what they actually need |
| 13:15:06 | <malcolmw> | with the new hackage policy of closed upper limits on base version, it does seem likely that it really will be _all_ packages breaking every year. |
| 13:15:08 | <quicksilver> | then they only break if one of the things they actually depend upon changed. |
| 13:15:08 | <JaffaCake> | yes, and some of those pieces will change rarely |
| 13:15:21 | <quicksilver> | malcolmw: only if base does indeed get bumped once a year |
| 13:16:15 | <JaffaCake> | it'll probably get bumped again this year |
| 13:16:26 | <byorgey> | I thought the idea was to always ship two versions of base, to give package maintainers a whole year to upgrade |
| 13:16:53 | <byorgey> | the upper limit is so that the packages don't break *by necessity*. |
| 13:16:54 | <JaffaCake> | byorgey: yes, but now we have a bunch of packages depending on last year's base, and they are all about to break |
| 13:17:23 | <malcolmw> | so the solution is to make them break more often? |
| 13:17:32 | <JaffaCake> | mind you, it's only 10% of hackage, which is surprisingly low |
| 13:17:52 | <jeffersonheard> | I'm getting "Map.find: Element not in the map", but I'm not using Map.find anywhere. Is it the same as Map.! |
| 13:17:53 | <Igloo> | malcolmw: Depaying each breakage by 1 year doesn't actually fix anything at all |
| 13:17:54 | <jeffersonheard> | ? |
| 13:18:03 | <byorgey> | ACTION is OK with things breaking occasionally in the name of progress |
| 13:18:25 | <JaffaCake> | Igloo: right |
| 13:18:29 | <Igloo> | JaffaCake: I suspect it's because most packages are unaffected by the changes, and don't specify any bounds |
| 13:18:38 | <quicksilver> | Igloo: erm. doesn't it? |
| 13:18:40 | <malcolmw> | Igloo: I'm not arguing in favour of delay |
| 13:18:46 | <JaffaCake> | Igloo: oh, so that's accidental, and it's about to get worse |
| 13:18:48 | <quicksilver> | Igloo: breaking less often is better than breaking more often. |
| 13:18:58 | <byorgey> | jeffersonheard: the source says yes |
| 13:19:06 | <Igloo> | quicksilver: Delaying all breakages by a year doesn't change the frequency of breakages |
| 13:19:30 | <quicksilver> | it does, dpeneding how you interpret that english phrase. |
| 13:19:33 | <byorgey> | it does in the short term ;) |
| 13:19:39 | <quicksilver> | if it means a library released in 2009 works until 2011 |
| 13:19:41 | <quicksilver> | instead of 2010 |
| 13:19:48 | <JaffaCake> | the only way to change the frequency of breakages is to change the frequency of changes, and the only way to do that (reasonably) is to split up base some more |
| 13:19:49 | <quicksilver> | then that's two years of working, not one. |
| 13:20:13 | <jeffersonheard> | byorgey: thanks. I suppose I should consult myself, but I've got an hour and a half before a demo of this, and I haven't had a lot of sleep |
| 13:20:47 | <JaffaCake> | quicksilver: good point - it means package authors can wait 2 years between updates instead of 1 |
| 13:21:36 | <quicksilver> | although the situation is worse if your program depends on more than one library |
| 13:21:43 | <quicksilver> | and the library authors fix things on different timescales. |
| 13:22:28 | <malcolmw> | to my mind, the underlying problem is that base is too closely associated with ghc. A really wide-ranging split-up would undoubtedly help, by reducing the surface area prone to breakage |
| 13:23:10 | <doserj> | sure, if old base versions could be installed from hackage, that would solve many problems. |
| 13:23:52 | <JaffaCake> | malcolmw: yes, though of course the act of splitting is itself breakage (that's what happened in the base-2 to base-3 transition) |
| 13:24:08 | <malcolmw> | yep |
| 13:24:22 | <quicksilver> | lots of jam tomorrow, but today we just have salt? |
| 13:24:24 | <Igloo> | Yes, but it's (hopefully) little pain now for much less pain in the future |
| 13:24:25 | <quicksilver> | ;) |
| 13:26:13 | <JaffaCake> | I suppose if we weren't that interested in sharing *code* between compilers, we could rename base to base-ghc, and put a base veneer on top of it to hide the GHC.* modules |
| 13:26:45 | <JaffaCake> | that would change less frequently |
| 13:27:24 | <Igloo> | We could do that anyway if we wanted, but choosing a different name for base-ghc |
| 13:27:37 | <Igloo> | And then e.g. nhc's base would just reexport all of the other package |
| 13:27:47 | <malcolmw> | I'm just pondering - this whole versioning semantics thing - why have we not yet got a true FP mindset on it? Isn't the PVP just a hacky way of specifiying a compatibility function (or relation), which necessarily ought to be more lazy in some of its arguments. e.g. is bytestring-3.4 compatible with base-5.2? well, we don't know until base-5.2 is released, so the answer is bottom until that point in time. |
| 13:27:57 | <Igloo> | Or it would not export NHC.*, or whatever |
| 13:28:22 | <Igloo> | malcolmw: So what does cabal-install do with the bottoms? |
| 13:29:26 | <Igloo> | JaffaCake: Even if we did that, I suspect that base's version number would need to be bumped for each major GHC release |
| 13:29:47 | <malcolmw> | Igloo: There are no bottoms for packages that are already released. |
| 13:29:57 | <JaffaCake> | Igloo: perhaps only the minor version though - e.g. what have we changed so far since base-4? |
| 13:30:09 | <Igloo> | malcolmw: OK, so when base 5.2 is released, what actually happens? |
| 13:30:43 | <malcolmw> | Igloo: so somehow, at the point of release, the compatibility function needs to be updated to resolve to a definite answer |
| 13:31:17 | <malcolmw> | Igloo: there may even be automatic ways of helping to do that |
| 13:31:19 | <Igloo> | malcolmw: Right, it's the "somehow" I'm interested in :-) |
| 13:31:27 | <JaffaCake> | what would be more useful is a way to make packages able to build against newer versions if they don't depend on anything that changed |
| 13:31:35 | <doserj> | who maintains the compatibility function? and how is that different to just changing the dependency field? |
| 13:32:23 | <JaffaCake> | refining dependencies to something more accurate, e.g. "I depend on Foo.Bar :: [a] -> Int" |
| 13:32:49 | <JaffaCake> | but that's hard, and requires heavy tool support |
| 13:33:06 | <malcolmw> | JaffaCake: it would be the Right Thing though |
| 13:33:25 | <JaffaCake> | not *the* right thing, but it is more accurate than versions, yes |
| 13:33:48 | <Igloo> | JaffaCake: Hmm, OK, I didn't see any changes that would need a major versino bump from a quick skim of the changes |
| 13:33:48 | <JaffaCake> | you can imagine even more accuracy, such as depending on strictness properties |
| 13:33:50 | <quicksilver> | doserj: its maintained by the authors of the library packages themselves, not the authors of the "client" packages |
| 13:33:52 | <Absolute0> | How do I bind a value to a name once and then update it thereafter? |
| 13:33:54 | <quicksilver> | doserj: that would be the key different. |
| 13:33:57 | <Absolute0> | in a do block |
| 13:34:28 | <quicksilver> | Absolute0: you don't. This is haskell. |
| 13:34:34 | <Absolute0> | quicksilver: i know |
| 13:34:36 | <quicksilver> | you can re-use a name if you want to, though. |
| 13:34:49 | <quicksilver> | but that's not really updating, it's shadowing. |
| 13:34:53 | <Absolute0> | quicksilver: I am having a problem where i initialize once and need to update |
| 13:34:59 | <JaffaCake> | Igloo: the unicode I/O stuff will change a lot under GHC.*, but nothing anywhere else |
| 13:35:19 | <JaffaCake> | except perhaps if we decide to add some new encoding-related functionality |
| 13:35:19 | <Absolute0> | is there a way to check if a name has already been binded to a value? |
| 13:35:28 | <JaffaCake> | but that will be a minor bump |
| 13:35:30 | <malcolmw> | Absolute0: do { x <- foo; x <- x+1; return x } |
| 13:35:34 | <Absolute0> | this way i can check the first time and the update afterwards |
| 13:36:29 | <quicksilver> | Absolute0: you can't update. |
| 13:36:52 | <quicksilver> | Absolute0: I'm not convinced I understand your question, but it really sounds to me like you're labouring under a misapprehension. |
| 13:36:57 | <quicksilver> | you can't update values. |
| 13:37:23 | <wli> | do { x <- foo ; x <- return $ x + 1 ; return x } |
| 13:37:24 | <quicksilver> | what you can do, is use a number of special reference box types (IORef, MVar) which have special primitives (writeIORef, putMVar) to change their contents. |
| 13:37:28 | <Absolute0> | http://pastie.org/499078 <- line 11 intializes line 19 updates |
| 13:37:30 | <quicksilver> | but I'm not sure if that's what you want. |
| 13:37:40 | <Absolute0> | but since it runs forever line 11 always runs |
| 13:37:48 | <Absolute0> | theres no way to initialize setup only once? |
| 13:38:08 | <quicksilver> | you can't change 'setup'. |
| 13:38:13 | <Absolute0> | If i could check if x is binded to a value, that would be a solution |
| 13:38:20 | <quicksilver> | (ignoring the fact that your code isn't quite valid) |
| 13:38:26 | <quicksilver> | you cannot update values. |
| 13:38:30 | <Absolute0> | if binded(setup) initalize else update |
| 13:38:35 | <quicksilver> | you cannot update. |
| 13:38:41 | <Absolute0> | quicksilver: s/update/rebind |
| 13:38:42 | <quicksilver> | I think we're failing to communicate, sorry ;) |
| 13:38:44 | <Absolute0> | is that better? :) |
| 13:38:47 | <quicksilver> | no. |
| 13:38:58 | <quicksilver> | all you would be deoing is making a new, local variable called 'setup' |
| 13:38:59 | <Absolute0> | you can do let x = 5; and then let x = 6; |
| 13:39:04 | <Absolute0> | so don't say you can't |
| 13:39:05 | <quicksilver> | it would be completely unrelated to the existing setup |
| 13:39:11 | <quicksilver> | it would just happen to have the same name. |
| 13:39:18 | <Absolute0> | ok that's what i want |
| 13:39:19 | <Absolute0> | :) |
| 13:39:22 | <Absolute0> | whatever you call it |
| 13:39:26 | <quicksilver> | no it's not. |
| 13:39:31 | <quicksilver> | because then when 'main' looped |
| 13:39:37 | <quicksilver> | the "new" local variable would be out of scope |
| 13:39:44 | <quicksilver> | and the "old" top-level setup would be back in scope. |
| 13:39:59 | <Absolute0> | so i need to resort to some sort of monadic solution? |
| 13:40:00 | <quicksilver> | what you could do is make 'setup' a parameter of main |
| 13:40:09 | <quicksilver> | and call yourself recursively (with the new value) |
| 13:40:11 | <Absolute0> | yeah |
| 13:40:21 | <quicksilver> | passing parameters through a recursion is one way to model a mutating value. |
| 13:40:24 | <Absolute0> | but can main take parameters? |
| 13:40:32 | <Absolute0> | i guess mainHelper :) |
| 13:40:33 | <quicksilver> | no |
| 13:40:35 | <quicksilver> | right :) |
| 13:40:37 | <Absolute0> | thanks |
| 13:41:06 | <quicksilver> | malcolmw: in your proposal, how would an 'end-user' specify a dependency? |
| 13:41:30 | <quicksilver> | malcolmw: an 'end-user' would say "I need bytestring-5.4", and it would be the job of the system to decide if bytestring-12.16 is backwards compatible or not? |
| 13:42:05 | <malcolmw> | quicksilver: it's not a proposal, just a random thought that occurred :-) |
| 13:43:45 | <malcolmw> | quicksilver: possibly the user says "I need the interface of bytestring-5.4", and some automatic tool discovers whether parts of the API in 12.16 have been removed or changed since 5.4 |
| 13:44:12 | <quicksilver> | ACTION nods |
| 13:44:24 | <JaffaCake> | like the tool we proposed as a SoC project? |
| 13:44:55 | <malcolmw> | quicksilver: so you would be specifying a minimum version, rather than a maximum |
| 13:45:05 | <quicksilver> | I'm not sure a tool would be sufficient |
| 13:45:10 | <quicksilver> | although it might be helpful |
| 13:45:15 | <SamB_XP> | malcolmw: I'm not quite understanding the differencew between "random thought" and "proposal" |
| 13:45:24 | <quicksilver> | the visible ABI/API might look totally compatible but some important semantic different might be there |
| 13:45:26 | <JaffaCake> | malcolmw: but the point is, the version was bumped because the API changed |
| 13:45:39 | <malcolmw> | SamB_XP: proposals are usually more well-thought out :-) |
| 13:45:50 | <malcolmw> | JaffaCake: yes, but changed in what way? |
| 13:45:52 | <quicksilver> | JaffaCake: but that is necessarily conservative. |
| 13:46:08 | <quicksilver> | JaffaCake: it might turn out to be backward compatible with a large class of programs. |
| 13:46:11 | <JaffaCake> | malcolmw: so just comparing APIs isn't enough, you need to know which part of the API the package depended on |
| 13:46:30 | <malcolmw> | version numbers are a poor substitute for the real information we want |
| 13:46:58 | <malcolmw> | so is there some compact way in which we could get closer to the semantics of what is going on? |
| 13:47:02 | <JaffaCake> | s/poor substitute/safe approximation/ :) |
| 13:47:25 | <JaffaCake> | malcolmw: I think it's really quite hard |
| 13:47:36 | <SamB_XP> | and the real problem is if one of the functions has the same type but does something a bit different ... |
| 13:47:40 | <malcolmw> | data VersionChange = SignaturesChanged | SignaturesAdded | SignaturesDeleted |
| 13:47:57 | <JaffaCake> | e.g. if you import a module M from a package without an import list, then you implicitly depend on the *absence* of everything that would name-clash |
| 13:48:23 | <malcolmw> | yes that is a nasty one |
| 13:48:33 | <JaffaCake> | and then there's instances.... |
| 13:48:34 | <SamB_XP> | JaffaCake: and, even worse, the list of things that would name clash is variable |
| 13:48:40 | <malcolmw> | but it could still be automated |
| 13:48:58 | <ksf> | data SemanticsChange = DontWorry | Hope | Pray |
| 13:48:58 | <quicksilver> | malcolmw: automation could never spot a semantic change. |
| 13:49:18 | <JaffaCake> | in theory you could come up with some more accurate dependency that could be derived automatically, yes |
| 13:49:45 | <quicksilver> | malcolmw: the function "happyBunny :: IO ()" could continue to have the same interface even though in version 5.1 it actually summons an angry bear. |
| 13:49:47 | <JaffaCake> | whether it would describe completely the conditions necessary for compilation to succeed, I'm not sure |
| 13:50:37 | <JaffaCake> | and semantic changes mean it's all hopeless, yes |
| 13:51:24 | <malcolmw> | quicksilver: we can't do anything about evil package makers who live in the IO netherworlds, but we _do_ know how to check type signatures, strictness, overlapping names, and so on. Just because these techniques don't solve the whole problem is not a reason to reject them |
| 13:52:32 | <quicksilver> | malcolmw: well IO might have been a bad example. |
| 13:52:40 | <quicksilver> | malcolmw: it certainly wasn't the point I was making. |
| 13:52:44 | <JaffaCake> | the advantage of version numbers is that they can be checked easily without heavyweight tool support |
| 13:52:54 | <malcolmw> | even in my own programs, never mind using other people's packages, I might accidentally make the happyBunny summon the angry bear, and the type system will not help me. |
| 13:53:08 | <quicksilver> | malcolmw: (+) :: Int -> Int -> Int continues to have the same API even if in version 5.1 I choose, for some reason to make it do multiplication. |
| 13:55:12 | <Saizan> | the idea of keeping version numbers around and updating the "compatibility" function might work though |
| 13:55:32 | <JaffaCake> | I doin't think I understand that |
| 13:56:36 | <quicksilver> | Saizan: yes, if the compatibility function was manually maintained, then yes. |
| 13:56:41 | <Saizan> | JaffaCake: instead of having the .cabal file specify the version range you can calculate them externally and store them in hackage, so tools can download them |
| 13:56:44 | <quicksilver> | Saizan: or at least partly manual. |
| 13:56:59 | <quicksilver> | Saizan: and in theory it could be higher-resolution than whole-package. |
| 13:57:26 | <JaffaCake> | Saizan: oh, so we'd determine automatically which versions a package depended on? |
| 13:57:27 | <quicksilver> | so, bunnyWorld-5.1 is entirely backward compatible with bunnyWorld-3.2 *except* for the function happyBunny. |
| 13:57:28 | <Saizan> | mostly automated, or at least automatically checked for silly errors is my main goal |
| 13:57:42 | <quicksilver> | since I am the maintainer I could maintain that fact. |
| 13:57:49 | <quicksilver> | I was the one who changed the semantics. |
| 13:58:03 | <quicksilver> | argubaly makes more sense for me to maintain it than some consumer of my code to try to work it out. |
| 13:58:21 | <JaffaCake> | it's not a bad idea to keep the dependencies separate and allow Hackage to update them |
| 13:58:24 | <Saizan> | JaffaCake: yes, maybe letting the maintaners override it with semantic information |
| 13:58:32 | <dcoutts> | Saizan: if hackage keeps a machine-readable description of the api then checking interface compatibility should be possible |
| 13:58:42 | <malcolmw> | so, type-inferrable API changes are discovered automatically, semantic changes are recorded manually - sounds good |
| 13:58:45 | <Saizan> | i.e. like type-inference with possibly user-supplied signatures |
| 13:59:08 | <SamB_XP> | dcoutts: but how will it know whether the semantics of a function have been altered in an incompatible way ? |
| 13:59:31 | <quicksilver> | SamB_XP: I believe you'd have to have a manual override. |
| 13:59:43 | <SamB_XP> | what if you forget until it's too late? |
| 13:59:46 | <dcoutts> | so what, the suggestion is that someone uploads a new version of a dependency and we email the authors of dependent packages to say, "we think your package will continue to work with this new version, would you care to test it and update the dep appropriately" ? |
| 13:59:48 | <quicksilver> | SamB_XP: "even though the API of foo :: Bar -> Baz looks the same, the semnatics have changed" |
| 13:59:57 | <SamB_XP> | ... will there not be a "too late" ? |
| 13:59:57 | <quicksilver> | SamB_XP: all possible systems contain room for human error. |
| 14:00:03 | <Saizan> | dcoutts: yeah, though it came out that it's complex and maybe expensive, so we might cache the result in the form of version ranges |
| 14:00:12 | <quicksilver> | dcoutts: no. |
| 14:00:15 | <JaffaCake> | dcoutts: if we follow the PVP, there's no need to do that |
| 14:00:26 | <quicksilver> | dcoutts: the dependent packages declare a dependency on one version which definitely works. |
| 14:00:40 | <Saizan> | dcoutts: and version ranges also allow maintainers to add semantic information |
| 14:00:48 | <quicksilver> | dcoutts: the dependEE pacakge is responsible for maintaining the fact that other later versions may also work. |
| 14:00:57 | <quicksilver> | dcoutts: so I depend on haxml-1.2.3 |
| 14:01:06 | <edwardk> | ACTION waves hello. |
| 14:01:10 | <quicksilver> | dcoutts: and malcolmw later adds the information that haxml-1.2.4 is perfectly compatible with it |
| 14:01:19 | <quicksilver> | dcoutts: so then cabal knows to allow my library to be installed with 1.2.4 |
| 14:01:31 | <dcoutts> | JaffaCake: but the PVP is about being conservative, I thought the suggestion was to work out when new versions came out if actually it's not using the bit that changed. |
| 14:01:45 | <JaffaCake> | quicksilver: but the version number tells you whether it's "compatible" or not |
| 14:01:48 | <quicksilver> | Yes. The suggestion is to explore the possiblity of something less conservative than the pvp. |
| 14:02:01 | <dcoutts> | quicksilver: I see |
| 14:02:13 | <quicksilver> | maybe there is nothing useful in this part of the design space |
| 14:02:15 | <JaffaCake> | the problem we're trying to solve is that packages don't depend on the whole API, and hence don't need to break when only a part of it changes |
| 14:02:16 | <quicksilver> | but I think that's the suggestion. |
| 14:02:59 | <JaffaCake> | so it's a property of the source of the dependency, not the target |
| 14:03:04 | <quicksilver> | JaffaCake: the other problem I'm trying to solve is that the dependENT package isn't necessarily the person in possession of the best information. |
| 14:03:04 | <Saizan> | ACTION is mostly concerned with the fact that build-depends field are completely unchecked, only tested |
| 14:03:04 | <dcoutts> | JaffaCake: exactly |
| 14:03:43 | <malcolmw> | dcoutts: we were musing on the likelihood of _all_ packages breaking every time that ghc is released, because of the new forced upper-bound on package versions, and trying to work out if there is a way to be less conservative |
| 14:03:44 | <doserj> | in short, do type-checking on the package level, i.e., compare needed interfaces with provided interfaces? |
| 14:04:10 | <sjanssen> | wait, forced upper bound? |
| 14:04:27 | <doserj> | (taking things into account like no name-clash inducing additions, no duplicate instance declarations, etc) |
| 14:05:03 | <dcoutts> | malcolmw: I prefer them "breaking" in easily recognisable ways with clear error messages than what we used to have. |
| 14:05:09 | <JaffaCake> | quicksilver: I'm not sure how you can improve things there, other than automating the PVP |
| 14:05:14 | <malcolmw> | sjanssen: well, closed upper bound on the version of base, but since base is bumped with every release of ghc, it affects all packages. |
| 14:05:18 | <dcoutts> | malcolmw: and if we can continue to ship multiple versions then it becomes pretty smooth. |
| 14:05:30 | <sjanssen> | ACTION predicts package authors will all use base < 1024 just so they don't have to release a new version every year |
| 14:05:54 | <dcoutts> | sjanssen: good point, perhaps we need to ban deps more than major+1 :-) |
| 14:06:01 | <malcolmw> | dcoutts: I think our worry is that packages will "break" according to the PVP, but in actually they are not borken at all. |
| 14:06:11 | <sjanssen> | dcoutts: are you going to ship every past version? |
| 14:06:40 | <Saizan> | is it that much of a problem to make a release once a year? |
| 14:06:41 | <sjanssen> | dcoutts: if you ship N past major versions, about 1/N packages will need to be updated per year |
| 14:06:52 | <doserj> | Saizan: yes |
| 14:07:09 | <sjanssen> | Saizan: if the updates are only in the meta-data, yes |
| 14:07:31 | <dcoutts> | malcolmw: on account of them making one tiny incompatible change |
| 14:07:42 | <dcoutts> | malcolmw: perhaps it'll make package authors think more :-) |
| 14:07:57 | <Saizan> | sjanssen: i'd think that if you've to only update the meta-data it'd be less of a problem |
| 14:08:12 | <sjanssen> | Saizan: it's less work, yes, but it's useless work |
| 14:08:34 | <dcoutts> | right, being able to adjust deps for packages that happen to continue to work would make the whole thing much more manageable |
| 14:08:52 | <JaffaCake> | so why don't we let Hackage do that on its own? |
| 14:09:03 | <JaffaCake> | we already have a separate set of .cabal files, don't we? |
| 14:09:03 | <dcoutts> | exactly, get bots doing builds to try it out |
| 14:09:16 | <dcoutts> | and then tell package maintainers the results |
| 14:09:21 | <JaffaCake> | right |
| 14:09:30 | <dcoutts> | with an interface in hackage to let the maintainers make the suggested adjustments |
| 14:09:37 | <malcolmw> | dcoutts: the point is that it is not the package author's fault. the package, with no changes, is still fully safe. But a change of version number elsewhere makes cabal think it is not safe |
| 14:09:42 | <dcoutts> | so there's a human in the loop to consider semantic changes |
| 14:09:43 | <JaffaCake> | don't let them update to a new version without taking into account the new deps, or something |
| 14:09:56 | <Saizan> | you won't solve the problem of doing "useless work" for the maintainers that way, though? |
| 14:09:58 | <sjanssen> | JaffaCake: so Hackage is going to generate versions of packages that don't exist in upstream source control? |
| 14:10:07 | <SamB_XP> | yeah "click here to not upload a new version" |
| 14:10:23 | <dcoutts> | sjanssen: no, only maintainers should do that |
| 14:10:35 | <dcoutts> | malcolmw: I do not follow that |
| 14:11:36 | <dcoutts> | Saizan: what's the useless work? |
| 14:11:52 | <dcoutts> | Saizan: checking if their package still works with a new major version of a dep? |
| 14:12:05 | <Saizan> | dcoutts: releasing a new version with an updated upper bound when it still works |
| 14:12:05 | <dcoutts> | doesn't seem especially useless to me |
| 14:12:17 | <sjanssen> | dcoutts: s/base < n/base < n+1/ and making a new release each year |
| 14:12:27 | <dcoutts> | Saizan: right, I'd like maintainers to just be able to adjust the deps of the package on hackage |
| 14:12:28 | <quicksilver> | also it increases the chance of bitrotting packages |
| 14:12:57 | <quicksilver> | that is, the situation of needing to re-release every year would increase the chance of bitrotting packages |
| 14:13:02 | <dcoutts> | Saizan: and hackage would just maintain the revision of the .cabal file. Clients could then choose to use the new or original one. |
| 14:13:14 | <sjanssen> | dcoutts: so it's click some buttons on Hackage once a year, you're just making the useless work a bit easier |
| 14:13:33 | <dcoutts> | quicksilver: for awol maintainers we can have "distro maintainers" who look at the build/test results |
| 14:13:44 | <dcoutts> | sjanssen: yes, exactly. |
| 14:14:00 | <quicksilver> | sjanssen: making work easier is quite a positive step ;) |
| 14:14:06 | <sjanssen> | dcoutts: I'd rather have no useless work |
| 14:14:14 | <quicksilver> | so would I. |
| 14:14:19 | <quicksilver> | do you have a proposal for how to acheive that? |
| 14:14:32 | <dcoutts> | sjanssen: perhaps you should tick the box "don't ask me, just do it! I abdicate responsibility" |
| 14:14:56 | <dcoutts> | sjanssen: in principle there's no problem with doing it automatically, except that as a maintainer that might make you nervous |
| 14:15:16 | <dcoutts> | sjanssen: especially if your package has no automatic testsuite being run by the hackage build clients |
| 14:15:26 | <sjanssen> | dcoutts: if we need all these mechanisms to cope with the policy, isn't that an indication the policy isn't the best one? |
| 14:15:55 | <dcoutts> | sjanssen: then look for a mechanism that captures the semantics too |
| 14:16:05 | <dcoutts> | api/types is only part of it |
| 14:16:07 | <Berengal> | What do other repositories do? |
| 14:16:17 | <dcoutts> | Berengal: test and iterate |
| 14:16:17 | <sjanssen> | quicksilver: off the top of my head, I'd rather see a 'preferred base version' field than required upper bound dependency |
| 14:16:44 | <sjanssen> | we make building without the preferred base version a strong warning rather than a build failure |
| 14:17:37 | <quicksilver> | but the base authors wouldn't have bumped the version without reason. |
| 14:17:44 | <quicksilver> | if they bumped the version that was because something changed. |
| 14:17:52 | <quicksilver> | why is base different from other packages |
| 14:17:59 | <quicksilver> | (I confess to playing devil's advocate) |
| 14:18:02 | <dcoutts> | the key thing is that you probably were not using the thing that changed |
| 14:18:14 | <SamB_XP> | they're just talking about NOT bumping the version to base-5 in #ghc right now ;-) |
| 14:18:16 | <dcoutts> | which is why doing more detailed api subtype comparisons is a useful thing |
| 14:18:25 | <dcoutts> | version numbers are an approximation |
| 14:18:27 | <sjanssen> | quicksilver: the preferred version thing should work on any package |
| 14:18:43 | <SamB_XP> | they're thinking 4.2 might be better |
| 14:18:45 | <sjanssen> | dcoutts: useful, but still "pie in the sky", right? |
| 14:18:51 | <dcoutts> | sjanssen: yes |
| 14:19:16 | <dcoutts> | sjanssen: I don't see how a "I know it worked with this version" is really any different from an upper bound |
| 14:19:31 | <dcoutts> | sjanssen: except perhaps in the ease of ignoring it? |
| 14:19:44 | <dcoutts> | sjanssen: assuming the packages are following the PVP |
| 14:19:47 | <SamB_XP> | dcoutts: well, the upper bound could be wrong |
| 14:19:54 | <sjanssen> | dcoutts: it's the difference between a warning and an error |
| 14:20:22 | <dcoutts> | sjanssen: we can add a flag to let user force override |
| 14:20:25 | <SamB_XP> | well, I mean, people could lie about what versions packages have worked with, too, but ... |
| 14:20:58 | <quicksilver> | dcoutts: "I know it worked with the version" says "If you can prove that some other version is as good as that version, then it should be OK" |
| 14:20:58 | <dcoutts> | sjanssen: cabal install foobar --try-it-anyway!! |
| 14:21:07 | <sjanssen> | dcoutts: that's hardly a solution, because users won't know about the flag, they'll still write me emails about my artificially outdated package |
| 14:21:09 | <quicksilver> | dcoutts: whereas an upper bound implies "definitely doesn't work" |
| 14:21:13 | <dcoutts> | quicksilver: that's equivalent to the PVP |
| 14:21:20 | <quicksilver> | no it's not. |
| 14:21:27 | <quicksilver> | if the proof can take into account specific things |
| 14:21:33 | <dcoutts> | quicksilver: huh? |
| 14:21:44 | <dcoutts> | quicksilver: specific to the package in question? |
| 14:21:46 | <quicksilver> | the reasons that base-4 *is* equivalent to base-3 for every single haskell program I personally have ever written. |
| 14:21:55 | <quicksilver> | yes, specific to the package in question. |
| 14:22:16 | <quicksilver> | (although I didn't personally know it would be, before base-4 came out, nonetheless it turned out to be the case) |
| 14:22:23 | <dcoutts> | quicksilver: ok, so it's not just "I know I worked with this version" then, it's also a whole lot of info about what that package uses |
| 14:22:40 | <dcoutts> | which is the "pie in the sky" idea I was mentioning to sjanssen |
| 14:22:42 | <quicksilver> | well the maintainer provides "I know I wored with this version" |
| 14:22:49 | <sjanssen> | quicksilver: you've never used exceptions? |
| 14:22:50 | <quicksilver> | and some automated tool works out what I *actually* used |
| 14:23:02 | <dcoutts> | quicksilver: right, that's what I've suggested |
| 14:23:06 | <dcoutts> | (and others) |
| 14:23:06 | <quicksilver> | and the base maintainer makes some kind of note of which parts of base *actually* changed |
| 14:23:13 | <quicksilver> | (that step could be manual, not automatic) |
| 14:23:16 | <dcoutts> | quicksilver: or that bit can be automated too |
| 14:23:23 | <quicksilver> | not covering semantics. |
| 14:23:30 | <quicksilver> | sjanssen: you better beleive it. And proud of it too. |
| 14:24:06 | <dcoutts> | quicksilver: right I accept that, it's different from what sjanssen was suggesting I think, which is just to make the suggestion/upperbound a warning rather than an error |
| 14:24:17 | <dcoutts> | so in other word it'd not be used in dep planning |
| 14:24:37 | <dcoutts> | but we'd warn after constructing the dep plan if any upper bounds were violated |
| 14:25:04 | <quicksilver> | sjanssen: (actually I've used killThread, which is an exception, but in a way which would work with either base version as it happenes) |
| 14:26:09 | <pozic> | Do you always package up your algorithm parameters in a datastructure? Or do you just use separate parameters (as a result you get e.g. an 7-ary function) |
| 14:26:22 | <dcoutts> | sjanssen: so if we ignored upper bounds by default in cabal-install's planner and then just warned later you think that'd be better than having it as a flag that users have to try after the first time when it says it cannot install something. |
| 14:26:38 | <sjanssen> | pozic: once you've got 7 parameters, some sort of alternative approache is necessary, yes |
| 14:26:53 | <dcoutts> | 7 is the magic number :-) |
| 14:26:57 | <sjanssen> | dcoutts: in my opinion, upper bounds in build-depends should be followed strictly |
| 14:27:24 | <dcoutts> | sjanssen: and "soft" recommended be a separate class of bounds? |
| 14:27:30 | <sjanssen> | dcoutts: right |
| 14:28:40 | <dcoutts> | hrm, I don't like it :-) |
| 14:28:49 | <dcoutts> | though in principle it doesn't make the solver harder |
| 14:28:56 | <dcoutts> | we've already got soft prefs from the users |
| 14:29:02 | <dcoutts> | but not from the packages themselves |
| 14:29:35 | <doserj> | "soft recommended" meaning first look for a solution following them; if that is not possible, ignore them? |
| 14:30:01 | <sjanssen> | doserj: ignore them and leave warning messages |
| 14:30:20 | <dcoutts> | doserj: it's somewhat less defined than that to give the solver some flexibility |
| 14:30:29 | <quicksilver> | sjanssen: but as a package author how am I supposed to decide when to use a soft depend? |
| 14:30:44 | <dcoutts> | doserj: otherwise the problem becomes exponential :-) |
| 14:30:52 | <dcoutts> | problem/solution |
| 14:30:59 | <quicksilver> | I just have some fuzzy feeling that people "try pretty hard" to keep base backward compatible, so a soft bound is acceptable? |
| 14:31:17 | <quicksilver> | but I think that the guys who wrote 'memotrie' are a bunch of fly-by-nights and I need a hard bound? |
| 14:31:21 | <dcoutts> | quicksilver: hah hah, base 2 -> 3 -> 4, major breakage each time |
| 14:31:46 | <quicksilver> | well I'm trying to understand when sjanssen would use soft + hard bounds |
| 14:31:50 | <JaffaCake> | but only for very good reasons :) |
| 14:31:55 | <quicksilver> | and what policy he'd reocmmend package authors follow |
| 14:32:07 | <dcoutts> | JaffaCake: of course |
| 14:32:13 | <sjanssen> | quicksilver: use an upper bound when that version exists and you know your package won't build with it |
| 14:32:22 | <quicksilver> | ah, OK. |
| 14:32:28 | <dcoutts> | that does seem pretty reasonable |
| 14:32:43 | <quicksilver> | that seems plausible indeed. Although in that case I might just fix it :P |
| 14:33:08 | <pozic> | Didn't all the autoconf (and Emacs) people decide that feature testing was better than testing version numbers? |
| 14:33:21 | <quicksilver> | yes. |
| 14:33:32 | <dcoutts> | pozic: when all you've got is software soup that's probably true |
| 14:33:33 | <quicksilver> | but listing all the features of a base that a package used would take a while |
| 14:33:37 | <sjanssen> | dcoutts: you could also support/enforce both of these policies. Require either an upper bound on base or a preferred version on base |
| 14:33:37 | <quicksilver> | and we don't have names for them. |
| 14:34:04 | <mapreduce> | pozic: Should we call that duck versioning? |
| 14:34:37 | <dcoutts> | sjanssen: how about deriving if the upper bound is soft or hard based on upload time? :-) |
| 14:34:52 | <dcoutts> | sjanssen: if they uploaded it before the other one was released then it's soft |
| 14:35:09 | <pozic> | mapreduce: it depends on your point of view. If you can encode all the properties you need from a package, you won't have version hell. |
| 14:35:15 | <sjanssen> | dcoutts: shouldn't uploading be referentially transparent, if possible? |
| 14:35:38 | <dcoutts> | sjanssen: why? it matches the semantics you wanted doesn't it? |
| 14:36:10 | <sjanssen> | dcoutts: I guess I wonder where the information will be stored, Hackage will modify my tarball? |
| 14:36:12 | <dcoutts> | sjanssen: I admit it seems a little odd, I was partly joking, but I don't see anything especially wrong with it except that it feels a little implicit |
| 14:36:33 | <dcoutts> | sjanssen: nothing needs modifying, the upload times are available to the clients |
| 14:38:14 | <sjanssen> | dcoutts: it seems odd to have installation via cabal install and manually via tarball have different behaviors |
| 14:38:19 | <mapreduce> | pozic: I imagine it's hard to verify binary compatibility with that approach, in a reasonable amount of time. |
| 14:38:38 | <sjanssen> | dcoutts: they already behave differently, but this difference is extreme |
| 14:38:50 | <dcoutts> | sjanssen: that's already the case and will be more-so when we allow maintainers to adjust deps on hackage |
| 14:39:15 | <dcoutts> | sjanssen: cabal uses the preferred versions stuff while Setup.hs doesn't |
| 14:39:54 | <sjanssen> | dcoutts: that's just really scary |
| 14:40:14 | <sjanssen> | dcoutts: what about from-source distros like Gentoo? |
| 14:40:16 | <dcoutts> | why? it's automatic vs manual package management |
| 14:40:26 | <Saizan> | pozic: pure feature testing doesn't let cabal-install do its job reasonably, i'd think, but i agree that we should develop a tool to check interfaces to help in inferring the right version constraints considering the libs available |
| 14:40:48 | <sjanssen> | dcoutts: will the ebuild maintainers manually patch packages where an upper dependency should actually be a soft dep? |
| 14:41:05 | <dcoutts> | sjanssen: sure, they do it all the time |
| 14:41:39 | <JaffaCake> | I missed the discussion - what's a soft dep? |
| 14:42:27 | <dcoutts> | JaffaCake: sjanssen would like to distinguish upper bounds that are there because we know it doesn't work vs speculative/pessimistic upper bounds on as-yet-unreleased versions |
| 14:42:36 | <sjanssen> | dcoutts: but every package is going to potentially have one of these, and every distribution is going to have to do the same work |
| 14:42:52 | <dcoutts> | JaffaCake: and to treat those kinds of upper bounds differently, more as suggestions than hard constraints |
| 14:43:15 | <JaffaCake> | sounds reasonable |
| 14:43:29 | <dcoutts> | sjanssen: there's plenty of infrastructure we can share to help automatic translation |
| 14:43:36 | <sjanssen> | dcoutts: and there's also the problem of non-hackage users determining when an upper bound should be soft or hard. Do I print out a table of base release dates and hang them on my wall? |
| 14:44:01 | <seliopou> | Well, it'd be nice if you could contain those differences in major/minor versions |
| 14:44:28 | <seliopou> | something like releases with the same major version have the same API, or something |
| 14:44:36 | <sjanssen> | dcoutts: I really think we want all the metadata in the tarball |
| 14:45:03 | <dcoutts> | sjanssen: so the advantage of making it explicit is that it's explicit! :-) you can see it clearly. On the other hand it's more semi-redundant information for package authors to supply |
| 14:45:45 | <dcoutts> | sjanssen: generally I agree that all the meta-data should be in the .cabal file (and the original is of course in the tarball) |
| 14:46:38 | <McManiaC> | has anyone used the Network.Curl librarie under windows? i tried to install it with cabal and get the error "sh: runProcess: does not exist (No such file or directory)"?? |
| 14:46:51 | <dcoutts> | McManiaC: it uses a ./configure script |
| 14:47:00 | <dcoutts> | McManiaC: meaning it needs MSYS/mingw |
| 14:47:18 | <McManiaC> | oh ok |
| 14:47:50 | <dcoutts> | McManiaC: feel free to complain to the package author :-) we'd like to reduce the number of packages using configure scripts for just that reason |
| 14:48:02 | <McManiaC> | ok cool |
| 14:52:32 | <Badger> | hah |
| 14:52:40 | <Badger> | the very same thing happens with SDL. |
| 14:53:06 | <Badger> | but I have msys :/ |
| 14:53:16 | <McManiaC> | dcoutts: what exactly do i need? ive installed mingw now, what next? |
| 14:53:27 | <roderyk> | http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2546 - can someone take a look at this snippet |
| 14:53:42 | <roderyk> | I can't seem to get a skeleton gtk2hs app to loop a timeoutAdd |
| 14:53:53 | <dcoutts> | McManiaC: MSYS is the command line bit, like a dos window but using a POSIX shell |
| 14:54:21 | <dcoutts> | Badger: you have to run it from within msys, so that sh.exe is actually on the path |
| 14:54:44 | <McManiaC> | ok |
| 14:55:35 | <Badger> | ah, l. |
| 14:55:37 | <Badger> | er, k |
| 14:56:40 | <gwern> | I have just discovered a downside to using trackballs instead of mice |
| 14:56:48 | <gwern> | it's really easy for someone to steal the ball |
| 14:57:26 | <dino-> | gwern: Oh wow, I'd be mighty upset. |
| 14:57:27 | <SamB> | gwern: it's easy either way, if there *is* a ball |
| 14:57:48 | <dino-> | <- dedicated Kensington user of 16 years |
| 14:57:50 | <SamB> | the problem with trackballs being that they NEED a ball |
| 14:57:52 | <Philippa> | SamB: it's the work of half a second on my trackball though |
| 14:57:56 | <gwern> | SamB: with a mouse, it's not so obvious how to steal it. heck, many people don't know they have balls |
| 14:58:03 | <SamB> | gwern: what??? |
| 14:58:04 | <Philippa> | many of them don't |
| 14:58:09 | <SamB> | how do you NOT KNOW THAT? |
| 14:58:26 | <Philippa> | by growing up with laser mice |
| 14:58:26 | <gwern> | dino-: well, I am fairly annoyed. but it's not such a big deal since all I really need a mouse for is firefox and copy-pasting of text |
| 14:58:26 | <SamB> | Philippa: true! |
| 14:58:38 | <SamB> | I didn't know it was possible to grow up with laser mice yet |
| 14:58:47 | <gwern> | and I just installed one of the hit-a-hint style extensions, so firefox is half-usable |
| 14:58:59 | <gwern> | xmonad/tiling wms ftw, btw |
| 14:59:01 | <Philippa> | if you're 18, plenty viable |
| 14:59:04 | <Badger> | dcoutts: what's the alternative to configure? |
| 14:59:15 | <SamB> | hey, I started with a serial mouse |
| 14:59:23 | <Berengal> | The thing about laser mice is... transparent tape |
| 14:59:25 | <SamB> | ... one that had ears! |
| 14:59:26 | <Baughn> | ACTION started with a freakin' busmouse |
| 14:59:34 | <dcoutts> | Badger: doing any necessary tests in the Setup.hs script |
| 14:59:38 | <SamB> | at least, I think it was serial ... |
| 14:59:38 | <gwern> | SamB: how long have laser mice been out? early 90s, right? so you could be fairly old and never use a mouse with balls for your computing pleasure |
| 14:59:41 | <Badger> | ah |
| 14:59:42 | <SamB> | it might have been bus |
| 14:59:43 | <SamB> | I forget |
| 14:59:44 | <Baughn> | Berengal: Won't the tape be awfully obvious? |
| 14:59:49 | <dino-> | gwern: absolutely, keep mousing to a minimum, yay xmonad |
| 14:59:55 | <SamB> | gwern: really ... ??? |
| 14:59:57 | <Adamant> | gwern: early 90's, I doubt |
| 15:00:22 | <Berengal> | Baughn: Depends on the tape and the mouse. I've found combinations that are almost invisible |
| 15:00:27 | <SamB> | what is a bus mouse anyway ? |
| 15:00:30 | <gwern> | the really irksome thing is that apparently firefox disabled the Backspace = go back in history |
| 15:00:42 | <dino-> | btw, I was so disappointed by the cheapness of that black Kensington with the scroll ring around the ball that I bought 2 extra of the silver one with blue ball to tough out the wait for something better. |
| 15:00:52 | <Baughn> | gwern: You can still use alt-left |
| 15:01:06 | <dino-> | It takes me about 5 years to wear out the left button on one of these usually. |
| 15:01:32 | <gwern> | hm. looks like *laser* mice only were released in 2004, but optical mice long preceded that |
| 15:01:43 | <Baughn> | SamB: http://en.wikipedia.org/wiki/Bus_mouse |
| 15:01:52 | <Adamant> | trackballs suck, all hail the MX Revolution! |
| 15:01:54 | <malcolmw> | ACTION used a laser mouse on a sun workstation in 1987 |
| 15:01:55 | <gwern> | those were invented in 1980, and seem to've been sold shortly thereafter |
| 15:02:04 | <Adamant> | malcolmw: seriously? wow. |
| 15:02:10 | <Zao> | malcolmw: And now you lack an eye? |
| 15:02:18 | <gwern> | malcolmw: how do you know it was laser and not just optical? |
| 15:02:18 | <dino-> | Also, if we're doing war stories, I have my first mouse ever from 1984. With the ginormous serial connector on the end. It's a square Logitech. |
| 15:02:20 | <Berengal> | Baughn: I had one of those on my first computer |
| 15:02:41 | <malcolmw> | ok, maybe it was jsut optical. it needed a special mousepad with a grid etched into it |
| 15:02:48 | <dcoutts> | sjanssen: will you be at ICFP btw? |
| 15:03:05 | <roderyk> | I consider myself a youngin, and even I remember the "mouse cleaning kits - liquid, ball, and chain!" :-) |
| 15:03:06 | <dcoutts> | sjanssen: or any of the related workshops, HIW, HS etc |
| 15:03:25 | <sjanssen> | dcoutts: I'm not planning on it |
| 15:03:43 | <dcoutts> | sjanssen: ah well |
| 15:04:55 | <gwern> | there's something very soothing about watching the links get dumped to stdout in my new wikipedia bot |
| 15:05:26 | <gwern> | each link was lovingly selected by a human and emplaced into a new article; one wonders who they are, what they're writing about, why. what kind of chair they are sitting in |
| 15:05:58 | <McManiaC> | dcoutts: do you have any idea why this fails? http://pastie.org/499193 |
| 15:06:10 | <Berengal> | gwern: Hehe, seems soothing indeed |
| 15:06:12 | <gwern> | this 'Singapore Sympony Children's Choir' link - is it being edited by someone from singapore? perhaps it is one of the well-paid elite mandarins, bringing an article about something his daughter is in up to snuff |
| 15:06:26 | <gwern> | who is this Lemuel Carpenter? |
| 15:06:43 | <gwern> | 'I Fight Dragons'? probably vandalism, but it sounds like a hazardous hobby |
| 15:07:01 | <dcoutts> | McManiaC: looks like it's not linking to openssl |
| 15:07:10 | <Berengal> | http://en.wikipedia.org/wiki/I_Fight_Dragons |
| 15:07:17 | <sjanssen> | gwern: are you watching all edits live? |
| 15:07:25 | <gwern> | or, 'Chiari Syringomyelia Foundation' - this makes me wince just reading it |
| 15:07:41 | <gwern> | sjanssen: just New Pages. Recent Changes would scroll by a bit fast to read |
| 15:08:44 | <gwern> | one almost can compose stories. 'I Fight Dragons, and in revenge they made my beloved Irina Salomykova succumb to septica; in revenege, I founded the Chiari Syringomyelia Foundation, that none need suffer like I did again!' |
| 15:09:39 | <gwern> | (and all this took place in the Albuquerque Air Defense Sector; if only the radar operators had been vigilant enough to spot the dragons that fateful day!) |
| 15:10:00 | <Zao> | malcolmw: One of these? http://sunstuff.org/hardware/systems/sun4/sun4m/SPARCstation10/sun.sparcstation10.jpg |
| 15:10:23 | <Zao> | I still have that gridded pad somewhere in storage. |
| 15:12:21 | <gwern> | 'Tmpk', 'Matrilineality in Judaism', almost sound like you know what they're about, but then you realize you don't |
| 15:14:04 | <gwern> | (you know, I half suspect Oleg implemented his new probability stuff in ocaml rather than haskell just because it meant he would have to use delimited continuations...) |
| 15:14:48 | <gwern> | it's a little interesting how many of the external links seem to be on sports subjects, when sports articles are not even close to a majority of new articles |
| 15:21:40 | <muiro> | hey, I'm a c, java and or ruby programmer and some folks told me I should learn your totally zany and bonkers language. Is this true or were they lieing to me? |
| 15:21:53 | <kpreid> | muiro: YES! |
| 15:22:17 | <muiro> | hmm |
| 15:22:20 | <kpreid> | > tails "YES! YES!" |
| 15:22:22 | <lambdabot> | ["YES! YES!","ES! YES!","S! YES!","! YES!"," YES!","YES!","ES!","S!","!",""] |
| 15:23:10 | <skorpan> | > fix ("YES! " ++) |
| 15:23:10 | <dmwit> | muiro: Yes, it's true or they were lying to you! |
| 15:23:11 | <lambdabot> | "YES! YES! YES! YES! YES! YES! YES! YES! YES! YES! YES! YES! YES! YES! YES!... |
| 15:23:14 | <gnuvince> | muiro: well, that depends mostly on you, but Haskell is different from most languages out there, so if nothing else, it'll open your eyes to a different way of doing things. |
| 15:23:51 | <dmwit> | > cycle "Well, yeah, kinda." |
| 15:23:52 | <lambdabot> | "Well, yeah, kinda.Well, yeah, kinda.Well, yeah, kinda.Well, yeah, kinda.We... |
| 15:23:52 | <muiro> | I have links to a few books, one looks silly as hell. I think I'll read that one today and see if I like the feel of it. |
| 15:24:08 | <sjanssen> | muiro: let me guess, LYAH? |
| 15:24:10 | <dmwit> | ?where lyah is silly as hell |
| 15:24:11 | <lambdabot> | www.learnyouahaskell.com |
| 15:24:12 | <gnuvince> | muiro: the silly as hell one wouldn't happen to be "Learn you a Great Haskell"? |
| 15:24:23 | <muiro> | mostly I justed wanted to gauge a reaction of a channel full of haskell programmers upon asking that question |
| 15:24:34 | <muiro> | because do you know what would happen in a channel full of c programmers if I asked that? |
| 15:24:37 | <dmwit> | Did you expect somebody to say no? |
| 15:24:42 | <kpreid> | muiro: haskell will stretch your brain |
| 15:24:53 | <muiro> | c/++: "Go F yourself kid" |
| 15:24:56 | <muiro> | anyway |
| 15:24:56 | <gnuvince> | muiro: if you asked whether you should learn C or whether you should learn Haskell? |
| 15:25:00 | <muiro> | yes, learn you a haskell |
| 15:25:16 | <muiro> | the title makes me laugh, so I'm going to read it right now |
| 15:25:21 | <kpreid> | the reaction of the C folks is more because they're the default, I think |
| 15:25:26 | <gnuvince> | muiro: go with LYAH, great intro, BONUS is a very good writer |
| 15:25:29 | <kpreid> | so It's A Silly Question |
| 15:25:44 | <muiro> | no, I didn't expect to hear "no", I just wanted to see the reaction |
| 15:25:48 | <gwern> | c programmers tend to be cranky |
| 15:25:50 | <muiro> | I'm sorry I manipulated you. <3 |
| 15:25:52 | <gwern> | don't blame'em |
| 15:26:08 | <gnuvince> | gwern: what do you expect? Break their concentration one second and they'll forget a free()! |
| 15:26:11 | <kpreid> | Has Haskell had any cranks? |
| 15:26:24 | <gwern> | kpreid: harmless ones like Cale and conal :) |
| 15:26:24 | <kpreid> | (I do mean cranks, not cranky) |
| 15:26:45 | <dmwit> | ?protontorpedo |
| 15:26:45 | <lambdabot> | does haskel work one windows? |
| 15:26:48 | <dmwit> | ?protontorpedo |
| 15:26:48 | <lambdabot> | and haskell is general purpose? |
| 15:26:49 | <gwern> | gnuvince: beat a dog long enough, and it'll snap at anything |
| 15:26:51 | <dmwit> | ?protontorpedo |
| 15:26:51 | <lambdabot> | I am banned from like 6 rooms |
| 15:26:54 | <gnuvince> | kpreid: those guys are scary, especially Cale. |
| 15:27:10 | <dino-> | gnuvince: Ok, that was hilarious! |
| 15:27:18 | <dino-> | Some make lamby remember that. |
| 15:27:22 | <dino-> | Somebody |
| 15:27:24 | <dino-> | I don |
| 15:27:32 | <dino-> | In addition to not being able to type, I don't know how. |
| 15:27:54 | <conal> | gwern: :) |
| 15:27:54 | <dmwit> | Also, that guy that was convinced the NSA was trying to stop him from developing his advanced mathematics. |
| 15:28:02 | <dmwit> | What was his nick again? |
| 15:28:20 | <dons> | for those who didn't see, late yesterday, the Haskell Platform 2009.2.0.1 is now out. http://www.reddit.com/r/programming/comments/8ph8u/the_haskell_platform_2009201_a_standard_haskell/ |
| 15:28:26 | <kpreid> | dmwit: Keal |
| 15:28:32 | <gwern> | @keal |
| 15:28:32 | <lambdabot> | what have you been smoking? you narrow minded Haskell user? |
| 15:28:40 | <gwern> | @keal |
| 15:28:41 | <lambdabot> | write an algorthim that generates the correct responses for a phone survey based on number of rings whether answered how quickly hung up on and the mood of the receiver |
| 15:28:43 | <dmwit> | Yeah, keal. what a guy |
| 15:29:12 | <gwern> | @quote qwe |
| 15:29:12 | <lambdabot> | jmelesky says: I've figured out the problem. qwe1234 has different definitions of "functional programming", "compiler", "complexity theory", "math", and "optimization" than everybody else who deals |
| 15:29:12 | <lambdabot> | with computers or computer science. |
| 15:29:12 | <gnuvince> | hahaha |
| 15:29:24 | <gwern> | @quote qwe |
| 15:29:24 | <lambdabot> | pjdelport says: [on qwe1234:] It must be a drag, being the sole beacon of sanity in a field where all the established researchers are unanimously insane. |
| 15:29:37 | <gwern> | @quote qwe |
| 15:29:38 | <lambdabot> | pjdelport says: qwe1234, boldly defining where no man has defined before! |
| 15:29:41 | <gnuvince> | That should be a QOTW |
| 15:30:43 | <muiro> | woah, this is weird |
| 15:32:28 | <gwern> | <reeves>WHOAH</reeves> |
| 15:33:42 | <sjanssen> | <reeves>I know lambda calculus</reeves> |
| 15:34:11 | <skorpan> | comparing strings should generally be slower than comparing constructors, right? |
| 15:34:45 | <Botje> | yeah |
| 15:34:55 | <Botje> | ehh |
| 15:34:58 | <sjanssen> | skorpan: assuming the constructors have no arguments? |
| 15:35:02 | <byorgey> | muiro: have fun stretching your brain! =) |
| 15:35:02 | <Botje> | unless they don't share a common suffix, of course |
| 15:35:03 | <skorpan> | yes, assuming that |
| 15:35:08 | <sjanssen> | skorpan: yes |
| 15:35:13 | <skorpan> | great, thanks |
| 15:35:24 | <Botje> | if you're comparing vs "apple", and "banana" you can still compare in O(1) |
| 15:35:29 | <sjanssen> | one less dereference in the worst case |
| 15:39:45 | <Berengal> | Comparing strings also compares constructors... |
| 15:50:37 | <gwern> | @hoogle (Monad m) => m a -> m () |
| 15:50:48 | <gwern> | @hoogle (Monad m) => m a -> m () |
| 15:50:48 | <lambdabot> | Control.Monad forever :: Monad m => m a -> m () |
| 15:50:48 | <lambdabot> | Control.Monad replicateM_ :: Monad m => Int -> m a -> m () |
| 15:50:48 | <lambdabot> | Prelude sequence_ :: Monad m => [m a] -> m () |
| 15:51:16 | <dmwit> | I love hoogle. |
| 15:51:25 | <Berengal> | hoogle is nifty |
| 15:51:29 | <gwern> | that's no good. you'd think that for forkIO alone, we'd have something like 'ignore = \x -> x >> return ()' |
| 15:51:51 | <gwern> | so you could do ' |
| 15:51:59 | <gwern> | forkIO (ignore stuff) |
| 15:52:18 | <fasta> | gwern: imho, a better solution is to change the type of forkIO |
| 15:52:28 | <mux> | I don't mind writing forkIO (stuff >> return ()) |
| 15:52:28 | <burp> | how would you make an cyclic permutation of a list? |
| 15:52:29 | <gwern> | fasta: probably, but everyone would scream |
| 15:52:30 | <lilac> | > fmap fmap fmap fmap fmap fmap (+) [1,2,3] <*> [Just 5, Nothing, Just 9] |
| 15:52:31 | <lambdabot> | [Just 6,Nothing,Just 10,Just 7,Nothing,Just 11,Just 8,Nothing,Just 12] |
| 15:52:34 | <Berengal> | Agreed with fasta |
| 15:52:47 | <fasta> | gwern: that's why you define these kinds of things in an Util library. |
| 15:52:55 | <fasta> | gwern: no need to get approval from anyone. |
| 15:53:09 | <gwern> | mux: once isn't too bad, but when your code starts to look like 'forkIO (foo bar baz >> return ()) >> return ()', then you start to think maybe this should be factored out |
| 15:53:16 | <fasta> | gwern: it's the same for when. |
| 15:53:18 | <jmcarthur_work> | forkIO $ () <$ stuff |
| 15:53:48 | <fasta> | gwern: also return () == void |
| 15:53:55 | <mux> | did you mean forkIO $ () <* stuff ? |
| 15:53:55 | <lilac> | forkIO $ (>>mzero) stuff |
| 15:53:58 | <gwern> | :t void |
| 15:53:59 | <lambdabot> | Not in scope: `void' |
| 15:54:05 | <fasta> | gwern: something from Util |
| 15:54:12 | <jmcarthur_work> | > () <$ Just 5 |
| 15:54:14 | <lambdabot> | Just () |
| 15:54:18 | <mux> | :t \f -> (<* f) |
| 15:54:19 | <lilac> | fasta: return () == mzero for IO |
| 15:54:19 | <lambdabot> | forall (f :: * -> *) a b. (Applicative f) => f b -> f a -> f a |
| 15:54:25 | <gwern> | fasta: well, the problem is that this wikipedia bot in theory should be usable by non-haskell devs, so even if I would upload a util library to hackage, I still wouldn't use it |
| 15:54:36 | <lilac> | fasta: perhasp that's what you were thinking of? |
| 15:54:54 | <fasta> | lilac: I was thinking of whatever I said, I am not sure what you are thinking of. |
| 15:55:00 | <mux> | :t let ignore f = () <* f in \stuff -> ignore stuff |
| 15:55:02 | <lambdabot> | Couldn't match expected type `f a' against inferred type `()' |
| 15:55:02 | <lambdabot> | In the first argument of `(<*)', namely `()' |
| 15:55:02 | <lambdabot> | In the expression: () <* f |
| 15:55:18 | <jmcarthur_work> | :t let ignore f = () <$ f in \stuff -> ignore stuff |
| 15:55:18 | <lambdabot> | forall (f :: * -> *) b. (Functor f) => f b -> f () |
| 15:55:32 | <mux> | ACTION nods |
| 15:55:42 | <mux> | applicative functors ftw ! |
| 15:55:46 | <jmcarthur_work> | :t let ignore f = return () <* f in \stuff -> ignore stuff |
| 15:55:47 | <lambdabot> | forall (f :: * -> *) b. (Applicative f, Monad f) => f b -> f () |
| 15:55:49 | <mux> | ACTION leaves work on that happy note |
| 15:55:56 | <jmcarthur_work> | :t let ignore f = pure () <* f in \stuff -> ignore stuff |
| 15:55:57 | <lambdabot> | forall (f :: * -> *) b. (Applicative f) => f b -> f () |
| 15:55:59 | <athos> | :t (<$) |
| 15:56:00 | <lambdabot> | forall a (f :: * -> *) b. (Functor f) => a -> f b -> f a |
| 15:56:19 | <jmcarthur_work> | (<$) = fmap . const |
| 15:57:12 | <Berengal> | <$ has some nifty uses |
| 15:58:00 | <jmcarthur_work> | > "yes" <$ "Is <$ cool, or what?" |
| 15:58:01 | <lambdabot> | ["yes","yes","yes","yes","yes","yes","yes","yes","yes","yes","yes","yes","y... |
| 15:58:20 | <lilac> | would have been nicer to have ($>) :: (a -> b) -> f a -> f b, (<$) :: f (a -> b) -> a -> f b, (<$>) :: f (a -> b) -> f a -> f b, IMO |
| 15:59:27 | <jmcarthur_work> | there are certainly nicer ways than what we have. i would need to think about your proposal a bit before i say i agree with that particular version though |
| 16:00:13 | <lilac> | basically it's a generalization of ($) where the arrows point to things in functors |
| 16:00:18 | <jmcarthur_work> | right |
| 16:01:37 | <lilac> | i've never been very happy with (<$) meaning 'this structure with that value' since $ and <$> are both function application |
| 16:01:46 | <jmcarthur_work> | agreed |
| 16:07:52 | <fynn> | So... to install the Haskell Platform, I need to install latest GHC, then the package from http://hackage.haskell.org/platform/ right? |
| 16:08:41 | <hatds> | ghci question: say I have an IO [Int] which is a really long list, is there a way to evaluate it and bind it to a result without printing it? |
| 16:09:54 | <gnomnain> | result <- list ? |
| 16:10:08 | <fasta> | hatds: rnf |
| 16:10:08 | <dmwit> | :set -fno-print-bind-result |
| 16:11:57 | <Jedai> | hatds: Do you mean evaluating it completely ? Then the solution is rnf from Control.Parallel.Strategies |
| 16:12:08 | <Jedai> | :t rnf |
| 16:12:09 | <lambdabot> | forall a. (NFData a) => a -> Done |
| 16:12:32 | <dmwit> | Or compare it for equality with itself as a quick hack. ;-) |
| 16:12:35 | <hatds> | Jedai: no, I just mean "compute" as in go from IO [Int] to [Int] like ghci does |
| 16:13:14 | <Jedai> | hatds: Well then gnomnain gave you the answer |
| 16:13:14 | <jmcarthur_work> | hatds, use functor/applicative/monad stuff |
| 16:13:45 | <Saizan> | if the problem is not getting flooded at the ghci prompt then you want :set -fno-print-bind-result |
| 16:13:53 | <hatds> | result <- list still prints it :/ |
| 16:13:55 | <Jedai> | hatds: you can't extract values from the IO monad, but you can use bind (>>=) to act on them inside the monad |
| 16:13:55 | <sm> | good morning haskell brothers and sisters |
| 16:13:57 | <sm> | what is the difference between regex-pcre and regex-pcre-builtin ? |
| 16:14:12 | <dmwit> | ACTION wins |
| 16:14:15 | <jmcarthur_work> | hatds, what do you mean it "prints" it if you aren't in ghci? |
| 16:14:18 | <Saizan> | hatds: :set -fno-print-bind-result |
| 16:14:20 | <sm> | ACTION just tried haskell platform on windows, pretty slick |
| 16:14:23 | <hatds> | I *am* in ghci |
| 16:14:41 | <hatds> | :set -fno-print-bind-result, and result <- list don't seem to have an effect |
| 16:14:50 | <quicksilver> | it bound a name to it |
| 16:14:56 | <quicksilver> | what were you expecting to see? ;) |
| 16:14:57 | <Jedai> | dmwit: Yay, you correctly understood the problem (which was quite amazing given the lack of details) |
| 16:15:13 | <Saizan> | hatds: try "head result" |
| 16:15:37 | <dmwit> | Jedai: Luck more than anything, once somebody suggested rnf I figured that was the most probable right answer. =P |
| 16:16:03 | <dmwit> | Maybe :set -fno-print-bind-contents? |
| 16:16:31 | <Saizan> | no i think you got the flag name right, and ghci will yell if it's wrong |
| 16:16:42 | <dmwit> | Both flags exist. |
| 16:17:33 | <dmwit> | But no-print-bind-result works for me, so I'm not sure. |
| 16:18:44 | <duaneb> | after ghci |
| 16:18:46 | <duaneb> | and hugs |
| 16:18:52 | <duaneb> | the ocaml repl seems to be lacking |
| 16:20:12 | <hatds> | man, none of the flags are work |
| 16:20:17 | <hatds> | *working |
| 16:21:01 | <Saizan> | how are you using them? |
| 16:21:02 | <dmwit> | hatds: Uh... what version of ghc(i)? |
| 16:21:26 | <dmwit> | ACTION demands proof in the form of a transcript |
| 16:22:09 | <hatds> | tried ":set -fno-print-bind-result" for both flags and also using the flags at startup "ghcii.sh -fno-print-bind-contents -fno-print-bind-result" |
| 16:22:33 | <sjanssen> | hatds: what are the symptoms? |
| 16:23:02 | <hatds> | sjanssen: evaluating an expression prints it, whereas I want to temporarily disable that |
| 16:23:25 | <sjanssen> | hatds: are you using "x <- theexpression"? |
| 16:25:30 | <hatds> | ah, you gotta use the flag and the "x <- " notation togeteher |
| 16:25:32 | <hatds> | :) |
| 16:25:44 | <quicksilver> | or you can just do "tehexpression >> return ()" |
| 16:25:58 | <quicksilver> | then it is of type IO () and ghci won't print the result anyway. |
| 16:26:05 | <hatds> | yea, but I don't want to bind () to it |
| 16:26:13 | <quicksilver> | that's not binding anything to anything. |
| 16:26:18 | <quicksilver> | that's just a way to avoid ghci printing anything. |
| 16:26:28 | <fynn> | To install the Haskell Platform, I need to install latest GHC, then the package from http://hackage.haskell.org/platform/ right? |
| 16:26:29 | <hatds> | in my case I do want to bind, just not print |
| 16:26:31 | <hatds> | :) |
| 16:26:43 | <quicksilver> | ok, then use x <- as suggested |
| 16:26:45 | <quicksilver> | ;) |
| 16:28:15 | <fynn> | Yes? No? Nobody ever installs the Haskell Platform? :) |
| 16:28:47 | <Jedai> | fynn: yes |
| 16:29:05 | <kpreid> | fynn: give it a lil more than 2 minutes. There may be well be lots of users who just aren't right-here-ready-to-answer! |
| 16:30:17 | <fynn> | cool, thanks. |
| 16:31:43 | <Zao> | fynn: I just installed the EXE installer :) |
| 16:32:02 | <lament> | what exactly does it mean that the haskell platform is blessed? |
| 16:32:28 | <fynn> | lament: a saint said a prayer over it |
| 16:32:54 | <fynn> | Zao: well, we're installing it on a bunch of *nix and Mac machine, so... :) |
| 16:34:18 | <fynn> | lament: also, that website could be better organized |
| 16:34:59 | <fynn> | You go to http://www.haskell.org/haskellwiki/Haskell_Platform and click on the big image as any reasonable person would do, but rather than let you in, it sends you to a page with some useless information about that image. |
| 16:35:47 | <fynn> | (it's the fault of the underlying Wiki software to be sure, but still a UI bug) |
| 16:36:20 | <gwern> | @hoogle Maybe a -> (a -> a) |
| 16:36:20 | <lambdabot> | Data.Maybe fromMaybe :: a -> Maybe a -> a |
| 16:36:21 | <lambdabot> | Prelude asTypeOf :: a -> a -> a |
| 16:36:21 | <lambdabot> | Data.Generics.Aliases orElse :: Maybe a -> Maybe a -> Maybe a |
| 16:36:39 | <gwern> | > fromMaybe 6 (Just 5) |
| 16:36:40 | <lambdabot> | 5 |
| 16:37:03 | <gwern> | :t maybe |
| 16:37:04 | <lambdabot> | forall b a. b -> (a -> b) -> Maybe a -> b |
| 16:37:47 | <gwern> | > let archiveBot = undefined in maybe () (archiveBot) (Just "foo" |
| 16:37:48 | <lambdabot> | <no location info>: parse error (possibly incorrect indentation) |
| 16:38:06 | <deech> | Hi all, I'm having trouble using HXT to parse an XML document. I have pasted a small program ( http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5538#a5539 ) that reproduces the error. It seems to be in importing the network module. Any ideas? Thanks ... |
| 16:38:45 | <gwern> | > let archiveBot = undefined in maybe () (archiveBot) (Just "foo") |
| 16:38:46 | <lambdabot> | * Exception: Prelude.undefined |
| 16:38:53 | <gwern> | > let archiveBot = id in maybe () (archiveBot) (Just "foo") |
| 16:38:54 | <lambdabot> | Couldn't match expected type `()' |
| 16:39:21 | <Zao> | fynn: Judging by the documentation on the site, that would be the right approach. |
| 16:39:24 | <gwern> | > let archiveBot = \x -> id x >> return () in maybe () (archiveBot) (Just "foo") |
| 16:39:25 | <lambdabot> | Couldn't match expected type `()' against inferred type `m ()' |
| 16:39:36 | <gwern> | > let archiveBot = \x -> id x >> return () in maybe (return ()) (archiveBot) (Just "foo") |
| 16:39:37 | <lambdabot> | [(),(),()] |
| 16:39:58 | <gwern> | hm. I guess I'll just leave that case expression alone; maybe doesn't seem any clearer |
| 16:40:07 | <quicksilver> | deech: you are loading two version of 'network' |
| 16:40:15 | <quicksilver> | Loading package network-2.2.1 |
| 16:40:21 | <quicksilver> | Loading package network-2.2.1.2 |
| 16:40:21 | <deech> | quicksilver: Yes I know, I don't know why it is doing that. |
| 16:40:32 | <quicksilver> | because one of your packages dpeneds on one and another depends on another. |
| 16:41:00 | <mux> | the dreaded diamond dependency problem |
| 16:41:13 | <quicksilver> | you'll have to compile them all (well all the ones you want to use together) with the latest. |
| 16:41:50 | <roconnor> | or the earliest |
| 16:45:40 | <deech> | quicksilver: Ok, so to unregister network-2.2.1 I had to unregister HTTP 4000.0.6. But I was able to re-install HTTP 4000.0.6 without a problem and the problem has gone away. Thanks! |
| 16:53:06 | <jmcarthur_work> | > let archiveBot = (() <$) in archiveBot <$> Just "foo" |
| 16:53:07 | <lambdabot> | Just [(),(),()] |
| 16:53:43 | <jmcarthur_work> | > (fmap.fmap) (const ()) (Just "foo") |
| 16:53:44 | <lambdabot> | Just [(),(),()] |
| 16:55:06 | <PeakerWork> | OS X is 64 bits right? Seems ghc says maxBound :: Int is just 2^31 - 1? |
| 16:55:11 | <jmcarthur_work> | > (fmap.fmap.const) () $ Just "foo" |
| 16:55:12 | <lambdabot> | Just [(),(),()] |
| 16:55:43 | <jmcarthur_work> | PeakerWork, the ghc binaries for os x seem to only be 32 bit |
| 16:55:50 | <PeakerWork> | jmcarthur_work: ah, thanks |
| 16:56:17 | <fynn> | PeakerWork: yeah, Leopard is 64 bit |
| 16:58:23 | <sm> | fynn, Jedai: I thought the point of the HP is that it includes ghc as well as everything else |
| 16:58:41 | <sm> | the windows installer certainly does |
| 16:59:37 | <Zao> | sm: If you're building from source, there's not much you can do. |
| 16:59:47 | <sm> | ah I see |
| 16:59:53 | <sm> | bring on the installers! |
| 16:59:54 | <Zao> | Distribution packages most likely do the Right Thing. |
| 17:00:25 | <Zao> | sm: I'm unsure, maybe the source package bundles source for the GHC version it wants? |
| 17:00:33 | <Zao> | sm: So the system one is just for bootstrapping? |
| 17:03:41 | <gwern> | jmcarthur_work: the actual code looks like 'case foo bar of Nothing -> return (); Just a -> (archiveBot $ baz $ buz a) >> return ()', and maybe just wasn't doing the right thing |
| 17:06:16 | <PeakerWork> | I like maybeAction :: Maybe a -> (a -> IO ()) -> IO () |
| 17:06:38 | <PeakerWork> | maybeAction = flip (maybe (return ())) |
| 17:07:10 | <gwern> | yeah, but defining maybeAction doesn't shorten my code |
| 17:07:38 | <PeakerWork> | @type ($>) |
| 17:07:39 | <lambdabot> | Not in scope: `$>' |
| 17:07:45 | <PeakerWork> | @type (<$) |
| 17:07:46 | <lambdabot> | forall a (f :: * -> *) b. (Functor f) => a -> f b -> f a |
| 17:07:51 | <PeakerWork> | If that's the goal, then replace >> return () ()$< :-) |
| 17:08:01 | <PeakerWork> | oops, ()<$ |
| 17:09:29 | <gwern> | but then I'd no longer understand it |
| 17:09:51 | <jmcarthur_work> | sequence_ $ archiveBot . baz . buz <$> foo bar |
| 17:10:02 | <gwern> | you haskellers with your crazy monads and applicatives; I'm happy just going along with my meager understanding of monads |
| 17:10:04 | <jmcarthur_work> | where sequence_ comes from Data.Traversable or Foldable or whichever |
| 17:10:15 | <jmcarthur_work> | @hoogle sequence_ |
| 17:10:15 | <lambdabot> | Prelude sequence_ :: Monad m => [m a] -> m () |
| 17:10:15 | <lambdabot> | Control.Monad sequence_ :: Monad m => [m a] -> m () |
| 17:10:15 | <lambdabot> | Data.Foldable sequence_ :: (Foldable t, Monad m) => t (m a) -> m () |
| 17:10:18 | <jmcarthur_work> | foldable |
| 17:10:32 | <edwardk> | http://graphics.cs.cmu.edu/projects/scene-completion/scene-completion.pdf is sexy |
| 17:12:09 | <gwern> | ACTION would click on that and read but my trackball ball was stolen |
| 17:13:22 | <inimino> | that's a good excuse :-) |
| 17:14:44 | <gwern> | well, that and I don't know how to copy-and-paste in screen |
| 17:14:51 | <gwern> | (probably should learn) |
| 17:15:03 | <sm> | wow, clever |
| 17:15:08 | <sm> | (edwardk ) |
| 17:15:36 | <sm> | gwern: forget it, you're never going to figure that out. Use dtach :) |
| 17:15:44 | <jmcarthur_work> | gwern, does (sequence_ $ archiveBot . baz . buz <$> foo bar) work for your mind? :) |
| 17:16:29 | <gwern> | sm: but the man page is right there! I'm sure I can figure it out if I just read carefully enough... |
| 17:16:48 | <gwern> | jmcarthur_work: that handles the case expression itself? |
| 17:16:54 | <sm> | oh alright, go forth and study |
| 17:16:58 | <gwern> | :t (<$>) |
| 17:16:59 | <lambdabot> | forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b |
| 17:17:03 | <inimino> | gwern: it's ^[ and then motion keys, and then space, more motion, space again, done |
| 17:17:19 | <jmcarthur_work> | gwern, if i did my thinking right, that should be the entire thing |
| 17:17:35 | <gwern> | inimino: and the pasting? |
| 17:17:41 | <defun> | what is difference of using Map datatype to store pairs or tuples to do the same? When should I prefer one over the other? |
| 17:17:51 | <inimino> | erm, ^A [, not ^[ |
| 17:17:59 | <gwern> | inimino: yeah, I got that much :) |
| 17:18:03 | <inimino> | gwern: the pasting is ^A ] |
| 17:18:14 | <gwern> | ah. that makes sense |
| 17:18:16 | <Saizan> | defun: a list of tuples you mean? |
| 17:18:33 | <Saizan> | defun: that lookup is O(log n) instead of O(n) |
| 17:18:35 | <gwern> | http://graphics.cs.cmu.edu/projects/scene-completion/scene-completion.pdf |
| 17:18:36 | <gwern> | yay |
| 17:18:51 | <inimino> | ^.^ |
| 17:18:58 | <defun> | Saizan: yes a list of tuples. |
| 17:19:12 | <defun> | Saizan what is O(..) mean |
| 17:19:36 | <Saizan> | defun: it refers to the time cost of the function |
| 17:19:46 | <defun> | so which is more costly? |
| 17:19:53 | <Saizan> | defun: the list of tuples |
| 17:19:59 | <defun> | i see. thanks. |
| 17:20:14 | <Saizan> | defun: because you'll pay a cost that increases linearly with the length of the list |
| 17:20:23 | <Saizan> | defun: instead of logaritmically |
| 17:22:50 | <FunctorSalad> | is there any documentation for this? http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hacanon-light-2008.10.28 -- seems cool otherwise |
| 17:23:36 | <FunctorSalad> | (not even in the source :() |
| 17:24:40 | <dons> | Platform out. upmods plz. We need to get the word out about the release. http://www.reddit.com/r/programming/comments/8pih1/the_haskell_platform_2009201_a_standard_haskell/ |
| 17:24:48 | <dons> | also, anyone tried the Mac OSX installer ? |
| 17:25:27 | <FunctorSalad> | first upvote ;) |
| 17:27:03 | <Zao> | So that's what those arrows to the left of reddit posts are. |
| 17:27:30 | <gwern> | I thought those were munchies for when one got hungry |
| 17:28:50 | <dons> | it was so nice to try the installer on a windows machine, and it just worked. |
| 17:29:06 | <Beelsebob> | Zao: they're for voting the post up/down |
| 17:29:10 | <Beelsebob> | i.e. saying you like it or not |
| 17:29:41 | <Zao> | Beelsebob: So I deduced after seeing dons talking about modding up. |
| 17:29:53 | <gwern> | I always thought they were for moving a post's count closer to what you thought they should be |
| 17:30:20 | <FunctorSalad> | "(\n -> [| \action -> action $(n)|])" |
| 17:30:35 | <FunctorSalad> | slightly confusing me ;) |
| 17:34:16 | <EvilTerran> | FunctorSalad, \n -> [| ($ $n) |] -- :D |
| 17:34:49 | <burp> | sandwich |
| 17:36:12 | <FunctorSalad> | EvilTerran: that would actually produce a clearer splice in this case, since these things get nested... |
| 17:41:00 | <jeffersonheard> | so I tried installing theHaskell platform on a fresh Windows install and then tried using the Gtk2Hs 0.10.0 installer, and it complains that it can't find GHC... is there a way to reconcile this without regedit? |
| 17:43:57 | <Saizan> | jeffersonheard: the gtk2hs installer probably wants an earlier version of ghc |
| 17:44:21 | <jeffersonheard> | Saizan - I got the versions correct. that much I'm sure of |
| 17:44:50 | <jeffersonheard> | it's that the paths the installer looks in for a GHC installtion are not the same as the paths the platform installs in |
| 17:47:26 | <Zao> | jeffersonheard: gtk2hs is horribly broken. |
| 17:47:35 | <Zao> | jeffersonheard: Especially with regard to paths with spaces in them. |
| 17:47:56 | <Zao> | jeffersonheard: I tried for a day or so to hack life into it. It's not meant to be built by mortals :) |
| 17:51:03 | <jeffersonheard> | I'm not trying to build it, just install it... I thought "Hey, Haskell platform, great idea" and I'm afraid it's unusable for me right now |
| 17:51:15 | <jeffersonheard> | I use Gtk2Hs in everything |
| 17:51:44 | <PeakerWork> | jeffersonheard: what stuff do you write with it? |
| 17:51:55 | <Zao> | As for installing gtk2hs, it requires 6.10.1 last I checked (yesterday). |
| 17:51:57 | <jeffersonheard> | Hieroglyph, and everything I write taht depends on it |
| 17:52:02 | <Zao> | They haven't built any .2 or .3 packages yet. |
| 17:52:10 | <Zao> | And it's highly non-trivial to build it yourself. |
| 17:52:21 | <Zao> | And I'm not sure if the author has fixed the finalizer bugs with .2+ yet. |
| 17:52:27 | <jeffersonheard> | I've built it myself just fine on Linux and Mac. Not easy on Windows |
| 17:52:48 | <jeffersonheard> | that is, everythign I write that depends on Hieroglyph |
| 17:52:50 | <Zao> | jeffersonheard: Building GTK is non-trivial. Building gtk2hs is even more so. |
| 17:52:54 | <jeffersonheard> | which since I'm a viz guy, is everything |
| 17:52:55 | <Zao> | (on windows) |
| 17:53:19 | <jeffersonheard> | yeah, which is why I'm going to have to stick to something that will work with the installer |
| 17:53:22 | <jeffersonheard> | not a problem |
| 17:53:26 | <fracture> | anyone here use wxHaskell much on windows? |
| 17:53:28 | <jeffersonheard> | I've been using cabal for awhile |
| 17:53:57 | <fracture> | (I have a problem where it pops up errors about comctl32.dll; nothing on the mailing list or faqs about it) |
| 17:54:02 | <PeakerWork> | all these non-pure toolkits have to be replaced :-) |
| 17:55:24 | <jeffersonheard> | PeakerWork: I agree, however at some level we've got to build the pure on the non-pure |
| 17:56:19 | <fracture> | well, also it'd just be nice to have a decent GUI library at all... ;) (I can't seem to get any of them to work right) |
| 17:56:40 | <jeffersonheard> | gtk2hs is a pain, but I'm used to programming with it these days |
| 17:56:57 | <roconnor> | I've used GuiTV for making little GUIs |
| 17:57:06 | <roconnor> | it depends on wxHaskell |
| 17:57:24 | <fracture> | I'm suspecting the problems I'm having might be vista-specific |
| 17:57:29 | <fracture> | dunno though |
| 17:58:04 | <jeffersonheard> | fracture, I've had luck with gtk2hs on Vista... |
| 17:58:10 | <jeffersonheard> | haven't tried anything else |
| 17:58:29 | <jeffersonheard> | actually, surprisingly, OpenGL seems to perform really well on Vista throug hthe Gtkglext |
| 17:58:55 | <fracture> | yeah... not so sure I'd want to use gtk on windows though |
| 17:59:31 | <jeffersonheard> | I actually use the gtk part of gtk fairly minimally, though. I basically just use dialogues and the gtkglext |
| 18:00:30 | <Cale> | Heh, I'm a crank? |
| 18:00:57 | <jeffersonheard> | Why hello, Cale! No, last time I checked you were a green leafy vegetable |
| 18:01:05 | <roconnor> | Cale: cool |
| 18:01:14 | <Cale> | jeffersonheard: That's Kale. :) |
| 18:01:22 | <roconnor> | Cale: do you have a list of scientist who have found no flaw in your proof? |
| 18:01:32 | <Cale> | (It sounds the same though.) |
| 18:01:34 | <Cale> | roconnor: haha |
| 18:01:37 | <jeffersonheard> | Cale: I'm aware ;-) but the consonant was not about to get in my way |
| 18:03:18 | <lament> | i thought Cale was a straight |
| 18:03:35 | <gwern> | a straight deuce |
| 18:03:46 | <roconnor> | Cale: who says you are a crank? |
| 18:05:01 | <Cale> | roconnor: kpreid asked if Haskell had any cranks, and gwern said "harmless ones like Cale and conal :)" |
| 18:05:11 | <Trafalgard> | ACTION didn't realize I had XChat already open :P |
| 18:06:24 | <monochrom> | It is probably due to advocating . for fmap. |
| 18:07:27 | <roconnor> | Cale: ah. Presumably shapr kicked out all the cranks. |
| 18:08:11 | <lament> | were there any even? |
| 18:08:24 | <lament> | does smerdyakov qualify? |
| 18:08:44 | <roconnor> | nope |
| 18:08:50 | <Cale> | Right, that was the name I was trying to think of... I'm not sure if he's a crank, but he is a bit ill-natured. |
| 18:08:55 | <roconnor> | he was kicked out for other reasons |
| 18:09:16 | <roconnor> | presumably keal is a crank |
| 18:09:23 | <olsner> | what's a crank? |
| 18:09:48 | <roconnor> | olsner: http://en.wikipedia.org/wiki/Crank_(person) |
| 18:09:50 | <monochrom> | My idea of a crank is someone who thinks he has the solution to all the world's problems. |
| 18:10:10 | <roconnor> | "Crank" is a pejorative term for a person who holds a belief that a vast majority of their contemporaries consider false. |
| 18:10:18 | <Cale> | Keal is as far as I can tell genuinely delusional. It's a bit sad, he's a pretty nice guy when he's on his medication. |
| 18:12:30 | <gwern> | monochrom: you see why I included conal in my pair |
| 18:13:24 | <conal> | ACTION is honored |
| 18:14:32 | <Cale> | My mathematical logic prof in university at one point said "It's well-known that I'm a quack. I tried to prove that P = NP for quite a few years." |
| 18:14:47 | <leimy_> | > printf "%0.2X" 10 |
| 18:14:48 | <lambdabot> | Add a type signature |
| 18:14:54 | <Baughn> | That's different. Trying to prove it is the same thing as trying to disprove it. :P |
| 18:15:02 | <leimy_> | > printf "0.2X" 10 :: String |
| 18:15:03 | <lambdabot> | "0.2X* Exception: Printf.printf: formatting string ended prematurely |
| 18:15:37 | <Cale> | Well, yeah, but even working on it directly is a bit strange to begin with, I think. |
| 18:16:17 | <leimy_> | , printf "%0.2X" 10 |
| 18:16:18 | <lunabot> | luna: Couldn't match expected type `t -> a' |
| 18:16:38 | <leimy_> | , printf "%0.2X" 10 :: String |
| 18:16:39 | <lunabot> | luna: Couldn't match expected type `t -> GHC.Base.String' |
| 18:17:02 | <Axman6> | :t printf "%0.2X" |
| 18:17:03 | <lambdabot> | forall r. (PrintfType r) => r |
| 18:17:15 | <leimy_> | I am finding that that works in ghci |
| 18:17:23 | <leimy_> | but that I am not able to get it to behave correctly |
| 18:17:30 | <leimy_> | it does not print the expected 0A |
| 18:17:32 | <leimy_> | just A |
| 18:19:04 | <Baughn> | > printf "%0.2x" 10 :: String |
| 18:19:05 | <lambdabot> | "a" |
| 18:19:16 | <Baughn> | > printf "%3.4x" 10 :: String |
| 18:19:17 | <lambdabot> | " a" |
| 18:19:39 | <leimy_> | ? |
| 18:19:41 | <leimy_> | weird |
| 18:19:47 | <Baughn> | > printf "%3.4d" 10 :: String |
| 18:19:49 | <lambdabot> | " 10" |
| 18:19:55 | <Baughn> | > printf "%3.9d" 10 :: String |
| 18:19:56 | <lambdabot> | " 10" |
| 18:20:15 | <edwardk> | cale: nothing wrong with trying, if nothing else it gives you an appreciation for the subtlety of the problem ;) |
| 18:20:28 | <leimy_> | > printf "%2.0X" 10 :: String |
| 18:20:29 | <lambdabot> | " A" |
| 18:20:36 | <leimy_> | That's wrong :-) |
| 18:20:55 | <leimy_> | it's %<pad>.<width><type |
| 18:21:09 | <tetha> | well, it is padded, with spaces |
| 18:21:16 | <Baughn> | > printf "%09d" 10 :: String |
| 18:21:18 | <lambdabot> | "000000010" |
| 18:21:20 | <leimy_> | the 0 means "pad with 0s" |
| 18:21:29 | <Baughn> | Aha. Right, reading the documentation is good. :P |
| 18:21:33 | <leimy_> | printf "%02X" 10 :: String |
| 18:21:36 | <Cale> | edwardk: Sure. :) |
| 18:21:38 | <leimy_> | oops |
| 18:21:47 | <leimy_> | > printf "%02X" 10 :: String |
| 18:21:48 | <lambdabot> | "0A" |
| 18:21:56 | <leimy_> | hmmm that works, but isn't what the docs say :-) |
| 18:22:02 | <leimy_> | nor is it C like :-) |
| 18:22:17 | <Baughn> | Right you are, but.. well, it works |
| 18:22:34 | <Baughn> | Probably a bug |
| 18:22:38 | <Baughn> | (So report it :) |
| 18:22:48 | <Cale> | edwardk: I think it would be really funny if P = NP, but that the best polynomial time algorithm for an NP-complete problem had some combinatorially large exponent. |
| 18:23:04 | <Cale> | (Like Graham's number, for example :) |
| 18:23:19 | <Baughn> | ..that DOESN'T COUNT, then. o_O |
| 18:23:39 | <Baughn> | Cale: Or perhaps the twenty-symbol busy beaver number? |
| 18:23:43 | <Cale> | :) |
| 18:23:47 | <edwardk> | i figure we're more likely to find a nice connection between say BQP and NP than P and NP in my lifetime, but that even there i'm not holding my breath |
| 18:23:55 | <tetha> | leimy_: how does that not match the documentation of Text.printf? it is "%" followed by "0" for "pad with 0", followed by a num, which is the width, followed by the type, which is x for hex |
| 18:24:14 | <leimy_> | I think I confused the "." for decimal places over width |
| 18:24:16 | <Baughn> | tetha: The documentation mentions a period |
| 18:24:19 | <leimy_> | but C lets you do it either way it seems. |
| 18:24:32 | <tetha> | Baughn: the period is for separating the width from a precision |
| 18:24:33 | <Baughn> | Oh.. |
| 18:24:33 | <leimy_> | it's num vs .num |
| 18:24:34 | <leimy_> | right |
| 18:24:36 | <Baughn> | Right you are |
| 18:24:42 | <leimy_> | C just lets you get away with it :-) |
| 18:24:52 | <leimy_> | so I'm in "undefined territory" |
| 18:25:34 | <Baughn> | > printf "%02.2f" pi |
| 18:25:36 | <lambdabot> | Add a type signature |
| 18:25:40 | <Baughn> | > printf "%02.2f" pi :: String |
| 18:25:41 | <lambdabot> | "3.14" |
| 18:25:55 | <Baughn> | > printf "%05.2f" pi :: String |
| 18:25:56 | <lambdabot> | "03.14" |
| 18:29:04 | <EvilTerran> | edwardk, my money's on P=NP being independent of the axioms, like AoC |
| 18:29:37 | <Elly> | is that just your sense of mathematical elegance talking? |
| 18:29:50 | <seliopou> | lol |
| 18:30:17 | <EvilTerran> | Elly, i guess so. then there's my evil side that's rooting for a non-constructive proof that P=NP |
| 18:30:51 | <edwardk> | evilterran: yeah. i think the BQP ?= NP question will hinge on something like a continuum hypothesis |
| 18:31:20 | <tetha> | hehe, I kind of hope of a constructive algorithm with a proof that all polynomials solving NP-problems must have some really huge degree |
| 18:31:21 | <seliopou> | supraempirical virtues ftw |
| 18:32:50 | <goldenpuffs> | is it faster to use b*b instead of b^2 ? |
| 18:32:58 | <monochrom> | A bit. |
| 18:33:05 | <goldenpuffs> | why is that? |
| 18:33:15 | <tetha> | goldenpuffs: dont micro-optimize |
| 18:33:35 | <goldenpuffs> | tetha: what's wrong with that? |
| 18:33:40 | <monochrom> | b^2 goes through one more definition to reach b*b. But inlining may very well eliminate it. |
| 18:34:00 | <edwardk> | @src (^) |
| 18:34:01 | <lambdabot> | x ^ 0 = 1 |
| 18:34:01 | <lambdabot> | x ^ n | n > 0 = f x (n-1) x |
| 18:34:01 | <lambdabot> | where f _ 0 y = y |
| 18:34:01 | <lambdabot> | f x n y = g x n |
| 18:34:01 | <lambdabot> | where g x n | even n = g (x*x) (n `quot` 2) |
| 18:34:03 | <lambdabot> | | otherwise = f x (n-1) (x*y) |
| 18:34:05 | <lambdabot> | _ ^ _ = error "Prelude.^: negative exponent" |
| 18:34:24 | <seliopou> | It's like using minimum on a list you always know the length of |
| 18:34:29 | <tetha> | goldenpuffs: a) the compiler might already do this for you. b) if your bottleneck really is such a multiplication, use a different algorithm or a different language if no better algorithm exists, that will result in far greater speedups |
| 18:34:44 | <seliopou> | it's a good thing to eliminate when you're concerned with speed |
| 18:36:20 | <akamaus> | hello all. I'm looking for "A Recursive do for Haskell: Design and Implementation" paper by by Erkök and Launchbury . I found this link in Haskell-Cafe archives, but presently it doesn't work. Does anybody know where to get this paper?? |
| 18:36:42 | <SamB> | akamaus: citeseer? |
| 18:37:03 | <edwardk> | akamaus I may have it on a flashdrive somewhere if it has vanished off the internet forever |
| 18:37:09 | <goldenpuffs> | ok thanks for the explanations |
| 18:37:35 | <edwardk> | rather i may have it on the flashdrive somewhere, and if it has vanished off the internet forever i might be bothered to spend a couple hours looking for it ;) |
| 18:37:54 | <SamB> | edwardk: you know that right after you find it, it's going to show up again! |
| 18:38:11 | <SamB> | ... and maybe not just because you uploaded it ;-P |
| 18:38:26 | <Berengal> | SamB: But if he doesn't it won't |
| 18:38:33 | <edwardk> | samb: like is difficult like that. i.e. you always find stuff in the last place you look. =) |
| 18:38:44 | <edwardk> | er life |
| 18:39:50 | <Baughn> | conal: Before I start searching, I'd like to ask - had you solved the partial time information problem for makeEvent? |
| 18:40:11 | <Baughn> | conal: That is to say, did it link up with the Ord instance for Improving properly? |
| 18:40:19 | <akamaus> | SamB, citeseer points there: http://www.ogi.edu/csee/PacSoft/projects/rmb/recdo.pdf |
| 18:40:20 | <conal> | Baughn: yes, i think so. |
| 18:40:40 | <byorgey> | akamaus: try http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.6.5172&rep=rep1&type=pdf |
| 18:40:46 | <SamB> | akamaus: citeseer usually has a download link of their own as well ... |
| 18:40:59 | <byorgey> | I found it by searching with Google scholar |
| 18:41:04 | <SamB> | like the one byorgey pasted just now |
| 18:41:51 | <edwardk> | conal: are you familiar with the WOOT algorithm? i was playing around the other day trying to see if i could use something like that for the 'locally clocked' distributed FRP stuff we talked about forever ago. |
| 18:42:06 | <conal> | edwardk: never heard of it. |
| 18:42:28 | <akamaus> | byorgey, thanks a lot |
| 18:42:40 | <Baughn> | conal: Okay. This should be fun, then.. |
| 18:42:51 | <Baughn> | conal: Since I can't actually find the code. :P |
| 18:42:54 | <conal> | Baughn: check out makeTVal and its uses (transitively). |
| 18:42:55 | <byorgey> | akamaus: sure, no problem =) |
| 18:43:14 | <aledge> | what's the most haskell-y way to implement a list that can be arbitrarily nested? |
| 18:43:28 | <conal> | Baughn: and i'm not at all satisfied with the simplicity of that code. |
| 18:43:28 | <edwardk> | conal: http://wooki.sourceforge.net/papers.htm |
| 18:43:34 | <SamB> | aledge: use a tree |
| 18:43:35 | <conal> | edwardk: thsx |
| 18:43:36 | <SamB> | call it a tree |
| 18:43:40 | <aledge> | you can imagine doing something like List = Empty | Cons (a, List) |
| 18:44:40 | <edwardk> | conal: you have to view it through really fuzzy lenses to see any application to this space, but as a nice 'eventually consistent' distributed event model it could be interesting. |
| 18:44:43 | <aledge> | SamB: hm that makes sense |
| 18:44:46 | <aledge> | SamB: hehe |
| 18:46:09 | <edwardk> | http://wooki.sourceforge.net/papers/oster06cscw.pdf is a direct link to the most interesting paper they have |
| 18:47:15 | <Baughn> | conal: Well, I'm having fun debugging joinE. Wish me luck. |
| 18:48:07 | <conal> | Baughn: glad to hear. good luck and thanks! :) |
| 18:57:35 | <bentson> | Has anyone seen the compiler for pH (as referenced in "Implicit Parallel Programming in pH")? |
| 18:58:21 | <Baughn> | conal: Oh, and I tried to explain FRP to an imperative programmer, in particular how yours works internally.. |
| 18:58:44 | <Baughn> | conal: He was quite impressed, actually, but decided the model wasn't for humans. ^^; |
| 18:58:45 | <Zao> | Baughn: I'd reckon one'd get better luck explaining it to an electrical engineer. |
| 18:58:53 | <Zao> | All those latches and whatnot. |
| 18:59:21 | <edwardk> | s/humans/people with an ingrained imperative mindset/ |
| 18:59:56 | <Baughn> | Mm. OTOH, it did get him thinking maybe he should learn haskell. |
| 18:59:57 | <Zao> | Using FRP feels like throwing a bunch of code in a sack, shake and put it on fire. |
| 19:00:11 | <FunctorSalad> | . o O (instained imperative mindset) |
| 19:00:22 | <conal> | programmers are also programmees |
| 19:00:32 | <Apocalisp> | Is there a datastructure for mapping (possibly overlapping) ranges to values? |
| 19:00:44 | <Baughn> | s/programmers/humans/, and if more people would understand that the world'd be a better place |
| 19:00:47 | <Baughn> | Apocalisp: Enum |
| 19:00:59 | <FunctorSalad> | ? |
| 19:01:06 | <tony__> | whats a .hsc file? |
| 19:01:12 | <conal> | Baughn: agreed |
| 19:01:17 | <Zao> | tony__: A .hs file that should be preprocessed with cpp. |
| 19:01:25 | <MyCatVerbs> | Erk. |
| 19:01:26 | <tony__> | Zao: oh thanks |
| 19:01:26 | <FunctorSalad> | Apocalisp: Map (Double,Double) Foo? |
| 19:01:31 | <Baughn> | tony__: Nononono |
| 19:01:35 | <MyCatVerbs> | tony__: a .hs file that should be preprocessed with hsc2hs. |
| 19:01:41 | <Zao> | tony__: http://www.haskell.org/ghc/docs/latest/html/users_guide/hsc2hs.html |
| 19:01:44 | <Baughn> | tony__: It's a .hs file that should be preprocessed with hsc2hs, which normally also involves cpp |
| 19:01:58 | <Zao> | MyCatVerbs: Am I confusing it with .chs? |
| 19:01:59 | <Baughn> | tony__: See also: c2hs |
| 19:02:16 | <Baughn> | Zao: {-# LANGUAGE CPP #-} works on .hs too |
| 19:02:33 | <MyCatVerbs> | Zao: c2hs and hsc2hs are different programs that do somewhat similar jobs. |
| 19:02:55 | <FunctorSalad> | Apocalisp: hmm, I guess you want fast lookup for points inside the ranges |
| 19:03:02 | <Apocalisp> | FunctorSalad: Yes, exactly |
| 19:03:04 | <tony__> | interesting |
| 19:03:31 | <MyCatVerbs> | Apocalisp: you want a mapping from values in a certain range to some other data type? |
| 19:03:52 | <MyCatVerbs> | Apocalisp: if the values that you are mapping from are dense, that is an array that you are describing. :) |
| 19:03:54 | <FunctorSalad> | Apocalisp: maybe a sort of decision tree "if x < pivot then search this subtree else this", with the leafs being sets of ranges |
| 19:04:08 | <Zao> | Handling overlaps sounds like fun. |
| 19:04:13 | <FunctorSalad> | (the leafs wouldn't be disjoint) |
| 19:04:22 | <Apocalisp> | Yes, something like (Ord a) => a -> [b] |
| 19:04:27 | <Zao> | Should the ranges have priorities or is it first/last in that goes? |
| 19:04:54 | <FunctorSalad> | I think he wants all the ranges inside of which the given point lies |
| 19:05:19 | <FunctorSalad> | the tree-with-sets-as-leaf would be good for that, don't know if updating it would be efficient |
| 19:05:30 | <FunctorSalad> | the rebalancing could be a bit messy ;) |
| 19:05:33 | <EvilTerran> | ACTION would suggest sth like Map Key (Map Key Val) |
| 19:05:36 | <Apocalisp> | FunctorSalad: I want all the values associated with the ranges inside of which the given point lies. |
| 19:06:01 | <FunctorSalad> | EvilTerran: that doesn't let you look up values inbetween ranges |
| 19:06:07 | <FunctorSalad> | *inbetween endpoints |
| 19:06:07 | <EvilTerran> | pull out all the elements with first key <x, then all the elements of those with second key >x |
| 19:06:22 | <FunctorSalad> | does Data.Map let you do that? |
| 19:06:58 | <EvilTerran> | FunctorSalad, sure, with split |
| 19:07:02 | <Apocalisp> | split! |
| 19:07:04 | <Apocalisp> | that's it |
| 19:07:12 | <FunctorSalad> | nice, didn't know. |
| 19:07:18 | <MyCatVerbs> | :t Data.Map.split |
| 19:07:20 | <lambdabot> | forall k a. (Ord k) => k -> M.Map k a -> (M.Map k a, M.Map k a) |
| 19:07:21 | <Zao> | I'd do it naively with filtering a list of (Range, t) according to a predicate on the input. |
| 19:07:29 | <Zao> | And then bother to optimize it if needed. |
| 19:07:38 | <EvilTerran> | > M.split 3 (M.fromList $ zip [0..] "abracadabra") |
| 19:07:39 | <lambdabot> | (fromList [(0,'a'),(1,'b'),(2,'r')],fromList [(4,'c'),(5,'a'),(6,'d'),(7,'a... |
| 19:08:23 | <Apocalisp> | nice, thanks |
| 19:08:40 | <Apocalisp> | FunctorSalad: How would you do "all the ranges"? |
| 19:09:16 | <FunctorSalad> | Apocalisp: like EvilTerran said, with Val := Range |
| 19:09:46 | <PeakerWork> | cool, binary search trees have many interesting properties that hash tables don't, and yet are relatively less popular in mainstream languages |
| 19:10:12 | <EvilTerran> | PeakerWork, like the O(log n) split, you mean? |
| 19:10:17 | <PeakerWork> | yeah |
| 19:11:00 | <FunctorSalad> | Apocalisp: hmm, wait |
| 19:11:09 | <jmcarthur_work> | yeah, it's amazing to me how general binary trees really are |
| 19:11:11 | <jmcarthur_work> | and finger trees |
| 19:11:35 | <FunctorSalad> | Apocalisp: I think you'd still need sets as values |
| 19:11:53 | <PeakerWork> | @type let takeBelow = fst . M.split in takeBelow |
| 19:11:55 | <lambdabot> | Couldn't match expected type `(a, b)' |
| 19:11:55 | <lambdabot> | against inferred type `M.Map a2 a1 -> (M.Map a2 a1, M.Map a2 a1)' |
| 19:11:55 | <lambdabot> | In the second argument of `(.)', namely `M.split' |
| 19:12:11 | <PeakerWork> | @type let takeBelow n = fst . M.split n in takeBelow |
| 19:12:12 | <lambdabot> | forall k a. (Ord k) => k -> M.Map k a -> M.Map k a |
| 19:12:23 | <PeakerWork> | @type let takeAbove n = snd . M.split n in takeBelow |
| 19:12:24 | <lambdabot> | Not in scope: `takeBelow' |
| 19:12:35 | <PeakerWork> | ACTION stops flooding :) |
| 19:13:22 | <FunctorSalad> | Apocalisp: nevermind what I said, I got a bit confused there |
| 19:15:38 | <sm> | ACTION wonders if recompiling an app with base4 vs. base3 is likely to affect performance |
| 19:16:23 | <FunctorSalad> | ACTION thought you meant number bases... |
| 19:16:43 | <sm> | heh |
| 19:18:24 | <sm> | I also wonder, when testing with alternate versions of ghc, when you need to use cabal's --with-hc-pkg flag. -w often seems sufficient |
| 19:19:41 | <FunctorSalad> | EvilTerran: did you mean to map every lower boundary L to (map every upper boundary U to the value associated with [L,U])? hmm |
| 19:22:15 | <FunctorSalad> | so you'd split the outer map at the given point and take the top entry of the lower part of the outer map :) |
| 19:23:19 | <sayyestolife> | so, how's it going with replacing gcc with c--? |
| 19:30:24 | <Chemistry> | fap fap fap |
| 19:30:44 | <FunctorSalad> | did you mean: fmap? |
| 19:31:19 | <gwern> | @hoogle fap |
| 19:31:19 | <lambdabot> | No results found |
| 19:31:42 | <Chemistry> | google fap fap fap |
| 19:32:17 | <ziman> | :t fmap fmap fmap |
| 19:32:18 | <lambdabot> | forall (f :: * -> *) a b (f1 :: * -> *). (Functor f, Functor f1) => (a -> b) -> f (f1 a) -> f (f1 b) |
| 19:33:23 | <Chemistry> | fap fap fap: the sound one makes when masturbating |
| 19:34:17 | <gwern> | masturbating? oh that thing you fleshly ones do |
| 19:34:21 | <facedown> | what if you have noiseless fapping |
| 19:34:28 | <gwern> | faking fitness, I understand is its function |
| 19:34:34 | <Chemistry> | then you need to fap fap fap harder |
| 19:34:39 | <FunctorSalad> | cf "how to be funny, not just stupid"... |
| 19:36:02 | <Chemistry> | cf? |
| 19:37:10 | <gwern> | pg 68, ibid. |
| 19:40:14 | <fracture> | any problem with installing the haskell platform if I have ghc installed already? |
| 19:40:29 | <fracture> | (maybe I should uninstall ghc and all its foo firsts?) |
| 19:41:22 | <Saizan> | if you install it from source it's required, otherwise i don't think it'll clash |
| 19:41:34 | <Saizan> | ghc is required, i mean |
| 19:42:25 | <SamB> | heck, GHC is required to install GHC from source ;-) |
| 19:43:31 | <FunctorSalad> | is it seriously floating in the air now with no way to bootstrap it? :) |
| 19:44:19 | <mle> | FunctorSalad: is C any different? |
| 19:44:40 | <FunctorSalad> | mle: I don't know |
| 19:45:06 | <Heffalump> | I doubt it |
| 19:45:11 | <mle> | Lots of languages require themselves to build. |
| 19:45:12 | <sayyestolife> | bootstrapping sounds kinky |
| 19:45:16 | <Heffalump> | except C has more implementations to cross-compile with |
| 19:45:41 | <fracture> | I distrust compiled languages that don't have at least one implementation in the language itself |
| 19:45:55 | <FunctorSalad> | I guess it's somewhat true of civilisation in general ;) |
| 19:46:26 | <FunctorSalad> | or technology |
| 19:48:24 | <PeakerWork> | fracture: what about total languages? They can't interpret themselves.. I guess they can compile themselves, though |
| 19:48:31 | <mib_cm40m336> | hi guys!i have a question.is it possible to write a type defintion for example f:: Float-> Float ,then write the function in the ghci shell ?thank you(sorry for my english) |
| 19:48:55 | <PeakerWork> | > let f :: Float -> Float ; f x = (x/2) in f 5 |
| 19:48:56 | <lambdabot> | 2.5 |
| 19:49:07 | <PeakerWork> | mib_cm40m336: that should work in ghci too |
| 19:52:01 | <fracture> | PeakerWork: I guess I feel differently about interpreted languages... |
| 19:53:07 | <PeakerWork> | fracture: interpreter implementations, I supposed you mean, languages that are interpreted can be compiled and vice-versa |
| 19:54:16 | <fracture> | right... |
| 19:55:46 | <mib_cm40m336> | thank you.but i have another question:whats the problem whit this: let f :: Double -> Double ; f x=3.0^x |
| 19:55:55 | <Berengal> | @type (^) |
| 19:55:57 | <lambdabot> | forall a b. (Num a, Integral b) => a -> b -> a |
| 19:56:09 | <Berengal> | mib_cm40m336: Wrong type, see above |
| 19:56:13 | <BONUS> | use ** |
| 19:57:33 | <mib_cm40m336> | thank you.but why is there two power function in haskell?(sorry im beginner) |
| 19:57:55 | <araujo> | because haskell is too powerful |
| 19:57:59 | <Berengal> | mib_cm40m336: There are three, actually, ^, ^^ and ** |
| 19:58:02 | <Cale> | mib_cm40m336: There are three actually. They have different types and correspond to three different definitions in mathematics. |
| 19:58:27 | <Cale> | mib_cm40m336: (^) works with any type of number for the base, but only admits positive exponents |
| 19:58:37 | <jeffersonheard> | here's a new one... I seem to be all over them today... runtime error: "no match in record selector" |
| 19:58:47 | <Cale> | mib_cm40m336: (^^) works with any *fractional* type of number for the base, and admits negative exponents as well |
| 19:59:37 | <Cale> | mib_cm40m336: (**) admits arbitrary real number (Floating) exponents but requires the same type of base. |
| 20:00:59 | <Cale> | Oh, I somehow neglected to mention that (^) and (^^) only allow integer-like exponents |
| 20:01:03 | <jeffersonheard> | anyone ever seen the No match in record selector error before? |
| 20:01:07 | <jeffersonheard> | not even sure what it means |
| 20:01:18 | <jeffersonheard> | I would assume such things would get caught by the type checker |
| 20:01:22 | <Cale> | jeffersonheard: hmm... |
| 20:01:33 | <Cale> | jeffersonheard: Is it a panic? |
| 20:01:44 | <jeffersonheard> | thebigboard: No match in record selector |
| 20:01:45 | <jeffersonheard> | Graphics.Rendering.Hieroglyph.Primitives.bottomleft |
| 20:01:47 | <jeffersonheard> | yes |
| 20:01:53 | <jeffersonheard> | it's an IOException anyway |
| 20:01:54 | <jeffersonheard> | dies |
| 20:01:58 | <Cale> | oh, that's different :) |
| 20:02:14 | <mib_cm40m336> | thanks for your help. |
| 20:02:19 | <Cale> | You don't see "The impossible happened!" or anything like that. |
| 20:02:24 | <jeffersonheard> | yeah -- iit's not the impossible happened |
| 20:02:29 | <jeffersonheard> | right |
| 20:02:34 | <jeffersonheard> | so no, not a panic |
| 20:02:37 | <jeffersonheard> | just a weirdness |
| 20:02:39 | <Cale> | Let's have a look... |
| 20:02:51 | <jeffersonheard> | you want an hpaste? |
| 20:02:52 | <hackagebot> | network 2.2.1.3 |
| 20:03:19 | <FunctorSalad> | can I indent stuff in haddock without ">"? (which ignores any further markup) |
| 20:03:41 | <Cale> | oh, I know what it is |
| 20:03:50 | <jeffersonheard> | do tell... |
| 20:03:50 | <Cale> | bottomleft :: Primitive -> Point |
| 20:04:05 | <Cale> | but only Text values have that field |
| 20:04:26 | <Cale> | So it means that you applied bottomleft to a Primitive value which was not a Text, I think. |
| 20:05:00 | <jeffersonheard> | ought to mean that. only thing I can think of is that I botched the Ord instance for Primitive, though |
| 20:05:59 | <Cale> | Do you explicitly call bottomleft from thebigboard? |
| 20:06:32 | <jeffersonheard> | Ah ha |
| 20:06:33 | <jeffersonheard> | I found it |
| 20:06:36 | <jeffersonheard> | good old grep |
| 20:06:41 | <jeffersonheard> | not where I thought I did |
| 20:07:22 | <jeffersonheard> | thought I was only using it as a record constructor. I really ought to disambiguate. I'm standardizing on cartesian plane, so all should be from bottomleft |
| 20:07:32 | <Cale> | ah |
| 20:07:45 | <jeffersonheard> | or southwest as it were |
| 20:07:50 | <jeffersonheard> | will probably change that in a few version |
| 20:08:03 | <jeffersonheard> | more people are using Hieroglyph now, so I'm going to have to have a deprecation policy |
| 20:08:53 | <hackagebot> | hack-middleware-cleanpath 0.0.1 |
| 20:11:54 | <hackagebot> | hack-handler-cgi 0.0.2 |
| 20:12:17 | <Berengal> | When will I learn not to start deleting things right away when they don't work? |
| 20:12:55 | <hackagebot> | hack-handler-fastcgi 0.0.4 |
| 20:13:56 | <hackagebot> | hashed-storage 0.3.2 |
| 20:18:32 | <BONUS> | interesting thing about ContT monad that i figured out: if you have a CPS transformed monadic value (a -> m a) -> m a, the resulting m a can be different than the one returned by the continuation |
| 20:18:44 | <BONUS> | which is pretty cool, anyone ever taken advantage of this? |
| 20:19:45 | <hatds> | I've struggled to use ContT practice |
| 20:19:53 | <hatds> | *in practice |
| 20:19:58 | <BONUS> | i find this good for using withFile |
| 20:20:42 | <BONUS> | you can do handle <- ContT $ withFile "foo" ReadMode; lift $ some_big_io_action |
| 20:20:59 | <BONUS> | and then when the big I/O action is done, the handle will get closed |
| 20:24:42 | <hatds> | how's that any different than what you can do without ContT? |
| 20:25:08 | <BONUS> | well without it you do withFile "foo" ReadMode (\handle -> some_big_io_action) |
| 20:25:37 | <hatds> | does the former offer any advantages? |
| 20:26:07 | <BONUS> | it pretty much evaluates to the same thing |
| 20:26:27 | <BONUS> | it might be easier to read if you have many functions that take (\blah -> something) as parameters |
| 20:26:32 | <BONUS> | where something can get pretty big |
| 20:27:16 | <BONUS> | or say you want to open like 5 files with withFile |
| 20:27:40 | <BONUS> | then it might be more readable |
| 20:27:56 | <Peaker> | BONUS: what might be more readable? |
| 20:27:59 | <hatds> | ContT is not hat readable to begin with though |
| 20:28:24 | <edwardk> | BONUS: re the ability to not have to use the continuation or to tweak the result of it. yes, thats actually kind of the point of using Cont(T) =) |
| 20:28:39 | <Peaker> | Need a composition operator for bracket that tuples up or such the multiple results, like Python's nested (withFile could be composed that way) |
| 20:28:48 | <Peaker> | (.) composes bracket_ nicely, but not bracket |
| 20:29:14 | <edwardk> | BONUS: without that, if you can only use the result without inspecting it, as in forall r. (a -> m r) -> m r -- you have the codensity monad! =) |
| 20:29:45 | <edwardk> | BONUS: (the ability to use alternative 'm r's that you have lying around is what lets you define callCC. |
| 20:30:04 | <BONUS> | aha |
| 20:30:19 | <BONUS> | previously i thought that the point of ContT was lifting other monads to ContT |
| 20:30:29 | <Berengal> | Hah, well what do you know, ripping out the guts of ghc and putting them back in worked relatively pain-free |
| 20:30:32 | <BONUS> | because >>= ContT doesn't use the underlying monad's >>=, but lift does |
| 20:30:55 | <edwardk> | if you just lift other monads into it then Codensity is a smaller type that serves that purpose. |
| 20:31:13 | <edwardk> | Codensity enforces that you never use callCC basically |
| 20:31:23 | <BONUS> | yeah i guess it's better to use codensity if you do just that |
| 20:31:36 | <SamB> | what's the point of Codensity? |
| 20:32:06 | <BONUS> | i was thinking of something like this http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5541#a5541 |
| 20:32:55 | <edwardk> | samb: tightening the asymptotics when you are working with monads with an expensive bind operation (i.e. a binary tree, etc) |
| 20:33:00 | <Cale> | Odd that the constructor isn't exported. I wonder if that's just an oversight. |
| 20:33:17 | <edwardk> | cale: of which? |
| 20:33:22 | <Cale> | Codensity. |
| 20:33:30 | <edwardk> | cale: oversight =) |
| 20:34:11 | <Daimonic> | Hail Haskell |
| 20:34:19 | <Daimonic> | This Summer 2009 - I will return |
| 20:34:20 | <Daimonic> | :D |
| 20:34:31 | <Cale> | hehe :) |
| 20:34:45 | <edwardk> | cale: you can always runCodensity to extract it |
| 20:34:58 | <Daimonic> | but only, because I failed my exams |
| 20:34:59 | <edwardk> | but i need to add that to my growing list of stuff i should fix |
| 20:35:15 | <Cale> | edwardk: Except that doesn't appear to be exported either. |
| 20:35:20 | <edwardk> | gah |
| 20:35:40 | <edwardk> | you can er codensityToRan and then pattern match to extract? =) |
| 20:37:05 | <Cale> | The fix is 4 characters long, shouldn't be too hard ;) |
| 20:37:27 | <edwardk> | gah, i feel like a sql newb i just fixed a heisenbug that has been plaguing me for two years. |
| 20:38:17 | <Cale> | Oh? |
| 20:39:09 | <edwardk> | (i had an update statement that used a select with a left join from the table against itself to copy down some information about the parent into the child (breaking 3rd normal form because its going into an olap database) that would occasionally deadlock on me. |
| 20:39:50 | <edwardk> | and the reason was i had other transactions that ran updates, so they would grab an upgradeable read lock, and then to get the data from the parents my update statement would grab a read lock, which would be permitted in by the upgradable read of the other update |
| 20:40:06 | <hashkool> | I've a nasty type problem: |
| 20:40:10 | <edwardk> | and then it would try to upgrade the read while an upgradable read was being held and deadlock |
| 20:40:29 | <edwardk> | of course it only showed up under load and on my biggest customers ;) |
| 20:40:34 | <hashkool> | Inferred type is less polymorphic than expected Quantified type variable `d' escapes In the first argument of `gmapQ', namely `(genf expr)' In the expression: (gmapQ (genf expr)) In the definition of `xpath': xpath expr = (gmapQ (genf expr)) |
| 20:41:19 | <Cale> | hashkool: Usually that kind of type error can be solved by commenting out your type signature and seeing what's inferred. |
| 20:41:34 | <Cale> | (or at least, it provides a decent clue) |
| 20:41:36 | <hashkool> |