Experimental IRC log haskell-2009-06-03

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>code is here: