Experimental IRC log haskell-2009-06-04

Available formats: content-negotiated html turtle (see SIOC for the vocabulary)

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

These logs are provided as an experiment in indexing discussions using IRCHub.py, Irc2RDF.hs, and SIOC.

00:00:00<fynn>Peaker: the kind of limited stuff you can do with them in Python probably means you don't really understand them
00:00:11<Cale>fynn: A big hint about whether you've properly implemented them is whether you can write a piece of code and have it work polymorphically with any monad.
00:00:20<Cale>If you can, then you've done it right.
00:01:35<Cale>If not, then you've done something like implemented one particular monad (or a few). The abstraction is only useful if you can have an equivalent of Control.Monad around.
00:01:43<Peaker>fynn: You can have a "duck-type-class" in Python with >>= (__irshift__) and a class-method "return"
00:02:19<Peaker>and then it can work on any value that happens to have those duck-type-class methods
00:02:22<Cale>return is actually the tricky part
00:02:35<Cale>because it's polymorphic in its result type
00:03:01<Peaker>yeah, you need to take in a class and use a class-method, much like type-classes translate to taking in a vtable/dictionary
00:03:04<Berengal>return would have to be some magic class of its own which calls __return or something when bound
00:04:29<Peaker>Data.Binary.Get uses "fail" in the Get monad which uses pure exceptions. It could be nice to have polymorphic fail there, but if you give it any (MonadGet m) then any transformer you have around Get needs a MonadGet instance too, causing the O(N^2) transformer instances problem.. any idea how this could be solved elegantly?
00:04:34<Berengal>a >>= b | a instanceOf return = b.__class__.return(a.val) >>= b
00:05:06<Berengal>(sorry for mixing syntax... it's been so long since I've done anything but haskell, anything else feels unnatural)
00:05:42<Twey>Woah
00:05:52<Twey>Heh, oh
00:06:13<mauke>sub liftM { my ($M, $mf, $mx) = @_; $M->{bind}($mf, sub { my ($f) = @_; $M->{bind}($mx, sub { my ($x) = @_; $M->{return}($f->($x)) }) }) }
00:06:27<Twey>ACTION threatens mauke with an axe
00:06:31<Berengal>augh!
00:06:33<Berengal>My eyes!
00:06:37<mauke>FATALITY
00:06:45<fynn>lol@Perl
00:06:47<Twey>Hahahaha
00:06:56<Twey>Truly
00:07:20<Peaker>Some people say Haskell operators sometimes look like Perl. This kind of code reminds us that they aren't quite THAT bad :)
00:07:29<luqui>come on, be fair. ->bind instead of ->{bind} at least
00:07:48<mauke>->bind is pointless
00:07:57<Peaker>mauke: taking a type-class dictionary explicitly?
00:08:01<mauke>yep
00:08:05<Peaker>cheat
00:08:14<Twey>ACTION twitches.
00:08:43<luqui>i think explicit dictionary passing is a better solution than trying to half-assedly piggyback on OO features
00:09:46<Berengal>luqui: How about full-assedly piggybacking?
00:09:49<mauke>def liftM(M, mf, mx): return M["bind"](mf, lambda f: M["bind"](mx, lambda x: M["return"](f(x))))
00:09:58<FunctorSalad>Peaker: obviously we should use 20-character method names for elementary operations instead of operators
00:10:00<mauke>hmm, python wins here because the functions are trivial
00:10:02<FunctorSalad>:-(
00:10:11<Peaker>FunctorSalad: false dichotomy..
00:10:31<FunctorSalad>Peaker: I wasn't making a dichotomy, I was ranting against certain languages ;)
00:10:40<kpreid>I think it is *possible* to make return happen in the absence of type inference by deferring the instantiation of it until you compose it with some other monadic action (of a known type)
00:10:48<Saizan_>Peaker: have you seen mmtl?
00:10:57<Peaker>FunctorSalad: Python has better naming than Haskell, IMO. Also simpler indentation rules (but I'm not sure how they could apply to an FP)
00:11:04<kpreid>At least, I wrote a Haskell interpreter that managed to work that way for trivial cases.
00:11:06<Peaker>Saizan_: nope, what's that?
00:11:11<kpreid>(I should publish that...)
00:11:31<Peaker>Saizan_: you referring to the MonadGet problem?
00:11:39<Saizan_>Peaker: yes
00:12:04<sm>I'm following http://haskell.org/ghc/docs/latest/html/users_guide/hpc.html , and not finding the .hpc directory
00:12:18<Peaker>Saizan_: What's mmtl? How does it solve the N^2 instance problem?
00:12:29<Peaker>Saizan_: Maybe Get itself should be in MaybeT, always, given its primitive operations use fail?
00:12:41<sm>I do --make -fhpc, then run the resulting binary - that should save tix files somewhere, am I right ?
00:12:55<Saizan_>@hackage mmtl
00:15:12<Saizan_>Peaker: it solves it with a richer MonadTrans and a single lifting instance per class
00:15:15<FunctorSalad>is beta reduction always correct in haskell? barring unsafe*
00:15:30<Peaker>Saizan_: ah, cool
00:15:52<Peaker>Saizan_: is its ListT also not broken?
00:16:07<Saizan_>Peaker: i don't remember
00:16:24<FunctorSalad>(actually I'm just beta reducing some template haskell splices for readability so it doesn't matter ;))
00:16:41<Saizan_>btw, if python had TCO you could implement only the Cont monad and piggyback everything else on it
00:16:42<Cale>FunctorSalad: It should be
00:17:02<Cale>FunctorSalad: But it may affect performance.
00:17:10<Cale>Depending on how you do it.
00:17:10<idnar>Saizan_: why do you need TCO?
00:17:17<FunctorSalad>Cale: yes, sharing...
00:17:42<Cale>FunctorSalad: But if you use let to reflect the sharing, then there's no problem.
00:18:00<idnar>Saizan_: if it's just to avoid blowing the stack, you can probably simulate it with generators and an appropriate trampoline; although it'll be a bit ugly...
00:18:50<Saizan_>idnar: heh, ok
00:19:01<goldenpuffs>is there a symbol for infinity?
00:19:16<mauke>
00:20:18<goldenpuffs>can you use that in haskell?
00:20:31<jrick>last [1..] ;)
00:20:33<goldenpuffs>to compare to other numbers?
00:20:37<dolio>If you implement TCO by hand, you don't need TCO. :)
00:21:15<FunctorSalad>goldenpuffs: you can, but it is an operator character
00:21:34<hatds>could use maxBound, goldenpuffs
00:21:37<FunctorSalad>goldenpuffs: so you need to put ( ) around it if you want to use it as a constant...
00:22:02<Saizan_>goldenpuffs: if you're dealing with floats you can use (1/0) as infinity
00:22:06<Saizan_>> 1/0
00:22:18<sm>so nobody's doing code coverage with -fhpc ?
00:22:40<dolio>I used it on uvector-algorithms.
00:23:04<dolio>You need to run the program to generate the tix file, I think.
00:23:17<sm>dolio: did you just build with -fhpc, run the program, and it made a .hpc dir containing tix files ?
00:23:32<goldenpuffs>cool thx
00:23:48<sm>mine isn't generating any .hpc or .tix
00:24:39<hatds>is there a common way of phrasing the difference between a function that is defined in a class declaration versus a function that is only overloaded on that typeclass?
00:25:35<Saizan_>the first is a class method while the second is only polymorphic with a typeclass constraint?
00:25:48<hatds>ah, 'class method', thanks
00:26:13<dolio>sm: I compile with -fhpc, I run the program, and then I do 'hpc markup <program>'.
00:26:32<Peaker>so, would it break Haskell if function arguments were fully polymorphic? I think maybe its right to say they'd be 2nd rank polymorphic
00:26:35<sm>dolio: and step 2 generates a .tix file ?
00:26:46<Peaker>are there really good reasons for function args not to be?
00:27:03<FunctorSalad>syb is really neat sometimes. TH beta reduction in 13 lines ;) http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5546#a5546
00:27:25<sm>this is weird
00:27:35<dolio>sm: I'm not sure. Let me see...
00:27:40<FunctorSalad>(I'm sure there are some corner case bugs there)
00:28:37<FunctorSalad>(er, 13 short lines. otherwise it wouldn't be very remarkable)
00:29:26<dolio>What's it look like in uniplate?
00:29:34<sm>ah! I should have cleared the old .o files. Thanks dolio
00:29:54<dolio>Ah, yeah. That'll do it, if you're not using -fforce-recomp.
00:31:55<Botje>FunctorSalad: don't you want go (f x1) at the last line? :)
00:32:02<Botje>or at least go x1
00:33:34<FunctorSalad>Botje: right, thanks! apparently my example case needed only 1 or 2 passes ;)
00:34:44<FunctorSalad>Botje: hmm wait, the current version is correct, just inefficient
00:34:51<FunctorSalad>I wanted go x1
00:34:55<Botje>yeah, so go x1:)
00:40:09<sm>I see.. the .hpc dir containing mix files is generated at build time, and the tix file in the current dir at run time
00:44:38<sm>dolio: is -fforce-recomp still supported ? I don't find it at http://www.haskell.org/ghc/docs/latest/html/users_guide/flag-reference.html
00:44:49<dolio>As far as I know.
00:46:54<dolio>-fforce-recomp is 4.17.9
00:48:30<sm>doh! I am losing it
00:48:36<sm>and I was typing --force-recomp
00:48:42<sm>--fforce-recomp. thanks
00:51:23<FunctorSalad>sm: one dash only
00:51:35<sm>yup
00:53:14<dolio>Yeah, it's the -f option with force-recomp parameter, or something.
00:53:17<dolio>Is how you justify it.
00:53:26<dolio>Although ghc breaks that convention elsewhere.
00:53:53<fynn>Twey: btw, why did you make a point of mentioning Haskell isn't fast, earlier?
00:54:05<Twey>I didn't
00:54:10<Twey>In fact I specifically said it was fast
00:54:37<Twey>It's just not one of the fastest options available (yet)
00:54:46<Twey>(for most uses)
00:54:50<fynn>From benchmarks I've seen, it doesn't look like there's a lot of faster choices out there...
00:55:06<fynn>only C/++.
00:55:09<Twey>So if you need to squeeze the last possible drops of performance out of something, you'd probably be better off going with C
00:55:28<fynn>yeah... but that might be the only exception =)
00:55:35<fynn>btw, did you use Python with Cython?
00:55:38<Twey>Heh
00:55:45<Twey>Pardon?
00:56:03<Twey>Oh, a successor to Pyrex
00:56:14<fynn>there's a library called Cython, that compiles Python to efficient C (*Some limitations apply)
00:56:16<fynn>yeah...
00:56:16<Twey>No, I didn't know it existed. I've never done high-performance stuff in Python
00:56:31<fynn>you didn't use Pyrex either then, I take it
00:56:35<Twey>And I suspect I switched to Haskell before it came out :)
00:56:38<Twey>No, but I looked at it
00:56:56<fynn>Cython offers quite the speedup for a few type annotations.
00:57:02<ik>has anyone done high-performance stuff in python?
00:57:04<ik>ACTION runs
00:57:29<Twey>ik: Yeah, Ruby programmers!
00:57:35<ik>hahaha
00:57:43<fynn>for example, you can reliably get a x200-300 boost for integer calculations just by annotating a function as taking integers.
00:57:54<fynn>ik: well, with Cython (or plain C) you can
00:57:57<Twey>fynn: Impressive
00:58:18<ik>fynn: just a dig, I really haven't kept up with the state of python lately
00:58:46<fynn>yeah, I'm a bit surprised it didn't make serious headlines already
00:59:06<p_l>I heard of people doing scientific stuff, but not really HPC
00:59:26<fynn>thinking of a benchmark like the Shootout, you can basically bounce Python to the top of the table with an extra 4-5 lines of code in most cases.
01:00:05<FunctorSalad>how do I get the TH Name of an operator?
01:00:28<dolio>, '+
01:00:29<lunabot> luna: parse error on input `+'
01:00:37<dolio>, ''+
01:00:39<lunabot> luna: parse error on input `+'
01:01:24<FunctorSalad>, Prelude.'+
01:01:25<dolio>, '(+)
01:01:25<lunabot> luna: parse error on input `+'
01:01:26<lunabot> GHC.Num.+
01:01:34<FunctorSalad>hmm thought I tried that
01:01:52<FunctorSalad>, '(>>=)
01:01:53<lunabot> GHC.Base.>>=
01:02:04<FunctorSalad>doesn't work here...
01:02:25<dolio>Do you have -XTemplateHaskell enabled?
01:02:28<dolio>' and '' are magic.
01:02:35<FunctorSalad>yep
01:02:38<Twey>What's the difference between them?
01:02:44<FunctorSalad>'' is for types
01:02:44<Twey>, ''(+)
01:02:46<lunabot> luna: Not in scope: type variable `+'
01:02:46<Twey>Oh
01:03:51<dolio>I don't know. "main = print '(+)" works here.
01:04:28<Cale>, '(+)
01:04:29<lunabot> GHC.Num.+
01:04:57<FunctorSalad>hmm it works at the toplevel but not inside this expression I have :)
01:05:24<aconbere>so, this might be a dumb question. But a monad provides order to computation, is there a analog to map in the monadic world, the provides a sequence of computational steps as opposed to a list?
01:05:57<SamB>aconbere: mapM_ ?
01:06:38<Twey>sequence?
01:06:44<Twey>Oh, no
01:06:50<Twey>You do want mapM(_)
01:07:45<FunctorSalad>dolio: oh, figured it out. I can't put names into a pattern ;)
01:07:54<dolio>Oh, yeah.
01:13:40<duaneb>I have a list of Maybe Bool
01:13:40<duaneb>s
01:13:52<duaneb>any good way to use `all' with it?
01:14:03<roconnor>what do you want to do with the nothings?
01:14:09<roconnor>@type catMaybes
01:14:34<roconnor>@bot
01:14:34<lunabot> :)
01:15:00<duaneb>roconnor: return a nothing
01:15:13<duaneb>basically, I want
01:15:16<kpreid>@type all
01:15:22<kpreid>erf
01:15:27<roconnor>duaneb: so if there is one Nothing in the list you want to return Nothing?
01:15:30<duaneb>(a -> Maybe Bool) -> [a] -> Maybe Bool
01:15:42<kpreid>that's called sequence
01:15:42<duaneb>err
01:15:50<roconnor>duaneb: maybe you should give us some sample inputs and outputs
01:15:53<duaneb>(Maybe a -> Maybe Bool) -> [Maybe a] -> Maybe Bool
01:15:55<kpreid>wait, no, that's MapM
01:16:10<kpreid>Or, no it isn't
01:16:13<hatds>mplus
01:16:15<hatds>:)
01:16:20<kpreid>Do you really have a Maybe a -> Maybe Bool function?
01:16:31<duaneb>roconnor: all' [Just True, Just False, Just True] = Just True, all
01:16:33<duaneb>sorry
01:16:39<duaneb>err
01:16:40<kpreid>Anyway, you can use sequence :: [Maybe Bool] -> Maybe [Bool] for one step.
01:16:45<duaneb>that was meant to be Just False
01:16:50<duaneb>sequence?
01:16:50<duaneb>ok
01:16:52<hatds>looks like all . msum, perhaps duaneb?
01:16:57<kpreid>all' = and . sequence
01:17:02<duaneb>I don't know msum
01:17:05<duaneb>ACTION looks up msum
01:17:12<roconnor>kpreid: is right
01:17:14<duaneb>gah
01:17:17<duaneb>I hate hugs
01:17:20<kpreid>it's not msum, it's sequence
01:17:22<roconnor>although this is a bit of an odd function.
01:17:25<duaneb>ACTION hugs ghci
01:17:35<kpreid>with respect to success/failure, msum is "or" and sequence is "and"
01:17:38<dolio>, [$ty| and . sequence |]
01:17:40<lunabot> luna: Exception when trying to run compile-time code:
01:17:46<dolio>, [$ty| fmap and . sequence |]
01:17:48<lunabot> forall a . (Functor a, Monad a) => [] (a Bool) -> a Bool
01:18:27<kpreid>ah yeah. and has to be lifted into the maybe
01:18:33<roconnor>Prelude> :type fmap and . sequence
01:18:35<roconnor>fmap and . sequence :: (Monad m, Functor m) => [m Bool] -> m Bool
01:18:49<hatds>ah yea, not msum then :)
01:19:07<kpreid>it's interesting just how many different 'obvious' functions you can write on [Maybe Bool] -> Maybe Bool
01:19:41<kpreid>if Djinn worked on lists I'd ask it what it would do
01:21:00<roconnor>duaneb: you realize if you have one nothing in your list, you will end up with nothing.
01:22:24<Berengal>roconnor: Assuming Nothing = False in this context: isJust <*> fromJust
01:23:00<Berengal>(&&) <$> ...
01:23:47<Ferdirand>would it make sense to define Bool as Maybe () ?
01:24:17<hatds>usually it reads better to use an actual Bool
01:24:33<dolio>They're (roughly) isomorphic.
01:24:54<Berengal>Appart from bottoms
01:24:58<dolio>() = 1, Bool = 2, Maybe a = 1 + a, Maybe () = 1 + 1 = 2.
01:25:32<Ferdirand>and there's this annoying dissymetry of join
01:25:53<roconnor>Berengal: I'd expect he want catMaybes
01:26:04<roconnor>only he knows :)
01:26:08<Berengal>Bool = False | True | _|_, Maybe () = Nothing | Just () | _|_ | Just _|_
01:26:32<duaneb>I just rolled my own function :P
01:26:37<duaneb>it's less brain explosion
01:26:44<roconnor>aww
01:26:50<roconnor>you don't get to learn sequence
01:27:14<roconnor>sequence is awesome cause it does everything.
01:27:21<dolio>Yeah, but we ignore bottoms. :)
01:27:28<dolio>Because fast-and-loose reasoning is morally correct.
01:27:40<roconnor>, sequence [(+1), (*2), (`div` 3)] 6
01:27:42<lunabot> [7,12,2]
01:27:43<Absolute0>How can I enforce a monad type on a simple return x expression?
01:27:46<fynn>ACTION is slightly uneasy about the fact that he couldn't compile GHC on his own
01:27:56<Berengal>dolio: Usually I would agree with you, but I like bottoms :)
01:28:04<roconnor>, sequence [[1,2],[3,4],[5,6]]
01:28:05<lunabot> [[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]
01:28:07<Absolute0>return 5::Maybe fails
01:28:21<fynn>I'm fairly sure GHC doesn't build on *BSD without some serious hacks.
01:28:28<Absolute0>> (return 5)::Maybe
01:28:41<Berengal>Absolute0: Maybe isn't a type, it's a type constructor
01:28:46<Absolute0>> (return 5)::Maybe Int
01:28:52<Absolute0> > (return 5)::Maybe Int
01:28:55<Berengal>Also, lambdabot is dead...
01:29:01<Berengal>:(
01:29:02<Absolute0>ehh
01:29:02<Absolute0>:)
01:29:10<Absolute0>ok that works anyways
01:29:10<Absolute0>thanks
01:29:11<Absolute0>:)
01:29:30<Absolute0>what is the purpose of the >> operator it seems to simply return the second parameter
01:29:43<Berengal>Absolute0: It also runs the first
01:29:49<roconnor>, Nothing >> Just 5
01:29:51<lunabot> Nothing
01:29:58<duaneb>fynn: don't worry about it
01:30:03<duaneb>nobody actually builds ghc
01:30:04<roconnor>, "hello" >> "world"
01:30:05<lunabot> "worldworldworldworldworld"
01:30:06<Berengal>putStrLn "hello" >> doStuff
01:30:10<Absolute0>(>>) :: (Monad m) => m a -> m b -> m b
01:30:25<fynn>duaneb: well, we're considering the usage of GHC in production
01:30:30<fynn>so that's kind of scary.
01:30:33<roconnor>, Left "hello" >> Right "world"
01:30:35<lunabot> Left "hello"
01:30:45<roconnor>, Right "hello" >> Right "world"
01:30:47<lunabot> Right "world"
01:30:56<Absolute0>, Just 5 >> Just 6
01:30:57<lunabot> Just 6
01:31:08<Absolute0>that's the example i originally played with.
01:31:13<Absolute0>so there is a function in play...
01:31:16<Absolute0>what does it do?
01:31:26<roconnor>, Nothing >> Just 5
01:31:27<lunabot> Nothing
01:31:43<Berengal>a >> b = a >>= \_ -> b
01:31:46<sjanssen>fynn: production for you is BSD? Yeah, that platform gets less love from the GHC team
01:31:48<Berengal>That's the default
01:32:06<roconnor>Berengal: not only that any non-default needs to be equivalent to that
01:32:11<sjanssen>fynn: but I'm not so sure about "serious hacks"
01:32:37<Berengal>roconnor: Indeed
01:33:11<Absolute0>Why does Just "Hello" >> Just "World" print world 5 times? doesnt "hello" match with _ ?
01:33:34<Berengal>, Just "Hello" >> Just "World"
01:33:35<lunabot> Just "World"
01:33:45<roconnor>, [[x] | x <- "hello"]
01:33:46<lunabot> ["h","e","l","l","o"]
01:33:51<roconnor>, [[x,x] | x <- "hello"]
01:33:52<lunabot> ["hh","ee","ll","ll","oo"]
01:33:56<Absolute0>ah "hello" >> "world" sorry
01:34:01<roconnor>, [[x,x]++"world" | x <- "hello"]
01:34:02<lunabot> ["hhworld","eeworld","llworld","llworld","ooworld"]
01:34:02<Berengal>, ["world" | n <- "hello"]
01:34:04<lunabot> ["world","world","world","world","world"]
01:34:07<roconnor>, ["world" | x <- "hello"]
01:34:08<lunabot> ["world","world","world","world","world"]
01:34:12<roconnor>, ["world" | _ <- "hello"]
01:34:13<lunabot> ["world","world","world","world","world"]
01:34:20<Absolute0>oh right lists are monads..
01:34:25<roconnor>, "hello" >> "world"
01:34:26<lunabot> "worldworldworldworldworld"
01:35:00<fynn>sjanssen: we also develop on BSD/Macs, and yeah, some of our production boxen are FreeBSD
01:35:01<Berengal>Not only are lists monads, but they're weird monads
01:35:12<Berengal>I'd say weirder even than reader
01:35:15<Absolute0>roconnor: why does [[x] | x <- "hello"] get evaluated by the >>?
01:35:43<Absolute0>recursive sequencing?
01:35:49<Ferdirand>Berengal, why is that ?
01:36:01<roconnor>, "hello" >>= (\x -> [x,x])
01:36:02<lunabot> "hheelllloo"
01:36:06<fynn>sjanssen: I've looked at the portfile for GHC... definitely more special case logic than for most other ports.
01:36:09<roconnor>, "hello" >>= (\x -> [x,x]++"world")
01:36:11<lunabot> "hhworldeeworldllworldllworldooworld"
01:36:15<Berengal>Ferdirand: Because of concatMap
01:36:16<roconnor>, "hello" >>= (\x -> "world")
01:36:17<lunabot> "worldworldworldworldworld"
01:36:21<roconnor>, "hello" >>= (\_ -> "world")
01:36:22<lunabot> "worldworldworldworldworld"
01:36:27<roconnor>, "hello" >> "world"
01:36:29<lunabot> "worldworldworldworldworld"
01:37:01<Absolute0>[x,x]++"world" ??
01:37:12<Berengal>, filterM (const [True, False]) [1,2,3]
01:37:14<lunabot> [[1,2,3],[1,2],[1,3],[1],[2,3],[2],[3],[]]
01:37:34<Ferdirand>ah yes, this one is amazing
01:37:39<roconnor>Absolute0: "hello" >>= \x -> foo x takes each character of "hello" and runs foo on that character and concats the results.
01:37:55<roconnor>, "hello" >>= (\x -> [x,x])
01:37:56<lunabot> "hheelllloo"
01:38:16<Berengal>Absolute0: Are you familiar with Prolog?
01:38:21<roconnor>in this example foo x takes the character and makes a string with each character twice.
01:38:25<Absolute0>Berengal: barely
01:38:47<Berengal>Absolute0: Well, consider what the list monad looks like in do notation, and compare that with prolog
01:38:58<roconnor>, "hello" >>= (\x -> "("++[x,x]++")")
01:38:59<Absolute0>Isnt "hello" similar to Just "hello" ?
01:38:59<lunabot> "(hh)(ee)(ll)(ll)(oo)"
01:39:16<roconnor>now we are putting parens around each [x,x]
01:39:24<roconnor>(remembering that strings are the same as lists of characters)
01:39:47<Absolute0>roconnor: thanks you've made it very clear :)
01:39:58<Absolute0>nice animation by the way!
01:40:14<roconnor>, "hello" >>= (\x -> "("++")")
01:40:15<lunabot> "()()()()()"
01:40:24<roconnor>now we are leaving out the pairs of characters entirely
01:40:29<roconnor>, "hello" >>= (\x -> "()")
01:40:30<lunabot> "()()()()()"
01:40:32<roconnor>same thing
01:40:37<roconnor>, "hello" >>= (\_ -> "()")
01:40:39<lunabot> "()()()()()"
01:40:40<roconnor>same thing
01:40:46<roconnor>, "hello" >> "()"
01:40:47<lunabot> "()()()()()"
01:40:50<roconnor>same thing again.
01:40:59<Absolute0>yup
01:41:09<aavogt>@src [] >>=
01:41:19<roconnor>one "()" for each character
01:41:34<roconnor>, "hello out there" >> "()"
01:41:35<lunabot> "()()()()()()()()()()()()()()()"
01:41:37<Absolute0>>>= seems like a fancy fmap chaining...
01:41:41<roconnor>, "h" >> "()"
01:41:42<lunabot> "()"
01:41:44<Absolute0>correct to think so?
01:41:45<roconnor>, "" >> "()"
01:41:46<lunabot> ""
01:42:00<roconnor>Absolute0: >>= is the same as concatMap
01:42:02<roconnor>for lists
01:42:20<roconnor>well, flip concatMap
01:42:22<Absolute0>ACTION looks up concatMap
01:42:29<aavogt>Cale: is lambdabot coming back soon?
01:42:44<roconnor>concatMap f x = concat (map f x)
01:42:54<Berengal>ACTION must admitt he sometimes uses >>= where concatMap would've been clearer
01:43:44<Ferdirand>btw, are there other clever use examples of filterM beyond the nice powerset trick ?
01:43:55<Apocalisp>You're better off if you ever want to replace [] with another monad :)
01:44:05<roconnor>Ferdirand: nope. :P
01:44:47<Berengal>Project Euler solution: p17 = length $ [1..1000] >>= showNumAsWord
01:45:00<Absolute0>concatMap (\x -> [x+1]) [1,2,3].. when would concatMap be useful?
01:45:17<Absolute0>project euler is cool :-P
01:45:30<Ferdirand>rconner: we were discussing that last week on .fr. The only vaguely interesting trick was interactive filtering by the user in IO
01:45:55<Axman6>> concatMap (\x -> if even x then "EVEN" else "") [1..10]
01:45:58<roconnor>, let x = 1:(concatMap (\a -> [a+1,1/(a+1)]) x) in x
01:45:59<lunabot> [1.0,2.0,0.5,3.0,0.3333333333333333,1.5,0.6666666666666666,4.0,0.25,1.333...
01:46:01<Axman6>rawr
01:46:06<Axman6>, concatMap (\x -> if even x then "EVEN" else "") [1..10]
01:46:07<roconnor>, let x = 1:(concatMap (\a -> [a+1,1/(a+1)]) x) in x::[Rational]
01:46:08<lunabot> "EVENEVENEVENEVENEVEN"
01:46:08<lunabot> [1 % 1,2 % 1,1 % 2,3 % 1,1 % 3,3 % 2,2 % 3,4 % 1,1 % 4,4 % 3,3 % 4,5 % 2,...
01:47:36<Absolute0>[1,2,3] >>= (\x -> [x + 1]) is much clearer than concatMap :P
01:47:43<roconnor>Ferdirand: oh neat. I can see it being used with the reader monad too.
01:48:06<Axman6>map
01:48:10<aavogt>Absolute0: but map (+1) is better
01:48:14<Axman6>map (+1) is eve clearer
01:48:15<Axman6>bah
01:48:19<Absolute0>yeah
01:48:25<roconnor>Absolute0: genreally you wouldn't use concatMap or >>= for a function of the form (\x -> return (foo x)), since that is just the same as map foo
01:48:27<Absolute0>i was referring to a previous comment
01:48:52<Absolute0>[21:42] * Berengal must admitt he sometimes uses >>= where concatMap would've been clearer
01:49:13<roconnor>, let x = 1:(x >>= (\a -> [a+1,1/(a+1)])) in x::[Rational]
01:49:15<lunabot> [1 % 1,2 % 1,1 % 2,3 % 1,1 % 3,3 % 2,2 % 3,4 % 1,1 % 4,4 % 3,3 % 4,5 % 2,...
01:50:09<Absolute0>x should go on a diet
01:50:13<Absolute0>its getting very fat
01:50:15<Absolute0>:(
01:50:15<duaneb>is there a readline module for haskell?
01:50:23<gwern>haskeline
01:50:24<Axman6>sure
01:50:29<Axman6>and readline
01:50:40<Axman6>ghci uses(/used) readline
01:50:44<duaneb>or editline or whatever
01:50:45<duaneb>haskeline
01:50:46<duaneb>ok
01:50:48<aavogt>and editline (libedit?)
01:50:55<Axman6>yeah
01:51:07<Axman6>there's at least three choices
01:51:16<Berengal>Gotta catch 'em all
01:53:36<duaneb>ahh
01:53:37<duaneb>I love haskell
01:53:43<duaneb>even if it does make me think too much
01:54:00<gwern>http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5548#a5548 <-- any thoughts on my code?
01:54:08<Axman6>programming is supposed to make you think. if you're not thinking, you're doing it wrong
01:54:28<Twey>He's right you know.
01:54:31<Absolute0>[1,2,3,4,5,6,7,8,9] >>= (\x -> if even x then "EVEN" else "ODD")
01:54:31<Absolute0>"ODDEVENODDEVENODDEVENODDEVENODD"
01:54:33<duaneb>Axman6: I know
01:54:36<Absolute0>thats very useful!
01:54:39<duaneb>I was saying it in an ironical sense
01:54:40<Absolute0>don't know why
01:54:41<Absolute0>:)
01:54:44<Twey>If you're not thinking then your job will shortly be replaced by a small plastic box with flashing lights
01:55:21<FunctorSalad>hmm I think programming tools *are* supposed to decrease the amount of routine thinking needed
01:55:21<Ferdirand>that applies to an horribly broad set of jobs
01:55:25<Absolute0>Twey: that's inevitable no matter how smart you are.
01:55:28<Twey>@let (y ?? n) p = if p then y else n
01:55:38<FunctorSalad>so we have more time for the mind-expanding stuff ;)
01:56:09<Berengal>I want one of those "go away, or I will replace you with a small <foo>" t-shirts, where foo is either "shell script" or "lambda expression"
01:56:10<Absolute0>fmap ceasarSaladNow! FunctorSalad :-P
01:56:14<Twey>> map (("EVEN" ?? "ODD") . even) [1..9]
01:56:29<Twey>Oh, yeah, lambdabot's not back yet?
01:56:57<Absolute0>where is ?? defined?
01:57:18<Twey>I just defined it
01:57:23<Twey>Well, I didn't
01:57:24<Absolute0>oh
01:57:25<inimino>4 lines up
01:57:26<Absolute0>missed that
01:57:27<Berengal>Twey: @let (y ?? n) p = if p then y else n
01:57:28<Absolute0>:)
01:57:29<Twey>Because there's no lambdabot
01:57:34<Twey>But I *would* have defined it
01:57:45<inimino>if a definition falls in the forest...
01:57:46<Twey>It's also in chrisdone's HigherOrder library
01:57:47<duaneb>ahh, cabal
01:57:49<Twey>inimino: *grin*
01:57:49<duaneb>I hate thee
01:57:58<duaneb>and thy ignorance of my config file
01:58:03<Berengal>If Twey defines, but no bot is around to bind it, is it really defined?
01:58:04<Absolute0>Twey: ternary operato?
01:58:14<Absolute0>p should go first
01:58:16<jimmyjazz14>quick question, is there a way to pattern match against a constructor using with out using all of its arguments
01:58:26<Berengal>What is the sound of a single client chatting?
01:58:28<Twey>Absolute0: No it shouldn't
01:58:30<Absolute0>jimmyjazz14: case of
01:58:35<Twey>That's if'
01:58:39<Twey>But if' is pointless
01:58:45<Twey>Nobody wants to curry on the no-branch
01:58:56<Peaker>woohoo! fixed lui's Image abstraction and thus scroll widget
01:58:58<Twey>The most common case is to curry on the predicate
01:59:06<Absolute0>Twey: well you expression is not consistent with the evaluation..
01:59:11<jimmyjazz14>hm
01:59:17<Twey>Absolute0: What do you mean?
01:59:20<Peaker>maybe I'm on a roll again :) (Takes staying up to 5 am though, with full-time job :( )
01:59:24<Berengal>Twey: I like to call the predicate-last function fi...
01:59:44<Absolute0>p is last -> (y ?? n) p p is first -> if p then y else n
02:00:16<Berengal>Absolute0: Why should the rhs matter when defining argument order?
02:00:31<Absolute0>just not consistent goddamnit
02:00:43<Twey>Absolute0: That's deliberate — if does not have a useful order
02:00:45<Absolute0>haskell is making you people too lazy
02:00:54<Twey>That's kind of the whole point of defining it in the first place
02:01:12<Twey>(rather than if' p y n = if p then y else n)
02:01:46<Absolute0>whats the use of ??
02:02:00<Absolute0>if you have if'
02:02:12<Ferdirand>partial application
02:02:20<Berengal>I like if' for its applicative though: if' <$> pred <*> true <*> false; if' <$> even <*> flip div 2 <*> (+1).(*3)
02:02:54<Absolute0>ooh look at the spaceships zoom
02:02:55<Absolute0>:)
02:03:14<Twey>Absolute0: Its arguments are in a sane order
02:03:32<Absolute0>sane shmane
02:04:07<Twey>map ("EVEN" ?? "ODD") is so much nicer than map (flip (flip if' "EVEN") "ODD")
02:05:06<SamB>@pl map (flip (flip if' "EVEN") "ODD")
02:05:27<Berengal>SamB: That's pretty pointless as it is
02:05:31<SamB>@pointless map (flip (flip if' "EVEN") "ODD")
02:05:37<Berengal>Also, lambdabot is dead
02:05:44<SamB>yeah, looks like
02:05:48<SamB>:-(
02:05:52<Absolute0>the question marks do nicely emphasis the question :)
02:06:01<Twey>SamB: It's already pointless
02:06:08<Absolute0>sort of shakespeare like :)
02:06:09<SamB>I realize it's pointleess
02:06:21<Twey>So @pl wouldn't do anything
02:06:23<SamB>but @pl can optimize already-pointless expressions too ...
02:06:30<Twey>Huh, truly?
02:06:36<SamB>to a certain extent
02:06:41<SamB>for some value of optimize
02:08:05<mmorrow>, [$pl| \a b -> g (f a b) |]
02:08:08<lunabot> (g .) . f
02:08:37<Twey>, [$pl| \x -> if' x "EVEN" "ODD" |]
02:08:39<lunabot> flip (flip if' "EVEN") "ODD"
02:08:42<Twey>There you go.
02:09:03<mmorrow>, [$bf| .+[.+] |]
02:09:05<lunabot> luna: No instance for (GHC.Show.Show
02:09:08<mmorrow>, [$bf| .+[.+] |] ""
02:09:09<lunabot> "\NUL\SOH\STX\ETX\EOT\ENQ\ACK\a\b\t\n\v\f\r\SO\SI\DLE\DC1\DC2\DC3\DC4\NAK...
02:09:26<FunctorSalad>ACK
02:10:04<Twey>Haha
02:10:39<Peaker>what does 400 error in upload mean, when trying "cabal upload .."? The package is already there?
02:10:42<Berengal>, map ord ([$bf| .+[.+] |] "")
02:10:43<SamB>> if' True 1 2
02:10:43<lunabot> [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,2...
02:10:48<SamB>, if' True 1 2
02:10:49<lunabot> luna: Not in scope: `if''
02:11:10<SamB>,let if' c x y = if c then x else y
02:11:12<lunabot> luna: parse error on input `)'
02:11:15<Peaker>hmm -- supposedly bad HTTP request, so maybe "cabal upload" is broken?
02:11:21<mmorrow>, [$pl| \a b -> take 4 (zip a b) |] $ [$bf| .+[.+] |] ""
02:11:23<lunabot> luna: Couldn't match expected type `a -> b'
02:11:28<SamB>lunabot: let if' c x y = if c then x else y
02:11:39<mmorrow>, [$pl| \a -> take 4 (zip a a) |] $ [$bf| .+[.+] |] ""
02:11:42<lunabot> luna: Couldn't match expected type `a -> b'
02:11:44<SamB>, if' True 1 2
02:11:45<lunabot> luna: Not in scope: `if''
02:11:51<SamB>lunabot: !let if' c x y = if c then x else y
02:11:53<Absolute0>doesn't all that punctuations cause eye sore?
02:12:08<mmorrow>lunabot doesn't have @let unfortunately
02:12:16<Absolute0>haskell is big on punctuation.
02:12:17<Berengal>Absolute0: Only if you read it, not when you write it
02:12:34<Absolute0>i like the longMethodNames from Java :)
02:12:35<Peaker>aha, 400 errors are used to complain about your .cabal file
02:12:39<Absolute0>very pleasant to read.
02:12:41<Berengal>So it's good to write as much of it as possible, to minimize the time you spend reading them instead
02:12:56<mmorrow>Absolute0: :o
02:13:40<Berengal>longMethodNames in haskell don't like it here and tend to march off somewhere, usually to the right...
02:13:41<Absolute0>Berengal: where are <$> <*> defined, they're not in Control.Monad
02:13:48<Berengal>Absolute0: Control.Applicative
02:13:51<Absolute0>ah thanks
02:14:28<mmorrow>, [$ty| [$pl| \a -> take 4 (zip a a) \|] |]
02:14:30<lunabot> Doc
02:14:38<mmorrow>oh no wonder
02:14:51<mmorrow>, 'plQ
02:14:52<lunabot> luna: Not in scope: `plQ'
02:15:10<mmorrow>, parseExp . render $ [$pl| \a -> take 4 (zip a a) |]
02:15:13<lunabot> Right (InfixE (Just (AppE (VarE take) (LitE (IntegerL 4)))) (VarE .) (Jus...
02:15:25<mmorrow>, $(either undefined . id . parseExp . render $ [$pl| \a -> take 4 (zip a a) |])
02:15:27<lunabot> luna: Couldn't match expected type `b -> c'
02:15:38<mmorrow>, $(either undefined return . parseExp . render $ [$pl| \a -> take 4 (zip a a) |])
02:15:40<lunabot> luna: No instance for (GHC.Show.Show ([a] -> [(a, a)]))
02:15:54<mmorrow>, $(either undefined return . parseExp . render $ [$pl| \a -> take 4 (zip a a) |]) $ $ [$bf| .+[.+] |] ""
02:15:55<lunabot> luna: parse error on input `$'
02:15:59<mmorrow>, $(either undefined return . parseExp . render $ [$pl| \a -> take 4 (zip a a) |]) $ [$bf| .+[.+] |] ""
02:16:01<lunabot> [('\NUL','\NUL'),('\SOH','\SOH'),('\STX','\STX'),('\ETX','\ETX')]
02:16:03<mmorrow>woo
02:17:11<Absolute0> (+1) <$> (+1) <$> Just 5 :)
02:17:13<Absolute0>fun stuff
02:17:27<Absolute0>for functors created before monads?
02:17:34<Absolute0>they seem to be essentially the same
02:17:48<mmorrow>join is the difference
02:17:53<Ferdirand>join and return
02:18:05<Berengal>Ferdirand: Applicatives have return, called pure
02:18:34<Ferdirand>ah, not reading enough lines, sorry :)
02:18:41<mmorrow>, join [[0..3],[4..8]]
02:18:42<lunabot> [0,1,2,3,4,5,6,7,8]
02:18:48<mmorrow>, join (Just Nothing)
02:18:49<lunabot> Nothing
02:19:06<Peaker>, join $ Just (Just 5)
02:19:07<lunabot> Just 5
02:19:42<Absolute0>data SimplyMaybe a =
02:19:50<Absolute0>data SimplyMaybe a = Simply a | Nothing
02:19:53<Absolute0>thats much better
02:20:12<Absolute0>i can practice monads on that
02:20:13<Peaker>Absolute0: in Functor, you cannot get rid of double-wrapped values, and in Monad you can. This disallows you from using contents of functors to get new functor values, but allows it in monad
02:20:17<Absolute0>as Maybe is already defined
02:20:28<Peaker>Absolute0: Nothing is a taken name :)
02:20:35<Absolute0>SimplyNothing
02:22:03<Peaker>cool, uploaded my new LUI to hackage. The widget set finally makes progress :-)
02:22:28<roconnor>LUI?
02:22:30<Absolute0>Lui is a French adult entertainment magazine created in November 1963 by Daniel Filipacchi, a fashion photographer turned publisher.
02:22:37<Peaker>roconnor: A purely functional widget set
02:22:41<Absolute0>yeah what is LUI??
02:22:51<hermanChess>what does it means that haskell has its roots on academia??
02:22:53<Peaker>roconnor: currently draws via haskgame (a simple incomplete SDL wrapper)
02:23:23<Peaker>roconnor: the software design of the widgets is innovative too, I'd like to believe :-)
02:23:44<Absolute0>hows is haskell GUI coding compared to OOP languages?
02:23:46<Peaker>(The way I do focus management, and widget composition, I think is new)
02:23:54<roconnor>Absolute0: awful
02:24:00<Peaker>or awesome
02:24:04<Absolute0>GUI's seem to be very object oriented :)
02:24:08<Peaker>There are many GUI paradigms
02:24:15<roconnor>Absolute0: awful until 5 minutes ago
02:24:22<Absolute0>:)
02:24:25<Peaker>heh, LUI isn't ready for real work yet
02:24:30<Peaker>but Phooey might be
02:24:38<Absolute0>Peaker: got any screenshots?
02:24:39<Peaker>and is already cooler than OO GUI's :)
02:24:58<Peaker>Absolute0: interesting idea -- though there's an example you can just run if you "cabal install lui"
02:25:24<hermanChess>what does an academic language is?
02:25:43<Absolute0>only used in courses?
02:26:52<hermanChess>hmm
02:27:06<Axman6>hermanChess: it's very actively developed by people working at universities, and they do a lot fo research with it
02:27:30<hermanChess>ahh I see
02:27:53<Axman6>it does not mean it has no real world use, nor does it mean that it's slow ;)
02:29:46<Peaker>Absolute0: can you cabal install lui and run the example therein?
02:30:00<Absolute0>Peaker: haven't tried
02:30:10<Absolute0>let me check if i have cabal
02:30:13<Absolute0>i am on archlinux
02:30:30<Absolute0>runhaskell == cabal?
02:30:38<Axman6>no
02:30:46<Absolute0>runhaskell Setup.hs == cabal?
02:30:55<Axman6>sort of...
02:30:56<Absolute0>community/cabal-install == cabal :)
02:31:05<Axman6>yes ;)
02:32:47<Peaker>btw, my UI toolkit is not very similar to Gtk/Qt in either API nor look&feel. I think they were both horrible
02:33:10<Absolute0>Peaker: whats the command to build?
02:33:17<Peaker>Absolute0: cabal install lui
02:33:27<Absolute0>under root?
02:33:31<Peaker>anywhere
02:33:33<Axman6>Peaker: how do you run the demo?
02:33:36<Peaker>though it won't build the example
02:33:44<Peaker>Axman6: You have to unpack the tarball, and compile the Example therein
02:33:45<Axman6>oh
02:33:49<Axman6>ah
02:33:51<Peaker>sorry about that, not sure how to make it better
02:34:05<Peaker>I don't want to install an executable. Maybe I can make the example a separate package, but its kind of useless
02:36:28<Absolute0>Peaker: i ran cabal install lui as regular user
02:36:31<Axman6>http://haskell.org/haskellwiki/LUI :(
02:36:39<Absolute0>where would the example reside?
02:36:53<Peaker>Absolute0: ~/.cabal/packages/*/lui/--tarball here--
02:36:58<Peaker>Axman6: editing this now
02:37:02<Axman6>:)
02:37:44<Axman6>ACTION finally upgrades to 6.10.3
02:37:56<Absolute0>Peaker: http://pastie.org/499924
02:38:21<Absolute0>haskgame-0.0.5 depends on SDL-ttf-0.5.5 which failed to install.
02:38:21<Absolute0>lui-0.0.4 depends on SDL-ttf-0.5.5 which failed to install.
02:38:37<Absolute0>configure: error: *** SDL_ttf lib not found! Get SDL_ttf from
02:38:37<Absolute0>http://www.libsdl.org/projects/SDL_ttf/index.html
02:38:46<Absolute0>let me do that
02:40:16<Peaker>Axman6: http://haskell.org/haskellwiki/LUI -- so far
02:40:30<Axman6>dang, just refreshed and missed it :P
02:49:35<Peaker>Absolute0: got it?
02:54:00<Peaker>Axman6: yet more updates: http://haskell.org/haskellwiki/LUI
02:54:17<Axman6>hoorah
02:56:10<goldenpuffs>is there a way to put a bunch of data types into another data type?
02:56:32<araujo>Peaker, interesting
02:56:39<araujo>Peaker, any web site yet?
02:56:45<Peaker>araujo: just that wiki
02:57:02<araujo>I like the name btw
02:57:03<araujo>hah
02:57:21<mmorrow>goldenpuffs: you mean without defining a new one?
02:57:56<mmorrow>data Foo a b c = Foo (Map a b) (Tree c) | Boo (Set (Foo a b c))
02:58:04<goldenpuffs>mmorrow: I am looking for a way to bundle some datatypes so that I can address all of them
02:58:24<mmorrow>goldenpuffs: what do you mean by "address"?
02:58:40<Peaker>araujo: thanks :)
02:59:17<araujo>Peaker, I am very interested on haskell gui stuff
02:59:18<Peaker>araujo: the name originated from the fact we were supposed to be 3 guys working on it, my name starts with L, another guy's with S, and if it were called LUIS with both our names, it spells the 3rd guy's name :)
02:59:24<araujo>Peaker, do you have any example up?
02:59:40<Peaker>araujo: yeah there's an example inside lui itself -- can you cabal install it?
02:59:50<Peaker>araujo: it requires SDL/SDL--tf
02:59:52<araujo>Peaker, hah, my name is that one
02:59:54<Peaker>SDL-ttf
03:00:04<mmorrow>goldenpuffs: if i'm guessing right, maybe you're looking to do something like:
03:00:05<Peaker>you're luis? :)
03:00:10<araujo>Peaker, hah yeah
03:00:23<araujo>Peaker, ok, I will give it a try
03:00:26<mmorrow>say you have types A a, B a b, C a b c, then you can do:
03:00:42<Peaker>araujo: are you interested in the way the example renders like, or the code looks like?
03:01:04<mmorrow>data D a b c d e f = One (A a) | Two (B b c) | Three (C d e f)
03:01:05<araujo>Peaker, the project itself
03:01:29<mmorrow>goldenpuffs: so kinda similar to a C union
03:01:41<araujo>Peaker, I work with gtk2hs for graphical development mainly , and it is always nice to see other toolkit around
03:02:55<Peaker>araujo: cool
03:03:12<goldenpuffs>mmorrow: I'm trying to get it straight in my head what I'm trying to do;), so I have data A, data B, data C and I want an arbitrary number of A, B,C to be part of some other datatype
03:03:43<timmaxw>goldenpuffs: so maybe data X = X [A] [B] [C]
03:03:54<timmaxw>goldenpuffs: is that what you want?
03:04:04<mmorrow>goldenpuffs: so i guess the question is, what do you want the structure of this other datatype to be?
03:04:59<goldenpuffs>mmorrow: yes, i think that is what i'm looking for
03:05:08<mmorrow>data Foo = Foo (Map A (Map B C)) ..... data Foo = One A | Two B | Three C; type Baz = [Foo], ..
03:05:19<Peaker>araujo: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5549#a5549 -- Here's the example, need to clean it more
03:05:28<Peaker>araujo: you know how examples tend to be more tests than examples :)
03:05:29<mmorrow>goldenpuffs: you mean timmaxw's X type?
03:05:45<Peaker>araujo: I have a little problem with Haskell record fields being getters rather than accessors :-(
03:06:04<mmorrow>type Foo = ([A],[B],[C])
03:06:11<mmorrow>(so many options :)
03:06:26<goldenpuffs>oh I see, I was confusing value constructors and values I think
03:06:59<goldenpuffs>data X = X [A] [B] [C] is what I'm looking for I believe
03:07:06<mmorrow>nice
03:07:12<goldenpuffs>thanks a bunch
03:07:14<Peaker>araujo: there's the thing here that you define the model separately from the view. Gtk/etc usually have a stateful model inside each widget -- here the widget gets an accessor to a model to edit
03:07:22<mmorrow>goldenpuffs: np
03:07:33<Peaker>araujo: It may seem a little less convenient, I am not sure, as I haven't yet used it for anything real...
03:10:19<araujo>nic Peaker
03:10:26<araujo>Peaker, it looks very nice code :)
03:11:05<Peaker>araujo: thanks :)
03:11:23<araujo>Peaker, I notice that part, the way you separate the model from the view
03:11:51<Peaker>araujo: if Haskell records didn't suck and used accessors, I wouldn't have to build accessors to each part of my model manually :(
03:12:17<Peaker>note the duplication of: avboxModel = accessor vboxModel (\new x -> x{vboxModel=new}) -- et al
03:12:54<Peaker>also, maybe it could be nice if type-inference built the record on its own
03:13:03<araujo>Peaker, yeah, i see it
03:13:03<Peaker>by seeing which fields and field types it had
03:13:43<Peaker>I could compose models anonymously and then no need for all that
03:14:47<Peaker>araujo: can you run it?
03:15:02<Peaker>I think its a nice riddle to figure out exactly what it does -- it is meant to test a bunch of things :)
03:15:37<araujo>Peaker, ok, i will get it installed first in a minute
03:15:38<araujo>:)
03:15:48<araujo>seems very nice code
03:16:20<Peaker>:)
03:17:18<aavogt>Peaker: you've seen data-accessor-template?
03:17:34<aavogt>or template haskell in general
03:17:48<Peaker>aavogt: nope, and yeah
03:19:21<Peaker>aavogt: oh cool, *exactly* what I need, except data-accessor didn't really compile with my code, maybe I'll try again
03:20:07<Nereid>@pl \a (b,_) -> c a b
03:20:28<Nereid>oh, it's gone
03:21:10<aavogt>(c .) . snd -- maybe?
03:21:47<aavogt>, ((,) .) . snd $ 1 (2,3)
03:21:48<lunabot> luna: No instance for (GHC.Show.Show (a -> b1 -> (b, b1)))
03:22:10<goldenpuffs>mmorrow:hi, I'm goldenpuffs' teammate, in charge of that Object business. So basically I have a type class called Surface (similar to an interface in Java I believe) that defines methods like intersect, computeNormal, etc... Then I have different shapes (data types) called Sphere, Plane, etc. I defined instances of Surface for those datatypes, bu I'd like to have a "superclass" called Shape that includes all of these, with several c
03:22:10<goldenpuffs>onstructors. This way I can have a list of shapes, and when I map a method like intersect on the list, it calls the right definition of intersect on depending on the type of shape. Do you get what I mean ?
03:22:32<aavogt>, flip (((,) .) . snd) $ 1 (2,3)
03:22:33<lunabot> luna: No instance for (GHC.Show.Show ((a1, a -> b) -> b1 -> (b, b1)))
03:22:44<timmaxw>goldenpuffs: try using existential types.
03:22:44<mmorrow>ACTION reads
03:23:10<timmaxw>something like: data AnyShape = forall a. (Shape a) => a
03:23:32<timmaxw>oops, data Shape = forall a. (Surface a) => a
03:23:44<timmaxw>no wait, data Shape = forall a. (Surface a) => Shape a
03:23:52<aavogt>, flip ((+) . snd) $ 1 (2,3)
03:23:53<lunabot> luna: No instance for (GHC.Show.Show ((a, b) -> b))
03:23:57<timmaxw>i think that's what you want
03:24:07<timmaxw>but read up on existential types
03:24:51<goldenpuffs>timmaxw:thx, I'll do that. the "forall a." has to do with existential types then?
03:24:54<aavogt>, flip (((,) .) . snd) 1 $ (2,3)
03:24:55<lunabot> luna: No instance for (GHC.Show.Show (b1 -> (b, b1)))
03:24:58<timmaxw>goldenpuffs: yes.
03:25:35<aavogt>ACTION gah, I'm no match for @pl :)
03:26:06<Peaker>@pl could make much prettier stuff if it used arrow combinators
03:26:27<hatds>speaking of - am I the only one suspect of using existentials?
03:26:39<BMeph>Peaker: ...and 'on', for that matter. :)
03:26:48<Peaker>yeah
03:27:36<mmorrow>goldenpuffs: ok, so one thing you might want to do is to intersect a Sphere and a Plane, correct?
03:27:53<aavogt>and those unknown pointfree combinators on hackage
03:28:27<mmorrow>goldenpuffs: because that setup, as-is, can't handle that. it can only handle intersecting two of the same type
03:29:27<mmorrow>goldenpuffs: so my first thought is that you'll need some way to separate from an arbitrary shape the information you'll need to do the ops in Surface
03:29:44<timmaxw>i think each pair of shapes would have to be hand-coded
03:30:14<timmaxw>the simplest solution might be data Shape = Sphere Sphere | Plane Plane | Line Line | ...
03:30:15<Nereid>well if f a (b,_) = c a b, then f a = c a . fst, but I don't know where to go from there
03:30:34<timmaxw>and intersect :: Shape -> Shape -> Bool (or whatever return type you want)
03:30:36<Nereid>ACTION is new
03:30:40<mmorrow>maybe include in the Surface class a (getConvexHull :: a -> TriangularMesh) (s/TriangularMesh/whatever)
03:30:54<aavogt>lunabot: help
03:30:56<hatds>sometimes creating a list of functions is better than creating a list of objects. If you have some top level array which maps "draw" over all your shape objects you could instead create an array of draw functions
03:30:59<mmorrow>, help
03:31:01<lunabot> type of an expression: , [$ty| \x -> x |]
03:31:01<lunabot> get info for a type/class: , src ''Monad
03:31:01<lunabot> get info for a var/con: , src 'fix
03:31:30<aavogt>, [$ty| (+) . fst]
03:31:30<lunabot> luna: lexical error in string/character literal at end of input
03:31:45<mmorrow> [$qq-name| ... |]
03:31:56<goldenpuffs>mmorrow: no intersections other than between a ray and an object so far, but maybe later
03:32:17<timmaxw>goldenpuffs: then you can go with the existential type solution for now
03:32:36<mmorrow>, [$ty| (+) . fst |]
03:32:38<lunabot> forall a b . Num b => (b, a) -> b -> b
03:32:57<hatds>imho I would avoid existenstials until I was convinced I needed them
03:33:12<mmorrow>data Shape = forall a. (Surface a) => Shape a
03:33:28<hatds>I think the data solution works fine, if you hide the constructors for data Shape then it is just as good as an existential
03:33:56<goldenpuffs>alright, the existential types seem exactly right, so I'll go with that, thanks again
03:34:09<mmorrow>hatds: but you need to modify the Shape type and every function that pattern matches on its cons with that way
03:34:18<mmorrow>(when you add a shape)
03:34:43<hatds>mmorrow: right, a data type would only work if you could keep it abstract
03:34:58<timmaxw>mmorrow: that might not be that hard.
03:35:09<timmaxw>what's considered bad about existentials, by the way?
03:35:11<mmorrow>yeah, it depends on the type
03:35:31<mmorrow>(say the type has 40 constructors that all intermesh with each other..)
03:35:50<mmorrow>that become a huge pita to add cons
03:36:19<timmaxw>mmorrow: remember that pattern matches dont have to be exhaustive
03:36:36<mmorrow>timmaxw: heh
03:36:44<Nereid>aha
03:36:48<Nereid>f = flip (.) fst . c
03:36:57<hatds>I'm with timmaxw here
03:37:07<hatds>I'd go with the naive algebraic type first
03:37:08<timmaxw>mmorrow: you can put off defining "intersect (ParabolicHyperboloid ...) r" until later
03:37:23<Nereid>, (flip (.) fst . (+)) 5 (6,7)
03:37:24<lunabot> 11
03:37:29<mmorrow>oh, we're debating goldenpuff's solution in particular here?
03:37:41<wli>You're intersecting quadrics?
03:37:43<mmorrow>hmm, yeah personally i'd use the ADT solution too
03:37:47<Nereid>aavogt: :)
03:37:59<goldenpuffs>wli: quadrics with rays, yes
03:37:59<timmaxw>wli: that was an example of a type that might hypothetically be added if there were 40 type constructors.
03:38:11<aavogt>, ((.fst) . (+)) 1 (2,3)
03:38:12<lunabot> 3
03:38:18<Nereid>that too
03:38:38<mmorrow>data Shape = Sphere ... | Cone .... | Plane .. | TriangularMesh ... | ParametricSurface ... |
03:38:40<wli>x^t A_k x + b_k^t x + c = 0 for 0 < k <= n?
03:39:01<wli>Oh dear, that can get real ugly real quick.
03:39:02<hatds>I'm skeptical of how often people really need to overload a function on 40 types
03:39:31<wli>3D quadrics only?
03:39:31<mmorrow>hatds: (>>=) ?
03:39:40<goldenpuffs>mmorrow: but when I do that, I can't use Sphere etc in the type class wich defines intersect and normal, right?
03:40:07<aavogt>define a hierarchy of typeclasses
03:40:09<timmaxw>goldenpuffs: no. if you define it as an algebraic type like in your last suggestion, then you have to do everything using pattern matching
03:40:09<mmorrow>goldenpuffs: with the ADT way, you no longer have a type Sphere, just a type Shape
03:40:11<wli>I'd just try to represent things via equations and inequalities.
03:40:27<hatds>mmorrow: still skeptical -- programs we write aren't at all like general purpose data libraries
03:40:49<jmcarthur>sometimes i think things like this can benefit from a Map rather than a type class so you can handle the presence or absence of an "instance" at runtime, and also get the benefits of the existential quantification approach since you can just carry around a tag to annotate what would otherwise be data all of the same type
03:40:56<goldenpuffs>timmaxw: that's what I was trying to avoid, so that I can add more shapes easily later
03:41:10<wli>So intersections are just conjunctions of conditions.
03:41:11<mmorrow>hatds: (what exactly are we discussing, the usefulness of existential types with class constraints in datatypes?)
03:42:11<timmaxw>so, exactly how hard is it to add a new type of shape with each method? i think with the ADT method you can just add a new constructor, and you can let the pattern matches be non-exhaustive for the functions if you don't need those capabilities.
03:42:14<jmcarthur>it's essentially the same thing as existential quantification, but with a little more work for a little more control
03:42:31<timmaxw>that doesn't seem insurmountable to me UNLESS the new shape is being added by an entirely new module
03:43:08<wli>So I don't think the algebraic data type helps.
03:43:42<timmaxw>wli: how?
03:43:55<hatds>mmorrow: I don't know, I just feel that going with fancy solutions first isn't always the best approach. Even typeclasses are fancy for certain things
03:44:06<mmorrow>yeah, if we're talking about the need to add Shapes without modifying the code of the module that defines Shape, then the ADT solution doesn't work... but you could make an ADT which defines the most basic building blocks of shapes, and has cons which "glue" (or something) other shapes together
03:44:29<hatds>I think it is easy to refactor simple -> fancy, but starting out with fancy gives you headaches
03:44:35<bos>ACTION is trying to come up with a good name for a type that handles unicode encoding errors
03:44:41<bos>CodingError? bleh.
03:44:42<wli>x^t A_k x + b_k^t x + c = 0 for 0 < k <= n, for instance, just wants the solution of a system of equations. You can get some more things like triangular planar patches with inequalities.
03:44:44<timmaxw>mmorrow: that's only important if third parties are going to extend it
03:44:50<bos>i thought about :-<
03:44:51<mmorrow>timmaxw: yes
03:44:55<bos>as in Char :-< Word
03:44:58<Cale>One thing you can do is decide which operations you need shapes to have and define a shape as a record consisting of those operations.
03:45:05<timmaxw>mmorrow: which seems unlikely to me, although i don't know exactly what goldenpuffs is doing
03:45:22<timmaxw>Cale: that's basically a desugared typeclass, i think
03:45:25<Cale>That's more or less the OO approach, and doesn't require existentials.
03:45:35<Cale>Desugared existential, sort of.
03:45:44<jmcarthur>Cale's suggestion allows you to create new shapes at runtime, even, by constructing new functions.
03:45:57<mmorrow>bos: i like infix constructors
03:45:58<jmcarthur>new *records
03:46:01<Cale>(though existentials are strictly speaking able to handle some cases which this method can't)
03:46:07<timmaxw>Cale: what are the advantages over an actual existential?
03:46:20<Cale>I think it's more straightforward sometimes.
03:46:37<wli>Triangular planar patches I think are just things like b_0^t x = c_0, and then b_k^t x <= c_k for 0 < k <= n, or some such.
03:46:53<Cale>and also that way you don't need to turn on extensions
03:47:07<wli>s/Triangular/Polygonal/
03:49:42<Cale>hmm, where did I put that example...
03:50:13<wli>I guess allowing A_k = 0 and also throwing in a case in the data type for individual "equations" for inequalities of the form b_k^t x <= c_k will do it.
03:50:46<timmaxw>wli: if you only need a handful of types, it's much simpler to hard-code the solutions for them than to have an solver for arbitrary polynomials
03:51:55<wli>I don't think the solver is that involved for 3 variables. Also, the "handful of types" explode combinatorially when you carry out intersections.
03:52:15<Cale>Oh, looking back at the previous text, if you already have a typeclass, an existential type should serve well.
03:52:39<mmorrow>yeah, i like wli's suggestion here
03:53:08<mmorrow>a shape is completely determined by its polynomial
03:53:39<mmorrow>Cale: yeah, the typeclass being a given makes an existential more attractive
03:53:42<amz>a bit off-topic, but I can't think of a better place to ask... I'm planning on starting a blog about game development, including studying gamedev in Haskell and other functional languages, so I wanted a title that reflects that. I was thinking of something along the lines of "The Gamedev Monad", or "Monadic Gamedev"... any thoughts? Too cheesy? Stupid? Wrong?
03:54:33<QtPlaty[HireMe]>I prefer "The Gamedev Monad" over the other one.
03:55:20<Twey>Fêl
03:55:36<amz>I do too, but I wasn't sure if it wouldn't sound bizarre
03:55:57<Cale>amz: hehe, I suppose it's fine, though conal might flinch a little.
03:56:05<falmor>i prefer " functional gaming "
03:56:10<Twey>(Ilaksh monadic perspective of ‘game’)
03:56:16<mmorrow>amz: heh, people in this channel are probably way to desensitized to that for their opinions to be representative :)
03:56:16<Cale>(Reactive is more Applicative than Monadic ;)
03:56:27<Twey>Conlang punning is fun for all the family.
03:56:30<pumpkin>Arrowdic?
03:56:36<mmorrow>functional gaming sounds good
03:56:37<falmor>functional gaming " makes it seem right
03:56:50<falmor>or pedantic people can get all fussy bout the terminology
03:56:58<amz>well, the blog isn't only ABOUT functional programming
03:57:03<amz>it will presumably also cover gamedev on oop
03:57:14<falmor>ah
03:57:18<aavogt>existential?
03:57:18<falmor>ok let me think
03:57:30<falmor>" gamedev 360"
03:57:33<amz>I feel that "Gamedev Monad" doesn't imply it's only functional, even if monads are a functional concept
03:57:47<amz>eh, that sounds like it's about the xbox 360
03:57:53<falmor>no
03:57:53<amz>also, twey, I have no idea what you just said :)
03:57:56<falmor>its like in chess
03:58:12<falmor>just meaning gamedev covered in all respects or more
03:58:13<falmor>most
03:58:18<falmor>gamedev 270 maybe
03:58:20<falmor>?
03:58:20<falmor>:D
03:58:29<ray>monads suck
03:58:34<Cale>Newsflash: Microsoft has patented geometry and the degree unit of angle.
03:58:34<amz>D:
03:58:38<amz>haha
03:58:47<falmor>Cale what
03:58:48<ray>you should be using radians anyway
03:58:48<pumpkin>ACTION invents the digree
03:58:55<pumpkin>there are 180 digrees in a circle
03:58:59<pumpkin>and 90 in a triangle
03:59:00<falmor>is that for real
03:59:09<Cale>falmor: Of course not :)
03:59:12<falmor>oh
03:59:13<falmor>:D
03:59:30<pumpkin>they are the perfect unit of digression
03:59:38<falmor>ok so amz
03:59:58<amz>if I forget Haskell for a moment and go with Wikipedia's definition of a Monad: "In functional programming, a monad is a kind of abstract data type used to represent computations (instead of data in the domain model). Monads allow the programmer to chain actions together to build a pipeline, in which each action is decorated with additional processing rules provided by the monad."
04:00:04<amz>then "Gamedev Monad" seems right
04:00:04<ray>how about "pointed discussion"
04:00:15<Cale>A license for Microsoft Degree 2009 Home Edition will only cost you $220.
04:00:23<amz>that would be really hard to google, ray
04:00:24<Twey>A bargain!
04:00:38<Twey>Heh, amz :-P
04:00:45<ray>how about applicative FUNctor
04:00:51<amz>hah
04:00:53<pumpkin>yeah, but if you want Degree Pro, you'll need twice that
04:00:59<amz>that's not a bad one ;)
04:01:02<pumpkin>with Degree Home you can only perform sines on it
04:01:10<pumpkin>no cosines or tangents
04:01:12<Cale>I hear the total cost of ownership is much lower than those "radians" the open source guys keep talking about.
04:01:14<Twey>I don't care what I can do with it, I want Pro
04:01:16<amz>if it was on ML, I could probably do a pun on "fun fact"
04:01:16<falmor>raay i was thinking along those lines
04:01:19<pumpkin>luckily, you can get the other ones, but it's a pain
04:01:22<falmor>but functor to pronounce is funny
04:01:25<Twey>It's called *Pro*
04:01:34<conal>amz: about "The Gamedev Monad", or "Monadic Gamedev"..., i worry that such a title would perpetuate the idea that Monad is somehow particularly important to functional programming. mostly (certainly not always), folks use Monad in haskell in order *not* to program functionally.
04:01:36<falmor>gamedev OOmonad
04:01:38<Twey>Unless there's an ULTIMATE version.
04:01:38<pumpkin>functor sounds like an ancient warrior
04:01:40<pumpkin>functOR
04:01:40<falmor>how about that?
04:01:44<SamB>Cale: what if I just want MCSE Home?
04:01:47<falmor>gamedev OO!monad
04:01:56<falmor>nay
04:01:57<falmor>skip
04:02:15<conal>amz: so, i'm with falmor. something with "functional" rather than "monad(ic)".
04:02:29<amz>conal: well, I thought that was the whole point, to build a procedural pipeline inside functional code
04:02:35<falmor>conal: but he's going to write stuff in OO too it seems
04:02:36<falmor>..
04:02:37<falmor>so
04:02:40<wli>x^2+y^2=1, y^2+k^2*z^2=1 gives you something perhaps more interesting (elliptic functions w00).
04:02:45<pumpkin>conal: I recommended unamb for the first time today! I feel so advanced (but I'm not sure I recommended it appropriately)
04:02:52<conal>pumpkin: woot!
04:03:12<pumpkin>ACTION beams
04:04:50<falmor>"gamedev functOOr"
04:04:51<falmor>:P
04:05:02<conal>amz: indeed, haskell is not only a awesome functional language, it's also "the world's finest imperative programming language". maybe you're more interested in the latter than the former. if so, then "monad" probably fits well.
04:05:31<amz>I'm not yet sure if I agree with Simon PJ on that comment ;)
04:05:46<Cale>Actually, I disagree with conal about most monads. Only the IO monad is really imperative.
04:05:55<conal>Cale: we don't disagree there.
04:06:02<Cale>Okay :)
04:06:25<Cale>Most monads just capture basic functional idioms.
04:06:44<amz>anyway, conal, the idea of the blog is to explore general topics in game dev and programming, but also explore how to do that stuff in FP
04:06:50<amz>which is why I wanted a nod at them in the title
04:06:51<BMeph>ACTION prefers to do trig using gradians - you cn't beat triangles adding up to 100! ;p
04:07:12<amz>but it's not an exclusive thing, so a title with "functional" might be misleading
04:07:23<conal>Cale: my impression is that most of the popularity of Monad is so that people can program imperatively. i'm not commenting on Monad itself. just its popular use.
04:07:33<Cale>okay
04:08:07<conal>for people who use Monad functionally, Monad is nothing special. for people who use it imperatively, it's very special.
04:08:24<amz>I see
04:08:48<Cale>Grads are cool when it comes to adding or subtracting right angles, but radians have the glorious property that it's easy to convert to lengths along circles to radian angles.
04:08:49<amz>what about "Higher-order fun"? :)
04:09:24<Cale>amz: That's a nice name. :)
04:09:33<monochrom>If I learned arithmetic in base pi, radians would be cool for adding right angles.
04:09:36<BMeph>FuncTours? ;)
04:09:54<amz>maybe "Higher-order FUNction"
04:09:58<roconnor>radians have the property that the derivative of sin is cos
04:09:59<amz>though that's harder to google
04:10:07<conal>amz: maybe something with "HOT" (higher-order typed)
04:10:17<monochrom>funtorial
04:10:31<SamB>HOT FUN
04:10:38<amz>"Fun and Functions"
04:10:52<amz>ACTION never even heard the "HOT" acronym, so it might be too obscure
04:10:57<conal>or "hot action", "hot pixels", ...
04:11:00<SamB>amz: are you kidding?
04:11:03<monochrom>hot high fun
04:11:10<amz>conal: I might get blocked by some family filters with a title like that ;)
04:11:20<amz>SamB: :(
04:11:20<conal>amz: oh yeah!
04:11:22<amz>I'm afraid I'm not
04:11:22<SamB>it's, like, one of our favorite jokes
04:11:32<amz>I don't hang around here much :(
04:11:36<monochrom>Everything is obscure. What's new.
04:11:53<conal>oh hey -- maybe a take-off on the "sexy types in action" paper title
04:11:58<monochrom>Also, HOT as a joke is so year 2000.
04:11:59<luqui>@bot
04:11:59<lunabot> :)
04:12:11<BMeph>SamB: Heck, according to one of sigfpe's blarticles, kowey never heard of CA until December '06. So sad, how Education os Failing our Kids... :\
04:12:30<SamB>BMeph: that's because he didn't read enough books about fractals!
04:12:40<SamB>or fractal programs
04:12:50<mmorrow>lunabot uptime:
04:12:51<BMeph>SamB: Or Bill Gosper. :)
04:12:53<monochrom>CA is Canada isn't it?
04:12:59<mmorrow>mmorrow 11442 0.1 0.1 239732 10984 pts/2 Sl+ Mar17 162:25 ./bot +RTS -N8 -RT
04:13:01<SamB>Cellular Automations
04:13:06<SamB>er.
04:13:08<SamB>automatons
04:13:08<mmorrow>2.5 months!
04:13:13<BMeph>monochrom: I meant Cellular Automata. :)
04:13:14<monochrom>ACTION 's domain is a ca, too.
04:13:20<mmorrow>forkIO for every irc message
04:13:24<SamB>er, yeah, automata is the right plural ;-P
04:13:43<mmorrow>ACTION wonders how many forkIOs that is over two and a half months
04:15:16<mmorrow>woo 163 hours of cputime
04:15:20<BMeph>So, can you install vacuum-cairo straight from the Platform?
04:15:44<mmorrow>BMeph: you need gtk2hs and all that jazz, which i think you can't
04:15:52<BMeph>mmorrow: Sugoi! ;)
04:15:54<mmorrow>ACTION needs to release his vacuum-gl
04:16:32<mmorrow>which is actually an interactive viewer for *any* haskell graph
04:17:11<mmorrow>ACTION digs that up
04:17:25<pumpkin>:o
04:18:50<conal>mmorrow: yow! sounds like great fun.
04:19:26<mmorrow>conal: it binds directly to graphviz C functions too, so it's all in-process
04:19:35<conal>mmorrow: sweet!
04:20:36<mmorrow>(the unfortunate part though is that for every graph it has to slurp up a .bmp from graphviz, then copy that into video memory, but i think that's the best one could hope for)
04:21:20<mmorrow>(using .bmp instead of png to avoid having to decompress the png right after graphviz compresses it)
04:21:31<conal>mmorrow: i've been playing with andy gill's data-reify, described at http://www.ittc.ku.edu/~andygill/paper.php?label=DSLExtract09 . have you seen/read it?
04:21:44<mmorrow>conal: ooh, yeah! that's a really nice concept
04:21:55<goldenpuffs>I have a question about the dotproduct between two vectors
04:22:03<goldenpuffs>I defined it this way: t \*/ v = map (t*) v
04:22:13<goldenpuffs>is there an easy way to make it commutative?
04:22:16<conal>mmorrow: yeah! i want to use it to replace the CSE in my functional->GPU compiler
04:23:12<conal>mmorrow: i wonder if there's some lovely merger of data-reify and vacuum.
04:23:24<mmorrow>conal: i used that idea recently to make self-describing C structure serialization.... so the datarep in serialized first, then the raw data, and to de-serialize you first read the description of the data, then use that info the parse the rest. where the "visible sharing" bit come in is in how you build C data descriptions, eg:
04:24:44<mmorrow>myRep = Struct[B, S, P myRep, Struct[..]]
04:25:34<mmorrow>so you need to break that (:: Rep) into a (type RepGraph = (Word32, [RNode]))
04:25:45<mmorrow>(where RNode isn't resursive)
04:26:22<mmorrow>conal: i think there is a merger for sure. they use basically the exact same idea. it'd be great to have:
04:26:30<mmorrow>serialize :: forall a. a -> ByteString
04:26:49<mmorrow>reify :: ByteString -> a -- this direction would need rts C code though
04:26:54<conal>mmorrow: capturing sharing & cycles?
04:26:58<mmorrow>exactly
04:27:04<mmorrow>all sharing being preserved
04:27:07<conal>totally
04:27:11<mmorrow>, vacuum (fix (0:))
04:27:13<lunabot> [(0,[1,0]),(1,[])]
04:27:15<mmorrow>wee
04:27:27<pumpkin>mmorrow: what would it do about functions?
04:27:40<chromakode>hey guys, I'm trying to define a type class with a parameter with the ST monad, and am running in a wall: the part with state requires the parameter s, but the Eq class does not expect it. could anyone take a look and let me know what I'm doing wrong? http://www.moonpatio.com/fastcgi/hpaste.fcgi/view?id=2548#a2548
04:28:38<mmorrow>pumpkin: that's a tough part, there're no hooks for the haskell side to get at that data in the rts currently, and even if you could, it'd be arch-specific (and reifying would probably be hard)
04:29:05<luqui>conal, you are a purity zealot like me. I wonder why you expect to be able to break the rules...
04:29:34<mmorrow>whose rules? ;)
04:30:27<luqui>R.T. mcFunction's.
04:30:51<pumpkin>scottish eh
04:31:02<pumpkin>gotta fight the man!
04:31:04<pumpkin>don't bow to the rules
04:31:08<mmorrow>wouldn't that be MacFunction then?
04:31:15<conal>luqui: i *am* a fellow purity zealot, indeed. have you seen andy's paper?
04:31:43<luqui>conal: which?
04:31:59<conal>luqui: http://www.ittc.ku.edu/~andygill/paper.php?label=DSLExtract09
04:32:04<yav>do we have any haskellers that use windows here?
04:33:10<mmorrow>goldenpuffs: u \*/ v = sum (zipWith (*) u v) -- ?
04:33:56<luqui>conal, I'll read it and present my argument later, if I still maintain it. :-)
04:33:58<conal>or (\*/) = (fmap.fmap) sum (zipWith (*))
04:34:05<mmorrow>:)
04:34:08<conal>luqui: please.
04:34:25<pumpkin>conal: I'm not sure I can approve of that operator
04:34:44<conal>luqui: i don't mind if internal representations break purity (distinguish between semantically equal representations), as long as there a semantically tight abstraction in the end.
04:35:09<mmorrow>pumpkin: are you throwing an UnapprovedOperator exception?
04:35:11<goldenpuffs>mmorrow: oh my bad, I said dotproduct but I meant multiplication with a scalar actually
04:35:17<luqui>conal, so because you are so good at programming, you don't need to use pure functions for reasoning, just for your interface? ;-)
04:35:21<pumpkin>mmorrow: indeed :/
04:35:26<conal>luqui: andy moves observable sharing into IO. from there, one can do a safePerformIO and wrap the rewult.
04:35:57<timmaxw>So. Cyclic data structures. Thoughts?
04:36:10<luqui>I'm becoming more and more of the impression that I have to follow the rules as much as anybody else.
04:36:15<timmaxw>for example, a graph
04:36:20<mmorrow>goldenpuffs: hmm, so you want :: Vec -> Scalar -> Vec and :: Scalar -> Vec -> Vec?
04:36:32<luqui>and if I run into limitations, those limitations should be brought to light so we can improve our language
04:36:43<mmorrow>goldenpuffs: you could make two versions: \* and /*
04:36:47<mmorrow>err, */
04:36:56<pumpkin>or a typeclass with fundeps
04:37:01<mmorrow>(*/) = flip (\*)
04:37:16<timmaxw>one way to deal with it is to have arcs be indices into a list, so type Graph = [(StateData, [Int])]
04:37:17<goldenpuffs>thought about that, was just wondering if there is something like Commutative a =>
04:37:24<conal>luqui: i'm with you. i think i follow the rules. the important tricky bit is clarifying the preconditions for safePerformIO
04:37:30<timmaxw>where StateData is associated with each state
04:37:35<timmaxw>and the Ints are indices into the Graph itself
04:37:37<timmaxw>but that's messy
04:37:43<luqui>conal: *IO is not following the rules :-)
04:37:50<timmaxw>Are there better ways?
04:37:51<mmorrow>timmaxw: a fast rep that i use a lot is IntMap Node
04:38:01<mmorrow>timmaxw: where there's some (Node -> [Int])
04:38:07<conal>luqui: all of pure functional programming is built on (un)safePerformIO
04:38:08<mmorrow>(or Node -> IntSet)
04:38:13<conal>luqui: s/built/implemented/
04:38:25<timmaxw>that's still the same general concept though
04:38:29<mmorrow>timmaxw: exactly
04:38:30<timmaxw>are there alternatives?
04:38:44<timmaxw>for example, i think you could build the entire graph as a cyclic data structure
04:38:51<timmaxw>so data Node = Node StateData [Node]
04:38:59<timmaxw>but you wouldn't be able to detect cycles
04:39:04<timmaxw>so that's only useful for some applications
04:39:29<timmaxw>i'm pretty sure it's possible to construct such a data structure because of lazy evaluation
04:39:33<luqui>conal, but going into IO and back out of it destroys the local reasoning properties of your program.
04:39:47<mmorrow>timmaxw: oh, well you can always map between (Map a (Set a) <===> IntMap Node), where Node = Node a IntSet
04:40:08<luqui>*local* being a key word
04:40:09<mmorrow>timmaxw: but other than this general idea i don't know of any
04:40:36<conal>luqui: it's a trickier kind of reasoning.
04:40:47<timmaxw>I can think of two ways to "untangle" a genuinely cyclic data structure
04:40:53<luqui>conal, by trickier you mean informal, thus unverifiable
04:40:54<timmaxw>into a finite-sized representation
04:40:57<mmorrow>timmaxw: oh, you can build a circular structure using sharing, but then you need to break it apart somehow (like with andyjgill's library's method or equiv)
04:41:10<timmaxw>i've got to google those then
04:41:20<mmorrow>(StableName + hashStableName) is one easy way
04:41:23<conal>luqui: no, i meant formal.
04:41:29<timmaxw>the ideas i had were System.Mem.StableName and adding unique tags to nodes
04:41:32<mmorrow>and throw an unsafePerformIO on top
04:41:39<timmaxw>where the algorithm generating the graph guarantees the tags are unique
04:41:45<mmorrow>timmaxw: that works well
04:41:49<luqui>conal, don't you need a semantics for IO for that?
04:41:55<timmaxw>which one?
04:42:02<mmorrow>StableName
04:42:15<mmorrow>(what's the other?)
04:42:17<timmaxw>the unsafePerformIO approach seems a little messy to me, but i'll consider it
04:42:18<luqui>also have to know how said semantics interact with the normal pure semantics of the language... which must endow them with a different semantics, no?
04:42:21<conal>luqui: i wouldn't start with all of IO.
04:42:37<mmorrow>timmaxw: well you can untangle with StableName without it just the same)
04:42:45<timmaxw>suppose we have data Node = Node (Maybe String) SomeData [Node]
04:43:07<timmaxw>where the (Maybe String) is the "name" of the node
04:43:14<timmaxw>and some nodes have strategically places names on them
04:43:24<mmorrow>the unsafePerformIO is only if you want (untangle :: Tangle -> Untangle) rather than (untangle :: Tangle -> IO Untangle)
04:43:39<timmaxw>the former is preferable
04:44:09<luqui>conal, i need my argument to simmer a bit. expect a blog post :-)
04:44:12<mmorrow>timmaxw: do everything in IO then put a single unsafePerformIO at the very top
04:44:21<timmaxw>i'll consider that
04:44:33<timmaxw>does the tagged/named node approach make sense?
04:44:46<Cale>whaaaat
04:44:54<timmaxw>or do i need to explain in more detail
04:45:11<Cale>ACTION needs to read this to see what mmorrow is really suggesting
04:45:26<mmorrow>Cale: this is how you break apart circular data
04:45:27<conal>luqui: okay. and i'm teasing you a bit. if you think we disagree, you're probably missing my meaning. and i'm not making a great effort to prevent you missing it.
04:45:30<Cale>oh
04:45:49<Cale>But that's not how you really want to represent graph structures in Haskell.
04:46:00<mmorrow>StableName+hashStableName + IntMap [(StableName, a)] -- keys are hashes of StableNames
04:46:32<mmorrow>Cale: oh, no. but it's a way to untangle if that's what you need to do
04:46:47<Cale>If you have lazy cyclic structures, I wouldn't recommend messing with them like that at all. If you need to manipulate them, you should not have chosen them in the first place.
04:46:59<timmaxw>what can i google for to find more about "andyjgill's library method"? I can't seem to find anything.
04:47:09<luqui>conal, it's possible. i am more inclined to think we disagree because i've had a recent change in perspective. but i still don't quite know what I'm saying...
04:47:10<mmorrow>Cale: sometimes it's more convenient though to build them with the facilities of the language, then untangle
04:47:17<Cale>If you need to represent a graph, use something like Map Vertex (Set Vertex)
04:47:28<mmorrow>Cale: edsls are the canonical example
04:47:38<conal>luqui: oh! i'll watch for your blog post.
04:47:48<Cale>mmorrow: hmm, maybe
04:47:56<Cale>mmorrow: But that seems really fragile.
04:48:02<conal>Cale: have you read andy's paper?
04:48:04<mmorrow>Cale: check out andyjgill's pap
04:48:05<mmorrow>yeah
04:48:19<Cale>I think you'd be better off in general constructing combinators which built an explicit graph.
04:48:23<timmaxw>"A Haskell Hosted DSL for Writing Transformation Systems"?
04:48:38<Cale>Than using unsafePerformIO and StableNames
04:48:52<conal>Cale: andy doesn't use unsafePerformIO
04:48:56<Cale>Okay
04:49:00<mmorrow>yeah, i added that part :)
04:49:06<Cale>I was only referring to mmorrow's suggestion
04:49:11<mmorrow>you don't need it for anything essential
04:49:14<bnijk>how do i write a program that, say
04:49:20<bnijk>computes value x, and writes it to ~/x
04:49:31<bnijk>for maximum monaditude
04:49:39<Cale>:t writeFile
04:49:41<conal>mmorrow: i wouldn't want to add unsafePerformIO unless it was really safePerformIO, i.e., it preserved functional semantics.
04:49:53<Cale>Is lambdabot still gone?
04:50:04<pumpkin>I can bring pumpkinbot in for a while if you want
04:50:05<mmorrow>conal: yeah, it's safe how i'm thinking of it being used
04:50:07<bnijk>yes
04:50:09<timmaxw>Is the andyjgill paper you're referring to the one titled "A Haskell Hosted DSL for Writing Transformation Systems"?
04:50:16<conal>mmorrow: me too
04:50:25<bnijk>not the type, i want to see the actual implementation
04:50:27<timmaxw>i'm trying to find the paper under discussion
04:50:37<conal>timmaxw: no. it's the one i linked to twice above.
04:51:05<conal>timmaxw: "Type Directed Observable Sharing" -- http://www.ittc.ku.edu/~andygill/paper.php?label=DSLExtract09
04:51:11<timmaxw>thanks
04:51:13<mmorrow>Cale: (the only reason the IO pops into the picture is when using StableName, which are all discarded after you've done your business)
04:51:13<Cale>bnijk: It's more or less primitive, but I suppose you could write it in terms of openFile and hPutStr
04:51:16<conal>to appear at the Haskell Symposium.
04:51:32<bnijk>you suppose?
04:51:34<Heffalump>is the paper list out yet?
04:52:11<mmorrow>Cale: so the unsafePerformIO just drops that IO after all remnants of IO have already been discarded
04:52:19<Cale>mmorrow: But isn't explicitly relying on how the compiler shares values a bit dangerous?
04:52:38<timmaxw>Cale: any sane implementation of StableName would produce an equivalent result
04:52:39<Heffalump>Cale: it's fine if it's just to save you doing CSE yourself
04:52:39<Cale>It seems to me that an optimisation could change that.
04:52:49<timmaxw>not necessarily the same result, but results that are equivalent enough
04:52:50<Heffalump>I'm not sure of any other safe uses
04:52:56<bnijk>ACTION reads the wiki
04:52:59<conal>mmorrow: you still have to be careful. if you expose a graph rep, then the sharing detection can distinguish between semantically equal values.
04:53:10<Cale>conal: right.
04:53:17<timmaxw>conal: that's acceptable.
04:53:25<Cale>It breaks referential transparency...
04:53:28<Cale>That's kind of bad.
04:53:33<mmorrow>conal: true, in some cases you can't use Eq for Eq
04:53:40<conal>however, you can wrap an abstraction around the graph rep and recover RT
04:53:48<mmorrow>totally
04:54:14<conal>that's what i call "safePerformIO"
04:54:31<mmorrow>and you can also always map *back* to the circular knotted version from the graph
04:54:34<mmorrow>so, then
04:54:37<falmor>is there a channel for monads?
04:54:43<mmorrow>a == b = reKnot a == reKnot b
04:54:46<mmorrow>et voila
04:54:48<mmorrow>:)
04:54:55<Cale>falmor: This is probably the closest thing you will find.
04:55:01<falmor>ok
04:55:09<^Someone^>Wow, a channel just for monads, lol
04:55:10<conal>mmorrow: make sure you don't "show" the graph. would also break RT
04:55:15<^Someone^>That'd be nice : D
04:55:42<mmorrow>ah true
04:55:48<conal>if we have a Monad channel, we'll have to have channels for Functor and Applicative, which are more common than Monad
04:56:47<chromakode>can you put a forall. in a class definition?
04:57:03<conal>chromakode: in some places but not others.
04:57:14<conal>chromakode: where do you want to put the forall?
04:57:42<chromakode>conal: I have a class that has a phantom type from the ST monad, and I'd like to make it inherit from Eq
04:58:00<chromakode>e.g. "Eq (a s) => Game a", but that breaks.
04:58:07<Hunner>I'm used to using regexes to parse strings in ruby and perl. What is the Haskell Way?
04:58:14<chromakode>I think what I mean is Eq (forall s. a s)?
04:58:28<timmaxw>so it looks like andyjgill is basically using StableName without unsafePerformIO... or do i need to read more than the first 2 pages?
04:58:42<mmorrow>timmaxw: unsafePerformIO isn't needed for StableName
04:58:54<chromakode>Hunner: maybe parsec?
04:59:01<conal>chromakode: i've wanted that ability also. haskell typing is *almost* a higher-order logic programming language (Lambda-Prolog), but not quite.
04:59:50<mmorrow>timmaxw: basically, you work in (StateT Env IO a), where
04:59:59<falmor>lol ^Someone^
05:00:06<falmor>thats why i joined that xmonads
05:00:10<mmorrow>data Env a = Env {graph :: IntMap [(StableName, a)]
05:00:11<falmor>stupid me
05:00:12<chromakode>conal: rats, thanks :(
05:00:21<mmorrow>err, so StateT (Env b) IO a
05:00:30<conal>chromakode: yeah, bummer :( leads to unfortunate hacks.
05:00:34<mmorrow>well, s/b/the untangled node rep/
05:00:36<timmaxw>i don't know what StateT is off the top of my head
05:00:45<chromakode>conal: so there's no way I can mitigate the lack of this, and properly inherit from Eq?
05:00:46<mmorrow>@src StateT
05:00:46<lambdabot>Source not found. You speak an infinite deal of nothing
05:00:58<mmorrow>it's just s -> IO (a, s)
05:01:16<mmorrow>so you accumulate the graph in the state
05:01:33<mmorrow>and runStateT :: StateT s m a -> s -> m (a, s)
05:01:59<conal>chromakode: i wouldn't jump to "no way".
05:02:11<timmaxw>i would have to look at that for a while to understand it - monads aren't my strong point
05:02:23<bnijk>what's good functional style
05:02:52<mmorrow>timmaxw: the method is essentially to perform the same algo that a Cheney GC uses
05:03:03<mmorrow>timmaxw: so reading about that might be helpful
05:03:13<mmorrow>(or at least, that's the algo i use)
05:03:20<timmaxw>ok, maybe i'll look at that
05:03:43<mmorrow>where the "tospace" is the IntMap in the StateT's state
05:03:50<conal>bedtime for me. good-night/day all!
05:03:53<mmorrow>night
05:03:58<chromakode>conal: thanks for the help, have a nice rest :)
05:04:04<conal>:)
05:04:12<chromakode>btw, I enjoyed your post on C as a pure language!
05:04:21<conal>chromakode: :)!
05:04:57<rick_2047>conal, what post
05:05:07<rick_2047>what do u mean by pure??
05:05:10<chromakode>it was good brain food as I was learning monads
05:05:25<bnijk>hmm
05:05:29<rick_2047>can i have a lin
05:05:32<rick_2047>link*
05:05:41<chromakode>http://conal.net/blog/posts/the-c-language-is-purely-functional/
05:05:49<chromakode>ACTION does not intend to stir up the flame war again
05:05:55<chromakode>read the reddit comments for some interpretation
05:06:13<rick_2047>chromakode, dont worry i never war
05:06:23<chromakode>:)
05:09:17<eck>is there a way to convert between the bytestring type of Data.ByteString.Internal and Data.ByteString.Lazy.Internal ?
05:09:25<rick_2047>chromakode, i dont get it does he mean c++ when he says cpp??
05:09:29<mmorrow>eck: toChunks/fromChunks
05:09:39<mmorrow>@hoogle toChunks
05:09:39<lambdabot>Data.ByteString.Lazy toChunks :: ByteString -> [ByteString]
05:09:40<lambdabot>Data.ByteString.Lazy.Char8 toChunks :: ByteString -> [ByteString]
05:09:45<mmorrow>@hoogle fromChunks
05:09:45<lambdabot>Data.ByteString.Lazy fromChunks :: [ByteString] -> ByteString
05:09:45<lambdabot>Data.ByteString.Lazy.Char8 fromChunks :: [ByteString] -> ByteString
05:10:04<eck>nat
05:10:06<eck>neat, even
05:10:45<chromakode>rick_2047: he means the c preprocessor
05:10:57<rick_2047>chromakode, o then all is well
05:16:28<ski>chromakode : iirc, you can make an auxilary `Eq' class
05:16:44<chromakode>ski: EqST, or something?
05:16:47<ski>no
05:17:02<chromakode>I'm afraid I don't understand, thne
05:17:05<ski> instance AllEq a => Game a
05:17:08<rick_2047>are tuples member of the Enum typeclass??
05:17:13<ski> class AllEq f
05:17:15<ski> where
05:17:25<ski> feq :: f a -> f a -> Bool
05:17:28<ski> fneq :: f a -> f a -> Bool
05:17:41<chromakode>ski: ! thanks, that's a great idea
05:17:49<ski> f0 `feq` f1 = not (f0 `fneq` f1)
05:17:54<ski> f0 `fneq` f1 = not (f0 `feq` f1)
05:18:02<bnijk>so x <- y, what is the definition of y
05:18:03<ski>if you had wanted
05:18:19<ski> instance (forall s. Eq s => a s) => Game a
05:18:23<ski>then you'd had
05:18:30<ski> feq :: Eq a => f a -> f a -> Bool
05:18:33<ski> et.c
05:18:34<ski>instead
05:19:04<ski>bnijk : where is this snippet coming from ?
05:19:10<bnijk>nowhere
05:19:14<bnijk>what are the possible values for y
05:19:25<ski>that depends on how you've defined `y'
05:19:36<chromakode>ski: thanks -- so I think you'd use feq instead of ==,?
05:19:44<ski>yes
05:19:48<chromakode>alright, it
05:20:01<bnijk>mmnn
05:20:01<chromakode>that's a reasonable workaround, thanks.
05:20:17<bnijk>what are all possible values for y
05:20:19<bnijk>is my question
05:20:25<bnijk>or types
05:20:27<bnijk>or whatever
05:20:43<ski>oh .. the possible types is a quite different question :)
05:20:45<chromakode>bnijk: I think your question is too vague to answer properly
05:21:05<bnijk>i don't know how to make it any more specific
05:21:22<ski>the possible types of that (assuming it's part of a `do'-block) is types of form `m a' where `a' is any type, and `m' is any type that is an instance of the typeclass `Monad'
05:21:32<bnijk>now there's the answer
05:21:39<bnijk>things are starting to come together
05:21:51<bnijk>what's going on if it's not part of a do block?
05:21:52<ski>if you provide more detail, we might be able to answer with more detail
05:22:03<mmorrow>Cale: (err, to be clear i wasn't suggesting using all that as a general-purpose way to do graph stuff with haskell, but rather as a special-purpose tool to accomplish certain things that are impossible otherwise)
05:22:10<ski>> [(x,y) | x <- "abc" , y <- [4,5]]
05:22:11<lambdabot> [('a',4),('a',5),('b',4),('b',5),('c',4),('c',5)]
05:22:22<Cale>mmorrow: Yeah, that became clearer :)
05:22:24<ski>bnijk : ^ it could be part of a list comprehension
05:22:43<bnijk>those things are nifty
05:22:59<ski>bnijk : also, it could be part of a "pattern guard" (an extension)
05:23:17<chromakode>I think what bnijk might be running against is Haskell's type inference?
05:23:21<ski>(and also possibly part of arrow syntax, iirc)
05:23:30<bnijk>> [(x,y,z) | x <- [1..2] , y <- [1..4] , z <- [1..8]]
05:23:31<lambdabot> [(1,1,1),(1,1,2),(1,1,3),(1,1,4),(1,1,5),(1,1,6),(1,1,7),(1,1,8),(1,2,1),(1...
05:23:42<bnijk>i wanted the whole thing you stupid bot
05:23:51<ski>bnijk : try in private :)
05:23:57<bnijk>> [(x,y,z) | x <- 1 , y <- [1..2] , z <- [1..4]]
05:23:58<lambdabot> No instance for (GHC.Num.Num [t])
05:23:58<lambdabot> arising from the literal `1' at <inter...
05:24:02<bnijk>> [(x,y,z) | x <- [1] , y <- [1..2] , z <- [1..4]]
05:24:03<lambdabot> [(1,1,1),(1,1,2),(1,1,3),(1,1,4),(1,2,1),(1,2,2),(1,2,3),(1,2,4)]
05:24:08<pumpkin>o.O
05:24:21<ski>bnijk : /msg lambdabot > [(x,y,z) | x <- [1..2] , y <- [1..4] , z <- [1..8]]
05:25:09<bnijk>:t $
05:25:09<lambdabot>parse error on input `$'
05:25:16<bnijk>:t ($)
05:25:16<ski>@type ($)
05:25:16<lambdabot>forall a b. (a -> b) -> a -> b
05:25:17<lambdabot>forall a b. (a -> b) -> a -> b
05:25:34<bnijk>WHAT
05:25:49<bnijk>hmmm
05:25:49<ski>@src $
05:25:49<lambdabot>f $ x = f x
05:26:03<bnijk>(drop 1 (drop 1 ("hello"))
05:26:10<bnijk>> (drop 1 (drop 1 ("hello"))
05:26:11<lambdabot> <no location info>: parse error (possibly incorrect indentation)
05:26:24<bnijk>uughhgs
05:26:26<ski>> (drop 1 . drop 1) "hello"
05:26:27<chromakode>that's odd.
05:26:27<lambdabot> "llo"
05:26:27<bnijk>> drop 1 (drop 1 ("hello")
05:26:28<lambdabot> <no location info>: parse error (possibly incorrect indentation)
05:26:36<ski>> drop 1 . drop 1 $ "hello"
05:26:37<lambdabot> "llo"
05:26:41<ski>> drop 1 (drop 1 "hello")
05:26:42<lambdabot> "llo"
05:26:51<bnijk>drop 1 . reverse . drop 1 $ "hello"
05:26:55<bnijk>> drop 1 . reverse . drop 1 $ "hello"
05:26:56<lambdabot> "lle"
05:27:00<pumpkin>> text "why not take it to PM?"
05:27:01<lambdabot> why not take it to PM?
05:27:08<bnijk>> text "why take it to PM?"
05:27:09<lambdabot> why take it to PM?
05:27:17<bnijk>are you guys doing something more important ;)
05:27:37<pumpkin>do 600 people really need to see your experiments unless you're trying to show us something?
05:27:43<pumpkin>ACTION shrugs
05:27:47<bnijk>600 people, 597 idling
05:28:00<lametier>I rather watch the joins and parts
05:28:04<pumpkin>I like to check up on my IRC client periodically to see if any interesting talk happens in here
05:28:15<pumpkin>seeing unread messages in here gets me excited :)
05:28:23<chromakode>hah, lametier
05:28:24<pumpkin>until I see they're just lambdabot output :)
05:28:25<lametier>pretty true
05:28:46<ray>lambdabot output is fine
05:28:55<ray>BORING lambdabot output, otoh
05:28:56<pumpkin>but, I'm guilty of it myself sometimes, so I'll just shut up
05:29:33<lament>> "boring output"
05:29:34<lambdabot> "boring output"
05:30:06<ray>@unpl fmap fmap fmap fmap fmap
05:30:07<lambdabot>fmap fmap fmap fmap fmap
05:31:08<chromakode>if you copy an STArray, will it be == the copy?
05:31:36<pumpkin>only if its elements are Eq ;)
05:31:37<bnijk>> pumpkin sucks
05:31:38<lambdabot> "yes he does"
05:31:42<bnijk>;)
05:31:52<pumpkin>is that a new kind of popsicle?
05:31:52<chromakode>pumpkin: but not if they aren't?
05:32:09<bnijk>ACTION wins, champagne for everyone
05:32:10<pumpkin>chromakode: well, if they aren't, the question isn't necessarily meaningful :)
05:32:18<chromakode>pumpkin: hmm.
05:32:32<chromakode>well, my derived Eq doesn't seem to be working
05:32:39<pumpkin>if I have an STArray of functions
05:32:57<chromakode>nah, I have an STArray of types with Eq
05:33:19<ski>chromakode : copy how ?
05:33:30<pumpkin>well, your equality needs to keep in mind that the STArray is in ST
05:33:40<bnijk>> pumpking andTheTravellingThieves
05:33:41<lambdabot> Not in scope: `pumpking'
05:33:43<bnijk>> pumpkin andTheTravellingThieves
05:33:44<lambdabot> "oh yeah baby, take off your wig, let me see that shav'd head"
05:33:44<chromakode>ski: bounds <- getBounds board
05:33:44<chromakode> elems <- getElems board
05:33:44<chromakode> newListArray bounds elems
05:34:19<pumpkin>:)
05:36:57<chromakode>ski: it seems it's not comparing the arrays by value
05:37:17<chromakode>I guess I'll just define Eq manually
05:37:41<bnijk>> pumpkin willYouMarryMe
05:37:43<lambdabot> "oh babyy u r so romanticc"
05:38:25<bnijk>that's a yes then
05:38:33<bnijk>legally binding you should know
05:39:04<ski>chromakode : yes, reference and (mutable) array equality is "pointer equality" .. i was going to let lambdabot demonstrate that, but it appears `newArray' is not in scope in its evaluator
05:39:28<pumpkin>, newArray
05:39:30<lunabot> luna: No instance for (GHC.Show.Show ((i, i) -> e -> m (a i e)))
05:39:38<chromakode>thanks ski! bummer :)
05:39:56<pumpkin>, let x = newArray (0, 5) 4 in x == x
05:39:58<lunabot> luna: No instance for (GHC.Classes.Eq (m (a t t1)))
05:40:38<pumpkin>, let x = newArray (0, 5) 4 :: ST s (STArray Int Int) in x == x
05:40:40<lunabot> luna: `GHC.Arr.STArray GHC.Types.Int GHC.Types.Int' is not applied to eno...
05:40:44<ski>(chromakode : and btw, that's the only sensible choice for mutable structures, given a non-IO/ST/whatever equality operation)
05:40:45<pumpkin>bah, I give up :)
05:40:52<bnijk>you're breaking my heart pumpkin ;(
05:40:53<pumpkin>I need more state types in there
05:40:58<chromakode>ski, ah, you're absolutely right!
05:41:49<pumpkin>bnijk: oh no!
05:41:53<bnijk>ACTION is heartbroken
05:42:04<ski>(however, i don't atm recall whether they're actually in `Eq' ..)
05:42:15<chromakode>ski, they are :(
05:42:19<bnijk>reddit keeps showing ads saying "You remember ________" and then a picture of a game, where that happens, and it's creeping me out because i DO remember them, and ALL of them
05:42:35<bnijk>not to mention all the chatbots i've seen recently which appear to be sentient
05:42:39<Gracenotes>is this really so
05:42:41<chromakode>you should give the marketers a pat on the back, then
05:42:52<pumpkin>it's just trying to send you to the games subreddit
05:43:03<chromakode>man, is everyone here a redditor?
05:43:12<bnijk>we're all internet deities i assume
05:43:19<bnijk>i'm loki, which makes pumpkin.....venus
05:43:30<chromakode>O_o
05:43:36<Gracenotes>pumpkin: I don't quite get why most reddit ads are internal
05:43:37<bnijk>ACTION inches closer to pumpkin
05:43:43<chromakode>Gracenotes: because they can
05:43:45<pumpkin>bnijk: #haskell-blah
05:43:50<Gracenotes>yeah, I know, but still..
05:48:51<ski>, let new :: Ix i => (i,i) -> a -> ST s (STArray s i a); new = newArray in runST (do board <- new (0,3) 'a'; bounds <- getBounds board; elems <- getElems board; board' <- newListArray bounds elems; return (board == board'))
05:48:53<lunabot> False
05:49:07<ski>, let new :: Ix i => (i,i) -> a -> ST s (STArray s i a); new = newArray in runST (do board <- new (0,3) 'a'; return (board == board))
05:49:08<lunabot> True
05:49:27<ski>, let new :: Ix i => (i,i) -> a -> ST s (STArray s i a); new = newArray in runST (do board <- new (0,3) id; return (board == board))
05:49:28<lunabot> True
05:49:47<ski>there
05:51:13<ski>(pumpkin : you were trying to compare `ST s'-actions, instead of arrays ..)
05:51:24<pumpkin>yeah, makes sense
05:52:01<ski>ACTION had a hard time convincing lunabot that those arrays actually were `STArray s's, though
05:52:59<bnijk>> drop 1 . take 2000 . show $ fix ("blah " ++)
05:52:59<lambdabot> "blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah...
05:53:04<bnijk>oh baby
05:53:41<ski> fix ("blah " ++) = cycle "blah "
05:54:58<Gracenotes>ski: sometimes you need scoped type variables too
05:55:22<quicksilver>Gracenotes: well you never *need* scoped type variables.
05:55:28<quicksilver>Gracenotes: but it can be a pain without them.
05:55:35<Gracenotes>ski: someone had written a module that acted as a specific "id" for mutable arrays to get around that issue
05:55:58<bnijk>> forever young
05:55:59<ski>ACTION tried with `foo :: forall s. ...; foo = do ...' as well as `board :: STArray s Int Char <- newArray ...' .. to no avail
05:56:00<lambdabot> Ambiguous occurrence `forever'
05:56:00<lambdabot> It could refer to either `L.forever', defin...
05:56:04<bnijk>mmn
05:56:16<Gracenotes>ski: which helped to infer the correct type
05:56:56<bnijk>> foreverr "young"
05:56:57<lambdabot> "youngyoungyoungyoungyoungyoungyoungyoungyoungyoungyoungyoungyoungyoungyoun...
05:57:01<bnijk>get it?
05:57:05<bnijk>ACTION winces
05:57:07<pumpkin>heh
05:57:17<Gracenotes>forever for [] actually doesn't do anything
05:57:35<Gracenotes>it makes more sense for IO
05:58:03<ski>(and for expression-monads ..)
05:58:07<Gracenotes>@undefine forever
05:58:24<ski>`undefine' doesn't take an argument
05:58:41<Gracenotes>eesh. messy system.
05:58:41<pumpkin>(his function was foreverr)
05:58:56<Gracenotes>I know, but there's a duplicate forever as well
05:59:33<ski>> forever Nothing
05:59:34<lambdabot> Nothing
05:59:40<Gracenotes>*there was
05:59:45<Gracenotes>eesh, no extraneous PM @lets. Such a mess to clean up :/
05:59:52<bnijk>ACTION burps
05:59:53<pumpkin>> forever id 5
05:59:57<pumpkin>:)
05:59:59<lambdabot> mueval-core: Prelude.read: no parse
05:59:59<lambdabot> mueval: ExitFailure 1
06:00:21<bnijk>> foreverr "disco-dancing "
06:00:22<lambdabot> "disco-dancing disco-dancing disco-dancing disco-dancing disco-dancing disc...
06:00:40<amckinley>how does lazy evaluation work with monads?
06:00:53<pumpkin>no differently
06:01:03<pumpkin>they're just another typeclass
06:01:13<pumpkin>or instances of one :)
06:01:42<amckinley>pumpkin: so if i have something like "regularList <- someActionThatReturnsAList" in my monad, that doesnt force the evaluation of the list?
06:02:08<pumpkin>nope, it's just syntactic sugar for someActionThatReturnsAList >>= \regularList ->
06:02:19<Gracenotes>well, monads do sequence things, but it might be possible for a monad's current state to include unevaluated parts of previous actions
06:03:06<amckinley>neat, thanks
06:03:47<Gracenotes>now, there are monads that are informally considered "lazy" and those that are considered "strict", and as far as I can tell it's partly due to whether these unevaluated parts occur "naturally", and in practice, if stack overflows result...
06:03:52<ski>("sequence" here is different from "force" .. the former is on a high conceptual level, while the latter is on a low operational level)
06:04:45<Gracenotes>or, s/naturally/inherently/...
06:05:34<amckinley>Gracenotes: what im doing is writing a parser in parsec. ive got a parser called lexer and a parser called tokenizer. for tokenizer to return the next token, it might need to consume multiple lexemes
06:05:46<pumpkin>:o
06:06:41<amckinley>so im trying to figure out if i can do something like "lexemeList <- many lexer", or if that will consume the entire input stream
06:07:14<Gracenotes>hmmm... well, it might be simpler to split the lexing and tokenizing phases for the time being...
06:07:36<amckinley>Gracenotes: as in, make two calls to runParser?
06:08:56<Gracenotes>if you do have "lexemeList <- many lexer", it will consume as many as possible before moving onto the next step
06:09:11<amckinley>Gracenotes: yeah, just discovered that :/
06:09:52<amckinley>Gracenotes: if you can explain how i could turn my lexeme list into a Stream that i can build another parser around, that would do it :)
06:11:35<Gracenotes>amckinley: well. For better or worse, Parsec is a very general parser :)
06:11:49<Gracenotes>so instead of parsing a String, you could parse a [String]
06:12:36<Gracenotes>or in terms of GenParser: having a GenParser of [Char] instead of one of Chars
06:13:25<amckinley>Gracenotes: right. im actually using parsec 3, so i think its even easier
06:13:43<Gracenotes>in general it makes sense to lex and then higher-level parse, although it differs from case to case of course...
06:13:57<amckinley>Gracenotes: thats fine with me :)
06:14:06<amckinley>heres the type signature for my lexer:
06:14:07<amckinley>lexer :: Parsec String DnsParseState Lexeme
06:14:21<amckinley>so i would need a tokenizer that looks like
06:14:35<amckinley>tokenizer :: Parsec [Lexeme] DnsParseState Token
06:15:05<Gracenotes>you could sometimes combine the steps without much harm..
06:15:17<Gracenotes>ah, you're parsing DNS?
06:15:28<amckinley>Gracenotes: guilty as charged :) dns zone files
06:15:45<Gracenotes>just wondering, for a client or a server?
06:16:34<amckinley>for a parser :) im building a library for programatically interacting with dns zone files
06:17:11<Gracenotes>ah
06:17:37<amckinley>and then validating the resulting config and pretty-printing it back out
06:19:25<amckinley>Gracenotes: so can i just declare a function like that^ and everything will work? or do i need to make [Lexeme] an instance of Stream or something?
06:19:48<Gracenotes>uh. I think lists already are stream
06:19:50<Gracenotes>s
06:20:03<amckinley>Gracenotes: oh, that would make sense :)
07:00:57<profmakx>?users
07:00:57<lambdabot>Maximum users seen in #haskell: 658, currently: 566 (86.0%), active: 2 (0.4%)
07:12:12<eck>is there a way to get printf to automatically do (show x) if you try to printf x as a string, and x is an instance of Show?
07:13:35<lament>write a wrapper
07:16:16<ivanm>lament: can you for arbitrary positions, etc.?
07:17:16<eck>it looks like printf just exposes the PrintfArg typeclass
07:17:35<lament>yeah, printf has crucial bits that say "Its implementation is intentionally not visible from this module."
07:18:01<lament>probably the best way to do it is to poke augustss and ask him what to do? :)
07:20:01<ivanm>lament: though depending on what client he uses, you may have already poked him ;-)
07:27:50<augustss>eck: You can't do that in H98.
07:28:31<eck>why not?
07:29:15<saynte>augustss: oh, I wanted to ask you something about LLVM, have a moment?
07:29:44<augustss>eck: it would need overlapping instances
07:29:49<augustss>saynte: go ahead
07:30:31<saynte>great, so I was looking at your bindings, and discussing it with someone else here on the channel a few days ago but: is it possible to take an abstract (data-type) description of a function and generate a function using the LLVM bindings on Hackage?
07:30:56<augustss>yes
07:31:10<saynte>Ah... how? :)
07:31:23<eck>i see now, thanks
07:32:19<augustss>saynte: first you generate code for the function getting a function using C calling conventions and then you convert that to a Haskell function.
07:32:47<augustss>saynte: you can look at the BASIC package for a very simple example.
07:33:08<saynte>augustss: is this on hackage? I saw something on your blog I think...
07:33:19<augustss>saynte: it's on hackage
07:33:55<augustss>it's a rather special case, but it shows how
07:35:13<roderyk>gtk2hs - onButtonPressed is supposedly deprecated, but I can't find any examples of what to replace it with? any hints at what onEvent-like functions I should be reading in the api docs?
07:36:02<dmwit>sec
07:36:08<saynte>augustss: still looking at the BASIC package, getting hopeful :)
07:36:14<davidL>is the P complexity class closed under concatenation?
07:37:15<dmwit>roderyk: onClicked looks close
07:37:41<dmwit>That's not quite the same, I know.
07:38:05<dmwit>onButtonPress?
07:38:16<dmwit>Is that the one you're saying is deprecated?
07:38:27<dmwit>yes it is
07:38:50<roderyk>dmwit: onClicked is for a button, I'm looking for the one that gets the mouse (x,y) clicked position in a drawingArea
07:39:00<dmwit>I know, I know.
07:39:54<saynte>augustss: looking at Gosub, do you model the calls using branching, or do you use the `call' instruction from LLVM?
07:40:26<roderyk>supposedly there is a buttonPressEvent (which doesn't seem deprecated), but it just returns a signal. Don't know how the hook is expected to look like
07:41:13<roderyk>(not familiar enough with gtk to know why they deprecated onButtonPressed - and what is the expected alternative)
07:42:40<augustss>saynte: BASIC's gosub is too weird to use the call instruction.
07:43:19<augustss>saynte: for any sane language you'd use call
07:43:55<augustss>saynte: btw, the LLVM package also has a brainfuck compiler as an example
07:44:06<saynte>augustss: Heh, yeah. So I guess I'm not sure how to confert some abstract syntax in the way you describe.
07:45:15<saynte>augustss: I sort of "get" everything except how to go from a datatype like "Func [Args] Body" to the LLVM-hs version, which seems very strongly typed.
07:48:00<dmwit>roderyk: buttonPressEvent -- ?
07:48:39<augustss>saynte: you could have a typed abstract syntax tree
07:48:48<roderyk>dmwit: yea, I have no idea how to hook that signal into my program :)
07:48:55<saynte>augustss: Hmmm.
07:49:28<dmwit>roderyk: on drawWindow buttonPressEvent handler
07:49:42<dmwit>roderyk: on :: object -> Signal object callback -> callback -> IO (ConnectId object)
07:50:01<roderyk>dmwit: ah, ok. thanks :)
07:50:08<augustss>saynte: I've not actually written a compiler to LLVM for a language with interesting types, so I'm not sure what the best way is.
07:50:32<saynte>augustss: It's generally hard to do that, I think. Essentially with parsing you have to go from String -> a, without ever saying what 'a' is.
07:51:25<augustss>saynte: you can do that with an existentially quantified a
07:51:39<dmwit>roderyk: That was a fun puzzle, thanks! =)
07:51:58<roderyk>dmwit: I'm sure I'll be back with more =)
07:52:18<augustss>saynte: but I agree, it's a bit tricky
07:53:03<saynte>augustss: Yeah, existentially qualified may work, I'd have to think about it. Initially I think then you'd run into the problem that you could never pin down the type-class again when you wanted reconstruct the function.
07:54:08<saynte>augustss: I'll think about it a bit, see where it goes.
07:54:57<augustss>saynte: You'd basically have parse::String->exist a.Expr a, and codegen::forall a.Expr a->Code. And then you compose the functions.
07:55:31<augustss>saynte: the type variable has to disappear from the final Code
07:56:49<jaSync>hello everyone!
07:56:56<jaSync>is this real? http://n.juokutis.lt/index.php?i=0c2e93265b179f56d30f7e4cbc073c0d
07:57:25<saynte>augustss: Yeah, it's the `forall' part that that scares me :)
07:57:27<flux>hmm, seems like a trick
08:03:17<roderyk>dmwit: just found http://www.haskell.org/gtk2hs/docs/devel/Graphics-UI-Gtk-Gdk-EventM.html very enlightening; thanks for the tip :)
08:04:37<saynte>augustss: Thanks for the help though. Depending on the skill-level required for the existential quantification, I may see if I can wrap the C-bindings at a less-safe level of typing.
08:13:42<saynte>augustss: FFI.Core, yay, I think this may do it :)
08:27:51<Tarrant>Is it not possible to export constructors?
08:28:06<opqdonut>it is possible to not export them
08:28:08<opqdonut>:)
08:28:16<opqdonut>module Foo (Foo (), ...)
08:28:27<opqdonut>just the type Foo is exposed w/o constructors
08:28:38<dmwit>Tarrant: Specify which constructors you want to export after the data type; (..) for all of them.
08:28:43<dmwit>data Foo = Bar | Baz
08:28:53<pozic>I get a <<loop>>. How can I show what exactly the loop is?
08:28:58<dmwit>module Quux (Foo(Bar)) -- for example
08:29:05<dmwit>module Quux (Foo(..)) -- another example
08:29:15<opqdonut>pozic: you might want to try the ghci debugger
08:30:15<Tarrant>I was confusing: "data Shape = Circle ... | Rectangle ..." Rectangle and Circle as the type. They aren't Shape is.
08:30:43<pozic>opqdonut: when I remove one call to Debug.Trace.trace I get hClose: illegal operation (handle is finalized) and no longer then <<loop>>.
08:30:54<dmwit>Tarrant: Yep, it's a common mistake, and easy to make.
08:31:00<dmwit>You'll get the hang of it, though. =)
08:38:45<pozic>opqdonut: Also, ghci doesn't do loop detection, AFAIK.
08:39:16<opqdonut>yeah that might be
08:46:43<quicksilver>well it's not really loop detection, it's blackhole detection
08:46:58<quicksilver>I think ghci is capable of observing blackholes but they're less likely to happen, or something.
08:50:48<doserj>http://hackage.haskell.org/trac/ghc/ticket/2786
08:54:47<pozic>How can I make this work? (4 lines) http://paste.debian.net/38012/
08:57:28<dmwit>:t let both :: Arrow (~>) => (forall b. b ~> c) -> (b, b') ~> (c, c); both f = f *** f in both
08:57:29<lambdabot>forall (~> :: * -> * -> *) c b b'. (Arrow (~>)) => (forall b1. (~>) b1 c) -> (~>) (b, b') (c, c)
08:57:40<dmwit>pozic: What's wrong with exactly what you wrote?
08:58:04<dmwit>> let both :: Arrow (~>) => (forall b. b ~> c) -> (b, b') ~> (c, c); both f = f *** f in both length ("abc", [1, 2])
08:58:05<lambdabot> Couldn't match expected type `b' against inferred type `[a]'
08:58:13<dmwit>ah!
08:58:16<dmwit>I know what's wrong. =)
08:58:28<opqdonut>there really isn't any nice way to make that work generically
08:58:31<dmwit>> let both :: Arrow (~>) => (forall b. [b] ~> c) -> ([b], [b']) ~> (c, c); both f = f *** f in both length ("abc", [1, 2])
08:58:32<lambdabot> (3,2)
08:58:39<opqdonut>but yeah, a [a]-version will work
08:59:12<dmwit>Right, so this works only for lists. And yours works only for functions that are really, really polymorphic. =)
08:59:13<pozic>dmwit: I actually wanted it to work for anything. Not just lists.
08:59:29<dmwit>pozic: Yours works for functions that can actually take anything.
08:59:35<dmwit>Not very many (useful) functions do that.
09:00:37<pozic>dmwit: oh, actually, I think I know the right type then.
09:00:48<dmwit>ACTION notes that "both f" is not that much shorter than "f *** f"
09:01:00<quicksilver>inferring the most general rank n type to satisfy a set of constraints is known to be "hard" ;)
09:01:01<Twey>It's more readable, though
09:01:13<Twey>And doesn't require brackets in places where (f *** f) does
09:01:14<dmwit>Yeah, I guess it could be.
09:02:45<ivanm>quicksilver: in kuribas' mode, is tab meant to cycle back to the beginning again when you've tabbed your way to the end?
09:03:00<pozic>dmwit: both :: Arrow (~>) => (forall b. container b ~> c) -> (container b, container b') ~> (c, c) works for any kind of container. Only, it still doesn't really do what I intended it to do.
09:03:05<doserj>ivanm: no
09:03:13<ivanm>*nod*
09:03:14<pozic>dmwit: this only works for one specific use-case.
09:03:28<ivanm>OK, from quicksilver's initial description the other day I thought it did
09:04:01<bastl>What is the best way to install GHC 6.10 on Ubuntu 9.04 on amd64 architecture? Are there binaries somewhere or should I compile from source ?
09:04:04<opqdonut>pozic: you see the problem is that "both f" forces both the fs in f *** f to have the same type
09:04:24<dmwit>:t \f -> (f . Left) *** (f . Right)
09:04:25<lambdabot>forall c b b1. (Either b b1 -> c) -> (b, b1) -> (c, c)
09:04:25<opqdonut>which needs to bee something like the union of b->c and b'->c in this case
09:04:29<pozic>opqdonut: yes, but "same type" is not actually needed.
09:04:38<opqdonut>yes, but it still forces it
09:04:46<dmwit>:t either length length
09:04:46<ivanm>bastl: is keeping ubuntu a pre-condition? :p
09:04:47<lambdabot>forall a a1. Either [a] [a1] -> Int
09:04:50<pozic>opqdonut: yes, that's what Haskell 98 does.
09:04:53<opqdonut>you need a much more powerful type system than haskells to express this
09:05:01<bastl>ivanm: what else?
09:05:06<opqdonut>not even arbitary rank polymorphism is enough
09:05:12<ivanm>get a distro with better haskell support?
09:05:19<bastl>e.g.?
09:05:25<ivanm>gentoo, arch
09:05:32<ivanm>even fedora 10 has ghc-6.10
09:05:33<pozic>opqdonut: what language can do that?
09:05:34<opqdonut>debian
09:05:35<kynky>arch seems to have really good support, i use gentoo
09:05:36<dmwit>:t let f = either length length; both f = (f . Left) *** (f . Right) in both f ("abc", [1, 2]) -- pozic: probably about the best you can do conveniently
09:05:37<lambdabot>(Int, Int)
09:05:40<opqdonut>err, i said union earlier, i guess i meant intersection
09:05:42<ivanm>(I can't recall which version though)
09:05:43<opqdonut>pozic: i really have no idea
09:05:49<opqdonut>dmwit's solution is nice
09:06:03<bastl>hmm. i live with ubuntu for some years quite good. but were getting OT.
09:06:22<bastl>so any answers to the above question?`
09:06:22<opqdonut>debian testing has 6.10, you could possibly backport that into ubuntu
09:06:24<dmwit>pozic: But that's really not better than just using (length *** length) in the first place.
09:06:50<pozic>dmwit: you are just using a let there, which nullifies the problem.
09:06:56<dmwit>pozic: Since the point was to avoid duplication (I guess), and we're just pushing the duplication onto the "either" instead of the (***).
09:07:03<pozic>dmwit: yes
09:07:35<dmwit>The let has nothing to do with it.
09:07:58<dmwit>Anyway, bedtime for me.
09:09:43<pozic>:t let f = [length] both f = (f . head) *** (f . head) in both f ("abc", [1, 2])
09:09:44<lambdabot>parse error on input `='
09:09:53<pozic>:t let f = [length]; both f = (f . head) *** (f . head) in both f ("abc", [1, 2])
09:09:54<lambdabot> Couldn't match expected type `a -> c'
09:09:54<lambdabot> against inferred type `[[a1] -> Int]'
09:09:54<lambdabot> In the first argument of `both', namely `f'
09:10:22<pozic>:t let f = [length]; both f = (head f) *** (head f) in both f ("abc", [1, 2])
09:10:23<lambdabot> No instance for (Num Char)
09:10:23<lambdabot> arising from the literal `1' at <interactive>:1:68
09:10:23<lambdabot> Possible fix: add an instance declaration for (Num Char)
09:12:39<dmwit>pozic: Is it really so bad to give your function a name and then call (foo *** foo)?
09:12:55<dmwit>pozic: I mean, this is exactly the use-case that let-polymorphism was made for.
09:13:04<dmwit>(Or any kind of polymorphism, really.)
09:15:31<Cale>:t let f :: [forall a. [a] -> Int]; f = [length]; both :: [forall a. a -> b] -> (c,d) -> (b,b); both f = (head f) *** (head f) in both f ("abc", [1, 2])
09:15:32<lambdabot>on the commandline:
09:15:32<lambdabot> Warning: -fno-th is deprecated: use -XNoTemplateHaskell or pragma {-# LANGUAGE NoTemplateHaskell#-} instead
09:15:32<lambdabot>Top level:
09:15:42<Cale>okay...
09:16:10<servotron3000>hey guys, one question. if i do getTemporaryDirectory, it returns /tmp. then i open a temporary file with openTempFile and give it that directory as the directory in which to be placed
09:16:32<servotron3000>if i try to move that file later, i get an error because /tmp and the directory into which i'm moving aren't on the same filesystem
09:17:21<Baughn>servotron3000: Yes..?
09:17:40<servotron3000>yeah well so is it better to just create the temporary file in .
09:17:44<Baughn>servotron3000: The most obvious solution is to open the file in the directory you want to put it in the first place
09:17:51<servotron3000>and not mess with getTemporary Directory at all
09:18:00<Baughn>getTemporaryDirectory is for /temporary files/
09:18:11<servotron3000>ah i see, makes sense yeah
09:18:13<Baughn>eg. ones where you don't care where they are, and you'll be deleting them later
09:18:24<koala_man>servotron3000: you can't move between fs, only copy and delete the original
09:18:33<Baughn>(Actually, typically you'll be deleting them right after opening them, in case your program crashes)
09:18:42<Cale>Prelude Control.Arrow> let f :: [forall a. [a] -> Int]; f = [length]; both :: [forall a. [a] -> b] -> ([c],[d]) -> (b,b); both f = (head f) *** (head f) in both f ("abc", [1,2])
09:18:42<Cale>(3,2)
09:18:59<Cale>Needs -XImpredicativeTypes though
09:19:01<Baughn>servotron3000: The move syscall is actually called "rename". There's a reason for that. ;)
09:19:08<Feuerbach>What is the purpose of large number of empty lines at the beginning of chs files in gtk2hs?
09:19:11<servotron3000>ah :)
09:19:24<Cale>pozic: ^^
09:19:44<jeffz`>bastl: you can get the binary dist of ghc from haskell.org
09:19:51<Baughn>servotron3000: Unix files can have any number of names, but.. they all have to be in the same filesystem as the data they're linked to, and /that data/ can only be deleted or copied, not moved
09:20:43<luqui>@seen diakopter
09:20:43<lambdabot>diakopter is in #perl6. I don't know when diakopter last spoke.
09:21:00<servotron3000>aha i see, i didn't know that, so that's what was confusing me
09:21:13<Badger>Why is lambdabot in #perl6? o_O
09:21:17<pozic>Cale: that was just a try to show that either was not needed, but still doesn't solve the original problem. Thanks, for showing that it was possible, though.
09:21:39<jeffz`>Badger: you might ask why is lambdabot in any channel?
09:21:59<BONUS>maybe it's learning perl?
09:22:06<Badger>hahaha
09:22:14<Baughn>servotron3000: Filesystems are contiguous sections of disk space. rename can work fast because it only deletes and recreates a name, but moving the file itself to another filesystem necessarily requires copying all the data; you can't say "these four hundred bytes are now part of this other filesystem". NEver mind if they are on different disks..
09:22:21<shachaf>The Perl people want karma.
09:22:22<shachaf>@karma-all
09:22:22<lambdabot> "moritz" 655
09:22:22<lambdabot> "pmichaud" 451
09:22:22<lambdabot> "lwall" 354
09:22:23<lambdabot> "jnthn" 348
09:22:25<lambdabot> "pmurias" 319
09:22:27<lambdabot>[1341 @more lines]
09:22:37<servotron3000>ah, isee. that makes sense.
09:23:39<Baughn>servotron3000: For what it's worth.. that's unix. Other systems could /theoretically/ act differently, but I'm pretty sure none do; the architecture that causes this is pretty basic.
09:24:01<Cale>shachaf: The perl people cheat by having a bot give them karma in lambdabot whenever they commit patches :)
09:24:06<Baughn>Though some (windows) only allow one name per file
09:24:22<servotron3000>is getCurrentDirectory basically just return "."?
09:24:31<ivanm>Cale: this is why I think we should split lambdabot into two instances: haskell and non-haskell
09:24:39<ivanm>servotron3000: either that or the full path
09:24:44<shachaf>They have their own bot in there anyway.
09:24:44<Baughn>servotron3000: It returns the current directory. You can /change/ the current directory too, so not really.
09:24:45<ivanm>different for windows though I think
09:24:48<Twey>And Perl needs a *lot* of patching... :-P
09:25:00<ivanm>Twey: lol
09:25:02<Baughn>servotron3000: However, . is bash's way to say "current directory", so basically yeah
09:25:06<Twey>Oh look, there's Larry Wall
09:25:18<Twey>I would think that it would make more sense to have separate karma databases for each channel
09:25:37<Baughn>@karma conal
09:25:40<lambdabot>conal has a karma of 4
09:25:44<shachaf>Is Pugs even still alive?
09:25:56<ivanm>shachaf: I believe it is
09:25:58<Twey>Alive and kicking
09:26:05<paolino>hi, is it any true that ContT c (State s) is leaking probably less than StateT s (Cont c) , when usinf callCC ?
09:26:11<ivanm>Twey: in some cases, it's valid to share it
09:26:16<ivanm>e.g. #haskell and #xmonad
09:26:26<Twey>I don't think so
09:26:35<Twey>Maybe #haskell and #haskell-fr
09:26:40<shachaf>Karma is karma. Why wouldn't it be shared?
09:26:46<Twey>But #xmonad is about XMonad, and #haskell is about Haskell
09:26:50<ivanm>shachaf: because the perl people cheat?
09:27:06<Twey>It's no more the same topic than ##c and #firefox
09:27:09<ivanm>Twey: there's a fair amount of overlap
09:27:24<ivanm>there's haskell talk in #xmonad sometimes, and xmonad talk in #haskell sometimes
09:27:33<BONUS>?umtl ContT r (State s) a
09:27:33<lambdabot>(a -> s -> (r, s)) -> s -> (r, s)
09:27:45<BONUS>?umtl StateT s (Cont r) a
09:27:46<lambdabot>s -> (a -> s -> r) -> r
09:27:53<shachaf>ivanm: So that's the problem. Work on the cheating. :-)
09:28:10<Twey>ivanm: Yes, but there *shouldn't* be
09:28:14<shachaf>Twey: The whole concept of karma is per-person, not per-person-per-channel.
09:28:14<BONUS>why does umtl always curry stuff like (a,s) -> r
09:28:41<ivanm>shachaf: which is why I'm saying we should have a haskellian lambdabot and a non-haskellian lambdabot
09:28:58<shachaf>ivanm: ?
09:28:59<paolino>BONUS: where ?
09:29:03<shachaf>What has that to do with cheating?
09:29:13<ivanm>shachaf: let the pugs people have their own lambdabot
09:29:35<Baughn>Twey: It's sort of inevitable, when half the questions in #xmonad are about the crazy configuration language. ;)
09:29:39<BONUS>well unnewtyped StateT s (Cont r) a is s -> ((a,s) -> r) -> r
09:29:46<Twey>Heheh
09:29:48<BONUS>but umtl says it's s -> (a -> s -> r) -> r
09:29:56<BONUS>it's isomorphic, but still why does it do it
09:29:58<Baughn>Twey: And while haskell is sort of off-topic in #xmonad, xmonad is not off-topic here
09:30:42<shachaf>ivanm: Why?
09:31:15<Twey>Baughn: Why is that?
09:31:24<shachaf>Karma is karma. If karma is given for helping people, say, and you help someone in #perl6, you should get the karma just the same.
09:31:30<BONUS>what do you mean exactly by "is leaking less"?
09:31:46<ivanm>shachaf: 1) it will increase stability from lambdabot crashing all the time (I think...), 2) we avoid all the non-haskellian quotes, karma, etc.
09:32:17<shachaf>@faq Can Haskell be used for real-world programs?
09:32:18<lambdabot>The answer is: Yes! Haskell can do that.
09:32:20<Baughn>Twey: Beyond being a useful program, xmonad is also an interesting example of how to use haskell well
09:32:26<shachaf>There you go, on-topic. :-)
09:32:37<Baughn>Twey: (Though I'd prefer it to be programmed using FRP. Oh well. :P)
09:32:39<Twey>shachaf: Is karma for helping people in #politics useful information for people in #haskell to know?
09:32:39<paolino>BONUS, that the more Cont monad is inside the more big contexts are saved for each callCC
09:33:03<paolino>(I'm asking, really)
09:33:04<Twey>Baughn: Of course, it is, but a program is not the same as the language in which it's programmed
09:33:22<shachaf>Twey: Yes. Karms is (supposed to be) this weird universal thing that comes back to haunt/help you in unexpected ways and places, right?
09:33:26<Twey>Like I said, you don't go to ##c asking for help to set a bookmark in Firefox
09:33:32<Baughn>Twey: Of course, but in practice #haskell isn't just about haskell-the-language; it's also about everything surrounding that
09:33:32<Twey>shachaf: Well, yes
09:33:47<Baughn>Twey: Such as how other people have used it, why they've done so, the details of their programs..
09:33:50<shachaf>Of course! And if lambdabot was in ##c, I wouldn't ask Haskell questions there.
09:33:58<Baughn>..it is
09:34:02<Baughn>Well, /a/ \bot is
09:34:46<Twey>shachaf: But the Internet concept of ‘karma’ is a little different, from what I've seen
09:35:11<Twey>It's used as a sort of status indicator, to show who can be trusted to give good advice
09:35:21<paolino>it's trust
09:35:24<shachaf>Eh, it shouldn't really be. A nice helpful interesting person is pretty universal.
09:35:49<Baughn>I don't know. I don't think anyone ever actually /uses/ karma for that
09:35:51<pozic>Twey: the karma system has no security. It's a silly number.
09:35:52<Twey>shachaf: But being helpful requires knowledge of the subject base
09:35:59<Baughn>Add to people's karma, yes, but check it? I've never seen that.
09:36:07<Twey>pozic: Sure, but it's an indicator
09:36:19<Twey>Maybe not a very reliable one
09:36:28<pozic>Twey: only because nobody seems to game it.
09:36:39<Twey>Except the Perl folks? :-P
09:36:45<paolino>Baughn: because it's not showed with the name, i suppose
09:40:31<Baughn>paolino: Right. Which makes this whole discussion relatively moot.
09:41:00<paolino>ACTION googles moot
09:41:07<Baughn>No! Don't!
09:41:24<Cale>Heh, some of the nonsense that Google Squares is capable of generating when you ask it stupid questions is funny. It suggested a 'Genre' column for my 'web browsers' square, which I added. Apparently Mosaic is Jazz, and Opera is Classical.
09:41:48<Cale>(Firefox is Browser)
09:41:51<Twey>Google Squares?
09:41:57<Twey>ACTION googles Google Squares
09:42:00<Cale>http://www.google.com/squared
09:42:10<Cale>Squared, sorry
09:42:28<Cale>(The tables you generate are called squares)
09:43:06<Twey>Heh... it's got some way to go
09:43:28<Baughn>Hm. I get "hip hop" for mosaic
09:43:39<Baughn>While firefox' genre is.. "browser". ^^;
09:43:45<Baughn>Opera's is,er, opera.
09:43:52<doserj>http://en.wikipedia.org/wiki/Mosaic_(jazz_album)
09:43:54<Cale>ACTION tries adding Genre columns to other tables... cloud types... Cumulus cloud -> Avant-Garde, Altostratus -> New Age, Stratus -> electronica, Stratocumulus -> Techno.
09:44:47<Cale>Contrail -> Rock
09:44:48<Twey>Haha
09:45:12<joga>heh, I tried searching for "programming languages" and it gave a nice chart, then I added a 'difficulty' column and it said "no value found" for all but Forth, which it gave "Hell" :)
09:46:26<Cale>Haskell is Rock, apparently
09:46:30<servotron3000>hmm, does every system use . for the current directory?
09:46:39<Baughn>Pretty much.
09:46:41<servotron3000>i.e. is it more portable to use getCurrentDirectory instead of just saying "."
09:47:21<paolino>@suorce getCurrentDirectory
09:47:21<lambdabot>getCurrentDirectory not available
09:47:37<shachaf>Hmm, you can add a Score field to most things.
09:47:55<Cale>Hahaha... Mathematica's Genre is Poetry -> Humorous
09:49:07<Twey>Cale: Haha :-P
09:49:38<Twey>Hm
09:49:43<Cale>Heh, the Score column is also amusing.
09:49:55<Twey>I get ‘Mathematical computation, symbolic, graphs, function plot’
09:50:03<Twey>11?
09:50:54<shachaf>"rotation" is apparently "science fiction
09:50:58<shachaf>"
09:51:12<Cale>Here are the scores of some scientists: Sir Isaac Newton: 401, Archimedes: 489, Albert Einstein: 11), Benjamin Franklin: 288, Stephen Wolfram: 2228815.
09:51:19<shachaf>Er, "reflection", rather.
09:51:44<Twey>Haha, Wolfram|Alpha got a score of ‘5, Informative)’
09:51:51<Twey>Thanks /.
09:51:51<Cale>haha
09:52:08<shachaf>Hmm. "Google" is listed as "comedy".
09:52:11<shachaf>Seems accurate...
09:52:15<Twey>Hehe
09:57:10<quicksilver>opqdonut: but unrestricted higher rank unification is undecidable, right?
09:59:03<amckinley>hey, can someone help me figure out why this doesnt work? http://www.hpaste.org/fastcgi/hpaste.fcgi/view?id=5559
09:59:16<otulp>A question re. Data.CompactMap and resources: I have a map of 2GB data distributed over 50k keys. Keys are of a type Coord !Int64 !Int64 and the values are lists of mostly just one fat element. Extracting the keys to a list works just fine, but trying to lookup a value results in a heap that outgrows the available memory (8GiB). The reason I'm using CompactMap is that just trying to build a normal Map would eat all memory. Does ...
09:59:18<amckinley>im getting *** Exception: Text.ParserCombinators.Parsec.Prim.many: combinator 'many' is applied to a parser that accepts an empty string.
09:59:22<otulp>... anybody have a clue what I'm doing wrong, or if perhaps my expectations of Map and CompactMap performance are a tad too high?
09:59:31<amckinley>when i call (many tokenizer)
09:59:44<amckinley>which is *madness*, because tokenizer doesnt even operate on strings :P
10:00:33<Berengal>amckinley: It means tokenizer can succeed without consuming any input
10:01:06<amckinley>Berengal: is that because im calling getInput without calling setInput?
10:01:06<Berengal>At least it thinks it can
10:01:25<Cale>amckinley: all parsers operate on strings of some sort :P
10:01:43<Berengal>amckinley: My guess is yes
10:02:13<amckinley>Berengal: more interestingly, is there some other way to interact with a Stream that isnt string-based besides calling get/setInput?
10:02:25<quicksilver>sure.
10:02:31<quicksilver>use the combinators.
10:03:17<amckinley>quicksilver: how? my parser isnt character-based: i did a full lexing pass that produces a list of [Lexeme]
10:03:58<quicksilver>I understood your question.
10:04:09<quicksilver>The majority of the combinators do not assume [Char]
10:04:27<quicksilver>none of the combinators in ".Prim" assume [Char]
10:04:33<Cale>otulp: hmm
10:04:40<quicksilver>nor any of the ones in .Combinator
10:04:52<quicksilver>they're all parameterised by an arbitrrary token typ 'tok'
10:04:59<amckinley>quicksilver: i guess the part i dont understand is how to get access to the underlying list
10:05:50<amckinley>i guess anyToken would wpork
10:05:53<amckinley>*work
10:05:54<Cale>otulp: that's interesting. How well does printing the toList of the CompactMap work?
10:06:12<Cale>otulp: It will probably consume lots of memory at some point, but how quickly, and when?
10:06:20<otulp>Cale: Wow. I haven't tried. That would be one large string.
10:06:38<otulp>I'll have a go..
10:06:40<quicksilver>amckinley: yes, anyToken for example.
10:06:53<quicksilver>amckinley: or primTokenBlah for more complex tricks
10:07:56<Cale>otulp: Also, it's almost a silly question, but you are compiling with -O2, right?
10:08:01<otulp>Cale: It behaves pretty much like the lookup does. Consumes all RAM, then grinds to a halt.
10:08:19<Cale>otulp: Does it least get as far as printing the first index?
10:08:20<otulp>Cale: Compiled using ghc and -O2, yes.
10:08:30<otulp>Cale: Nope. No printout.
10:08:35<RickBarnev>what is the solution to: map length []
10:08:36<Cale>Oh, right, when compiled, maybe it's line buffered too..
10:08:37<RickBarnev>?
10:08:48<amckinley>quicksilver: thanks, that works. where are the primTokenBlah functions hanging out?
10:08:49<Cale>RickBarnev: []
10:08:53<Cale>> map length []
10:08:54<lambdabot> []
10:09:01<RickBarnev>tnx
10:09:20<quicksilver>amckinley: .Prim
10:09:22<Cale>RickBarnev: If you don't have ghci, I would recommend getting that
10:09:33<Cale>RickBarnev: it comes with ghc
10:09:34<RickBarnev>I have
10:09:40<RickBarnev>ok tnx
10:10:17<Cale>... oh well :)
10:11:04<mmorrow>@pl \(a,b) -> f a (g b)
10:11:04<lambdabot>uncurry ((. g) . f)
10:11:44<mmorrow>@pl \a b -> f a (g b)
10:11:44<lambdabot>(. g) . f
10:11:50<mmorrow>@pl \a b c -> f a (g b (h c))
10:11:51<lambdabot>(. ((. h) . g)) . (.) . f
10:12:15<Cale>otulp: hmm -- and you've tried Map and it failed?
10:12:26<mmorrow>@type \f g h -> (((. h) . g) . f)
10:12:27<lambdabot>forall b c a b1 a1. (a1 -> b1) -> (b1 -> b -> c) -> (a -> b) -> a1 -> a -> c
10:12:39<Cale>otulp: I've never tried CompactMap myself.
10:13:14<otulp>Cale: Yes. Map would simply run out of memory while constructing with fromList.
10:13:19<mmorrow>@pl \a b -> f b (g a)
10:13:19<lambdabot>flip f . g
10:13:38<mmorrow>@unpl (((. h) . g) . f)
10:13:38<lambdabot>(\ d m -> g (f d) (h m))
10:13:43<Cale>otulp: I suspect that's what's happening with CompactMap, only the construction is deferred until the first access
10:13:43<mmorrow>forgot about @unpl
10:14:15<mmorrow>@unpl ((((. d) . c) . b) . a)
10:14:16<lambdabot>(\ h q -> c (b (a h)) (d q))
10:14:24<mmorrow>@unpl (((((. e) . d) . c) . b) . a)
10:14:24<lambdabot>(\ i u -> d (c (b (a i))) (e u))
10:14:53<Cale>otulp: For such a large amount of data, an indexing scheme which kept the actual contents on disk or something would seem more appropriate...
10:15:00<otulp>Cale: What's interesting is that I've successfully written the structure to disk with Binary's encodeFile. Shouldn't that mean that the full map was created?
10:15:10<Cale>oh, well, that is interesting
10:15:52<otulp>Cale: Hehe. Well.. This is the indexing data. :)
10:17:04<SavMyDreams>http://savemydreams.blogspot.com/
10:17:31<Cale>otulp: The lists are mostly one element, or always one?
10:18:34<Cale>Well, I would expect only mostly one, or you wouldn't be using lists...
10:20:02<otulp>Cale: Mostly. A select few are as many as 1920 elements.
10:20:31<otulp>All the others are one.
10:23:09<Cale>If push comes to shove, separating the few which really need to be in lists might save some space. I'm not certain how *much* space, as I'd expect the Binary instance for lists to already be pretty compact.
10:24:28<Cale>Apparently the representation is counted
10:24:40<Cale>So it puts the length of the list followed by each of the elements.
10:25:40<Cale>ah, and the instance for Int assumes 64 bits.
10:26:04<Cale>So that'll be 8 bytes per element, to store what is usually a 1
10:26:11<EvilTerran>Cale, ... so the first cell gets held for outputting the elements, while the spine is forced counting the length
10:26:39<EvilTerran>not that that should be a problem if there aren't very many long lists
10:26:43<otulp>Cale: Still.. that would be n*8*50k, which is still not much compared to the data contained in the list?
10:26:56<Cale>ah, there are 50k keys?
10:27:03<otulp>Yup.
10:27:36<Cale>Yeah, that can't be the problem then, it must be the elements themselves which are the problem.
10:27:54<Cale>In fact, if that's the case, I don't see why Map won't do.
10:28:31<otulp>Me neither. :)
10:28:56<Cale>So I don't think it's the associative structure itself.
10:29:05<Cale>What is the element type of the map?
10:29:16<Cale>[Something]...
10:30:17<inbuninbu>what's the best way to override a default fail in a monad?
10:30:30<Cale>Don't use fail
10:30:53<inbuninbu>i'm using the Data.Binary.Get monad, though
10:31:02<inbuninbu>and if there's an unexpected EOF
10:31:08<inbuninbu>then it fails
10:31:12<otulp>Cale: The map is Map Coord [Blk], where Coord is data Coord !Int64 !Int64, Blk is data Blk !FilePath !Int64 !Int64 (Array Int Int64) (Array Int Int64) (Array Int Int)
10:31:43<Berengal>ACTION thinks fail should've been called epicFail
10:32:00<otulp>Cale: ...deriving Eq, Ord for Coord.
10:32:01<Cale>inbuninbu: Yeah, it calls error in that case, since that monad doesn't really handle failure.
10:32:09<EvilTerran>Berengal, nah, epic should be a combinator of its own
10:32:28<Cale>inbuninbu: Though it does manage to print a message about the position at which it failed.
10:32:34<EvilTerran>"epic fail", "epic error"...
10:32:37<Cale>inbuninbu: Get (error (err ++ ". Failed reading at byte position " ++ show bytes))
10:32:40<otulp>Cale: And the arrays are unboxed.
10:32:53<inbuninbu>Cale: yes, unfortunately i've seen that error too often
10:33:02<Berengal>EvilTerran: How does one add epicness to functions though?
10:33:06<Cale>otulp: Wouldn't they be UArray then?
10:33:07<Berengal>I mean, fail already has it...
10:33:24<EvilTerran>Berengal, uhhh...
10:33:36<inbuninbu>Cale: this is network-oriented, so of course network failure could crash a program in this instance
10:33:40<otulp>Cale: They're A.Array, where A is Data.Array.Unboxed
10:33:41<Berengal>> let epic = fix in epic error
10:33:42<lambdabot> "* Exception: * Exception: * Exception: * Exception: * Exception: * Excepti...
10:34:05<EvilTerran>Berengal, yeah, that's what i was thinking
10:34:05<inbuninbu>Cale: will wrapping everything in Maybe do it?
10:34:09<EvilTerran>although then epic fail = ""
10:34:26<Berengal>> let epic = fix in epic fail
10:34:26<Cale>inbuninbu: Right, so you should not use pattern matching on the left of <- in do-notation and don't explicitly call fail
10:34:27<lambdabot> ""
10:35:24<Cale>inbuninbu: making use of Maybe is one way to help things, but it's not magic
10:35:33<inbuninbu>Cale: but when i run runGet someGetAction bytestring
10:35:36<Cale>inbuninbu: You just have to write functions which result in Maybe values.
10:35:55<inbuninbu>if there is any EOF at any point in someGetAction, it seems to fail
10:36:39<quicksilver>inbuninbu: Data.Binary.Get isn't really designed to be used on a bytestring which is wrong.
10:36:49<quicksilver>inbuninbu: (if you see what I mean)
10:36:52<Cale>inbuninbu: The Data.Binary stuff is mostly good when you have absolute control over the binary format being sent and where you are fairly certain there will be no error.
10:37:00<quicksilver>it doesn't have any sensible way to flag error.
10:37:12<quicksilver>You should only feed it bytestring which you know to be the right thing.
10:37:41<quicksilver>in particular, it's not appropriate for network channels without a separate pre-validation step.
10:37:46<quicksilver>IMO.
10:37:48<inbuninbu>Cale,quicksilver: but then what else am i supposed to use? i need to worry about endianess
10:37:50<Cale>(In fact, it's mostly good for reading stuff which was also written with Data.Binary, and not much else)
10:38:04<quicksilver>inbuninbu: use it to decode the endianness by all means :)
10:38:08<quicksilver>but validate the data first.
10:38:22<quicksilver>Cale: no, that's not true.
10:38:35<quicksilver>Cale: possibly you're confusing Data.Binary (the class) and Data.Binary.Get/Put
10:38:55<quicksilver>Get/Put can be used to decode other know external formats - but only if you've somehow validated first.
10:39:07<quicksilver>or if you can arrange for every input to be valid.
10:39:15<Cale>Well, okay, yes.
10:39:25<quicksilver>(possibly using Maybe does this - every input is valid, but some inputs cause 'Nothing' as the result)
10:39:30<quicksilver>but it depends on the case.
10:39:45<Peaker>Cale: it could be nice if Data.Binary.Get was in a MaybeT to properly represent failure
10:39:47<inbuninbu>well my problem isn't validation; it's making sure there's enough data to parse
10:40:04<inbuninbu>if the data isn't valid, i can throw an error at a higher level
10:40:06<Cale>Peaker: Yeah, or was just a proper parser.
10:40:21<inbuninbu>i just need to read/write bytestrings to the network in a failsafe way
10:40:35<Peaker>Cale: I don't like monadic parsers, though -- backtracking is rarely necessary (everyone is context-free), especially in binary parsers
10:40:39<Cale>You know, you can use Parsec with bytestrings now.
10:41:40<quicksilver>inbuninbu: not enough data is one kind of invalid.
10:41:50<quicksilver>inbuninbu: at least, that's how I intended my comments to be understood.
10:42:02<Cale>hmm, but it seems to default to the Char8 variety of ByteStrings, so maybe you'd have to write a quick instance of Stream
10:42:04<inbuninbu>quicksilver: ah, ok
10:42:10<inbuninbu>well, it making a custom get monad with MaybeT an option?
10:42:22<inbuninbu>it=is
10:42:24<quicksilver>yes, it's an option.
10:42:36<quicksilver>but is eof observable in Get ?
10:42:42<quicksilver>ACTION forgets the api
10:42:44<Cale>It is...
10:43:07<Cale>http://hackage.haskell.org/packages/archive/binary/0.5.0.1/doc/html/Data-Binary-Get.html#v%3AisEmpty
10:43:22<quicksilver>yes, it is.
10:43:24<quicksilver>good.
10:43:26<Cale>see also right above that is remaining
10:43:41<quicksilver>inbuninbu: note that MaybeT (Get a) is really just Get (Maybe a)
10:43:52<Peaker>Cale: Char8 is its own ByteString type? I thought it was just a set of convenience functions (pack/unpack)
10:43:53<quicksilver>inbuninbu: the different is in how the combinators treat stuff :)
10:44:15<quicksilver>but Get (Maybe a) might be good enough.
10:44:20<Peaker>quicksilver: MaybeT (Get a) is not worth much because the get stuff that can fail aren't in it :(
10:44:36<quicksilver>Peaker: it's not really a different type but the api looks like it is.
10:44:38<Peaker>unless one wraps all of the Get combinators with ones that fail properly
10:44:49<quicksilver>Peaker: I'm not suggesting inbuninbu ever runs a failing combinator
10:44:54<quicksilver>I'm suggesting he checks first
10:45:04<quicksilver>which is why I was asking about remaining and isEmpty
10:45:09<Cale>Ah, okay
10:45:23<inbuninbu>actually, let me check, does ByteString.Lazy.hGet fail?
10:45:26<Cale>Right, it's not different.
10:45:38<Peaker>quicksilver: yeah, its what I do too
10:46:02<Peaker>Cale: there's actually ByteString.{Strict,Lazy}.Char8
10:46:21<quicksilver>inbuninbu: hGet is in IO so it throws a catchable IO exception I suspect.
10:46:36<Cale>Peaker: right, but the .Char8 just reexports the same type as the non-Char8 version
10:46:48<quicksilver>you don't get interlaved IO unless you call the despicable getContents or readFile, I hope.
10:46:59<Peaker>I dislike the code duplication w.r.t ByteStrings. And the fact they're just unboxed arrays of Char, and should probably be type-polymorphic. Type-classes shouldn't slow things down when the types are known at compile-time, but at least get rid of some code duplication
10:48:24<quicksilver>unboxed arrays of Word8, ITYM.
10:49:02<quicksilver>yeah, possibly it would be nice if there was a big bytestring interface that Strict/Lazy could both instance
10:49:17<quicksilver>although personally I quite like distinguishing rather visibly between the two
10:49:22<quicksilver>(L.hGet, S.hGet)
10:49:37<Peaker>quicksilver: ITYM? Its what I mean? Yeah
10:49:50<quicksilver>I Think You Mean.
10:49:53<Peaker>yeah
10:50:22<Cale>Unboxed and type polymorphic don't mix so well
10:50:24<Peaker>quicksilver: hGet :: L.ByteString -- nicer, carries the strict/lazy polymorphism to callers too
10:50:43<Peaker>Cale: Even if its the instances that are unboxed?
10:50:52<Peaker>(and might be boxed, too)
10:51:00<quicksilver>> length "hGet :: L.ByteString" - length "L.hGet"
10:51:01<lambdabot> 14
10:51:06<Peaker>I mean, the whole (UArray Word8) would be an instance
10:51:08<quicksilver>Peaker: 14 characters longer. No deal.
10:51:23<Peaker>quicksilver: heh, you could alias L.ByteString to LBS if you want
10:51:34<Peaker>> length "hget :: LBS" - length "L.hGet"
10:51:35<lambdabot> 5
10:51:46<maltem>type LazyByteString = LazyString Word8; type StrictByteString = StrictString Word8 -- ?
10:51:57<Peaker>not to mention "characters" is not a nice measure, and not to mention you're not likely to use the forced type everywhere, but only once somewhere
10:52:08<Peaker>quicksilver: its likely it will shorten code, actually, because you'll just remain polymorphic
10:52:11<Peaker>quicksilver: so its just hGet
10:52:22<quicksilver>btu I don't *want* to be polymorphic.
10:52:26<Cale>Peaker: well, that much works
10:52:35<quicksilver>if I'm writing for bytestrings, I want to know if it's strict or laxy
10:52:40<quicksilver>the semantics is very different.
10:53:38<Peaker>quicksilver: yeah, but you can force the strict/lazy behavior from above, and allow the functions below to be more useful by allowing both. Only if it makes no sense to allow both (probably a minority of the functions) you should force the types, and then you don't need to do it by (:: ...) but just the function's type signature + inference will do it for you
10:53:52<quicksilver>sure, I follow the argument.
10:54:01<quicksilver>I just disagree with (probably a minority)
10:54:06<maltem>quicksilver, fwiw, the semantics of IO and Reader are very different, too
10:54:16<quicksilver>the only time you would ever use a bytestring in the first place is when you care deeply about the semantics.
10:54:23<quicksilver>sorry, abotu the efficiency
10:54:37<quicksilver>(was reading maltem's comment as I was typing, my brain stole a word)
10:54:38<Peaker>quicksilver: ok, but even if its a majority, its still not longer if you let inference do the job, most of the time (you eventually return or take a bytestring in those functions and you typically put a top-level type signature, right?)
10:55:05<inbuninbu>actually i think the simplest solution is to use the ByteString hGet
10:55:13<Peaker>quicksilver: yeah, but type-classes and UArray Word8 shouldn't harm performance here?
10:55:17<inbuninbu>if it reaches the end of the file, it doesn't throw an error
10:55:33<inbuninbu>it just returns what it can. so if it's too short, you can check before you call runGet
10:55:55<Peaker>@type Data.ByteString.hGet
10:55:56<lambdabot>GHC.IOBase.Handle -> Int -> IO BSC.ByteString
10:56:46<EvilTerran>muhahahaha
10:57:17<otulp>Cale: Oh well. Thanks for the input. I'm going to try to store all values in an array now instead, and possibly make a map of coords to array indices. It shouldn't work, but.. perhaps?
10:57:25<Peaker>EvilTerran: ?
10:57:54<Peaker>hmm. I keep rewriting traceId prefix x = trace (prefix ++ show x) x everywhere. Is it sane to cabalize just one function in something like a traceutils package?
10:57:57<inbuninbu>actually, hGet won't work either. you could lie in the header about the size of the payload
10:58:11<inbuninbu>that lets anyone make it crash
10:58:20<inbuninbu>if they really want to
10:58:43<Peaker>inbuninbu: I think you should just write Get primitives that check the length and format and return MaybeT Get instead of Get, calling get primitives only when they are certain that they cannot fail
10:59:02<quicksilver>inbuninbu: that's wthe kind of thing hat I mean about checking first
10:59:06<quicksilver>;)
10:59:16<quicksilver>you probably want to do saity checks anyway.
10:59:23<inbuninbu>Peaker, quicksilver: thanks.
10:59:29<quicksilver>If the payload advertises a 4G message you may not want to read that, in fact :)
10:59:37<quicksilver>s/payload/header/
10:59:51<quicksilver>damn words. Always the wrong one in the wrong place. Sometimes I can't even understand myself.
11:00:38<Peaker>I wonder how Iteratee plays with ByteString handling of binary files?
11:04:44<ClaudiusMaximus>if i import Prelude(), ghci lets me use (:), but hugs doesn't (and i can't figure out the syntax to import it explicitly)
11:06:12<quicksilver>ClaudiusMaximus: import Prelude((:))
11:06:24<quicksilver>ghc makes (:) special. A bit too special, arguably.
11:06:34<Peaker>weird indeed. is it not a bug that GHC imports (:) and () and [] and lots of other stuff even if not requested to, from Prelude?
11:06:40<quicksilver>> let (:) = (+) in 1:3
11:06:41<lambdabot> Constructor `:' should have 2 arguments, but has been given 0
11:06:47<ClaudiusMaximus>quicksilver: ERROR "Test.hs":3 - Syntax error in import declaration (unexpected symbol ":")
11:07:07<quicksilver>ah, it's a constructor
11:07:11<quicksilver>I wonder what the syntax is
11:07:21<quicksilver>import Prelude([](:)) maybe ?
11:07:39<ClaudiusMaximus>quicksilver: ERROR "Test.hs":3 - Syntax error in import declaration (unexpected `[')
11:07:54<Peaker>I guess that's why GHC does this, there doesn't seem to be a syntax to do this
11:07:55<quicksilver>Peaker: I'm not sure if it's a bug relative to the standard or not. [], (:) and () are not merely symbols, they are actually syntax.
11:08:06<Peaker>probably list syntax sugaring is unnecessary
11:08:15<quicksilver>They're syntax which stands for symbol, obviously.
11:08:19<quicksilver>but they're technically syntax.
11:08:21<Peaker>1:2:3:[] is not so bad
11:08:58<inbuninbu>one other quick question... i was recently facing an issue where i had a monstrous (well, 30-odd line) case statement, and tried to figure out a way to make it shorter
11:08:58<Peaker>quicksilver: () is understandable (all tuples are), but (:) and [] shouldn't probably be syntax
11:09:05<inbuninbu>this is what i came up with:
11:09:07<inbuninbu>caseOneLine arg = snd $ head (filter ((\a (b,c)->a==b) ) $ zip [1..100] [action1,action2,action3,action4,action5])
11:09:27<inbuninbu>is there a better way to do this?
11:10:22<quicksilver>Peaker: (:) probably doesn't need to be.
11:10:25<quicksilver>Peaker: [] does.
11:10:34<Peaker>quicksilver: Only for [Int] rather than [] Int ?
11:10:51<Peaker>quicksilver: I think if [Int] is so nice, then other functors should also get to wrap around the type
11:11:28<Peaker>perhaps if : is the infix constructor, then [<symbols here> .. <and here>] should be the surrounding constructor
11:11:49<Peaker>inbuninbu: why is your filter taking a function of two args?
11:12:02<Peaker>ibid: did you not mean to compare with arg there, and not take a?
11:12:08<Peaker>inbuninbu: that is
11:12:08<inbuninbu>that should be: caseOneLine arg = snd $ head (filter ((\a (b,c)->a==b) arg) $ zip [1..100] [action1,action2,action3,action4,action5])
11:12:24<Peaker>inbuninbu: you know Haskell is lexically scoped, right? :)
11:12:32<Peaker>inbuninbu: you can use arg in the filter's lambda, without re-passing it into there
11:13:16<inbuninbu>i knew i was missing something :-)
11:13:17<Peaker>\arg xs -> snd $ head (filter (\(b,c)->arg==b) xs
11:13:20<Peaker>@type \arg xs -> snd $ head (filter (\(b,c)->arg==b) xs
11:13:21<lambdabot>parse error (possibly incorrect indentation)
11:13:29<Peaker>@type \arg xs -> (snd $ head (filter (\(b,c)->arg==b) xs)
11:13:31<lambdabot>parse error (possibly incorrect indentation)
11:13:35<Peaker>@type (\arg xs -> (snd $ head (filter (\(b,c)->arg==b) xs))
11:13:36<lambdabot>parse error (possibly incorrect indentation)
11:13:38<Peaker>sorry
11:13:55<Peaker>@type (\arg xs -> snd $ head (filter (\(b,c)->arg==b) xs))
11:13:56<lambdabot>forall b a. (Eq a) => a -> [(a, b)] -> b
11:14:05<Peaker>inbuninbu: you know this function is unsafe right?
11:14:09<Peaker>@type Data.List.lookup
11:14:10<lambdabot>forall a b. (Eq a) => a -> [(a, b)] -> Maybe b
11:14:19<Peaker>inbuninbu: You want to use Data.List.lookup which is safe
11:14:52<inbuninbu>right; mostly i was wanting it to work before being safe :-)
11:16:06<inbuninbu>but it's nice to know there's a out-of-the-box function that does it. i need to start looking at type sigs more carefully
11:16:36<Peaker>@type \key -> fromMaybe (print "missing key, do whatever here") . Data.List.lookup key $ [(1, print 1), (2, print 2)]
11:16:37<lambdabot>forall a. (Num a) => a -> IO ()
11:17:09<Peaker>inbuninbu: I wouldn't use zip there, because you might "mis-align" your list to handle the cases all wrong. Use explicit tuples IMO
11:18:40<inbuninbu>Peaker: i've got two algebraic data types actually, and derived enum on them both
11:18:54<inbuninbu>i guess i could map an offset (there's an offset on one)
11:19:07<inbuninbu>and then zip; it should be safe, since they are in the same order
11:19:20<inbuninbu>just need to make sure when i update on i update the other
11:19:33<inbuninbu>oh wait, that doesn't make sense :-/
11:20:10<Peaker>@hoogle Eq a => (b -> a) -> [b] -> b
11:20:10<inbuninbu>i call get methods based on the input type
11:20:10<lambdabot>Data.Generics.Schemes everywhere :: (a -> a) -> a -> a
11:20:10<lambdabot>Data.Generics.Schemes everywhere' :: (a -> a) -> a -> a
11:20:10<lambdabot>Distribution.Simple.Utils equating :: Eq a => (b -> a) -> b -> b -> Bool
11:20:30<Peaker>@hoogle Eq a => a -> (b -> a) -> [b] -> b
11:20:31<lambdabot>Distribution.Simple.Utils equating :: Eq a => (b -> a) -> b -> b -> Bool
11:20:31<lambdabot>Control.Parallel.Strategies parZipWith :: Strategy c -> (a -> b -> c) -> [a] -> [b] -> [c]
11:20:31<lambdabot>Distribution.ParseUtils simpleField :: String -> (a -> Doc) -> ReadP a a -> (b -> a) -> (a -> b -> b) -> FieldDescr b
11:20:54<Peaker>inbuninbu: zipping with some result and then running lookup deserves its own function
11:21:53<Peaker>@type \key f xs -> Data.List.lookup key . map (f&&&id) xs
11:21:54<lambdabot> Couldn't match expected type `a -> [(a1, b)]'
11:21:54<lambdabot> against inferred type `[(c, a2)]'
11:21:54<lambdabot> In the second argument of `(.)', namely `map (f &&& id) xs'
11:22:13<Peaker>@type \key f xs -> Data.List.lookup key . map (f&&&id) $ xs
11:22:14<lambdabot>forall a a1. (Eq a) => a -> (a1 -> a) -> [a1] -> Maybe a1
11:22:34<Peaker>@hoogle lookupBy
11:22:34<lambdabot>No results found
11:22:47<Peaker>inbuninbu: I think you should use that then. I'd call it lookupBy, and then (lookupBy offset) or whatever you have there
11:22:51<inbuninbu>Peaker: whoah, looking at strategies makes my brain hurt
11:23:01<Peaker>inbuninbu: strategies?
11:23:24<inbuninbu>Peaker: i don't know. i saw it from hoogle and looked
11:26:14<Peaker>inbuninbu: anyway, do you have lookupBy now? :-)
11:26:36<Peaker>@let lookupBy key f xs = Data.List.lookup key . map (f&&&id) $ xs
11:26:37<lambdabot> Defined.
11:27:20<Peaker>@type \default key f xs -> fromMaybe default $ lookupBy key f xs
11:27:21<lambdabot>parse error on input `default'
11:27:25<inbuninbu>Peaker: i'm still trying to understand exactly what's going on in it, from the context of my problem. didn't recognize &&& at first, have't really tried arrows yet
11:27:26<Peaker>@type (\default key f xs -> fromMaybe default $ lookupBy key f xs)
11:27:27<lambdabot>parse error on input `default'
11:28:03<ClaudiusMaximus>default is a keyword, i discovered that by accident today
11:28:14<Peaker>what is it for?
11:28:21<ClaudiusMaximus>defaulting types
11:28:27<ClaudiusMaximus>i think
11:28:32<Peaker>how?
11:28:33<Peaker>@type \def key f xs -> (fromMaybe def $ lookupBy key f xs)
11:28:34<lambdabot>forall a a1. (Eq a1) => a -> a1 -> (a -> a1) -> [a] -> a
11:28:48<Peaker>inbuninbu: This is the function I think you need
11:31:24<inbuninbu>Peaker: so... in the case of
11:31:30<inbuninbu>case x of
11:31:36<inbuninbu>10 -> action10
11:31:41<ClaudiusMaximus>Peaker: http://haskell.org/onlinereport/decls.html#sect4.3.4
11:31:45<inbuninbu>11 -> action11
11:32:18<inbuninbu>a woud be, say, 11
11:33:21<Peaker>wow, didn't know that feature existed at all
11:33:23<Peaker>ClaudiusMaximus: interesting
11:33:38<Peaker>though I think it is pretty much an inherently broken feature, which might be the reason its not well known
11:34:14<dcoutts>Feuerbach: you were asking about the spaces in .chs files, you're probably looking at the .chs file generated from a .chs.pp file, try looking at the original source file.
11:34:55<Peaker>inbuninbu: no no, if you have: case x of 10 -> action10 11 -> action11 _ -> actionDef then you need lookupWithDefault actionDef x [(10, action10), (11, action11)]
11:36:03<inbuninbu>Peaker: what is actionDef?
11:37:14<inbuninbu>ohhh
11:37:28<inbuninbu>Peaker: the default. i thought def meant definition
11:38:44<ivanm>@wn def
11:38:46<lambdabot>No match for "def".
11:38:53<ivanm>nope, def doesn't mean anything
11:38:56<ivanm>;-)
11:39:57<Feuerbach>dcoutts: oh, thanks, I thought .chs files were original.
11:47:14<inbuninbu>Peaker: i must be missing something
11:47:20<inbuninbu>let x = lookupByDefault (print "null") x [(10,print "ten"),(11,print "eleven")] results in an error
11:47:49<Peaker>inbuninbu: note your use of x in both places there?
11:47:57<inbuninbu>Peaker: yep
11:48:02<deiga>dons: Hey, I've tested your Network.Download package and it doesn't work. It install fine, but it sprays error message when trying to use it
11:48:53<Peaker>inbuninbu: you don't want x to be both the input, and the result, of lookupByDefault
11:49:19<deiga>dons: <interactive>: /usr/lib/download-0.3/ghc-6.10.3/HSdownload-0.3.o: unknown symbol 'stat64'
11:50:02<inbuninbu>shouldn't the result come from evaluating the entire expression?
11:50:35<quicksilver>inbuninbu: your definition is recursive.
11:50:38<quicksilver>those are the same 'x'
11:50:40<quicksilver>as in
11:50:46<inbuninbu>quicksilver,Peaker: thanks, duh
11:50:48<quicksilver>> let x = 1 : x in x
11:50:49<lambdabot> [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,...
11:50:54<inbuninbu>brainfart maneuver
11:51:47<komar_>How to force ./Setup to not touch package.conf?
11:53:59<inbuninbu>Peaker: apparently i'm in braindead mode: let y z = lookupByDefault (print "null") z [(10,print "ten"),(11,print "eleven")] still gives me the same error
11:54:58<inbuninbu> Couldn't match expected type `IO () -> ()'
11:54:59<inbuninbu> against inferred type `[a]'
11:55:07<Peaker>inbuninbu: how is lookupByDefault defined? I suggest naming it lookupWithDefault, and not ByDefault
11:55:45<inbuninbu>\def key f xs -> (fromMaybe def $ lookupBy key f xs)
11:58:55<LeCamarade>@hoogle postgresql
11:58:55<lambdabot>package PostgreSQL
11:58:55<lambdabot>package haskelldb-hdbc-postgresql
11:58:55<lambdabot>package haskelldb-hsql-postgresql
11:59:06<LeCamarade>?where postgresql
11:59:06<lambdabot>I know nothing about postgresql.
11:59:18<LeCamarade>?where haskelldb-hdbc-postgresql
11:59:18<lambdabot>I know nothing about haskelldb-hdbc-postgresql.
11:59:23<LeCamarade>?where haskelldb
11:59:23<lambdabot>http://haskelldb.sourceforge.net/
11:59:24<dancor>how do you add 1 day to a UTCTime
11:59:43<dancor>i can use addDays
11:59:53<dancor>ok, how do you add 8 hours to a UTCTime
11:59:53<LeCamarade>?where hsql
11:59:53<lambdabot>http://htoolkit.sourceforge.net
12:00:10<LeCamarade>dancor, Add it in seconds, if memory serves.
12:00:40<inbuninbu>Peaker: monomorphism problem?
12:02:35<LeCamarade>Is HaskellDB still alive? Or, what should I use to talk to PostgreSQL in Haskell?
12:02:52<Saizan_>hdbc?
12:03:23<LeCamarade>?where hdbc
12:03:23<lambdabot>http://quux.org/devel/hdbc
12:03:44<LeCamarade>@karma+ Saizan_
12:03:44<lambdabot>Saizan_'s karma raised to 4.
12:04:19<LeCamarade>Dear Jesus, I'm surfing Gopher! :-o
12:04:27<LeCamarade>For HDBC!
12:04:31<LeCamarade>http://gopher.quux.org:70/devel/hdbc
12:04:53<QtPlaty[HireMe]>I can't recall how long its been since i've used Gopher.
12:06:47<Saizan_>just look at the hackage page.
12:11:24<LeCamarade>Building HDBC, I get that System.Time cannot be found. Now, obviously I have it, and I have GHC 6.10. Why is this build being so insolent?
12:11:43<LeCamarade>And I checked the code, it looks like what I'd write to use System.Time.
12:11:46<LeCamarade>:o(
12:12:22<dancor>LeCamarade: there is also takusen. i have a patch out for adding support for postgres bytea
12:12:46<LeCamarade>?where takusen
12:12:46<lambdabot>I know nothing about takusen.
12:13:08<dancor>@where+ takusen http://hackage.haskell.org/cgi-bin/hackage-scripts/package/Takusen
12:13:09<lambdabot>Done.
12:15:22<quicksilver>LeCamarade: it's now in old-time
12:15:29<quicksilver>LeCamarade: it was moved in 6.10.somethingorother
12:15:44<quicksilver>I think.
12:16:11<LeCamarade>I've moved to Takusen.
12:16:20<LeCamarade>Is Takusen the one that Oleg was working on?
12:16:27<LeCamarade>The Oleg?
12:17:48<quicksilver>yes, that's right I believe.
12:21:40<Berengal>What's the quickest and easiest way to push pixels?
12:22:18<quicksilver>to the screen?
12:22:21<Berengal>Yes
12:22:32<quicksilver>quickest is probably opengl, or some other api which ultimate binds to it.
12:22:41<quicksilver>I've no idea what the easiest is
12:22:48<quicksilver>(almost certainly *not* opengl)
12:23:06<Twey>I don't know, OpenGL is pretty easy for pixel-pushing
12:23:19<Twey>It's just the complicated stuff
12:23:46<Berengal>I just want something like 'putPixel position color'
12:23:52<Twey>Yeah
12:24:23<quicksilver>Twey: I disagree.
12:24:25<Twey>Oh, but that's within a window, right?
12:24:38<quicksilver>Twey: you have to learn about viewports, transformations, textures, texture coordinates, pipelines, blending modes
12:24:42<Twey>If you want to do it over the whole screen you'll need the confusingly-named X11
12:24:45<quicksilver>Twey: that's a long pathway to just pushing a pixel :)
12:24:54<Twey>quicksilver: What, just to push a pixel?
12:24:57<ray>putPixel color position sounds better
12:24:59<quicksilver>Yes.
12:25:06<Twey>I was drawing polygons and I never knew what those things meant.
12:25:19<quicksilver>then someone else must have written the boilerplate code for you
12:25:26<quicksilver>or you copied it form somewhere.
12:25:29<Twey>Come to think of it, I was using GLUT
12:25:32<quicksilver>and polygons are easier than pixels, in opengl.
12:25:37<Twey>Truly? Huh.
12:25:49<ray>opengl isn't really meant to do pixels
12:26:01<quicksilver>it does it very well though.
12:26:08<quicksilver>I jsut doubt it would be the 'easiest' way :)
12:26:15<Twey>You could just do a tiny polygon. :-P
12:26:20<quicksilver>Berengal: you don't push pixels one at a time if you want decent performance though :)
12:26:35<Berengal>quicksilver: I'm not looking for performance. I just want to push pixels :P
12:26:41<Berengal>Besides, I've got a bitchin' GPU
12:27:24<ray>opengl isn't even really meant to do 2D
12:27:48<Twey>Silly OpenGL — current monitors are flat!
12:27:50<Berengal>I'm thinking about implementing an L-system, I just want to make sure I can draw the results when the time comes
12:28:18<ray>well, i guess it's meant to do 2D *projections*
12:28:31<Twey>Heh
12:28:41<dancor>how do i go from POSIXTime (= NominalDiffTime) to seconds?
12:28:47<ray>opengl 2D is just an orthographic projection
12:29:40<Saizan_>L-systems were the cairo bindings demo, iirc
12:29:44<Twey>dancor: What library are you using?
12:29:57<dancor>Twey: Data.Time
12:30:14<Twey>Why not System.Time?
12:30:28<quicksilver>because System.Time is deprecated
12:30:31<quicksilver>and has a broken API.
12:30:37<dancor>and is not in hoogle
12:30:46<dancor>my keyhole into the world of haskell
12:31:05<Twey>Oh really? Huh.
12:31:32<Saizan_>Berengal: http://haskell.org/gtk2hs/archives/2005/08/31/the-potential-of-pratical-haskell-2nd-edition/ and other posts
12:31:34<quicksilver>dancor: use realToFrac
12:31:43<quicksilver>dancor: it's a Num/Real/RealFrac instance
12:31:46<dancor>ok
12:31:48<Berengal>Saizan_: Nifty, thanks
12:31:48<LeCamarade>Takusen won't load Database.PostgreSQL.Enumerator.
12:31:50<LeCamarade>:o(
12:31:55<Twey>Boo
12:32:04<Twey>I just found it and someone had already answered :-P
12:32:06<LeCamarade>God, DBs are hard, eh? Let's stick to plain text. ;o)
12:32:30<quicksilver>dancor: if you mean "seconds since the epoch"
12:32:36<Berengal>Cairo, huh?
12:32:41<quicksilver>dancor: if you mean "seconds after the current hour" that's not what you want :)
12:32:57<dancor>i do mean since epoch
12:33:04<dancor>but it's already Fractional
12:33:22<quicksilver>yes but you can convert it to a Double.
12:33:28<quicksilver>or you can simply round it to an Int
12:33:30<quicksilver>:t round
12:33:31<lambdabot>forall a b. (RealFrac a, Integral b) => a -> b
12:33:37<quicksilver>because it is a RealFrac instance.
12:36:17<LeCamarade>Who uses Takusen here?
12:37:01<Berengal>round should work
12:47:41<ksf>opengl is fine for 2d.
12:48:21<ksf>...look at all that glRaster stuff, or just draw a textured fullscreen quad.
12:51:22<akamaus>I'm using Network.Browse module from http package. It's built around a custom monad BrowserAction which is a wrapper on IO. That's convenient, but how to handle exceptions there? 'try', 'catch' and the rest are in IO.
12:51:37<Peaker>ksf: Not very convenient, it isn't
12:53:52<ksf>akamus, there should be a liftIO somewhere... look at the connections to Monad.Trans.
12:53:55<WorkyBob>ACTION ponders... is there any documentation on when ghc garbage collects CAFs?
12:54:38<Axman6>when it feels like it!
12:54:52<WorkyBob>yeh... that's what I'm seeing :P
12:55:00<WorkyBob>i.e. I've got one that seems to be collected sooner than it should be
12:55:13<doserj>akamaus: the liftIO is called ioAction
12:55:48<ksf>Peaker, well, at least you get free alpha composition and superb polygon support.
12:58:59<akamaus>doserj, yes, but I cant pass (BrowserAction a) to 'try' anyway. And if I use 'browse' I'll lose state
13:00:14<Axman6>hmm, would deleting the 6.10.2 and 6.10.1 folders under ~/.cabal/lib/PACKAGE be ok?
13:00:42<Axman6>trying to make my .cabal dit not 2.5GB
13:00:45<Axman6>dir*
13:03:12<doserj>akamaus: you can set an error handler. setErrHandler :: (String -> IO ()) -> BrowserAction t ()
13:04:30<akamaus>doserj, oh, thanks. I was looking for something like this
13:04:59<doserj>Axman6: if you don't use 6.10.2 and 6.10.1 anymore, sure
13:05:28<Axman6>ok, cheers
13:10:55<akamaus>doserj, hmm, looks like setErrHandler won't prevent BrowseAction to fail, it's just a handler for error message
13:13:26<doserj>fail in the BrowseAction monad calls fail in the IO Monad.
13:54:50<byorgey>ACTION makes lambdaberry muffins
13:55:02<Badger>ACTION eats
13:55:28<ray>\berry -> muffins
13:55:33<Hong_MinHee>2
13:55:45<EvilTerran>const muffins?
13:56:09<byorgey>I guess that's one way to look at it
13:56:12<Athas>What's the most common reason of stack space overflow?
13:56:20<byorgey>the berries get erased at compile time
13:56:36<Berengal>Athas: Too much lazyness
13:56:38<ray>giant thunks
13:56:49<ray>tremendous thunks
13:56:51<Athas>I can believe that.
13:57:18<byorgey>THUNK <--- sound of a giant thunk blowing the stack
13:57:28<cjay>"thunks bigger than your mum"
13:57:44<byorgey>who invented the term "thunk"? I would like to buy that person a beer.
13:57:51<byorgey>or a drink of their choice.
13:57:53<duaneb>ok
13:57:56<duaneb>I'm gonna do something fun
13:57:57<Twey>It's actually not a thunk but a T-hunk, as I recall
13:58:03<duaneb>I'm gonna write an MP3 decoder in haskell :D
13:58:12<Axman6>good idea
13:58:16<Peaker>byorgey: who would have thunk it
13:58:19<Twey>http://en.wikipedia.org/wiki/Thunk
13:58:31<Twey>P.Z. Ingerman
13:58:42<Berengal>Thunking in general is hard...
13:58:54<Twey>You're in luck: he's still alive
13:58:57<madhadron>Berengal, Yes, the past is typically immutable
13:59:06<opqdonut>yeah, thunk is a great term
13:59:27<cjay>I always thaught "thunk" was a cross between "think" and "chunk"
13:59:44<madhadron>I've got a oddball design problem I'd appreciate opinions on...
13:59:55<madhadron>I'm writing a microscope control application (in Haskell)
13:59:57<Berengal>I used to think it was just another name for foo
14:00:19<madhadron>and while I've got a decent purely functional structure as a substrate for the logic for the microscope state
14:00:23<byorgey>Twey: where did you find the fact that he is still alive?
14:00:42<madhadron>I'm trying to figure out where to put frames coming back from the camera when it's actually hooked up to hardawre
14:00:45<Twey>Cursory Google, verifiability low
14:00:55<byorgey>\o/ apparently he was at U Penn when he published the original thunk paper!
14:01:06<byorgey>clearly I go to the best school ever
14:01:48<ray>u penn, home of the thunk
14:02:09<madhadron>byorgey, You should start a movement to change the school mascot
14:02:37<byorgey>madhadron: totally. I think our current mascot is the 'quaker' or something lame like that
14:03:25<duaneb>I've come to a realization
14:03:35<duaneb>I've been writing a ton of lisp primitives in haskell
14:03:41<duaneb>and writing lisp in haskell is NOT FUN.
14:04:01<Berengal>duaneb: Then don't? Or switch to lisp...
14:04:01<QtPlaty[HireMe]>duaneb: Which primitives?
14:04:31<jmcarthur>duaneb: http://blog.bjrn.se/2008/10/lets-build-mp3-decoder.html
14:04:33<duaneb>Berengal: I wasn't complaining, I was just observing
14:04:40<duaneb>jmcarthur: no fun
14:04:41<duaneb>that's cheating
14:04:47<Peaker>Implementing a dynamically-typed imperative language (mutable objects that have identities) in Haskell doesn't sound nice
14:04:47<jmcarthur>heh
14:04:50<jmcarthur>just pointing it out
14:05:16<duaneb>QtPlaty[HireMe]: car, cdr, cons, eq(v|ual)?, arithmetic, etc
14:05:37<EvilTerran>Peaker, eh, shouldn't be too hard to make an interpreter with ST/IORefs
14:05:50<EvilTerran>and Data.Dynamic :P
14:07:21<Athas>What makes a thunk allocate on the stack, rather than the heap?
14:08:09<Berengal>Athas: Thunks are allocated on the heap, but evaluating them uses the stack
14:08:20<Athas>Hm.
14:08:35<nitrofurano>how can i compile Monadius shmup (uses haskell and opengl) on Ubuntu Linux?
14:08:45<byorgey>right, it's the evaluation of huge thunks that blows the stack, not the thunks themselves.
14:08:58<Saizan>the stack grows as the distance from the outermost application and the first reducible expression, roughly
14:09:10<Athas>Yeah, most of my other space leaks blew up the heap instead.
14:09:16<Saizan>s/and/to/
14:09:30<Peaker>EvilTerran: ST is deterministic, Lisp isn't
14:09:33<Saizan>@wiki Stack overflow
14:09:33<lambdabot>http://www.haskell.org/haskellwiki/Stack_overflow
14:09:38<Saizan>have you read that?
14:09:43<EvilTerran>> foldl f e [x,y,z] :: Expr
14:09:44<lambdabot> f (f (f e x) y) z
14:09:58<Athas>No, but I will now. Thanks.
14:10:02<quicksilver>Peaker: lisp isn't deterministic?
14:10:12<Berengal>Athas: You can try simple substitution.. for example, foldl (+) 0 [1..foo] reduces to 1+2+3+4+5+..., and evaluating that requires stack
14:10:18<Peaker>quicksilver: nope, it can call undeterministic imperative functions freely
14:10:24<madhadron>quicksilver, Nope. McCarthy actually created a fascinating little nondeterministic operator
14:10:27<Peaker>it needs IO, not ST
14:10:37<quicksilver>Peaker: "undeterministic imperative functions" ?
14:10:40<madhadron>quicksilver, Which he called 'amb' if I recall correctly. One of his typical games
14:10:43<quicksilver>Peaker: like what?
14:10:44<EvilTerran>^ long foldls can have a long way between the outermost application and first reducible expression
14:10:46<Peaker>quicksilver: yeah, like getCPUTemperature
14:10:57<quicksilver>Peaker: that's not part of lisp.
14:11:10<quicksilver>lisp can contain bindings to non-deterministic library functions, sure.
14:11:31<quicksilver>so can all useful languages - only haskell doesn't call them functions.
14:11:40<quicksilver>but the core language lisp as generall understood is deterministic.
14:11:54<Peaker>quicksilver: well, you can't run Lisp in ST, its not powerful enough, needs IO
14:12:01<Berengal>quicksilver: Multivalued returns?
14:12:31<quicksilver>madhadron: mccarthy "added" amb to lisp; he didn't create it in lisp.
14:12:35<quicksilver>Berengal: ?
14:12:51<Peaker>I don't get these silly features like multi-value return, lisp-2, dynamic scoping
14:12:52<quicksilver>Peaker: the core lisp language can be easily run in ST, or indeed without ST.
14:13:01<Berengal>quicksilver: Sort of like python generators...
14:13:01<madhadron>quicksilver, Ah, you're really talking about the axiomatic structure as Lisp. Sure, in that case you're absolutely right.
14:13:04<quicksilver>just using a Data.Map for symbol looking.
14:13:11<Berengal>Or the list monad
14:13:15<Peaker>quicksilver: how do you separate the core from non-core? Is "equal" or "eq" not in core?
14:13:22<madhadron>quicksilver, And a state monad's the right place for it to live.
14:13:38<quicksilver>Peaker: they both are, and that's fine.
14:14:05<quicksilver>I don't know how I define it, but it's pretty obvious to me what's part of the lisp language and what isn't.
14:14:08<quicksilver>;)
14:14:20<quicksilver>'eq' and 'caddr' are part of lisp.
14:14:24<madhadron>quicksilver, Like pornography, huh?
14:14:26<quicksilver>'getCPUTemperature' is not.
14:14:28<quicksilver>quite.
14:14:34<Peaker>quicksilver: I guess if you remove all non-pure things from Lisp, and consider identities as pure attributes of values, that can work
14:14:40<quicksilver>I don't know much about lisp but I know what I like.
14:14:47<quicksilver>Peaker: I don't try to remove all non-pure things from lisp
14:14:47<madhadron>Peaker, Lisp-2 and dynamic scoping were mistakes before people knew better. Multi-value return was as well, but pattern matching and tuples took longer to be accepted.
14:14:58<quicksilver>Peaker: I wasn't arguing about lisp being impure
14:15:01<quicksilver>that's obviously true.
14:15:08<quicksilver>I was arguing abot it being non-deterministic
14:15:12<quicksilver>that's very different.
14:15:30<quicksilver>"setq" or "set" or whatever you wish to call it is impure but perfectly deterministic.
14:15:46<Peaker>quicksilver: yeah, core Lisp is deterministic, if you exclude amb
14:15:56<Peaker>quicksilver: but typically a Lisp interpreter wants to be able to run the libraries and what not
14:16:02<madhadron>quicksilver, Though...have you read Dijkstra's 'Predicate Calculus and Program Semantics'? He works in a purely logical structure but allows nondeterminism.
14:16:21<madhadron>Admittedly a very different approach to programming than functional
14:16:27<madhadron>but beautiful nevertheless
14:16:40<quicksilver>madhadron: I haven't, no. I can well believe it. I was just suprised by the characterisation here of lisp as non-determnistic.
14:16:59<Peaker>madhadron: Some Lispers still don't know better :P
14:17:20<madhadron>Peaker, No, they're just getting by with what they have.
14:17:20<madhadron>brb
14:17:54<quicksilver>Some kinds of dynamic scoping type effect are quite useful.
14:17:58<quicksilver>But I prefer it to be explicit.
14:18:09<quicksilver>explicitly looking up a key in a mutable environment
14:18:21<quicksilver>(so changing the environment and then changing it back is dynamic scoping)
14:18:36<quicksilver>dynamic scoping as the default form of symbol resolution is painful though.
14:18:45<Peaker>madhadron: heh, me in #lisp: <Peaker> Hey, do you consider dynamic scoping, Lisp-2, and multi-return values to be mistakes in various Lisp designs?
14:18:50<Peaker><tcr> Peaker: No to the contrary, I value all three very much, and wouldn't want to live without
14:19:05<quicksilver>to be fair you did look you were trolling
14:19:18<QtPlaty[HireMe]>ACTION reas the MP3 posts "It says that huffman encoding is used in zip. I didn't think that was the case."
14:19:18<quicksilver>;)
14:19:27<Peaker>quicksilver: Politely asked, though :-)
14:19:44<quicksilver>the best trolls are polite.
14:20:06<Berengal>Haskell has dynamic scoping...
14:20:13<Peaker>Berengal: ghc does
14:20:17<Peaker>Berengal: Haskell98 too?
14:20:48<Berengal>Peaker: Dunno. "Haskell" is "some implementation" to me...
14:21:03<Peaker>Berengal: you referring to ?implicit args right?
14:21:09<Berengal>Yes
14:22:00<quicksilver>implict args are pretty much deprecated.
14:22:03<skorpan>hi. i'm using windows and would like to make an image (pdf, png, jpg, bmp, whatever) displaying a 2d graph. what is the easiest way to accomplish this?
14:22:18<doserj>implicit parameters are still lexically scoped
14:22:19<skorpan>i'm using the haskell platform if that matters
14:22:20<quicksilver>they're not quite dynamic in the normal sense either
14:22:26<Peaker>doserj: how so?
14:22:29<quicksilver>they're lexical but in a funny way.
14:22:38<quicksilver>the scoping remains a static not a dynamic property of the code.
14:23:13<Athas>I can't figure out where my program creates (or evaluates) these large thunks. Are there any tools available to help me?
14:23:22<quicksilver>Athas: heap profiling.
14:24:37<Berengal>quicksilver: Can't you do 'let ?foo = findMeAFoo ...'
14:25:35<Peaker>madhadron: #lisp is making it very clear people don't think Lisp-2, multi-value return, etc are bad features
14:27:32<SamB>Peaker: sure! what do you suppose (# , #) is for?
14:28:04<SamB>the thing that makes lisp 2 a pain is that mutability
14:28:26<opqdonut>what does lisp-2 mean?
14:28:37<Peaker>opqdonut: a special separate namespace for function names
14:28:37<ski>Lisp-1 vs. Lisp-2 (vs. Lisp-N) is about the number of namespaces
14:28:46<opqdonut>ah
14:28:52<opqdonut>yeah it sucks imo
14:28:56<Peaker>opqdonut: (funcname argname) funcname is looked up in a different namespace than argname :(
14:29:30<Peaker>SamB: I think what makes it a pain is that every function in the world that deals with namespaces has to be duplicated and yet more created to be able to use function-named values as values and vice versa
14:29:56<Peaker>complicating the model for no gain, and even less readability and newbie-friendliness
14:30:32<idnar>quicksilver: so what's the replacement for implicit args? :P
14:30:48<madhadron>Peaker, <shrugs> Anyone who has used both Scheme and Common Lisp knows that Lisp-1 is the only way to go
14:31:12<madhadron>Peaker, And again, anyone who's lived in Haskell or Erlang for a while knows that pattern matching is a vastly easier approach than multi-return
14:31:19<quicksilver>idnar: programming.
14:31:31<ski>i would be interesting to allow any number of namespaces .. e.g. consider creating a separate namespace for a DSL (possibly also allowing sub-expressions of the host language inside that)
14:31:40<ski>s/i would/it would/
14:31:56<quicksilver>the main thing (the only thing?) I don't like about functions in a separate namespace is it makes them feel less first-class.
14:31:56<Peaker>madhadron: how is pattern-matching a replacement for multi-return? Tuple unpacking?
14:32:03<madhadron>Peaker, Exactly
14:32:18<Peaker>madhadron: I think the multi-return thing is mainly about implicit type-coercion of users only aware of the first N args
14:32:32<Peaker>madhadron: they can "extend" a function without breaking its type/callers
14:32:55<madhadron>Peaker, Yes, it's a great way to patch things
14:33:32<Peaker>madhadron: Hmm you know what? Could be interesting (and hellish!) to be able to write compatibility type adapters for Haskell functions
14:33:54<madhadron>Peaker, Thus "avoid success at all costs" (:
14:34:26<Xenox>Can some-one tell me what the show instance for a data type like: data (Num a) => Size2D a = Size { sizeW :: {-# UNPACK #-} !a , sizeH :: {-# UNPACK #-} !a } should be
14:34:47<Peaker>madhadron: Say you converted f :: Double -> Int to f :: Double -> (Int, Double) maybe you could write a pragma or such: adapt_f :: Double -> Int ; adapt_f = fst . f -- and have the compiler try adapters if types don't check
14:34:55<Xenox>I supposed it should be : instance Show (Num a) => (Size2D a) where
14:34:56<Xenox> show (Size w) = "{" ++ show w ++ show h ++ "}".But it isn;
14:36:40<quicksilver>Xenox: don't use constraints in data times, it doesn't really work.
14:36:44<quicksilver>data types.
14:36:58<lilac>i suspect we'll find at some point in the future (when dependent typing comes of age) that Haskell having separate type and value namespaces was a mistake...
14:37:10<ski> instance (Show a,Num a) => Show (Size2D a) where
14:37:48<quicksilver>the derived show instance would be "Size { sizeW = " ++ show (sizeW w) ++ ", sizeH = " ++ show (sizeH w) ++ " } "
14:37:52<quicksilver>I believe.
14:40:12<quicksilver>but you could just derive Show :)
14:41:12<Xenox>When i use the derive show I get: {rectLeft = 0, rectTop = 0, rectWidth = 0, rectHeight = 0}. And I think that is to much ;)
14:41:21<Xenox>I just want {0,0,0,0}
14:41:21<Xenox>:)
14:41:53<ski>maybe not use `show' ?
14:42:23<EvilTerran>Xenox, show is meant to produce valid haskell, which that wouldn't be
14:42:31<ski>`show' is intended for producing a Haskell-readable string
14:42:48<gwern>EvilTerran: well, he could define read and show instances which would work for that couldn't he?
14:42:59<ski>(.. i should have said Haskell-`read'able)
14:43:07<gwern>as long as he assumes the rectLeft,rectZTop,rectWidth,rectHeight ordering in the read function
14:43:17<paper_cc>Xenox: a good (conforming) 'show' could only return (Size 0 0 0 0)
14:43:45<EvilTerran>ACTION is under the impression that the jury's out on whether "show" instances should only ever produce valid haskell, or if that's just how the derived instances happen to work
14:44:06<opqdonut>well read.show should be id
14:44:33<yaxu>http://blip.tv/file/2198920
14:44:39<EvilTerran>most non-derived Show instances in the libraries seem to work that way, too
14:45:01<EvilTerran>> M.singleton 23 "foo"
14:45:02<lambdabot> fromList [(23,"foo")]
14:45:30<ski>> listArray (0,3) "abcd"
14:45:31<lambdabot> array (0,3) [(0,'a'),(1,'b'),(2,'c'),(3,'d')]
14:45:38<Xenox>I Use show. But the derived show of my data type constructs created the readable string (using show) -> Size {sizeW = 0, sizeH=0} for Size 0 0
14:46:04<Xenox>And I want to send the string over the network, so I don't want all the sizeW and sizeH appearing in my readable string
14:46:38<ski>Xenox : the suggestion was to stop using `show', instead defining your own function (not called `show') for producing the string you want
14:46:50<EvilTerran>Xenox, if you're worried about network usage, Data.Binary would probably be a better choice than Show
14:46:52<Axman6>or Data.Binary
14:47:16<gwern>I always wondered how 'fromList' could work in a read function; it's obviously not being compiled & run via the GHC API or something; so is the string "fromList" just hardwired in a little parser or something?
14:47:16<ski>(/me just remembered `Data.Binary' :)
14:47:21<Xenox>@Ski, sorry I think I read over that. Using a self defined function would also work :)
14:47:22<lambdabot>Unknown command, try @list
14:47:25<Berengal>Xenox: If you want derived Read to be able to read it, you could make it print something like "(Size 0 0 0 0)"
14:47:28<gwern>Xenox: not twitter
14:47:46<Xenox>@gwern not twitter?
14:47:46<lambdabot>Unknown command, try @list
14:47:51<EvilTerran>gwern, i think the "fromList" or whatever is hard-wired, yeah
14:48:02<Axman6>Xenox: no need for the @
14:48:04<lilac>EvilTerran: for parameterised types, some convention is needed on how to read the individual elements. saying "must parse as haskell" solves that pretty nicely afaics
14:48:04<ski>gwern : i believe so
14:48:07<Jedai>gwern: I do believe it's hard wired
14:48:09<EvilTerran>Xenox, an @ at the start of a line is interpreted as a command by lambdabot
14:48:13<paper_cc>Xenox: username: not @username
14:48:25<Xenox>sorry :)
14:48:25<paper_cc>@help
14:48:25<lambdabot>help <command>. Ask for help for <command>. Try 'list' for all commands
14:48:38<Xenox>I sometimes forget that :)
14:49:30<Berengal>ACTION makes his computer do as he wants. Dance puppet, dance!
14:55:18<cads>hey, if we have f and g, a, b
14:55:27<cads>aw crud I hate this keyboard..
14:55:55<adekoba>what should I do if I do not have enough memory to build a package? encoding-0.5.1 keeps hitting swap.
14:56:28<cads>we have f, g, a, b such that foldl f a = foldr g a... what can we say about the realation between f and g, a and b?
14:58:08<cads>if f is commutative and associative and has a zero element, I think f = g, a = b = 0
14:59:20<sampointon>hi guys, any idea why [d| data Foo = Foo; instance Show Foo where { show _ = "Foo" } |] fails with "`show' is not a (visible) method of class `Show'"?
15:01:17<EvilTerran>cads, do you mean foldl f a = foldr g b?
15:03:12<dino->adekoba: I'm not sure, have never run into that. But there may be a switch for ghc
15:04:33<quicksilver>adekoba: you could give ghc a hard memory limit but I suspect that would just make it crash with an out of memory error.
15:04:41<quicksilver>I think if it needs that memory it needs it :(
15:05:07<adekoba>I'll give it a try
15:05:38<JaffaCake>you could try GHCRTS=-c
15:06:46<ray>i keep running out of memory when linking
15:07:05<JaffaCake>ah, well there's not much we can do about shoddy linkers
15:07:12<ray>i ended up passing --no-keep-memory to ld
15:07:14<ray>which is harder than it sounds
15:07:27<quicksilver>spray them with shodkiller
15:08:00<dino->ray: Now you've got me interested in hard how, in case I run into it.
15:08:22<adekoba>JaffaCake: I got an ExitFailure 15 using that
15:08:47<ray>had to pass -optl --no-keep-memory to ghc, which required some kind of flag to cabal's configure
15:09:20<EvilTerran>ray, heh, sounds like the flag equivalent of Leaning Toothpick Syndrome
15:09:31<dino->I see. Not just a switch passed down through ghc.
15:09:38<sampointon>what about using --ghc-options on with cabal build?
15:09:45<ray>yeah, that's the flag
15:09:58<mmorrow>can anyone think of a function (preferably already written ;) that would be an interesting case for a pattern match compiler?
15:10:05<JaffaCake>adekoba: ExitFailure 15 from what?
15:10:13<adekoba>using GHCRTS=-c
15:10:40<adekoba>I let ghc do its stuff for about two hours and it still hadn't even reached the linking stage yet.
15:10:46<mmorrow>so, one that has at least two args and that has some overlap in the patterns in each "column"
15:10:47<dino->adekoba: I'll try to build that encoding too in a minute here.
15:10:52<adekoba>I'll deal with ld when I come to it, lol.
15:11:17<mmorrow>(and that has more that two "rows"))
15:11:31<adekoba>quicksilver: but setting a hard memory limit seems to be working. Still taking a while, but not hitting swap.
15:11:34<mmorrow>@src transpose
15:11:34<lambdabot>transpose [] = []
15:11:34<lambdabot>transpose ([] : xss) = transpose xss
15:11:34<lambdabot>transpose ((x:xs) : xss) = (x : [h | (h:t) <- xss]) : transpose (xs : [ t | (h:t) <- xss])
15:11:47<quicksilver>mmorrow: merge of two lists, written in such a way that it has a special case for 1-elt lists.
15:11:57<mmorrow>quicksilver: hmm, nice
15:11:59<quicksilver>mmorrow: which isn't the only way to write it, but it does at least meet your specs :)
15:12:14<mmorrow>ACTION writes it
15:12:16<ski>mmorrow : Berry's majority ?
15:12:21<quicksilver>adekoba: well it will GC more and more often as it runs out of memory.
15:12:35<quicksilver>adekoba: eventually it will peg your CPU. But let's see if it squeezes through.
15:12:41<adekoba>quicksilver: yar. We'll see how this goes.
15:13:13<roconnor>@hoogle (Monoid a) => (a -> a -> b) -> [a] -> [a] -> [b]
15:13:13<lambdabot>Prelude zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
15:13:13<lambdabot>Data.List zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
15:13:13<lambdabot>Data.List deleteFirstsBy :: (a -> a -> Bool) -> [a] -> [a] -> [a]
15:13:27<cads>WHat do you guys think, if f is not associative, is it even possible to write g | foldl1 f = foldr2 g? I feel like it is not.
15:13:49<ski>mmorrow : maybe the Gustave function ?
15:14:12<mmorrow>ski: ?
15:14:19<roconnor>@type foldl1
15:14:21<lambdabot>forall a. (a -> a -> a) -> [a] -> a
15:14:31<quicksilver>ski++ # wise about intriguingly named obscure functions.
15:14:35<mmorrow>heh
15:15:01<dino->huh, building encoding really isn't crapping out my system that bad yet.
15:15:40<ski>mmorrow : hm, i had a link to an old hpaste with them, but it appears that has vaporized
15:15:45<dino->Only pulled in another maybe 200-300M ram and no swap used at all still by anything. A whole core is way way busy on it.
15:16:48<dino->But boy is it ever busy with those Data.Encoding.JISX* sources. :o
15:17:03<Peaker>about the Lisp-2 thing, the constant argument I get is people who want to call their lists list, heh
15:17:07<cads>roconnor, I use foldl/r1 in this case because I think reasoning about the initial value isn't necessary in this case... trying to work a proof but my brain's farting
15:17:10<ski>a quick search turns up
15:17:16<adekoba>dino-: Yes. This is a known issue. It's heavy on the template Haskell.
15:17:17<quicksilver>it's one file in particular which is the painful one, dino.
15:17:18<ski>Berry's majority function : <http://wiki.portal.chalmers.se/agda/agda.php?n=ReferenceManual.PatternMatching>,<http://www.nabble.com/On-Berry's-Majority-Function-td4832574.html>
15:17:50<mmorrow>ski: hah, perfect :)
15:18:01<dino->What a beast!
15:18:16<roconnor>cads: I was just checking to see if the function for foldl1 was even an operator. It is.
15:19:48<dino->It's still busy but holding steady on ram. top says 284M
15:20:12<adekoba>how much system ram do you have?
15:20:20<dino->adekoba: 2G
15:20:37<Peaker>ok, very clearly Lisp guys still like their Lisp-2, dynamic scoping and multi-value returns, heh
15:21:00<adekoba>yeah, you're probably fine. I have 512MB
15:21:13<roconnor>what is multi-value retunrs?
15:21:17<dino->adekoba: Another thing, if this is a disaster for small machines, we could maybe do some binary dist of this.
15:21:29<dino->If you're on a Debian-based, a .deb could be made.
15:21:35<adekoba>archlinux
15:22:09<sampointon>roconnor: think like returning tuples, except you can't treat them as a tuple. All you can do is unpack them in some way
15:22:12<dino->It got through to the next JIS source, ghc up to 410M
15:22:15<dino->yowza
15:22:34<roconnor>sampointon: so they are like continuations?
15:22:47<sampointon>roconnor: no, they're basically just cartesian products
15:23:20<roconnor>how does it differ from returning (a . b) ?
15:24:01<conal>roconnor: i think efficiency
15:24:02<sampointon>roconnor: efficiency I believe, but my lisp-fu is not strong
15:24:05<dino->would some kind of lunatic hackery like packing up the dist/ dir with the .o files and sending off work? I guess if it's the same architecture, perhaps.
15:24:08<roconnor>ok
15:24:31<dino->Or sending the post linker results
15:24:56<quicksilver>surely in a decent lisp implementation (a . b) is pretty damn efficient?
15:25:10<quicksilver>or is it return by reference instead of by value, somehow?
15:26:04<sampointon>quicksilver: I think CltL being 25 years old has something to do with it. I don't know how advanced fusion and deforestation was back then
15:26:31<conal>quicksilver: maybe the goal is to return multi-results in registers and avoid consing altogether.
15:26:50<quicksilver>that sounds like a goal for an optimising compiler
15:26:58<conal>quicksilver: indeed
15:27:00<quicksilver>not a justification for a new language construct
15:27:22<quicksilver>ACTION shrugs
15:27:44<conal>i wonder what we tolerate that's analogous
15:29:27<dino->Got to 484M then it finished, succeeded.
15:30:25<ski>shortening `Either',`Left',`Right' to `E',`L',`R' :
15:30:34<ski> gustave :: (a,E a0 a1) -> (b,E b0 b1) -> (c,E c0 c1) -> (E a (E a0 a1),E b (E b0 b1),E c (E c0 c1))
15:30:40<sampointon>hmm, wikipedia thinks that GHC invented analysing return types and optimising wrt register use
15:30:41<ski> gustave (a,_ ) (_,L b0) (_,R c1) = (L a ,R (L b0),R (R c1))
15:30:48<ski> gustave (_,R a1) (b,_ ) (_,L c0) = (R (R a1),L b ,R (L c0))
15:30:53<ski> gustave (_,L a0) (_,R b1) (c,_ ) = (R (L a0),R (R b1),L c )
15:30:58<ski> gustave (_,L a0) (_,L b0) (_,L c0) = (R (L a0),R (L b0),R (L c0))
15:31:00<ski> gustave (_,R a1) (_,R b1) (_,R c1) = (R (R a1),R (R b1),R (R c1))
15:31:06<Zao>I hear that hpaste is awesome.
15:31:08<ski>mmorrow : there
15:31:53<ski>(Zao : in this case i wanted to refer to a hpaste, but it was gone .. so i figured it might be nice if i could search for it in the logs, next time ;)
15:32:53<ski>(specifically <http://hpaste.org/9451> .. maybe that's still available somewhere .. i don't know where to look, though)
15:34:15<ski>roconnor : it's like returning an unboxed tuple, more or less
15:36:36<adekoba>After setting a hard memory limit, encoding failed to build. Ghc reported an error saying the heap was exhausted.
15:36:51<dino->adekoba: I'll leave the build artifacts from encoding around for a while. If you have failure and want anything.
15:37:20<mmorrow>ski: haha, that's even bettar
15:37:52<ski>ACTION wonders how that's better
15:38:00<mmorrow>err, right ...
15:38:16<ski>what, what ?
15:38:23<mmorrow>(and also my parser only does single-level deep patterns)
15:38:29<ski>ACTION looks confused in the hope that mmorrow will explain
15:38:30<dino->I'm not really a build wizard, is it possibly valuable for me to pack up this (50M) block of files into a .tar.gz, with the dist/ intact after linking? It's Intel 32-bit.
15:38:54<dino->Put somewhere you can dl.
15:39:04<mmorrow>ski: not better than Berry's since... err, maybe it is "better" (in the sense that it's a more complex case)
15:39:25<mmorrow>ski: but since it has nested patterns i can't use that example as-is..
15:39:37<mmorrow>ski: but Berry's is exactly what i was looking for :)
15:39:39<adekoba>dino-: Maybe. Upload it to mediafire/rapidshare and I'll try it out.
15:39:42<ski>(mmorrow : you could easily curry `gustave' into six separate arguments .. the original had only one, but i split that into the three above)
15:40:02<mmorrow>ski: ah, good point
15:40:05<mmorrow>ACTION does that
15:42:06<ski>"The Gustave function is an example of a function which is stable but not Vuillemin Sequential."
15:42:17<quicksilver>conal: newtype, I guess.
15:42:32<quicksilver>conal: but, I wouldn't describe newtype as an interesting or important haskell feature.
15:42:50<dino->adekoba: http://ui3.info/d/misc/encoding-0.5.1_prebuilt.tar.gz
15:43:00<dino->9.2M
15:43:07<mmorrow>hehe, gustave is epic
15:43:21<quicksilver>seems to be a good way of demonstrating failure of full abstraction
15:43:25<quicksilver>having googled around it a bit
15:44:14<roconnor>What is Lisp-2?
15:44:24<osfameron>twice as good as Lisp-1 !
15:44:25<quicksilver>roconnor: where functions and values are in different namespaces
15:44:31<quicksilver>apparently.
15:44:47<Berengal>Isn't shadowing good enough for them?
15:44:57<roconnor>quicksilver: that sounds like a small step in the right direction.
15:45:01<ski>"The maj function is total: its patterns are exhaustive and disjoint. However, these patterns do not arise as the fringe of a splitting tree. Hence it is not possible to give an implementation of maj with conventional eliminators or in Coquand's pattern matching language (henceforth, Alf) which satisfies those five equations definitionally on open terms."
15:45:12<quicksilver>it means in (f f) those are different fs
15:45:24<quicksilver>the first f is looked up as a function, the second as a value.
15:45:36<quicksilver>I don't like it because I want, personally, to be able to pass a function as a value.
15:45:42<EvilTerran>ACTION concurs
15:45:45<quicksilver>in fact, I would argue that's one of things that functional programming is about.
15:46:04<roconnor>quicksilver: oh, so the two don't get different types.
15:46:09<roconnor>heh
15:46:13<Berengal>quicksilver: There's always #, but I agree...
15:46:14<roconnor>what was I thinking.
15:46:15<quicksilver>types? it's lisp we're talking about.
15:46:26<quicksilver>persumably you do (f 'f)
15:46:33<quicksilver>which passes the "name" of f as a parameter.
15:46:36<Botje>#'f even
15:46:42<Botje>or you can do (f (function f))
15:46:46<quicksilver>but then you don't know if the function is going to choose to use it as a function or a value.
15:47:35<sampointon>quicksilver: well, you can't pass things directly from the function namespace as parameters. #' does that and passes the function as a value
15:47:45<quicksilver>ACTION nods
15:47:56<quicksilver>it is primarily cosmetic.
15:47:57<ski>quicksilver : elaborate on "choose to use it as a function or a value" ?
15:48:22<sampointon>if you pervasively use #' and squint, common lisp is an acceptable lisp-1
15:48:30<quicksilver>ski: having been passed a symbol, you can then use the value of that symbol-as-a-value or the value of symbol-as-a-function
15:48:31<cads>when we say that an operator + is right associative, does that simply mean that in writing conventions, a + b + c + d is meant to uniquely represent (((a + b) + c) + d), rather than ((a + b) + (c + d)), (a + (b + (c + d))), or any other combination?
15:48:33<quicksilver>can't you?
15:48:34<sampointon>for some values of 'acceptable' :)
15:48:39<quicksilver>I do get confused between lisps
15:48:50<ski>quicksilver : no, not in CL
15:48:56<quicksilver>ah, ok.
15:48:59<dmwit>cads: Yes.
15:49:07<ski>(maybe in Emacs Lisp, i don't know)
15:49:10<dmwit>cads: Except that right-associative is the other way. =)
15:49:13<cads>quicksilver: it's "lithpth"
15:49:18<quicksilver>right :)
15:49:33<cads>dmwit, doubledamn :)
15:49:34<dmwit>cads: If (+) is right-associative, a + b + c + d === a + (b + (c + d))
15:49:42<dmwit>=)
15:50:03<ski>quicksilver : in (foo #'foo) a closure is passed, not a symbol .. passing a symbol would be (foo 'foo)
15:50:21<byorgey>And if (+) is unassociative it wants nothing to do with a, b, c, and d.
15:50:30<dmwit>cads: In ghc, (+) is infixl, so keep that in mind for the next example.
15:50:48<dmwit>> (a + (b + (c + d)), ((a + b) + c) + d)
15:50:49<lambdabot> (a + (b + (c + d)),a + b + c + d)
15:51:00<sampointon>byorgey: a reclusive operator? :)
15:51:12<cads>working on this problem from a lisp forum where essentially our charachter gives us an f and a, and would like us to tell him if we can create a g and b such that opposite folds with f, a and g, b will resepctively yield the same result
15:51:16<byorgey>sampointon: oh good, someone got my joke =)
15:51:35<cads>and it occurs to me that lisp is very terrible for equational reasoning in this case
15:52:18<cedricshock>Is there a way to safely load object code, say a function from integers to integer) into a running haskell program. I.e. something like name::String -> objectcode::String ->IO (Int -> Int)
15:52:40<quicksilver>ski: but once I do (foo 'foo) to pass in a symbol, can I not lookup that symbol as a value/function ?
15:52:43<sampointon>cedricshock: hs-plugins?
15:52:53<dmwit>cedricshock: You'll want to check out the GHC API, and especially hint.
15:53:02<EvilTerran>cedricshock, ghc-api would be the current way of doing that sort of thing
15:53:10<dmwit>cedricshock: Don't bother with that hs-plugins mess any more, it's deprecated. ;-)
15:53:11<sampointon>quicksilver: if it's in scope, sure
15:53:12<ski>cads : no, `++' being right-associative implies that `a ++ b ++ c ++ d' is the same as `(a ++ (b ++ (c ++ d)))'
15:53:17<Berengal>cads: I don't think it's possible in general. Try f = (-), a = 0
15:53:32<quicksilver>sampointon: good, well that's what I thought I meant in the first place :)
15:53:37<byorgey>cads: you can do it if 'f' is symmetric (i.e. f x y == f y x)
15:53:46<quicksilver>byorgey: commutative :)
15:53:52<byorgey>err, right.
15:53:55<byorgey>ACTION smacks forehead.
15:53:55<ski>quicksilver : you can look up that symbols *global* value as a ordinary/function variable, yes
15:54:02<sampointon>symmetric works too
15:54:05<dmwit>We were talking about this the other night. It's sufficient for f and a to form a monoid.
15:54:13<dmwit>Then g and b are (flip f) and a.
15:54:18<ski>quicksilver : however, doing that is discouraged in most cases
15:54:24<quicksilver>symmetric is normally of a relation, meaning x R y ==> y R x
15:54:37<quicksilver>extending that to functions, a 'symmetric' function would be an involution.
15:54:41<quicksilver>(and it would be unary)
15:54:53<quicksilver>ski: right, I can see why.
15:55:15<sampointon>oh, I was thinknig graphically. A commutative function has a symmetry along y = x, hence calling it symmetric
15:55:24<quicksilver>ski: I find using lisp at all is discouraged in most cases. Probably that says something about the company I keep.
15:55:41<quicksilver>sampointon: sure. It has an obvious intuitive justification, it's just not what the word normally means.
15:56:18<ski>ACTION finds lisps (well, scheme mostly) interesting mostly for the macro systems
15:56:25<quicksilver>although curiously the equivalent property of a (bi)functor is normally called symmetry, not commutativity.
15:56:38<quicksilver>ski: interesting is not the same as a good tool
15:56:46<Peaker>knowing Haskell, I think I can only find use for C and Haskell, (perhaps Python's interactive shell, still used to that)
15:56:50<quicksilver>ski: I find it all very intresting, or I wouldn't be partaking in this discussion.
15:57:28<quicksilver>ski: the thing I don't like about (say) CL is that when you're trying to understand code you don't know very well
15:57:35<quicksilver>ski: you can't tell which bits are macro and which bits aren't.
15:57:54<quicksilver>ski: and the macro bits behave substantially differently, in that they can use their arguments without evaluating them, etc.
15:58:24<ski>i can understand that
15:59:15<Berengal>I like lisp. It's a bit outdated, but still better than most other languages I've tried...
15:59:40<ski>the only response i can give is that typically, not that many different macros are used in a piece of code, so one can usually keep in head which are macros (after one has discovered/read which are)
16:00:05<cedricshock>dmwit, etc: thanks
16:01:43<dino->How about that Arc Lisp?
16:02:16<p_l>dino-: isn't it deader than dead?
16:02:51<mmorrow>ski, quicksilver: the case tries for berry and gustave http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5570#a5570
16:03:02<dino->p_l: Beats me. I know that it only just kind of was available to the public recently. According to Mr Graham.
16:03:35<p_l>dino-: and is a joke among CL community, as much as one can talk about one :P (at least among the part I met)
16:03:52<mmorrow>ski, quicksilver: crap, the decls got out of order when i Map.toList from my Trie..
16:04:07<quicksilver>;)
16:04:21<ski>mmorrow : you appear to miss a lot of parens in the `gustave' definition at the top .. is that intensional ?
16:04:41<mmorrow>ski: oh, that's just prettyprinter suckiness
16:04:55<ski>i see
16:05:05<mmorrow>ACTION makes a note to fix that
16:05:11<quicksilver>I wonder, is it better to have a sucky prettyprinter or a pretty suckyprinter...
16:05:36<mmorrow>questions for the ages
16:05:40<ski>maybe a sucky prettyparser would be nice ?
16:19:20<pozic>Is there a generic zip library? It should be varargs and work on any kind of container. I know of zips which have one of the two features, but not both. Otherwise, consider it to a challenge to abuse the type-system.
16:20:10<psnively>I'm sure Oleg has already written it.
16:20:36<roconnor>pozic: what is any kind of container?
16:20:39<jmcarthur_work>maybe some combination of applicative and traversable or something
16:20:41<jmcarthur_work>?
16:21:01<jmcarthur_work>err... foldable
16:21:17<roconnor>like a noetherian container?
16:21:45<Beelsebob>pozic: isn't it just liftA2, with appropriate data types
16:21:47<jmcarthur_work>ZipList . Data.Foldable.toList -- done
16:22:03<mmorrow>oh wow, gustave just made me realize how much it has to suck when you have patterns that have to backtrack...
16:22:06<jmcarthur_work>well, i guess you need a fromList, also
16:22:10<cedricshock>Ok. This is awesome: dynCompileExpr :: GhcMonad m => String -> m Dynamic
16:22:21<mmorrow>ACTION redoes his whole algo :(
16:22:22<roconnor>jmcarthur_work: in that case you end up with a list and not the original container structure.
16:22:36<jmcarthur_work>roconnor, right, hence the need for a fromList as well
16:22:59<roconnor>that isn't necessarily structure preserving
16:23:17<pozic>roconnor: Sequence/Array/List/anything user defined, which I guess would be Traversable/Foldable.
16:23:21<jmcarthur_work>does a zip necessarily have to be structure preserving?
16:23:41<byorgey>pozic: Stephanie Weirich and ccasin have a paper they just submitted doing such a thing in Agda. It's surprisingly tricky.
16:23:44<jmcarthur_work>pozic, ^^ would be a good question for you to answer
16:23:52<byorgey>pozic: there's some hope that their approach could be translated to Haskell.
16:24:37<byorgey>pozic: but it doesn't exist ATM.
16:24:39<pozic>jmcarthur_work: I don't mind about that.
16:24:54<roconnor>pozic: rose trees?
16:25:54<jmcarthur_work>if it doesn't have to be structure preserving then applicative+foldable is probably perfect
16:26:04<jmcarthur_work>if it does... whole new ball game
16:26:19<roconnor>jmcarthur_work: agreed
16:26:38<gwern>@seen dcoutts__
16:26:38<lambdabot>dcoutts__ is in #darcs, #gentoo-haskell, #ghc, #haskell, #haskell-in-depth, #haskell-overflow and #haskell-soc. I don't know when dcoutts__ last spoke.
16:26:40<gwern>@seen dcoutts_
16:26:41<lambdabot>dcoutts_ is in #haskell-in-depth, #gentoo-haskell, #ghc and #haskell-overflow. I last heard dcoutts_ speak 30m 50s ago.
16:26:44<gwern>@seen dcoutts
16:26:44<lambdabot>I saw dcoutts leaving #haskell-soc, #haskell-in-depth, #gentoo-haskell, #darcs, #ghc, #haskell-overflow and #haskell 3h 7m 42s ago, and .
16:26:51<gwern>he uses entirely too many nicks
16:27:01<Deewiant>@seen dcoutts___
16:27:01<lambdabot>I haven't seen dcoutts___.
16:27:11<gwern>ACTION doesn't know which one to leave a message for
16:27:14<roconnor>http://en.wikipedia.org/wiki/Container_(Type_theory)
16:27:27<quicksilver>pozic, jmcarthur_work : I wrote a zip which works on Foldatble/Travesable
16:27:36<gwern>well, single-underscore seems to've been most recently active
16:27:39<Deewiant>gwern: The one with one _... yeah
16:28:25<gwern>@ask dcoutts_ while cabalizing my wikipedia bot, I noticed it's possible to declare build-depends which are unused with neither cabal-install nor cabal check complaining about the unnecessary dependencies. is this an open bug or anything?
16:28:25<lambdabot>Consider it noted.
16:28:54<gwern>(I copied the rss2irc ,cabal, and it needs mtl and strict-concurrency while my bot doesn't)
16:29:18<roconnor>@hoogle fromList
16:29:19<lambdabot>Data.HashTable fromList :: Eq key => (key -> Int32) -> [(key, val)] -> IO (HashTable key val)
16:29:19<lambdabot>Data.IntMap fromList :: [(Key, a)] -> IntMap a
16:29:19<lambdabot>Data.IntSet fromList :: [Int] -> IntSet
16:29:23<roconnor>@more
16:29:27<roconnor>@hoogle+
16:29:27<lambdabot>Data.Map fromList :: Ord k => [(k, a)] -> Map k a
16:29:27<lambdabot>Data.Sequence fromList :: [a] -> Seq a
16:29:27<lambdabot>Data.Set fromList :: Ord a => [a] -> Set a
16:29:34<roconnor>@hoogle+
16:29:34<lambdabot>Distribution.Simple.PackageIndex fromList :: Package pkg => [pkg] -> PackageIndex pkg
16:29:34<lambdabot>Data.IntMap fromListWith :: (a -> a -> a) -> [(Key, a)] -> IntMap a
16:29:34<lambdabot>Data.Map fromListWith :: Ord k => (a -> a -> a) -> [(k, a)] -> Map k a
16:29:36<roconnor>bah
16:29:54<roconnor>quicksilver: how does that work?
16:30:50<gwern>'The dependency 'build-depends: base' does not specify an upper bound on the version number. Each major release of the 'base' package changes the API in various ways and most packages will need some changes to compile with it. The recommended practise is to specify an upper bound on the version of the 'base' package. This ensures your package will continue to build when a new major version of the 'base' package is released. If you are ...
16:30:56<gwern>... not sure what upper bound to use then use the next major version. For example if you have tested your package with 'base' version 2 and 3 then use 'build-depends: base >= 2 && < 4'.'
16:31:00<gwern>argh. bit already!
16:31:41<roconnor>bit?
16:31:42<quicksilver>roconnor: it uses the 'shape' from the traversable one
16:31:59<gwern>yes, bit
16:32:02<gwern>@wn bit
16:32:05<quicksilver>roconnor: and it effectively uses toList from Foldable to souce the items on the othe
16:32:05<lambdabot>*** "bit" wn "WordNet (r) 2.0"
16:32:05<lambdabot>bit
16:32:05<lambdabot> n 1: a small quantity; "a spot of tea"; "a bit of paper" [syn: {spot}]
16:32:05<lambdabot> 2: a small fragment of something broken off from the whole; "a
16:32:05<lambdabot> bit of rock caught him in the eye" [syn: {chip}, {flake},
16:32:07<lambdabot>[59 @more lines]
16:32:11<gwern>@more
16:32:11<lambdabot> {fleck}, {scrap}]
16:32:11<lambdabot> 3: an indefinitely short time; "wait just a moment"; "it only
16:32:13<lambdabot> takes a minute"; "in just a bit" [syn: {moment}, {minute},
16:32:15<lambdabot> {second}]
16:32:17<lambdabot> 4: an instance of some kind; "it was a nice piece of work"; "he
16:32:19<lambdabot>[54 @more lines]
16:32:23<cedricshock>There's a huge gap between hs-plugins and ghc-api in terms of instructiveness of documentation.
16:32:25<gwern>-_-
16:32:30<roconnor>gwern: keep going
16:32:43<gwern>I didn't realize 'bit' as in 'bitten' was such a tertiary definition
16:33:04<roconnor>quicksilver: but zip should produce the shape of the "intersection" of the two shapes.
16:33:12<quicksilver>yes, that would be better
16:33:15<quicksilver>but traversable can't do that.
16:33:20<roconnor>no
16:33:29<quicksilver>so my solution is jsut one part of the space
16:33:37<quicksilver>it's useful for, for example, labelling a tree with labels from a list.
16:33:37<roconnor>quicksilver: what if there isn't enough stuff in the non-traversable parameter?
16:33:42<quicksilver>it dies.
16:33:47<roconnor>error?
16:34:13<roconnor>error "quicksilvers zip died here. RIP"
16:34:15<roconnor>like that?
16:34:21<quicksilver>yup.
16:34:23<roconnor>ok
16:34:27<jmcarthur_work>ew :(
16:34:36<roconnor>ACTION wonders what pozic wanted
16:35:03<quicksilver>@go haskellwiki foldable and traversable
16:35:04<roconnor>and why can't i find the container's project blog or wiki or whatever it was?
16:35:05<lambdabot>http://www.haskell.org/haskellwiki/Foldable_and_Traversable
16:35:05<lambdabot>Title: Foldable and Traversable - HaskellWiki
16:35:08<quicksilver>roconnor: there.
16:35:32<quicksilver>sorry, I wasn't repsonding to your last comment
16:35:39<quicksilver>I meant 'there is quicksilver's zip'
16:39:06<roconnor>ah
16:39:08<roconnor>http://sneezy.cs.nott.ac.uk/containers/blog/
16:39:12<roconnor>@where containers
16:39:12<lambdabot>I know nothing about containers.
16:39:27<roconnor>@where+ containers http://sneezy.cs.nott.ac.uk/containers/
16:39:27<lambdabot>Nice!
16:40:09<roconnor>ah it was Naperian containers not Noetherian containers
16:40:21<roconnor>I fail at Haskell
16:42:40<roconnor>someone needs to explain what conatiners, shapes, and positions are sometime.
16:45:33<quicksilver>a container is what you put nuclear waste in.
16:45:39<quicksilver>every haskell programmer knows that.
16:45:55<roconnor>I thought that was a monad
16:47:03<jmcarthur_work>some like to claim that all monads are containers. i am not one of those people
16:49:34<jmcarthur_work>@djinn a -> (a -> b) -> b
16:49:35<lambdabot>f a b = b a
16:49:51<jmcarthur_work>@. @pl @djinn a -> (a -> b) -> b
16:49:51<lambdabot>Plugin `compose' failed with: Unknown command: "@pl"
16:50:23<gwern>when ANN'ing programs, do we cc haskell, or is it just haskell-cafe?
16:50:26<ski>@. pl djinn a -> (a -> b) -> b
16:50:26<lambdabot>f = flip id
16:50:34<jmcarthur_work>ah, no @s
16:50:48<ski>@@ @pl @djinn a -> (a -> b) -> b
16:50:48<lambdabot> f = flip id
16:50:58<jmcarthur_work>ah! no wonder i was confused
16:51:37<jmcarthur_work>gwern, i think most people cc haskell
16:51:46<gwern>'k
16:51:46<jmcarthur_work>and -cafe, that is
16:53:46<gwern>ACTION sends the message off. fly away little birdy!
16:59:10<gwern>oh drat! I don't even get the satisfaction of deleting 'write & release wp-archivebot' from my TODO
16:59:16<gwern>because I forgot to add it in the first place
17:02:28<randomguy>on Lenny stable
17:02:30<monochrom>haha
17:02:57<randomguy>on Lenny stable
17:03:25<randomguy>what are you using to install it?
17:03:55<randomguy>If perl segfaults with an "Unaligned access" error, where should I look first?
17:04:13<paper_cc>randomguy: look in #perl
17:04:25<randomguy>Desen: well what do they lack and what are you looking for?
17:04:51<byorgey>randomguy: I think you're typing in the wrong channel.
17:05:48<monochrom>(When I'm back from lunch I'll remember to unban)
17:07:28<byorgey>monochrom: why, was that guy in here before?
17:07:30<lament>that's what they all say
17:07:37<byorgey>or was it a bot just echoing stuff from another channel?
17:07:37<ski>ACTION resists putting that into `@remember monochrom'
17:08:04<mauke>heh
17:08:18<mauke>looks like a bot that prints to all channels it's in
17:08:25<paper_cc>@seen randomguy
17:08:25<lambdabot>I saw randomguy leaving #haskell 3m 35s ago, and .
17:08:33<ski>(`@tell' would be more appropriate, i suppose)
17:08:42<byorgey>I see.
17:09:05<byorgey>ACTION is too willing to give the benefit of the doubt, once again
17:09:20<monochrom>Not sure "why" refers to which. why ban? because it's clearly delusional. why unban? because the banlist is finite and sometimes I judge wrong too.
17:09:59<byorgey>I meant why ban. I was asking under the assumption that it was just some confused guy typing in the wrong channel and not noticing it somehow, which doesn't seem like grounds for a ban
17:10:01<SamB>also sometimes people learn!
17:10:09<byorgey>but given that it was a bot, banning is fine =)
17:10:29<SamB>oh, it's a bot?
17:10:41<byorgey>so says mauke
17:10:43<mauke>I don't know if it was a bot
17:10:52<mauke>but it said the same lines in #perl (and was banned)
17:33:12<rick_2047>http://pastebin.com/d7a3ba4c3 <-- i made this small program and haskell give me error
17:33:16<rick_2047>the error is
17:33:29<rick_2047>hello.hs:5:10: The last statement in a 'do' construct must be an expression
17:33:33<rick_2047>can anybody explain
17:33:41<mauke>are you using tabs?
17:34:10<rick_2047>mauke, how do u mean??
17:34:24<mauke>:-(
17:34:39<rick_2047>mauke, its vim automatic indentation
17:34:52<mauke>what does ':set et?' say?
17:34:52<rick_2047>mauke, is haskell white space sensitive?
17:35:14<rick_2047>mauke, in ghci?
17:35:14<mauke>parts of its syntax are, yes
17:35:18<mauke>rick_2047: no, in vim
17:35:30<rick_2047>mauke, it says nothing
17:35:37<mauke>impossible
17:35:47<rick_2047>but it is happening
17:35:53<mauke>I doubt that
17:36:02<rick_2047>no nothing
17:36:06<rick_2047>what is it for?
17:36:16<mauke>it tells me whether 'et' is set
17:36:30<rick_2047>but it says nothing to me
17:36:31<mauke>or rather, it's supposed to say either 'expandtab' or 'noexpandtab'
17:36:32<inimino>ACTION also doubts
17:36:46<travisbrady>rick_2047: just try dedenting your code and indenting again by hand by using spaces
17:36:57<rick_2047>travisbrady, ok
17:37:02<mauke>my crystal ball says: PEBKAC
17:37:25<inimino>that's not how you use vim
17:37:55<rick_2047>travisbrady, i tried what u said but nothing
17:38:21<rick_2047>travisbrady, also tried removing all indentation
17:38:57<travisbrady>rick_2047: what error are you getting?
17:39:07<rick_2047>hello.hs:5:10:
17:39:07<rick_2047> The last statement in a 'do' construct must be an expression
17:39:55<travisbrady>your code works for me
17:40:04<rick_2047>and plz anyone explain what this error is tring to say
17:40:07<rick_2047>trying*
17:40:30<mauke>it thinks the part after 'do' is a single statement
17:40:33<kpreid>rick_2047: It has parsed your code such that the last item in a do block is not "foo" but "x <- foo"
17:40:34<travisbrady>rick_2047: haskell determines structure by layout (indentation) though you can also use {}
17:40:49<mauke>which is invalid, because you can't have a "<-" statement with nothing after it
17:40:50<kpreid>rick_2047: and <- may not be used as the last statement in a "do"
17:40:51<travisbrady>rick_2047: and your indentation is busted somehow
17:40:52<Vulpyne>Everything in Haskell has to evaluate to a value. If the last thing in a do block is for example "blah <- something" that's just binding, and has no value.
17:41:37<rick_2047>travisbrady, and it should work coz its an example from a book
17:41:49<rick_2047>there is some problem in indentation?
17:41:57<mauke>yes
17:42:03<mauke>everything else looks ok
17:42:05<travisbrady>rick_2047: the code is fine, the indentation is the problem
17:42:09<kpreid>rick_2047: maybe you have nbsps instead of regular spaces or some such thing?
17:42:16<kpreid>if you copied from a web page that could happen
17:42:19<kyagrd>Can someone explain what are the differences between "forall a b. (C a, C b) => T a -> T b -> T (a,b)" and just "(C a, C b) => T a -> T b -> T (a,b)"? I thought they were the same, but I found out that it was not the case ...
17:42:38<kpreid>rick_2047: the important thing is that you use plain spaces and that 'args' and 'putStrLn' start in the same column
17:42:44<mauke>kyagrd: none, except for scoped type variables maybe
17:43:00<kpreid>rick_2047: if you have trouble with that try putting a line break immediately after the 'do'
17:43:02<rick_2047>kpreid, but i am typing it by hand
17:43:28<travisbrady>rick_2047: delete all the spaces in the last line before the putStrLn and then enter insert mode and hit space until the putStrLn lines up with the 'a' in args in the line above
17:43:32<kpreid>rick_2047: like this: http://pastebin.com/m75458125
17:43:35<kyagrd>mauke: Yeah the code I saw had scoped type variable and was using forall
17:44:03<Peaker>kyagrd: scoped type variables use "forall" as a sort of explicit type variable declaration, and that's what scopes it
17:44:29<rick_2047>kpreid, your thing worked
17:44:57<rick_2047>i will have to look more into the problem afterwards though
17:45:08<rick_2047>coz its a vim problem
17:45:34<mauke>well, it's because expandtab is off
17:45:36<kyagrd>Peaker: So, if I'm going to use scoped type variable, I must always use forall ... am I understanding it right?
17:45:46<rick_2047>mauke, how do you turn it on
17:45:50<rick_2047>set et?
17:45:56<mauke>rick_2047: no, :set et
17:46:02<mauke>rick_2047: :set et? is how you query it
17:46:03<Peaker>kyagrd: I think so
17:46:17<kyagrd>Thanks,
17:46:22<rick_2047>mauke, it set to noexpandtab
17:46:59<rick_2047>ACTION sets it to expandtab
17:47:13<rick_2047>ACTION again blesses the community for help
17:47:18<rick_2047>ACTION and back to work again
17:47:29<skorpan>lol
17:47:32<skorpan>oops, wrong channel
17:47:53<sm>morning all
17:50:21<J11>Is there a difference between (+) 4 $ (*) 7 3 and (+) 4 $ 7 * 3 ?
17:50:29<skorpan>no
17:50:48<kyagrd>I stick -- vim:sw=2:ts=2:expandtab:autoindent on top of all my haskell scripts
17:52:20<J11>my parser thinks otherwise
17:52:38<J11>HsInfixApp (HsApp (HsVar +) (HsLit (HsInt 4))) $ (HsApp (HsApp (HsVar *) (HsLit (HsInt 7))) (HsLit (HsInt 3)))
17:52:48<J11>HsInfixApp (HsInfixApp (HsApp (HsVar +) (HsLit (HsInt 4))) $ (HsLit (HsInt 7))) * (HsLit (HsInt 3))
17:54:25<inimino>well of course they must parse differently
17:55:11<byorgey>J11: after the parse is done, you should go through and translate applications of HSVar * into actual multiplication nodes, perhaps
17:55:34<inimino>and unify HsInfixApp and HsApp
17:56:10<Cope>Hello - is haskell well suited to text processing? I normally use ruby or python, but am looking for a functional language to play with prior to erlang factory, and have some text processing tasks to do.
17:57:08<jmcarthur_work>Cope, haskell has *excellent* parsing libraries, but if you are used to regexes it may feel odd
17:57:18<byorgey>Cope: well, it kind of depends what sort of text processing you are trying to do
17:57:39<byorgey>Haskell is great for text processing, but it is not well suited to text processing in the *same style* as ruby or python
17:57:49<byorgey>so it might feel awkward for a while
17:58:05<jmcarthur_work>for example, haskell comes with no split function
17:58:23<byorgey>jmcarthur_work: cabal install split =)
17:58:27<J11>the second example looks like ((+) 4 $ 7) * 3 which results in 33 instead of 25 by (+) 4 $ 7 * 3
17:58:28<dons>Any Mac users want to test the platform installer beta? http://projects.haskell.org/pipermail/haskell-platform/2009-June/000501.html
17:58:32<jmcarthur_work>byorgey, i said "comes with"! :P
17:58:38<Cope>I'm used to unix text processing, sed, cut, awk, etc, and python/ruby string libraries, and regexes
17:58:51<byorgey>jmcarthur_work: well, who's going to do text processing without installing some libraries? =)
17:58:55<jmcarthur_work>Cope, yeah, haskell's text processing libraries are very different from those
17:59:11<Cope>i have a copy of 'real world haskell'
17:59:17<Cope>is this is good place to start?
17:59:23<jmcarthur_work>byorgey, right. i was just trying to convey that haskell does things differently than ruby/python
17:59:28<jmcarthur_work>Cope, there is a chapter on parsec, i think
17:59:30<byorgey>well, actually, Haskell does well with stream processing, a la sed, cat, awk etc.
17:59:32<jmcarthur_work>which would be relevant
17:59:38<travisbrady>Cope: i do a fair amount of that with Haskell, take a look at Data.ByteString and the pcre bindings
18:00:09<monochrom>"real world haskell" is a good start!
18:00:11<travisbrady>Cope: Parsec is awesome, but may be overkill and doesn't yet work with ByteStrings to my knowledge
18:00:23<dons>parsec 3 does, also attoparsec
18:00:27<dons>the latter is well optimized
18:00:46<jmcarthur_work>and there are other parsing libraries besides parsec that i hear are good too, although i haven't tried them
18:00:52<Cope>ok
18:01:05<jmcarthur_work>pcre is worth looking at for something familiar i think
18:01:09<travisbrady>Cope: i'd take a look at some of the Haskell widefinder implementations, that's a common task. here's mine: http://github.com/travisbrady/funzone/blob/a16c6e3f21ef339d095f6f68f116f2de213a06c9/Widefinder.hs
18:01:33<Cope>well I have close to zero idea about haskell - I know python list comprehensions are an idea from haskell, and I know about map, reduce, and lambda
18:01:36<Cope>that's about it
18:01:39<Cope>in python, that is
18:01:55<Cope>I suppose ruby has some functional stuff with inject, collect, etc
18:01:59<jmcarthur_work>Cope, dive in! there's a *ton* you can learn :)
18:02:12<J11>Well it seems that Language.Haskell.Parser returns the same for (+) 4 $ 7 * 3 and ((+) 4 $ 7) * 3
18:02:22<JusticeFries>dons
18:02:29<JusticeFries>i'm not near my mac, but i'll give it a shot in a bit.
18:02:34<dons>thanks
18:02:34<travisbrady>Cope: Haskell is really much easier than it's made out to be, you can get a lot done with the list processing stuff
18:02:44<dons>and faster...
18:02:59<J11>I thought it was capable of handling infix declarations
18:03:11<dons>http://shootout.alioth.debian.org/u64q/benchmark.php?test=all&lang=python&lang2=ghc&box=1 sooo much faster
18:03:16<jmcarthur_work>Cope, the "functional" features of ruby/python are not good indications of what functional programming is like simply because they are not universal/general
18:03:51<Cope>jmcarthur_work: i'd heard that
18:03:51<dons>oh, we're not quite 1000x faster than ruby on mandelbrot, doh.http://shootout.alioth.debian.org/u64q/benchmark.php?test=all&lang=ghc&lang2=ruby&box=1
18:03:54<dons>should work on that for the win.
18:03:59<CosmicRay>bos, dons: I seem to remember a tweet from one of you about a new unicode library recently... can you tell me what it's called?
18:04:04<CosmicRay>dons: heh
18:04:05<dons>"text"
18:04:09<Cope>so where do I start? I don't have a mathematical background, so lambda calculus is a bit scary
18:04:16<CosmicRay>dons: we're not 1000x faster than ruby? we most be slipping ;-)
18:04:24<dons>right!
18:04:28<CosmicRay>dons: what advantages does it have over utf8-string?
18:04:29<jmcarthur_work>Cope, real world haskell is good
18:04:34<JusticeFries>real world haskell
18:04:43<Cope>great, well I have that book :)
18:04:52<dons>CosmicRay: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/text
18:04:57<JusticeFries>i've been actually grappling with whether haskell or erlang suits my research problems before i dive too far. :3
18:04:59<CosmicRay>dons: already there
18:05:08<jmcarthur_work>Cope, my impression is that rwh would suit a ruby/python programmer very well, too
18:06:10<Cope>super dumb question: how does haskell differ from erlang? I'm interested in learning 'a' functional language, but which is suited to text processing, prior to going to the erlang conference in a few weeks, so I am not clueless
18:06:30<Cope>I'm reading the erlang book too, just so I have some diea of the langauge and terminology
18:06:49<jmcarthur_work>Cope, erlang and haskell are almost entirely different, beside favoring recursion and immutability
18:06:52<jmcarthur_work>*besides
18:06:58<travisbrady>Cope: i come from Python too and the thing that's worked best for me is to pick a problem i'm familiar with and solve that.
18:07:04<CosmicRay>Cope: I haven't used erlang myself, so take this with a large grain of salt. but I believe it's a question of focus. Erlang is focused around network communications, especially binary protocols and IO clustering
18:07:06<jmcarthur_work>and they both have pattern matching, too
18:07:22<thoughtpolice>really erlang is focused around fault tolerance
18:07:22<CosmicRay>Cope: Haskell is more a general-purpose language, though you can solve a variety of problems with either, of course.
18:07:30<thoughtpolice>it is only natural that things like concurrency come from that
18:07:37<thoughtpolice>as well as immutability, since the problem is then easier
18:07:45<Cope>I'm really tempted to have a go at solving some of the ruby quiz problems in haskell
18:08:02<travisbrady>lots of people start with project euler stuff
18:08:13<Cope>are you familair with ruby quiz? it's a super concept - a little challenge to solve
18:08:19<CosmicRay>Cope: url?
18:08:20<thoughtpolice>CosmicRay: but it does apparently work excellent for web stuff (yaws seems really cool)
18:08:38<thoughtpolice>@go ruby quiz
18:08:39<edwardk>grr. http://lwn.net/Articles/336039/
18:08:39<lambdabot>http://rubyquiz.com/
18:08:39<lambdabot>Title: Ruby Quiz
18:08:45<Cope>http://rubyquiz.com/quiz1.html
18:08:52<JusticeFries>yaws is pretty awesome.
18:08:53<CosmicRay>thoughtpolice: I have used it low-level with FastCGI, and that is great. I have not messed with toolkits in any language for a long while.,
18:09:12<jmcarthur_work>erlang is a lot "looser" than haskell because it must be resilient with changing requirements on live systems
18:09:21<CosmicRay>thoughtpolice: "works well for web stuff" seems to be a widely divergent concept. A lot of folks think that Java application servers that require 2GB of ram just to initialize are great. I don't. ;-)
18:09:32<CosmicRay>jmcarthur_work: which, I'm not sure, is a good thing.
18:09:40<p_l>CosmicRay: Worse, there are people who run PHP :P
18:09:42<jmcarthur_work>CosmicRay, i think for erlang it's great
18:09:58<CosmicRay>jmcarthur_work: I run ejabberd a couple of places. it seems to lead to unnecessary complexity
18:10:07<jmcarthur_work>CosmicRay, for example, you can make a process accept new types of data without even having to define a data type
18:10:15<thoughtpolice>CosmicRay: well, in the famous yaws v. apache benchmark, apache + mtm (multithreading module I think or something?) was dying out at around 4k concurrent connections; yaws kept going up into 80,000 concurrent clients
18:10:19<edwardk>cope: erlang has very few kinds of things you can store, you just have lists, tuples, an atoms, in haskell you have constructors which have multiple slots, in erlang you'd use a tuple and make the first entry an atom
18:10:23<thoughtpolice>CosmicRay: I've also spent a day or so with erlyweb
18:10:27<thoughtpolice>and it's pretty neat
18:10:43<p_l>CosmicRay: Sometimes you have to choose - fast live update of code or slow recompiling to make sure everything is right. Both have their place
18:10:46<jmcarthur_work>i love erlang, but for entirely different reasons than i love haskell
18:10:49<Cope>ahh... lists tuples and atoms... I think this rings a bell from 'the little schemer'
18:10:50<jmcarthur_work>apples and oranges
18:10:57<p_l>jmcarthur_work: right
18:11:00<CosmicRay>Cope: The Haskell type system is amazingly helpful and flexible. It lends itself well to working with larger programs where correctness is important.
18:11:01<thoughtpolice>jmcarthur_work: agreed, erlang is a lot of fun.
18:11:08<CosmicRay>Cope: as far as I'm concerned, that works well for web apps
18:11:11<dons>p_l: dynamic code update is done in haskell too, fwiw.
18:11:19<dons>code update isn't erlang's killer app.
18:11:37<p_l>dons: I didn't say that it isn't done - I was talking about amount of complexity it might require :)
18:11:43<edwardk>cope: on top of that haskell is lazy, so it doesn't bother fleshing out a structure in memory until the result is needed. erlang builds them strictly, this results in some differences. i.e. in haskell you work with infinite lists without problem and in erlang some problems necessarily take an extra logarithmic time factor
18:12:06<Cope>ok
18:12:10<CosmicRay>Cope: here's what I'd say. If you want something truly different from what you've done before, try Haskell.
18:12:30<CosmicRay>Cope: As edwardk says, Haskell is a language in which we routinely create and process infinite lists ;-)
18:12:33<EvilTerran>it's maths... for breakfast!
18:12:37<Cope>:)
18:12:45<edwardk>erlang excels in inter-process communication. since they have so few primitives its easy for them to define a universal 'on the wire' format.
18:12:48<CosmicRay>Cope: I like to say that Haskell manipulates functions like Perl manipulates strings.
18:13:18<mmorrow>ski, quicksilver: woohoo, gustave: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5570#a5574
18:13:22<edwardk>haskell has a few variations on that theme, but none that really say is competitive with erlangs model in all fairness.
18:13:27<EvilTerran>CosmicRay, it's a bit more structured than perl's string manipulation, but i guess it's similar in terms of expressivity
18:13:38<dons>edwardk: for serializing data?
18:13:39<edwardk>er that I could really say
18:13:40<jmcarthur_work>in fact i'd say that 95% of my identifiers in haskell are functions and not values
18:13:41<CosmicRay>EvilTerran: it was a loose metaphor, yes ;-)
18:14:00<jmcarthur_work>haskell's concurrency is as good as erlangs, in my experiences...
18:14:05<Cope>So how is haskell different from lisp? by which I mean scheme or emacs lisp, as that's all I have any exposure to?
18:14:14<jmcarthur_work>you have channels, STM, MVars, etc.
18:14:18<dons>statically typed, pure, parallel.
18:14:26<dons>its the grandchild of lisp.
18:14:29<Cope>sorry if these are dumb questions - I'm just getting my head around the domain
18:14:39<CosmicRay>Cope: Type system including type inference, purity are the big ones.
18:14:46<jmcarthur_work>Cope, your questions are too common to be dumb
18:14:56<EvilTerran>mmorrow, what's with "case :4 of :10 -> ..." etc?
18:15:00<CosmicRay>Cope: syntax, of course, too.
18:15:06<Cope>jmcarthur_work: maybe that makes them FAQs and I sould go read a book / website!
18:15:09<CosmicRay>Cope: what other languages have you used?
18:15:43<jmcarthur_work>Cope, http://haskell.org/haskellwiki/Introduction
18:15:45<Cope>CosmicRay: python, ruby, shell, basic
18:16:09<jmcarthur_work>Cope, and http://haskell.org/haskellwiki/Comparison_of_functional_programming_languages
18:16:13<mmorrow>EvilTerran: those are the patterns that are just vars... i should eliminate those and sub the :4 in for :10 there.
18:16:19<EvilTerran>mmorrow, i'm guessing this is going for elegant and correct code over gratuitously optimal output?
18:16:24<edwardk>jmcarthur: within one machine, yes. across machines there is a world of difference. i love haskell. but when you consider erlang's communication model you have to realize it works uniformly across machines.
18:16:37<CosmicRay>Cope: ok, I used to use Python too. I actually wound up with Haskell because I wanted something to learn that was different enough from Python, and Ruby wasn't.
18:16:41<mmorrow>EvilTerran: oh i'm going for gratuitously optimal output
18:16:44<mmorrow>:)
18:16:54<jmcarthur_work>edwardk, right, but i call that distributed computation, not concurrent computation
18:16:55<moshisushi>is there a Haskell list type with O(1) indexing?
18:16:56<EvilTerran>aha. also good. :)
18:16:58<mmorrow>EvilTerran: suggestions for improvement?
18:17:01<CosmicRay>Cope: I think of Haskell as what Python ought to have evolved to. There's actually a bit of sharing of concepts between the too (but just a bit)
18:17:05<EvilTerran>moshisushi, well, we've got arrays
18:17:19<jmcarthur_work>CosmicRay, really? python seems to be the exact opposite of haskell to me
18:17:28<lament>i'm going to a doctor, can someone quickly recommend a cool paper to read?
18:17:31<mmorrow>EvilTerran: (i think that's optimal wrt everything but the matching the var patterns like you pointed out)
18:17:33<J11>I just saw the diference between the declarations(hsinfixapp) , now I just have to find a way to rearange them while taking precedences into account
18:17:34<EvilTerran>moshisushi, those are in Data.Array; we also have Data.Map, which has O(log n) insert, delete, lookup, etc
18:17:51<CosmicRay>Cope: so Python (back when I used it), had a list type. Then it had a generator, that could simulate a list, and build it up lazily. Haskell's list is lazy, so it can be file-backed if needed.
18:17:52<moshisushi>EvilTerran: oh right, very good!
18:18:05<EvilTerran>moshisushi, and, on 64-bit machines, log n < 64, so that's near enough constant time for a lot of things :)
18:18:10<edwardk>jmcarthur: yes, but in erlang they are one in the same. its kind of like if you only have one thread per process all 'inter-thread' communication is IPC, so you get good at IPC. They've cut off their hands, so they got good and working with their toes
18:18:12<moshisushi>EvilTerran: so Map is a redblack tree or something?
18:18:17<jmcarthur_work>moshisushi, Sequence has log n indexing
18:18:31<dino->CosmicRay: I have days where I don't understand why more of the Perl programmers I know don't like Haskell. They do so much with list processing in Perl. And some things like assigning the result of a function to a list is sort of pattern matchy.
18:18:49<EvilTerran>moshisushi, it's some kind of balanced tree structure, yeah
18:18:53<jmcarthur_work>edwardk, i would still call erlang a massively distributed language and not just a massively concurrent language
18:19:09<jmcarthur_work>edwardk, and as i said already, it's *excellent* for that
18:19:09<CosmicRay>dino-: I've got a colleague that's been a Perl fan for years. Even goes to YAPC. He's enjoying learning Haskell, and getting somewhat frustrated with Perl in the process.
18:19:11<moshisushi>well what i'm actually looking for is a matrix with O(1) indexing, but i guess arrays of arrays is good then
18:19:26<dino->CosmicRay: That's what I like to hear. That describes me.
18:19:29<EvilTerran>moshisushi, arrays indexed by tuples is the conventional way of doing that in haskell
18:19:31<jmcarthur_work>moshisushi, you could check the math libraries on hackage
18:19:40<CosmicRay>dino-: if you're used to playing with dangerous refs and regexps everywhere, the greater structure of Haskell could seem foreign or constricting, I suppose.
18:19:59<moshisushi>jmcarthur_work yep, i will
18:20:00<EvilTerran>moshisushi, ie, Array (Int,Int) Float would be an array of Floats indexed by pairs of Ints
18:20:16<moshisushi>EvilTerran i see!
18:20:20<moshisushi>thanks for the help
18:20:53<Cope>CosmicRay: right - I know about generators
18:20:56<Cope>yield blocks etc
18:20:59<Cope>and list comprehensions
18:21:04<edwardk>In any event, i tend to use erlang when i need to compute a big result, and i want to throw all the hardware I have at it. I use haskell when I want to work smarter within a box.
18:21:04<CosmicRay>exactly
18:21:21<dino->dangerous refs!
18:21:24<Cope>I think python's pretty awesome :)
18:21:32<edwardk>jmcarthur_work: the only reason i bothered to clarify was because of the running discussion with Cope =)
18:21:32<CosmicRay>Cope: the other thing is that Python used to be the language of simple purity.
18:21:49<CosmicRay>Cope: but they keep adding so many __blah__ methods that it no longer meets either.
18:21:55<Cope>yeah, totally
18:21:59<EvilTerran>mmorrow, the outermost case in the output strikes me as a similar-but-slightly-different situation, what with the distinct ":6 ->" and "_ ->" cases
18:22:04<jmcarthur_work>a good library for distributed computation in haskell would be nice to have
18:22:14<edwardk>python used to brag that it was the new perl... now it is.
18:22:21<CosmicRay>Cope: the other thing is that there is a limit to how big it can scale before it starts becoming unwieldy due to dymanic typic.
18:22:32<CosmicRay>edwardk: hah
18:22:37<jmcarthur_work>maybe even separate things for parallelism and concurrency, like we already have for single-machine stuff
18:23:10<CosmicRay>Cope: Haskell has type inference, which means that the compiler guesses what type you want (most of the time) based on how you use things.
18:23:14<Berengal>jmcarthur_work: first order of business: Serializeable closures
18:23:24<Cope>Yeah, I'm not really sure what typing is... have heard of type inference
18:23:28<CosmicRay>Cope: So you don't have to sprinkle Int and String all over your code like you would in Java, yet you still have strong static typing.
18:23:47<CosmicRay>Cope: so typing is what makes sure that you don't pass a string to something that wants a list of ints or something
18:23:50<edwardk>i had a nice little toy 'hot thunk' model i was using in a toy interpreter a while back that used to send uninterpreted thunks back and forth over the network, so you could share codata as well as data
18:24:02<jmcarthur_work>Berengal, actually, first order of business would be tighter restrictions on data types, like Int
18:24:27<CosmicRay>Cope: in Python, you won't know if you've had the problem until you run the program. and maybe you hit some rarely-used part of the code and realize you expected a tuple with 3 elements and got one with just 2
18:24:32<Cope>CosmicRay: right - ok, and python has dynamic typing, i think?
18:24:35<CosmicRay>result: crash.
18:24:36<edwardk>but doing that for something like ghc is kinda terrifyingly complicated =)
18:24:36<CosmicRay>right.
18:24:42<CosmicRay>so in Haskell, this is caught at compile time
18:24:44<Cope>CosmicRay: right, you get the same with ruby
18:24:47<Berengal>jmcarthur_work: You mean giving them one size on all platforms and such?
18:24:48<CosmicRay>before your program is ever run.
18:24:50<CosmicRay>Cope: right
18:24:53<jmcarthur_work>Berengal, yup
18:25:05<Cope>ah, is this like ocaml?
18:25:07<CosmicRay>Cope: so normally the static typed languages force you to tell the compiler what type everything is.
18:25:10<CosmicRay>Cope: yes, exactly
18:25:21<EvilTerran>well, ours is better than ocaml's ;)
18:25:29<CosmicRay>Cope: they have very similar type system to haskell's
18:25:36<Berengal>jmcarthur_work: Maybe I just want the serializeable closures...
18:25:46<Cope>got you
18:25:57<dino->I feel that this strong-enough-to-cause-you-grief typing drives people all the way in the other extreme to things like Perl.
18:26:03<jmcarthur_work>Berengal, that combined with the serialization would make a pure dpar :: a -> b -> b possible, aside from the possibility of network failure...
18:26:19<dino->With them feeling like things like Java is the pinnacle of typing. Or something.
18:26:21<edwardk>i.e. if i send 'let repeat x = xs where xs = x : xs in repeat 1' over the network it'll send a closure that will evaluate out to 1:1:1:1... when inspected, but it'll send the graph, not the unfolded list.
18:26:24<Cope>oh i forgot i've done a heap of OO php too
18:26:27<dino->s/is/are/
18:26:45<Berengal>jmcarthur_work: Yep, it would be great to see something like that happening
18:26:46<mauke>dino-: possibly related: http://perl.plover.com/yak/typing/
18:26:47<EvilTerran>ACTION grabs the holy water spraybottle and points it at Cope
18:26:51<Cope>thank you!
18:26:56<EvilTerran>;)
18:26:58<Cope>I needed that! the memory was hurting!
18:27:16<edwardk>but that can't be done directly in haskell, it'd need compiler support to provide the inspection of unevaluated thunks
18:27:17<Cope>oh... is there a unit testing library for haskell?
18:27:31<edwardk>cope: like HUnit?
18:27:32<CosmicRay>Cope: HUni
18:27:39<dino->mauke: Thanks. I was also thinking of this: http://www.pphsg.org/cdsmith/types.html
18:27:43<CosmicRay>Cope: there is also QuickCheck, which is even cooler for some problems.
18:27:46<jmcarthur_work>Cope, hunit, but we have something even better for pure functions
18:27:50<edwardk>cope: there is HUnit, and a more haskelly kind of testing library folks use called quickCheck
18:27:50<CosmicRay>Cope: It generates test cases for you automatically.
18:28:03<Cope>CosmicRay: ex eventu?
18:28:11<Cope>I prefer to write the test first, then make it pass
18:28:12<edwardk>QuickCheck is disturbingly cool
18:28:12<jmcarthur_work>@check \x -> (x :: Int) == read (show x)
18:28:13<lambdabot> "OK, passed 500 tests."
18:28:46<monochrom>haha disturbingly
18:28:56<jmcarthur_work>i also like smallcheck
18:29:01<Cope>jmcarthur_work: ok - how do I read that line - it's very unfamiliar
18:29:05<monochrom>Is it because it smells like SkyNet?
18:29:15<Cale>edwardk: Yeah, I've wanted such a thing for a while. It would be really cool to store partially evaluated expressions and values to disk or over the network.
18:29:22<jmcarthur_work>Cope, basically i just used quickcheck to verify that serialization and deserialization are inverses for Int
18:29:52<EvilTerran>Cope, "check, for all x, that x (which must be an Int) equals read (show x)"
18:29:53<mauke>function (Int x) { return x == x.toString().parseInt() }
18:29:56<CosmicRay>Cope: "\x ->" creates an anonymous function that takes one parameter named x.
18:30:15<CosmicRay>(x :: Int) means that we force it to be of type Int, since this is a case where inference can't help us
18:30:16<Berengal>@quote firehose
18:30:16<lambdabot>No quotes match. Do you think like you type?
18:30:27<Cale>Cope: That if x is an Int, then showing x (turning into a string) and then reading that string (turning it back into an Int) produces x again.
18:30:32<EvilTerran>@quote fugue
18:30:32<lambdabot>monochrom says: Welcome to #haskell, where your questions are answered in contrapuntal fugues.
18:30:35<Berengal>@quote fire.*hose
18:30:35<lambdabot>byorgey says: sometimes asking #haskell for help can be like taking a drink from a fire hose
18:30:36<jmcarthur_work>the @check is a command for lambdabot, the \x -> means i'm defining an anonymous function with parameter x, the x::Int means i'm restricting the type of x (not always necessary, but it is for quickcheck), and the rest is the test code
18:30:40<CosmicRay>then we just say that x == read (show x) -- in other words, that converting an int to a string and then back to an int should produce the original value.
18:30:41<monochrom>Does it help to attach typechecking information to thunks when you pass them around or store them? Like proof-carry-code except the proof just proves types.
18:30:45<edwardk>cale: yeah, 'lazy HOT pickles' (higher order type)
18:30:55<Cale>edwardk: :)
18:31:00<edwardk>sounds like a band
18:31:00<CosmicRay>Cope: then QuickCheck comes up with the most diabolical Ints it can think of to test it with.
18:31:03<Cope>CosmicRay: ok so is that like a lambda?
18:31:04<jmcarthur_work>Cope, quickcheck generated 500 Ints and tested them all
18:31:11<CosmicRay>Cope: Yes, that's what we call it even.
18:31:17<CosmicRay>Cope: sorry, forgot you used python for a sec ;-)
18:31:29<edwardk>I'll let you know when I release the next Lazy Hot Pickles album.
18:31:34<Cale>edwardk: another thing I think would be cool is the ability to take the current continuation of a thread and store it to disk as an executable.
18:31:34<Berengal>Cope: We even have editors sugaring \ to lambdas
18:31:57<EvilTerran>Cope, the \ is supposed to be reminiscent of the main stroke of a lambda
18:32:01<Cale>edwardk: Or indeed, freeze the entire process with all its threads and store that continuation. :)
18:32:04<edwardk>dump core? =)
18:32:44<Cale>edwardk: But you could use this to trivially turn an interpreter into a (very bad) compiler.
18:32:51<Berengal>fixedPoint f = newton (λx → f x − x)
18:33:28<CosmicRay>Cale: doesn't emacs do that?
18:33:53<Cale>CosmicRay: I don't know enough about emacs to say...
18:33:55<CosmicRay>I thought that I remembered that part of building emacs involved dumping core to make the binary or something
18:34:03<JamesSanders>How does one convert a Int to Word16?
18:34:09<Cale>fromIntegral
18:34:10<Zao>CosmicRay: You forgot the rubber chicken bit.
18:34:17<edwardk>cale: that was basically what a lot of old projects used to use core dumps and fixups for
18:34:24<Cale>> fromIntegral (5 :: Int) :: Word16
18:34:25<lambdabot> 5
18:35:37<JamesSanders>I see
18:35:49<Cale>edwardk: Of