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