Experimental IRC log haskell-2007-07-16

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:02:26<int-e>shachaf: Hmm. You'd still have to lift IO actions into your monad to use them wouldn't you? So I expect the difference in amount of code between a monad transformer (used on a user provided monad) and a monad transfromer transformer (used with a user provided transformer which is applied to the IO monad) to be small.
00:03:51<shachaf>int-e: But a function that doesn't use any part of the transformer (say, refresh :: IO ()) wouldn't need any extra, would it?
00:05:15<shachaf>int-e: That is, functions that use a part of UserT would have to, say, add (MonadIO m) =>, but functions that don't (part of the regular code, that assumes IdentityT) wouldn't.
00:05:21<shachaf>int-e: Or would they?
00:08:58<int-e>shachaf: hmm. this is all too vague. I'd like to stop here unless there's a concrete code example to discuss.
00:12:49<shachaf>int-e: Probably, yes. :-)
00:12:53<shachaf>int-e: I was just wondering.
00:13:23<shachaf>ACTION probably has no idea what he's talk about. :-)
00:13:27<shachaf>s/k/king/
00:45:29<ddarius>There you go Philippa
00:45:52<Philippa_>?
00:45:56<Philippa_>ah
00:46:03<PeterMc>Hi there, Philippa.
00:46:11<Philippa_>hi
00:47:02<PeterMc>Had much response to the lambda-the-ultimate announcement? (Apart from me wondering about Haskell vs. Asperger's Syndrome, that is.)
00:47:19<dolio>This Hugh Perkins fellow is quite something.
00:47:40<Philippa_>it's tricky to know what's specifically in response to the LtU announcement rather than other ones - nothing else on the site itself
00:47:51<dons>dolio: :/
00:48:21<PeterMc>Scary, innit!
00:48:35<PeterMc>Trying to organise something, I mean.
00:49:28<dolio>I wonder what SuperO does for a high level prime sieve.
00:49:39<Philippa_>heh, yeah. ndm's been a big help though, and thankfully the 'established' tradition is such that doing everything ad-hoc and at the last minute^W^W^W^Won demand is what's expected
00:53:34<dolio>If 'print . length . words =<< getContents' can beat C, maybe a lazy list prime sieve can beat a C# loop. :)
00:57:22<EvilTerran>probably not a list as such. the O(n) lookup complexity would sting.
00:59:12<dolio>Well, I haven't looked at what they're doing with it closely, but I think they're traversing it once to see how many primes are below a certain value...
00:59:13<EvilTerran>ACTION was thinking about a lazy data structure of the form 'array (0,1) ... : [array (2^i,2^(i+1)) ... | i <- [0..]]' a while ago. that might suit itself to that sort of thing.
00:59:21<ddarius>EvilTerran: But you don't "lookup" stuff in that case.
00:59:25<dolio>So the O(n) may be moot.
00:59:42<EvilTerran>hm. i don't know what algorithm you're thinking of exactly, so i can't say.
01:00:19<EvilTerran>(that thing i just mentioned needs a '-1' inserted somewhere, and probably arranged a bit differently at the start, but you get the idea)
01:02:17<hpaste> int-e pasted "something like this? (for EvilTerran)" at http://hpaste.org/1701
01:02:56<int-e>(this uses exactly such a data structure to memoize a recursive function on natural numbers)
01:03:53<EvilTerran>looks about right. am i right in thinking that yields O(log n) lookup time?
01:04:01<int-e>yep
01:04:12<EvilTerran>spiffing
01:04:25<|Steve|>There was an efnet math problem posed a while back about finding a function f such that for all natural number f(f(n)) = h(n) where h(n) was something like n^2 - 19n + 99. Is there anyway to speed this up, it gets extremely slow: http://pahtak.org/~steve/f.hs
01:05:15<|Steve|>Oh, g is the function, not h. and I got it right.
01:07:42<dolio>I can't seem to connect...
01:07:56<|Steve|>Oh, yeah, bit torrent is killing my connection.
01:08:00<|Steve|>I'll paste on hpaste.
01:08:04<dolio>:)
01:08:58<PeterMc>I can't get through to pahtak.org either.
01:09:11<int-e>I could but it took ages :)
01:09:27<|Steve|>_Something_ just really hates bit torrent. It's either my router or my ISP.
01:09:40<|Steve|>I pasted on hpaste, we'll see if it times out or not.
01:10:15<shachaf>|Steve|: (By the way, you can use "case comparse x y of LT -> ...; EQ -> ...; GT -> ..." instead of comparing up to three times.)
01:10:56<ddarius>where comparse = compare
01:10:59<|Steve|>Good point. I wrote this some time ago. I only learned about case recently.
01:11:10<shachaf>ddarius: Uh, yes. :-)
01:11:31<shachaf>|Steve|: The important thing is compare, not case.
01:11:49<campusblo>hi is there a function that will tell you the position of an element in a list ?
01:12:01<shachaf>|Steve|: You can always say "f (compare x y) where f EQ = ...;..."
01:12:03<|Steve|>I don't think the numbers are getting large enough that doing the comparison is actually a bottleneck.
01:12:15<campusblo>eg positionNum 6 [1,2,3,6,7] = 4
01:12:19<ddarius>Bah, where is ordering :: Ord a => a -> a -> b -> b -> b
01:12:29<TSC>campusblo: elemIndex
01:12:49<TSC>> elemIndex 'e' "hello"
01:12:50<shachaf>|Steve|: (Which is why I only said this incidentally, in parentheses.)
01:12:50<lambdabot> Just 1
01:12:50<|Steve|>Heh, timed out.
01:12:51<hpaste> Steve pasted "f.f = g" at http://hpaste.org/1702
01:12:54<campusblo>in the prelude?
01:12:57<|Steve|>There we go.
01:12:58<PeterMc>The download from pahtak.org worked this time.
01:13:02<PeterMc>Now what?
01:13:04<shachaf>campusblo: In Data.List.
01:13:19<campusblo>ok thanks
01:13:20<shachaf>campusblo: Why would you need it to be in the Prelude?
01:13:26<|Steve|>Meh, it might get pasted twice.
01:13:39<campusblo>i just wanted to know where it was.
01:13:51<ddarius>@index elemIndex
01:13:52<lambdabot>Data.List
01:14:15<shachaf>@hoogle a -> [a] -> Int
01:14:15<lambdabot>No matches, try a more general search
01:14:18<shachaf>@hoogle a -> [a] -> b
01:14:19<lambdabot>Prelude.foldl :: (a -> b -> a) -> a -> [b] -> a
01:14:19<lambdabot>Prelude.foldr :: (a -> b -> b) -> b -> [a] -> b
01:14:19<lambdabot>Data.List.foldl' :: (a -> b -> a) -> a -> [b] -> a
01:14:25<ddarius>@hoogle elemIndex
01:14:25<lambdabot>List.elemIndex :: Eq => a -> [a] -> Maybe Int
01:14:25<lambdabot>Data.List.elemIndex :: Eq a => a -> [a] -> Maybe Int
01:14:37<campusblo>how would i import that into a file im working on?
01:14:45<ddarius>import Data.List
01:14:48<shachaf>campusblo: "import Data.List".
01:15:14<ddarius>Haskell and it's cryptic naming... </prick>
01:15:25<campusblo>so ill just copy that and put it at the top of the file
01:17:25<campusblo>ddarius why do i get the word "just" when i use that elemIndex function?
01:17:36<campusblo>i can't use that
01:17:42<campusblo>the just i mean
01:17:45<shachaf>campusblo: What if the element isn't in the list?
01:17:47<ddarius>> elemIndex 3 [1,2]
01:17:48<|Steve|>> elemIndex 5 [1,2,7,9]
01:17:49<lambdabot> Nothing
01:17:50<lambdabot> Nothing
01:17:52<shachaf>> elemIndex [5] [1,2,3,4]
01:17:53<lambdabot> add an instance declaration for (Num [t])
01:17:53<lambdabot> In the expression: 4
01:17:56<shachaf>> elemIndex 5 [1,2,3,4]
01:17:57<lambdabot> Nothing
01:18:00<|Steve|>> elemIndex 7 [1,2,7,9]
01:18:01<lambdabot> Just 2
01:18:15<|Steve|>It's the Maybe datatype.
01:18:29<|Steve|>data Maybe a = Nothing | Just a -- Something like that.
01:18:47<campusblo>ok
01:18:51<shachaf>|Steve|: Just like that. :-)
01:18:57<campusblo>@paste
01:18:57<lambdabot>Haskell pastebin: http://hpaste.org/new
01:19:18<|Steve|>Whee.
01:19:35<shachaf>@instances Ord
01:19:37<lambdabot>(), All, Any, Bool, Char, Double, Either a b, Float, Int, Integer, Maybe a, Ordering, Product a, Sum a, [a]
01:19:51<EvilTerran>> () >= ()
01:19:52<lambdabot> True
01:19:53<EvilTerran>heh
01:20:00<|Steve|>@instances Monad
01:20:01<lambdabot>((->) r), ArrowMonad a, Cont r, ContT r m, Either e, ErrorT e m, IO, Maybe, RWS r w s, RWST r w s m, Reader r, ReaderT r m, ST s, State s, StateT s m, Writer w, WriterT w m, []
01:20:08<ddarius>@src () compare
01:20:08<lambdabot>compare () () = EQ
01:20:33<shachaf>> Nothing `compare` Just 5
01:20:33<lambdabot> LT
01:20:38<shachaf>> Just 3 `compare` Just 5
01:20:40<lambdabot> LT
01:20:59<|Steve|>Nothing is less than Just 5?
01:21:10<shachaf>@src Maybe compare
01:21:10<lambdabot>Source not found. Have you considered trying to match wits with a rutabaga?
01:21:20<ddarius>It's derived.
01:21:26<TSC>Nothing is probably the minimum for all Maybe types
01:21:35<|Steve|>Odd.
01:21:37<dolio>> Nothing < Just undefined
01:21:38<lambdabot> True
01:21:43<hpaste> campusblo pasted "aaaarrgggggh" at http://hpaste.org/1703
01:21:53<campusblo>so what's wrong with that?
01:21:57<campusblo>why do i get that error?
01:22:08<ddarius>> [Nothing..] :: Maybe Int
01:22:08<lambdabot> Parse error
01:22:09<ihope_>> Just undefined < Just undefined
01:22:10<lambdabot> Undefined
01:22:12<ddarius>> [Nothing ..] :: Maybe Int
01:22:12<lambdabot> Couldn't match expected type `Maybe Int'
01:22:21<ddarius>> [Nothing ..] :: [Maybe Int]
01:22:22<lambdabot> add an instance declaration for (Enum (Maybe Int))
01:22:22<lambdabot> In the expression: [...
01:22:25<ddarius>Darn
01:22:40<ihope_>> [minBound..] :: [Int]
01:22:42<lambdabot> [-2147483648,-2147483647,-2147483646,-2147483645,-2147483644,-2147483643,-21...
01:22:45<dolio>> minBound :: Maybe Int
01:22:46<lambdabot> add an instance declaration for (Bounded (Maybe Int))
01:22:46<lambdabot> In the expression...
01:23:10<ihope_>When can you derive Enum?
01:23:17<Cale>campusblo: postitonNum
01:23:29<campusblo>oh
01:23:32<campusblo>lol
01:23:33<campusblo>ok
01:23:41<campusblo>im tired
01:24:37<campusblo>i thought i was going crazy. nevermind me
01:25:18<Cale>positionNum x = maybe 0 (+1) . elemIndex x
01:25:28<|Steve|>Does haskell guarantee tail recursion like scheme does?
01:25:38<TSC>campusblo: Compiling with warnings on would help to find errors like that
01:26:04<SamB>|Steve|: not that I know of
01:26:07<Cale>|Steve|: I don't think the Haskell standard says anything at all about evaluation.
01:26:10<SamB>but it would be stupid not to implement it
01:26:39<|Steve|>So an conforming implementation could stack overflow on a simple read-eval-print loop?
01:26:50<campusblo>TSC im in hugs
01:26:58<geezusfreeek>|Steve|: i'm pretty sure that writing a tail recursive function can still help you to avoid a space leak in most cases
01:27:01<TSC>Hugs doesn't have warnings?
01:27:14<campusblo>and the good news is im done a project im working on
01:27:16<campusblo>yay!
01:27:19<SamB>TSC: hugs doesn't compile ;-)
01:27:42<campusblo>well more or less done
01:28:12<SamB>|Steve|: it would be shunned
01:28:58<SamB>they don't write "don't be stupid" anywhere in the report either, you know ;-)
01:29:29<|Steve|>geezusfreeek: Well, what if you did something like: main = do { line <- getLine; if line == "" then return () else do {putStrLn line; main } }
01:29:55<|Steve|>And it did that as function calls?
01:30:10<SamB_XP>|Steve|: no big deal
01:30:21<Cale>|Steve|: Well, strictly speaking, I think all stack overflows sort of violate the semantics of the language already.
01:30:53<geezusfreeek>i'm pretty sure most implementations would garbage collect most of the old trash there
01:30:56<Cale>After all, they sort of make values into _|_ which shouldn't be _|_.
01:30:57<ddarius>As does running out of memory...
01:31:02<Cale>right
01:31:15<|Steve|>geezusfreeek: There is no garbage, it's all on the stack if it's doing function calls.
01:31:36<ddarius>|Steve|: Not true at all.
01:31:43<ddarius>Necessarily.
01:31:47<geezusfreeek>are thunks done on the stack? (i don't know much about haskell implementations)
01:31:48<SamB_XP>|Steve|: the Haskell standard, like the C standard, does not say anything about this matter
01:32:02<SamB_XP>... that doesn't stop a good C compiler either...
01:32:03<|Steve|>The scheme standard does.
01:32:17<|Steve|>But in C, I can write a loop. I can't in haskell.
01:32:20<Cale>|Steve|: The Haskell standard doesn't say anything about the order of evaluation, or how an evaluator might even work. It just says what programs mean.
01:32:30<|Steve|>I _have_ to use recursion.
01:32:36<SamB_XP>C doesn't have a stack any more than Haskell has
01:32:46<ddarius>|Steve|: You can safely assume that all implementations do tail call optimization.
01:32:49<SamB_XP>anyway, as I said, we would *shun* any implementation that got it wrong
01:32:51<Cale>|Steve|: It's safe to use recursion, because any *sane* implementation will do tail recursion optimisation.
01:33:01<|Steve|>Okay.
01:33:14<SamB_XP>after all, the report doesn't say "don't be stupid" either ;-)
01:33:18<|Steve|>Fair enough. It just seems like it's something that should be in the language given that there are no looping constructs.
01:33:26<ddarius>You'd think.
01:33:40<SamB_XP>ddarius: it would be too hard to say
01:33:52<Cale>Given that the language spec doesn't specify what order expressions are reduced in, it's sort of meaningless to even talk about the stack.
01:33:53<geezusfreeek>i don't know, i always thought it was kind of pointless to put implementation details into a language spec
01:33:55<Cale>What stack?
01:34:06<SamB_XP>C doesn't have a stack, why should we?
01:34:24<ddarius>SamB_XP: You'd more talk about space rather than stack.
01:34:43<Cale>You might just have an implementation which works by treating the program as a big graph and doing matching and reduction on that in a semi-random order.
01:34:56<SamB_XP>I don't believe that the report *ever* mentions space
01:35:01<|Steve|>You're right, the c99 standard doesn't use the word stack once.
01:36:11<SamB_XP>now, of course, it's less stupid to leave out tail-call optimization in a C compiler since, as you say, you can loop in C
01:36:32<|Steve|>The c++98 standard does mention stack unwinding.
01:37:09<SamB_XP>C++ is a bit of a different beast
01:37:38<|Steve|>It never refers to a call stack though.
01:37:57<SamB_XP>it might have been a slip-up ;-)
01:38:11<|Steve|>What might have been a slip up?
01:38:23<SamB_XP>using the word stack in "stack unwinding"
01:38:41<|Steve|>They use it 7 times.
01:39:01<SamB_XP>or maybe they couldn't come up with a better term...
01:39:07<|Steve|>And say stack is unwound twice more and stack shall not be unwound once.
01:39:23<|Steve|>But they're talking about object destruction.
01:39:36<SamB_XP>anyway, the stack doesn't actually need to be a conventional stack
01:39:45<|Steve|>"The process of calling destructors for automatic objects constructed on the path from a try block to a throw-expression is called "stack unwinding."
01:41:26<SamB_XP>anyway, C++ is a bit different I think
01:41:33<SamB_XP>since it has those pesky destructors
01:41:35<|Steve|>The c++ standard is way to long. 776 pages.
01:41:45<|Steve|>too*
01:41:54<|Steve|>I no speak the English.
01:42:18<SamB_XP>um, that's no excuse! I speak english and I still make mistakes like that ;-P
01:42:58<|Steve|>It was a joke since apparently I failed in that sentence.
01:43:18<SamB_XP>ACTION was somewhat kidding too
01:47:12<Baughn>This is why IRC should have humor tags
01:47:59<SamB_XP></joke>
01:49:15<msouth>so I could tell if "stack is unwound twice more and stack shall not be unwound once." was a reference to the Holy Hand Grenade?
01:50:33<|Steve|>It wasn't.
01:50:47<|Steve|>I was reading off stats about the standard.
01:50:49<Baughn>"Once shalt thou free objects. Objects shall be freed once, and one shall be the number of the freeing."
01:51:08<Baughn>I'm going to have to remember that one, for a channel where it actually fits
01:51:22<|Steve|>Heh.
01:51:36<SamB_XP>why doesn't it fit here?
01:51:49<SamB_XP>we can even free *functions* here
01:52:23<dons>have people see http://leiffrenzel.de/eclipse/cohatoe/ ?
01:52:24<lambdabot>Title: Cohatoe - Contributing Haskell to Eclipse
01:52:47<Baughn>SamB_XP: I'm thinking up a.. poem?.. that explains malloc/free in a rememberable way
01:52:58<Baughn>Remembrable?
01:53:12<SamB_XP>memorable
01:53:32<Baughn>I prefer remembrable.
01:53:32<msouth>"mnemonish"
01:53:58<dons>http://programming.reddit.com/info/26nde/comments
01:53:59<lambdabot>Title: Cohatoe: Extending Eclipse in Haskell (reddit.com)
01:54:40<cytzol>:r
01:54:42<cytzol>whoops
01:54:49<geezusfreeek>:)
02:02:33<hpaste> int-e annotated "f.f = g" with "using Data.Set as a priority queue" at http://hpaste.org/1702#a1
02:02:53<EvilTerran>hm. GHC's postfix operator support doesn't seem to extend to type constructors.
02:03:31<dons>http://programming.reddit.com/info/26nfh/comments
02:03:32<lambdabot>Title: An introduction to unit testing in Haskell with HUnit (reddit.com)
02:03:50<int-e>|Steve|: see annotation. it's quite a bit faster
02:04:37<sjanssen>dons: psssh, unit tests are just zero arity quickchecks :)
02:04:54<|Steve|>int-e: Looking.
02:05:02<geezusfreeek>sjanssen: what about for effectful code?
02:05:15<dons>sjanssen: I agree :)
02:05:23<sjanssen>geezusfreeek: that might be another story. I'm partly joking
02:05:25<dons>geezusfreeek: we can do that in QC these days too
02:05:27<|Steve|>Well, once the stupid page loads anyway.
02:05:31<geezusfreeek>dons: orly?
02:05:34<dons>see swiert's HW paper
02:05:42<geezusfreeek>ACTION peeks
02:06:29<geezusfreeek>ACTION is searching and not finding
02:06:47<dons>let's see..
02:07:26<dons>http://programming.reddit.com/info/26nge/comments
02:07:27<lambdabot>Title: Beauty in the Beast: testing impure code with QuickCheck (reddit.com)
02:07:37<dons>hang on, got to fix that
02:07:38<dons>its a pdf
02:08:28<int-e>|Steve|: the Queue type implements a queue made up off finitely many, sorted, infinite lists. the nextQ function is badly named - what it does is pick the next number (starting from m) that is *not* in the queue.
02:08:40<dons>http://programming.reddit.com/info/26ngk/comments
02:08:41<lambdabot>Title: Beauty in the Beast: checking IO, state and concurrent code with QuickCheck (pdf ...
02:08:56<geezusfreeek>dons: thanks
02:09:04<|Steve|>Okay.
02:09:54<dons>sjanssen: we could take a similar approach to QC X11
02:10:10<sjanssen>dons: that would require a purely functional spec of an X server
02:10:12<dons>(a data type for X11 operations, form a monad, test that purely, evaluate it it to actually execute the actions)
02:10:16<sjanssen>I imagine
02:10:16<dons>yes :)
02:10:22<|Steve|>Ugh, the page hasn't loaded yet. I'm going to put some laundry in and then look.
02:11:05<dons>yes, just have to write down the dX server semantics
02:11:06<dons>then its easy
02:12:38<|Steve|>You have an embedded delete character in there.
02:13:43<|Steve|>(Between the d and the X.)
02:19:21<SamB_XP>|Steve|: perhaps he thought he'd deleted the d?
02:21:59<dons>bad wifi, control chars not getting escaped by a bit too much latency
02:25:47<|Steve|>0x7f is typically a forward delete though.
02:26:19<|Steve|>0x08 is backspace.
02:26:52<glguy>> "\x7f"
02:26:59<glguy>?bot
02:26:59<lambdabot>:)
02:27:00<lambdabot> "\DEL"
02:27:19<glguy>> "\8"
02:27:20<lambdabot> "\b"
02:27:26<glguy>> "\x08"
02:27:28<lambdabot> "\b"
02:27:40<|Steve|>int-e: I have to admit, I don't quite know what this is doing.
02:30:55<int-e>|Steve|: it's the same algorithm as yours really, except for two major differences: a) instead of removing entries from a list of candidates ([12..]) it keeps a list of forbidden candidates; secondly these lists are stored in a Queue (basically getting O(log m) instead of O(m) processing time per element for merging m infinite lists)
02:31:32<glguy>what algorithm is this?
02:31:36<glguy>ACTION came in a bit late
02:31:43<|Steve|>Ah. I'm amazed you could even follow the algorithm.
02:32:02<|Steve|>glguy: It's a construction for a function f such that f . f = n^2 -19n + 99 for all natural numbers n.
02:32:04<int-e>|Steve|: well I did that problem of the day, too. my haskell version was worse than yours actually ;)
02:32:11<|Steve|>Heh, okay.
02:32:29<|Steve|>I didn't actually solve the problem. TRWBW did. I just implemented it.
02:32:43<int-e>well I did it the same way :)
02:32:56<|Steve|>It took him about half an hour to explain it to me. Then he solved it some other way that I didn't follow.
02:33:20<necroforest>Is there anything like arrays in haskell? Or do you have to access things sequentially in lists?
02:33:26<bos>ACTION loves conor mcbride's Punter -> (String -> Punter)
02:34:04<|Steve|>necroforest: There are arrays.
02:34:54<int-e>|Steve|: anyway it eats a crazy amount of memory now but is fast enough to verify that f . f = g for 1..500 in 12 seconds here
02:35:38<|Steve|>More memory than mine?
02:36:29<int-e>|Steve|: I'm not patient enough to test that :)
02:36:56<|Steve|>heh
02:37:48<hpaste> int-e annotated "f.f = g" with "a strategical `seq` cuts memory usage by a factor of 4" at http://hpaste.org/1702#a2
02:38:30<campusblo>hi folks. I wrote a program to crack code which takes strings as input
02:38:36<int-e>(if you're building a huge list, make sure that all list elements are fully evaluated)
02:38:45<campusblo>only problem is that its cant get around a " in the string
02:38:53<campusblo>anybody have any suggestions for that?
02:39:06<campusblo>i can get around everything else
02:39:16<oklopol>get around it?
02:39:23<dons>`to crack code' ?
02:39:27<campusblo>oh
02:39:28<glguy>> " a b \" c d " -- is this related?
02:39:30<lambdabot> " a b \" c d "
02:39:36<campusblo>its a ceaser cipher
02:39:46<glguy>the " stays a "
02:40:02<bos>i think a ceaser cipher would be defined as \_ -> []
02:40:16<oklopol>campusblo: what do you mean you can't around a " in a string?
02:40:26<dons>do you mean you can't pattern match on " ?
02:40:33<campusblo>it creates an encrypted or decrypts messages by shifting all letters a certain number of letters down the alphabet
02:40:35<dons>> '"' == 'x'
02:40:37<lambdabot> False
02:40:40<campusblo>yes okpool
02:40:53<campusblo>if i put a " the string terminates
02:40:58<oklopol>ah
02:40:59<oklopol>\"
02:40:59<campusblo>and i get an error
02:41:01<oklopol>escape it
02:41:10<oklopol>\" where you want the "
02:41:36<campusblo>but thats still 2 characters
02:41:41<oklopol>unless i'm confusing languages here, i shouldn't be teaching on this channel, but the other way around :)
02:41:46<campusblo>i think it would still terminate
02:41:50<campusblo>lol
02:41:52<oklopol>campusblo: that will mean "
02:41:58<oklopol>it's a way to get a " in a string
02:42:04<campusblo>oh ok
02:42:12<oklopol>read up onescape sequences
02:42:17<oklopol>*on escape
02:42:17<campusblo>ill try it
02:42:22<campusblo>will do
02:43:40<dolio>campusblo: Is Haskell your first language?
02:43:51<campusblo>yes
02:44:00<dolio>Nice.
02:44:04<glguy>ACTION points out that he solved campusblo's problem before he knew what the problem was :)
02:44:19<ddarius>Lucky you.
02:44:53<campusblo>i guess. but why do you say that ddarius?
02:44:57<glguy>Haskell it is terrible first language, you won't bother to learn any others ;)
02:45:12<jfredett>tru that.
02:45:15<SamB_XP>glguy: but then what will you write in it?
02:45:16<glguy>Most people start on an imperative language, and get all sorts of bad habits
02:45:20<dolio>Heh. He can always go on to Coq/Epigram.
02:45:24<SamB_XP>anyway, you'll then want to learn C
02:45:25<ddarius>There are many worse languages to start learning programming on (though in my opinion there are better ones too)
02:45:28<chrisamaphone>sml, twelf :)
02:45:34<oklopol>glguy: i did too, i just don't like giving advise until i'm sure :)
02:45:40<ddarius>Yarrow or Agda.
02:46:12<campusblo>well cool. i like haskell.
02:46:20<glguy>oklopol: You should try to give advice early and often
02:46:23<SamB_XP>I didn't make it to the end of the agda tutorial
02:46:27<campusblo>and i hear functional programmers make the big bucks
02:46:34<dons>yeah, twelf or epigram would make strange first languages
02:46:34<jfredett>ddarius: I like Scheme for a first language, Haskell for the real work
02:46:36<SamB_XP>oh no!
02:46:42<glguy>oklopol: there was a thread on the mailing list about how we need to transition people into "answering questions" sooner to keep the community going
02:46:44<SamB_XP>he's in it for the money!
02:46:47<campusblo>scheme is the next languae i do
02:46:49<SamB_XP>kick him quick
02:46:58<|Steve|>campusblo: Heh. Big bucks. =)
02:47:01<jfredett>Scheme < Haskell, in terms of power and hardness to learn.
02:47:18<jfredett>i guess difficulty is what i meant.
02:47:20<ddarius>jfredett: Scheme is one of the languages I would recommend as better, though it could still be a better starting language that it is.
02:47:23<|Steve|>Scheme is easier to learn. Side effects, consistent syntax.
02:47:25<glguy>You can express more programs in Scheme than Haskell though
02:47:46<campusblo>i see. i guess ill see next semester
02:47:47<chrisamaphone>uh, they're both turing complete.
02:47:49<|Steve|>I wouldn't expect to make money writing scheme though...
02:48:02<glguy>Haskell's type system eliminates programs that are otherwise valid in some cases
02:48:04<int-e>glguy: how many countable infinities are there?
02:48:14<glguy>int-e: relatively more :)
02:48:26<jfredett>glguy: yes, but those programs are most often not needed.
02:48:29<glguy>chrisamaphone: we tend to leave the turing complete argument at the door
02:48:41<campusblo>i hear you. i think we learn on these then we have to choose a language. right now im thinking C# and Java
02:48:46<oklopol>glguy: you are saying there are problems haskell can't solve and lisp can? :)
02:48:49<dons>given unsafeCoerce#, they accept the same set of programs
02:48:49<ddarius>Actually, Scheme is ridiculously powerful.
02:49:02<chrisamaphone>glguy: fine, you can argue in terms of more expressive power, but saying one can write "more programs" than the other is false.
02:49:06<campusblo>so scheme is lisp?
02:49:09<jfredett>I agree its quite powerful, but that power is often less accessible
02:49:12<jfredett>campusblo: yes and no
02:49:12<ddarius>Last I checked Scheme code didn't parse as Haskell or vice versa.
02:49:15<chrisamaphone>dymanic languages are embeddable in static type systems.
02:49:34<glguy>to set some sort of starting point, I love Haskell and use it as my primary language at work :)
02:49:35<chrisamaphone>*dynamic
02:49:40<campusblo>I see ppl reccomending lisp all the time
02:49:44<glguy>I'm just defending the other languages since no one else was :)
02:49:45<|Steve|>Scheme is a lisp.
02:49:49<geezusfreeek>glguy: where do you work that you get to use haskell?
02:49:53<glguy>Galois
02:50:25<ddarius>Scheme has a lot of good introductory resources and is a rather nice language.
02:50:28<jfredett>IMO, Scheme and Haskell are useful in different situations
02:50:45<|Steve|>ACTION is teaching Scheme. It's a bit of a joke.
02:50:47<jfredett>and that set is mostly disjoint
02:50:55<int-e>> (map ((+) 2) ([1,2,3]))
02:50:56<|Steve|>I don't really know that much scheme. If my students know n, I try to know n+1.
02:50:57<lambdabot> [3,4,5]
02:51:02<ddarius>jfredett: Not my experience at all.
02:51:29<|Steve|>(map (lambda (n) (+ n 2)) '(1,2,3))
02:51:57<oklopol>lose the ,
02:52:15<glguy>isn't 1,2,3 a symbol?
02:52:28<jfredett>its a symbol for a list
02:52:33<oklopol>i don't think a number can start a symbol
02:52:38<ddarius>'(1 2 3)
02:52:43<|Steve|>oops, yeah.
02:52:45<glguy>ACTION fires up DrScheme to find out
02:52:47<jfredett>'(1 2 3) is the list (1 2 3)
02:53:00<|Steve|>guile> (map (lambda (n) (+ n 2)) '(1 2 3))
02:53:00<|Steve|>(3 4 5)
02:53:05<glguy>> '(1,2,3)
02:53:05<lambdabot> Improperly terminated character constant
02:53:06<glguy>(1 ,2 ,3)
02:53:14<glguy>is what DrScheme returned
02:53:23<|Steve|>As was pointed out, lose the commas.
02:53:29<jfredett>bah, we need mzbot in here too.
02:53:32<int-e>uh does scheme have the , unquote character?
02:53:34<oklopol>does lambdabot do lisp?
02:53:39<glguy>|Steve|: I'm not concerned with correcting your example :)
02:53:45<glguy>|Steve|: I was wondering how that actually parsed
02:53:45<ddarius>jfredett: You'd think, but it actually doesn't come up that often.
02:53:46<jfredett>or at least a Lisp> for Lambdabot
02:53:53<dons>oklopol: no, because we can't analyse it for safety
02:53:56<|Steve|>Ah.
02:54:00<dons>which we can do with haskell
02:54:05<dons>> readFile "/etc/passwd"
02:54:07<lambdabot> <IO [Char]>
02:54:08<glguy>ACTION high fives haskell
02:54:10<ddarius>jfredett: You can write one with @let
02:54:29<glguy>dons: the safety check is just a more complicated version of:
02:54:39<glguy>> unsafePerformIO (putStrLn "this")
02:54:40<lambdabot> Not in scope: `unsafePerformIO'
02:54:50<jfredett>ddarius: hmm. I'll have to do that sometime.
02:54:52<glguy>You'd just have to take stuff out of scope, and kill off intern or something
02:54:59<glguy>and eval
02:55:12<dons>more than that, we only show types from a given class
02:55:29<dons>so the type checker rules out side effects. that's the strong weapon we use
02:55:37<ddarius>jfredett: I wrote a Joy interpreter in a mostly pure untyped lambda calculus interpreter that I had written as a plugin for lambdabot.
02:55:41<dons>the other stuff, a trusted base, timeouts and other things , are sugar after that
02:55:53<campusblo>can i do this | x == '\"' = '\"'
02:55:54<glguy>dons: I understand that aspect of it, but you fill the holes by not importing certain functions
02:56:03<ddarius>campusblo: Yes.
02:56:08<dons>right. nothing that hides an effect inside a pure value
02:56:22<campusblo>to keep the quote in the string
02:56:29<campusblo>ok cool ill test it now
02:56:33<glguy>campusblo: '\"' and '
02:56:37<glguy>'"' are the same
02:56:43<glguy>(saves you a character ;) )
02:57:21<oklopol>because " inside a '' doesn't end the string and thus needs no escaping from
02:57:28<ddarius>"not importing <things>" is the key to security anyways.
02:57:50<int-e>> ['\34', '\x22', '\"', '"']
02:57:51<lambdabot> "\"\"\"\""
02:58:00<campusblo>ERROR - Syntax error in input (unexpected `;', possibly due to bad layout)
02:58:04<glguy>> fix show
02:58:06<lambdabot> "\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\...
02:58:13<oklopol>> 1
02:58:15<lambdabot> 1
02:58:18<oklopol>hihi
02:58:35<glguy>?vixen Have you met oklopol?
02:58:36<lambdabot>yeah, i'm ok
02:58:49<oklopol>? :I
03:03:54<glguy>ACTION wonders if Haskell's type system could be implemented in Lisp using macros...
03:04:16<ddarius>glguy: Of course it can.
03:04:34<glguy>without having to change too much of the lisp code at least
03:04:46<SamB_XP>oh, probably not ;-)
03:05:12<ddarius>So your question is is typical Lisp code reasonably typeable in a H-M style type system?
03:05:37<glguy>I suppose it is
03:06:08<thorat>it's going to take a few milliOleg's of macro hackery
03:06:36<ddarius>thorat: No, you just implement the type checker exactly as you would normally.
03:07:05<dons>`Personally, I don't really classify CL as an FP language' -- i've been saying that for years :)
03:07:20<ddarius>dons: What about Scheme?
03:07:21<glguy>ACTION saw that on reddit
03:07:40<dons>I'd say if its not pure by default, its not functional. but that might be a little controversial
03:07:51<Cale>It seems that preventing I/O from occurring in pure code in CL would be tricky to accomplish with just macros.
03:07:52<dons>you have to have (.) anyway
03:08:11<Cale>CL makes it too much of a pain to write higher order functions
03:08:12<thorat>ddarius: ok, I thought glguy meant a similar approach to Kanren
03:08:50<ddarius>dons: ?
03:09:02<Cale>You have to quote things in funny ways, and use funcall/apply to call functions passed as parameters. That tends to make uses of functional programming less casual.
03:09:25<ddarius>The lack of TCO is one of the bigger issues for me.
03:09:31<Cale>Oh, that too.
03:09:34<ddarius>But I don't consider TCO an FP thing.
03:09:35<glguy>CL doesn't require tail recursion optimization either, right?
03:09:59<Cale>glguy: Many implementations don't support it.
03:10:08<glguy>ACTION wasn't paying attention when he typed that
03:10:12<dons>ddarius: did you see this thread, http://groups.google.com/group/comp.lang.lisp/msg/43090ddeeb50051c?dmode=source
03:10:14<lambdabot>Title: New Computer Language Shootout? - comp.lang.lisp | Google Groups, http://tinyurl.com/2uhxva
03:10:20<dons>(besides being started by Jon Harrop... :/ )
03:10:35<dons>it makes a good case for why you never see lisp papers at ICFP :)
03:10:39<ddarius>dons: Unless it happened several years ago, I haven't been following c.l.l (or any newsgroups now)
03:10:49<Cale>The fact that Haskell isn't required to have TCO doesn't bother me, since it's defined at a completely different level of abstraction from that.
03:11:05<ddarius>Cale: And the fact that it is effectively required anyways.
03:11:12<Cale>yeah
03:11:32<Cale>at least, if you're doing anything like an ordinary implementation of it
03:14:47<dancor>can i somehow get Just 1 + Just 2 = Just 3 and Nothing + Just 4 = Nothing to work
03:15:18<shachaf>dancor: Use fmap (<$>).
03:15:26<ddarius>dancor: Make Maybe an instance of Num.
03:15:34<int-e>> liftM2 (+) (Just 1) (Just 2) -- hmm
03:15:35<shachaf>dancor: Or liftM2, I guess.
03:15:42<lambdabot> Just 3
03:15:50<dancor>cool
03:15:58<shachaf>int-e: Yes, liftM2 is probably better in this case.
03:16:17<dons>> liftM2 div (Just 1) (Just 0)
03:16:18<lambdabot> Exception: divide by zero
03:16:31<dons>div should be in Maybe :)
03:16:38<ddarius>I'd rather it not.
03:16:44<int-e>> (+) <$> Just 2 <*> Just 3 -- or Applicative (as shachaf also suggested)
03:16:46<lambdabot> Just 5
03:16:50<ddarius>Though I guess I could just throw a fromJust on it.
03:17:06<dons>unsafeDiv for things other than Rational
03:20:04<glguy>dons: Haskell is the most referenced nick?
03:20:08<glguy>I suppose that is my fault?
03:20:39<shachaf>glguy: Were you Haskell at one point?
03:20:40<dons>yeah :) told you so.
03:20:40<dons>
03:21:00<glguy>shachaf: yeah , I registered that at one point for fun
03:22:27<glguy>shachaf: according to the whowas, so were you :)
03:22:43<shachaf>glguy: Just for a moment. :-)
03:23:28<glguy>that way I could nickserv ghost someone that used the nick to do stuff like
03:23:45<Haskell>ACTION is strongly typed for weak minds
03:24:12<shachaf>What does "strongly typed" mean, anyway?
03:24:39<glguy>doesn't automatically coerce types, generally
03:25:41<glguy>I believe that "weak typing" is used to describe things like: "2" + True = 3
03:27:30<ddarius>Usually it's a bit stronger than that, that you can't apply a function to a type that does not support it, i.e. unsafeCoerce 3 5
03:27:55<ddarius>I.e. that the type system is sound
03:28:06<ddarius>For statically typed languages.
03:28:56<oklopol>> "2" + True
03:28:57<lambdabot> Couldn't match expected type `[Char]' against inferred type `Bool'
03:29:17<oklopol>> "2" + True /= 3
03:29:19<lambdabot> Couldn't match expected type `[Char]' against inferred type `Bool'
03:29:29<glguy>(+) :: Num n => n -> n -> n
03:29:45<glguy>the two addends need to have the same type
03:29:50<oklopol>yeah, i'm just playing around :)
03:29:58<oklopol>> "23"+"44"
03:29:59<lambdabot> add an instance declaration for (Num [Char])
03:29:59<lambdabot> In the expression: "23" + ...
03:30:04<oklopol>> "23"++"44"
03:30:05<lambdabot> "2344"
03:30:11<siti>> 1/2.0 ;)
03:30:12<lambdabot> Parse error
03:30:16<siti>> 1/2.0
03:30:17<lambdabot> 0.5
03:30:22<glguy>oklopol: through a gross instance definition "1" + "2" could work
03:30:34<dolio>> let a + b = read a Prelude.+ fromEnum b in "2" + True
03:30:35<oklopol>can you show me? :)
03:30:36<lambdabot> 3
03:30:43<shachaf>oklopol: Not in lambdabot.
03:30:55<oklopol>i c
03:30:57<shachaf>oklopol: But "instance Num String where (+) = (++)" should work.
03:31:44<Figs>hi
03:31:46<glguy> a + b = show $ readInt a + readInt b
03:31:57<shachaf>Figs: Hello.
03:31:59<Figs>hi
03:32:29<Figs>http://rafb.net/p/krffm450.html <-- some real evil :)
03:32:30<lambdabot>Title: Nopaste - No description
03:33:01<Figs>a math expression parser that I *think* does order of ops correctly as it builds the tree
03:33:08<shachaf>Figs: Wasn't that your C++ thing?
03:33:13<Figs>it's build on it
03:33:25<Figs>this is what I'll test my rewrite with
03:33:33<Figs>it's not done yet
03:33:38<Figs>so this won't work in all cases
03:33:51<shachaf>Figs: Now try it in Haskell and see how much better it is. :-)
03:33:55<Figs>hehe :P
03:33:58<ddarius>I wonder how close to Tcl we can get if we just start making String an instance of everything.
03:34:06<Figs>I figured out something interesting
03:34:17<Figs>that you guys can probably give me some perspective on
03:34:28<Figs>My parser is very easily extensible, so
03:34:32<Figs>I can write things like
03:34:47<Figs>(or will be able to)
03:35:19<ddarius>What algorithm does it use to parse?
03:35:37<Figs>regex equalnumb = (S[0] << *A) >> repeat(B,count(S[0],A)) >> repeat(C,count(S[0],A)); //etc
03:35:59<Figs>which would match something like AAABBBCCC
03:36:04<Figs>AAAABBBBCCCC
03:36:05<Figs>etc
03:36:15<dancor>> printf "hi"
03:36:16<lambdabot> Add a type signature
03:36:25<shachaf>> printf "hi" :: String
03:36:26<lambdabot> "hi"
03:36:32<dancor>> printf "%.2f" pi
03:36:33<lambdabot> Add a type signature
03:36:37<shachaf>dancor: Lambdabot can't print to stdout.
03:36:38<dancor>man
03:36:44<shachaf>> printf "%.2f" pi :: String
03:36:46<lambdabot> "3.14"
03:36:54<glguy>printf could return a function, an IO action, or a String
03:36:58<glguy>you always have to specify
03:37:03<dancor>shachaf: then why did yours work
03:37:10<ddarius>Figs: The order of operations is right, but you can't write 3+4+5 without parentheses.
03:37:15<shachaf>dancor: I told it that it was a String.
03:37:18<ddarius>:t printf
03:37:20<lambdabot>forall r. (PrintfType r) => String -> r
03:37:25<shachaf>dancor: Keep in mind that printf is a bit magical.
03:37:32<Figs>ahh, I did miss something then
03:37:42<glguy>@instances PrintfType
03:37:44<lambdabot>Couldn't find class `PrintfType'. Try @instances-importing
03:37:57<dancor>is there a less magical way to get printf "%.2f" x :: String
03:38:00<ddarius>Similarly for *
03:38:11<dancor>ACTION isn't really into magic
03:38:23<shachaf>dancor: Not THAT magical.
03:38:28<ddarius>dancor: It's just normal type class resolution
03:38:33<Figs>http://rafb.net/p/NGVY1D91.html
03:38:35<Figs>is that better?
03:38:36<lambdabot>Title: Nopaste - No description
03:38:43<ddarius>But check out the stuff in Numeric perhaps?
03:38:47<glguy>(PrintfArg a, PrintfType r) => PrintfType (a -> r)
03:38:47<glguy>PrintfType (IO a)
03:38:47<glguy>IsChar c => PrintfType [c]
03:39:00<shachaf>dancor: It's just that a normal function in Haskell has a fixed number of arguments.
03:39:27<shachaf>dancor: Using type-classes, printf can work around it, because it knows how many arguments to expect (from the format string).
03:39:29<dolio>> showFFloat (Just 2) pi ""
03:39:29<dancor>shachaf: so why doesn't printf take [Dynamic]
03:39:30<lambdabot> "3.14"
03:39:36<glguy>:t printf "" :: Int -> String
03:39:38<lambdabot>Int -> String :: Int -> String
03:39:39<dancor>oh
03:39:41<ddarius>Figs: Can your parser handle that? And I believe 2+3+4*1 won't parse.
03:39:54<ddarius>dancor: Because this is Haskell.
03:40:18<dancor>do you mean Haskell :: ProgrammingLanguage
03:40:30<dancor>bc otherwise i will give you a meaningless error message
03:40:43<shachaf>dancor: No, printf is a special case.
03:40:54<shachaf>dancor: Normally the types can be inferred.
03:41:04<Figs>2+3+4*1 should parse fine
03:41:07<glguy>printf just doesn't have defaulting
03:41:13<dolio>> let c = 299790000 in showEFloat (Just 4) c ""
03:41:14<lambdabot> "2.9979e8"
03:41:18<glguy>while Num and Floating do
03:41:24<Figs>oh
03:41:26<Figs>hmm
03:41:29<Figs>no
03:41:44<ddarius>Figs: It will be addterm(2+3)+error(4*1 doesn't parse as number)
03:41:53<glguy>printf is the standard case, Num and Floating are special cases
03:42:13<Figs>ok, that's resolveable though by adding one more case
03:42:22<shachaf>glguy: I didn't mean defaulting, I meant "your types not being inferred easily". :-)
03:42:37<ddarius>Figs: You don't need this many cases, further will your parser handle left recursion?
03:42:49<ddarius>shachaf: No worse than Read.
03:43:07<glguy>shachaf: I was saying that the type of 7 can not be inferred easily, that the reason you don't have to specify is defaulting
03:43:29<glguy>and that since PrintfType isn't special cased, you ave to specify
03:43:35<Figs>http://rafb.net/p/J8YNus24.html
03:43:36<lambdabot>Title: Nopaste - No description
03:43:42<shachaf>ddarius, glguy: You're right, I guess lambdabot specificaly is a bad place to test this.
03:43:58<Figs>ddarius, give me an example, and I'll think about it
03:44:09<shachaf>dancor: Normally, from the context (e.g., a do block), the type of printf can be inferred.
03:44:18<Figs>I'm not sure exactly what you mean.
03:44:33<oklopol>A = A | B; is left recursion
03:44:34<oklopol>err
03:44:40<oklopol>A = A >> B;
03:44:46<Figs>hi oklopol :)
03:44:47<oklopol>and hi Figs
03:44:48<oklopol>:)
03:44:52<dancor>> printf "%.2f" ((fromIntegral 4) / (fromIntegral 6) :: Float) :: String
03:44:54<lambdabot> "0.67"
03:45:02<dancor>that's what i had to do in my context
03:45:09<ddarius>If you use recursive descent, you have a problem.
03:45:24<shachaf>dancor: What was your context?
03:45:30<Figs>It's doing recursive descent right now, I think.
03:45:35<Figs>so probably not.
03:45:36<dolio>The fromIntegrals there should be redundant.
03:45:38<shachaf>dancor: You don't need those fromIntegrals.
03:45:53<ddarius>Then things like multerm and addterm won't terminate.
03:46:00<dancor>CM.liftM2 (divF) justMyIntA justMyIntB
03:46:12<dancor>which is later Show-n
03:46:31<shachaf>dancor: (You generally don't need to qualify Control.Monad, by the way.)
03:46:42<dancor>shachaf: i like to qualify everything
03:46:45<ddarius>shachaf: s/generally/usually
03:47:07<shachaf>ddarius: Yes, sorry. :-)
03:47:18<Figs>hmm, I don't know how hard it would be to fix that
03:47:21<Figs>:P
03:47:34<Figs>it could be simple, or it could be very difficult
03:47:37<dancor>and without the fromIntegral's i gett a "Couldn't match Float" blahblah
03:47:52<shachaf>dancor: That shouldn't happen.
03:47:58<Figs>the simple case would involve rewriting by_ref and operator >>
03:48:00<shachaf>dancor: Are the 4 and 6 hard-wired like in your example?
03:48:02<glguy>dancor: you don't need fromIntegral for literals
03:48:09<Figs>well, a seq object
03:48:11<dancor>they aren't literals
03:48:13<glguy>dancor: but you do for values in your code
03:48:17<dancor>20:46 < dancor> CM.liftM2 (divF) justMyIntA justMyIntB
03:48:42<glguy>shachaf: that's why :)
03:49:06<shachaf>glguy: Yes, I guessed that myself. :-)
03:49:11<ddarius>Figs: You can use a different algorithm in which left-recursion is not a problem, require that left-recursion not be there, or "preprocess" the grammar to detect it and rewrite it.
03:49:39<Figs>the easiest solution would be to change the behavior of the search, I think
03:49:51<shachaf>dancor: Can you @paste with some more context?
03:50:10<ddarius>Just name the printf expression and give it a type.
03:50:43<Figs>actually
03:50:49<Figs>hmm
03:50:53<dancor>i think i see now that i will always need the :: Float and the :: String for my context
03:51:06<dancor>and i'm going to start the lengthy process of getting-over it now
03:51:15<shachaf>dancor: How are you using the printf?
03:51:20<Figs>do you have the name of another algorithm I can use?
03:51:20<hpaste> aeyakovenko pasted "fast sha1" at http://hpaste.org/1704
03:51:55<ddarius>Look up LR parsing or if you want to be very friendly GLR parsing.
03:52:53<Figs>well the thing I need to be careful of is to keep it extensible
03:53:20<Figs>since that's the real power: it's easy to write a new parser type
03:53:20<ddarius>> let printFloat :: Float -> String; printFloat = printf ".2f" in printFloat 3
03:53:22<lambdabot> Exception: Printf.printf: formatting string ended prematurely
03:53:35<ddarius>> let printFloat :: Float -> String; printFloat = printf "%.2f" in printFloat 3
03:53:36<lambdabot> "3.00"
03:54:07<Figs>I could number the rules and keep track of the parents and detect infinite loops, couldn't I?
03:54:41<ddarius>Figs: Completely new? Wouldn't most be compositions of primitive parsers?
03:54:52<hpaste> dancar pasted "shachaf: printf needs lots of :: Love" at http://hpaste.org/1705
03:54:56<Figs>most probably, but like my repeat example
03:55:09<Figs>I could just easily do something like
03:55:26<mm_freak>> div 15 (fromIntegral (3::Int))
03:55:28<lambdabot> 5
03:55:35<Figs>regex bothways = (S[0] << pattern ) >> '|' >> reverse(S[0]);
03:55:39<mm_freak>will this be translated into a long-short-division?
03:55:57<mm_freak>i.e. mpz_tdiv_q_ui instead of mpz_tdiv_q
03:56:13<dancor>oh interesting, hpaste truncates without telling where it will
03:56:37<dancor>i should have been counting
03:56:53<dolio>Actually, on the 'new' page it says it 'truncates after 5k'.
03:57:04<dancor>hence should have been counting
03:57:07<shachaf>dancor: You can simplify toDay to use pattern matching (unrelated).
03:57:08<ddarius>Is that characters or bytes?
03:57:10<dolio>Although, I suppose it could warn you if you try to post something big.
03:57:36<SamB_XP>I think it should truncate on 1kloc or something
03:59:16<Figs>you heard about the 500 mile email problem before?
03:59:42<hpaste> dancor pasted "shachaf: the end of my printf example" at http://hpaste.org/1706
03:59:50<Figs>http://www.ibiblio.org/harris/500milemail.html :)
03:59:51<lambdabot>Title: The case of the 500-mile email
04:00:03<dancor>shachaf: ok i'll do that
04:00:43<Figs>ddarius, do you have any idea how I can check for infinite cycles?
04:00:56<shachaf>dancor: You're not using divF at all.
04:01:01<Figs>(when it is not so obvious as A = A|B?
04:01:09<Figs>like for example...
04:01:10<shachaf>dancor: Where are you planning to use it?
04:01:17<Figs>A = B|C
04:01:19<dancor>shachaf: http://hpaste.org/1706
04:01:24<Figs>B = C|D
04:01:33<Figs>C= A
04:01:43<shachaf>dancor: Yes, I see that.
04:01:51<oklopol>Figs: if the string isn't consumed at all during a loop
04:01:52<shachaf>dancor: You're defnining it but never using it.
04:01:59<oklopol>then you have an infinite loop
04:02:32<dancor>shachaf: second post (1706 not 1705) 4th line from the bottom is: (i, CM.liftM2 (divF) (CM.liftM2 (-) (Just nowTime) t)
04:02:34<oklopol>in case your system is as flexible as i think it is, you'll get to undecidability and have to have a timeout.
04:02:43<Figs>I could just allow a "time out" of 10 hits to the same pattern with the same string length input
04:02:48<hpaste> aeyakovenko annotated "fast sha1" with "(no title)" at http://hpaste.org/1704#a1
04:03:02<shachaf>dancor: Oh, sorry, I thought I was looking at 1706.
04:03:16<shachaf>dancor: Generally, you can annotate a post.
04:03:28<Figs>or check against the string passed :)
04:03:49<hpaste> aeyakovenko annotated "fast sha1" with "5k limit on hpaste sucks" at http://hpaste.org/1704#a2
04:03:51<shachaf>dancor: putStrLn . show is called print (unrelated).
04:04:12<Figs>hmm, actually
04:04:16<Figs>if it hits the same one
04:04:20<Figs>without changing the length
04:04:24<Figs>then it's failed right?
04:04:31<Figs>because it will NEVER change the length?
04:04:49<oklopol>Figs: yes
04:04:51<Figs>of course, this means that I need to give each regex an ID
04:04:59<Figs>but that's not too hard really
04:05:44<oklopol>yes, but the problem is even if it's not tc and it's always decidable, it still might take weeks to match something if set up correct
04:05:54<oklopol>so the id wont save you all the time
04:05:57<oklopol>so make a timeout
04:06:04<Figs>and to make sure I haven't gone in a loop, I just need to have a simple test on each forwarding to make sure that the id of the instance isn't already in a list of ids
04:06:04<oklopol>as well i mean
04:06:39<Figs>no one would wait weeks anyway ;)
04:06:48<Figs>and it would be very hard I think
04:06:52<hpaste> glguy annotated "fast sha1" with "5k limit because hpaste is for snippets" at http://hpaste.org/1704#a3
04:06:56<Figs>to set it up to take weeks
04:07:01<Figs>unless you can think of an example
04:07:17<Figs>I mean, there are plenty of stupid things you can do
04:07:19<oklopol>Figs: yes, but my point is it's better if it's automatically terminated than that the user will have to terminate it
04:07:25<Figs>but you'll run out of stack first
04:07:28<oklopol>by force
04:07:31<oklopol>yeah
04:08:03<Figs>my regex parser shouldn't have to deal with time
04:08:07<Figs>that is illogical
04:08:11<ddarius>@google detecting left recursion
04:08:13<lambdabot>Plugin `search' failed with: IRCRaised Lib.URL.isTextHTML: getHeader failed
04:08:14<Figs>what if it's running in another thread
04:08:23<ddarius>wtf?
04:08:24<Figs>and someone pauses the thread while waiting for the user to input something?
04:08:36<oklopol>Figs: indeed, i meant the kinda thing you said yourself, a match limit
04:08:39<chessguy>@go 3 parsecs in miles
04:08:39<lambdabot>3 Parsecs = 5.75205844 x 10^13 miles
04:08:40<Figs>yeah
04:08:45<Figs>as soon as you hit one recursion
04:08:47<ddarius>wtf?
04:08:49<chessguy>@go recursion
04:08:49<ddarius>@google detecting left recursion
04:08:49<Figs>it will recurse again
04:08:51<lambdabot>http://en.wikipedia.org/wiki/Recursion
04:08:51<lambdabot>Title: Recursion - Wikipedia, the free encyclopedia
04:08:52<lambdabot>http://home.earthlink.net/~ltrammell/tech/recurs1.htm
04:08:52<lambdabot>Title: Detecting left recursion
04:08:56<chessguy>heh
04:09:05<ddarius>Whatever.
04:09:23<chessguy>ddarius, you must have caught google napping :)
04:09:26<shachaf> @ty (/)
04:09:42<ddarius>chessguy: Again!
04:09:56<chessguy>shameful
04:10:07<shachaf>@botsnack
04:10:07<lambdabot>:)
04:10:20<shachaf>@ty (/) -- Oh, extra space
04:10:22<lambdabot>forall a. (Fractional a) => a -> a -> a
04:10:29<chessguy>@quote extra.space
04:10:29<lambdabot>souwh says: <shapr> hm, I have extra spaces there. \n <souwh> oooh, those can be saved and reused later!
04:11:12<shachaf>ACTION stashes space in the Haskell code corner.
04:11:35<chessguy>and on that note...
04:12:23<ddarius>Indeed.
04:16:26<Figs>wow long load times
04:16:59<shachaf>Figs: For what?
04:18:10<Figs>home.earthlink.net .../ example from ddarius's search
04:18:22<shachaf>Oh.
04:18:34<Figs>see? forgotten about it already :D that long ago.
04:18:59<shachaf>Figs: First I thought you meant hpaste, then I thought you meant GHC or some other Haskell program.
04:19:34<shachaf>Figs: It loads instantly for me, though.
04:20:11<Figs>:S
04:20:14<shachaf>Figs: Have you done anything with Parsec yet, or is this only about your C++ parser?
04:20:24<Figs>only about C++ right now
04:20:48<Figs>so far this channel has been the most helpful :)
04:21:25<Figs>ergh
04:21:31<Figs>this hurts my head :P
04:22:39<shachaf>Of course #haskell is more helpful than ##c++ about C++... :-)
04:23:07<Figs>well, I was talking about #linguistics
04:23:44<Figs>they helped me a bit earlier, but they were offtopic for the last while
04:23:57<Figs>and have been fairly quiet
04:24:04<Figs>(I probably just picked a bad time :P)
04:24:58<shachaf>Figs: How can you be off-topic in #linguistics? They were probably just showing you some examples of colloquial English. :-)
04:25:24<Figs>you can be. :)
04:25:55<Figs>but it's ok
04:27:36<Figs>hmm, I guess I should make left-recursion a silent problem
04:28:00<Figs>since obviously if you have left-recursion, it's a dead end.... that goes on forever
04:28:14<Figs>and you can just go up and try the next branch
04:28:42<brad_>can someone provide a short, direct answer for what monad transformers (MaybeT) are, and where i would want to use them? i'm reading http://en.wikibooks.org/wiki/Haskell/Monad_transformers but it seems to not explane the motivation too well
04:28:44<lambdabot>Title: Haskell/Monad transformers - Wikibooks, collection of open-content textbooks
04:29:13<brad_>whoops, explane/explain...me kan spell!
04:29:25<shachaf>brad_: Have you used State yet?
04:29:42<dolio>Monad transformers let you augment one monad with the capabilities of another.
04:29:48<brad_>shachaf: not explicity, i have read about them a bit
04:29:58<dolio>Without having to rewrite them from scratch.
04:30:00<oklopol>Figs: left recursion isn't a "bug" in a regex, it's just hard to parse
04:30:16<dolio>So, state is 's -> (a, s)'
04:30:18<Figs>oklopol, if it goes on forever, it would count as a bug in my book.
04:30:18<oklopol>i mean, hard to match
04:30:26<dolio>And environment is 'r -> a'
04:30:30<oklopol>Figs: it doesn't necessarily go on forever
04:30:41<Figs>in the cases I'm talking about as bugs, it could
04:30:52<Figs>A = A|T
04:30:57<dolio>So, if you want state and environment, you could write a type 'newtype StateEnvironment r s a = SE (r -> s -> (a, s))'
04:30:59<Figs>would go on forever in my parser
04:31:03<oklopol>well, that's obviously a bug, yeah
04:31:15<Figs>actually, it's A = by_ref(A)|T
04:31:16<oklopol>but the state system would handle that easily
04:31:16<Figs>but meh
04:31:16<bos>is there a way to recover a real url from the clickthrough that reddit obfuscates with?
04:31:19<dolio>Or you could use 'ReaderT r (State s) a'
04:31:31<Cale>brad_: My take on it is that monads are, at least as far as programming is concerned, sort of like special-purpose programming languages. Monad transformers are things which construct new such programming languages from existing ones by adding features.
04:31:32<dolio>Which stacks environment on top of state.
04:31:34<bos>i find myself stymied every time i want to bookmark a pdf from reddit.
04:31:43<Figs>oklopol: what state system?
04:31:45<brad_>ah, thanks guys!
04:32:01<oklopol>Figs: the one for noticing infinite loops
04:32:07<brad_>it almost seems like monad transformers are a mechanism to do monad composition? or should i not abuse the term composition?
04:32:12<Figs>the one I'm trying to figure out how to write :)
04:32:14<shachaf>bos: Go to reddit.com/info/<id>/comments
04:32:22<oklopol>heh
04:32:26<brad_>thanks cale, that is a good explanation
04:32:28<oklopol>it shouldn't be that hard
04:32:35<bos>shachaf: exactly what i wanted, thanks!
04:32:35<dolio>brad_: Yeah. It's like composition.
04:32:40<Figs>it is
04:32:50<Figs>the problem is a bit hard to explain
04:32:59<Figs>you see, I expect this parser to be expanded on endlessly
04:33:04<Cale>The word "composition" gets my hopes up in ways that makes me not want to use it here, but yes.
04:33:15<Figs>composition?
04:33:17<Figs>:P
04:33:25<shachaf>bos: (Why do you want this, by the way?)
04:33:28<Figs>oh
04:33:30<Figs>never mind
04:33:48<brad_>thanks for the info guys! you are helpful as always. take care!
04:34:02<Figs>oklopol: I can extend my parser to do things most normal parsers don't really allow
04:34:12<Figs>like reversing strings
04:34:20<bos>shachaf: i bookmark the occasional reddit article in delicious
04:34:30<oklopol>Figs: can you parse code with it? :)
04:34:33<bos>ACTION has a few hundred haskell links in his delicious stream
04:34:43<Figs>if I can solve this problem, you can do a lot with it
04:34:50<dancor>is there a not for Ordering
04:34:51<shachaf>bos: Why not just go the reddit URL? It redirects anyway.
04:35:08<Figs>I'm trying to impliment exhaustive backtracking which is why this is just now becoming a problem
04:35:13<dancor>and why does @hoogle Ordering -> Ordering show me things for a -> a
04:35:28<shachaf>@hoogle Ordering -> Ordering
04:35:28<lambdabot>No matches, try a more general search
04:35:37<Figs>oh, crap :S
04:35:41<dancor>http://haskell.org/hoogle/?q=Ordering%20-%3E%20Ordering
04:35:43<lambdabot>Title: Ordering -> Ordering - Hoogle
04:35:48<bos>shachaf: i don't like the obfuscation and indirection
04:35:51<dancor>i didn't realzie that was diff from @hoogle
04:35:55<dons>after that silly thread last night about bit sieves, i updated the shootout entry, runs rather well! http://shootout.alioth.debian.org/gp4/benchmark.php?test=nsievebits&lang=all
04:35:57<lambdabot>Title: nsieve-bits benchmark | Gentoo : Intel&#174; Pentium&#174;&nbsp;4 Computer Langu ..., http://tinyurl.com/sxpth
04:36:30<Figs>M = (T >> M) is ok, for example, since it will always pull of a T
04:36:33<Figs>or fail
04:36:45<Figs>*off
04:37:03<shachaf>bos: How is it more obfuscated to go through the reddit link?
04:37:12<Figs>but, M = M|T is bad
04:37:17<bos>because i can't see what it's pointing at?
04:37:25<Figs>M = T|M is bad too
04:37:25<shachaf>bos: Why not?
04:37:31<dons>reddit hides links
04:37:46<bos>for example, if i'm bookmarking a paper on wouter swierstra's home page, i can't see that in the url on delicious.
04:37:53<bos>all i see is a reddit link.
04:38:17<shachaf>bos: If I go to http://programming.reddit.com/goto?id=26nfh , it redirects me to the real URL.
04:38:18<lambdabot>Title: Getting started with HUnit
04:38:23<dons>authors should be encouraged to create .html pages for their papers
04:38:27<bos>shachaf: yes, but it's a redirect!
04:38:29<dons>?go Stream Fusion
04:38:30<lambdabot>http://www.cse.unsw.edu.au/~dons/papers/CLS07.html
04:38:30<lambdabot>Title: Stream Fusion: From Lists to Streams to Nothing at All
04:38:32<shachaf>bos: And then I can just copy that one.
04:38:34<dons>like that, imo.
04:38:44<bos>shachaf: doesn't work if it's a PDF
04:39:00<bos>dons++
04:39:07<Figs>hmm
04:39:13<shachaf>bos: Oh.
04:39:20<Figs>what about M = M>>T
04:40:13<Figs>it would be a bug eh
04:40:14<dolio>Figs: Isn't M = M>>T an infinite string of Ts?
04:40:30<Figs>basically, it'd turn into that, I think
04:40:43<Figs>not really what I meant though
04:41:03<dolio>If it were M = M>>T | e then it'd be T*.
04:41:26<Figs>yeah
04:41:43<shachaf>bos: I guess that might be the easiest way, then.
04:41:50<Figs>basically that'd be M = opt(by_ref(M) >> T);
04:42:23<Figs>which could be legal
04:42:32<Figs>ie, TTT
04:43:11<Figs>let's see... what'd happen though?
04:43:24<Figs>it tries to grab a by_ref(M) >> T...
04:43:34<Figs>the M will recurse and no change to input
04:43:38<Figs>at that point it should fail
04:43:42<Figs>go back up
04:43:48<Figs>then see a T
04:43:51<Figs>grab the T
04:43:55<Figs>and head out
04:44:00<Figs>but
04:44:07<Figs>that's not what it really means, is it?
04:48:02<dancor>> let notComp x = case x of EQ -> EQ; LT -> GT; GT -> LT in (notComp . compare) 4 5
04:48:03<lambdabot> Couldn't match expected type `Ordering'
04:48:21<dancor>> (id . compare) 4 5
04:48:23<lambdabot> LT
04:48:40<dolio>((notComp .) . compare)
04:48:58<dolio>Of course, flip compare gets the same effect, I think.
04:49:59<Jicksta>hey guys
04:50:10<dancor>oh flip compare, brilliant
04:50:18<shachaf>Jicksta: Hello.
04:50:24<Jicksta>has anyone seen a comparison of the concurrency features in Haskell versus Erlang?
04:52:18<dons>Jicksta: good question
04:52:23<Cale>Jicksta: That would be useful, actually.
04:52:38<Jicksta>yeah. I'm very, very curious myself
04:52:58<dons>speedwise, compiled haskell concurrency seems to be a bit faster, but erlang supports distributoin better. erlang uses message passing a lot, haskell has Chans, Parallel hints, parallel arrays, STM and other things.
04:53:30<dons>the only speed benchmarks we know of are the two shootout benchmarks on concurrency
04:53:41<siti>I think ghc needs a parallel GC
04:53:48<Jicksta>does Haskell have an analog to Erlang's reloadable code?
04:53:55<siti>and haskell needs more standard libraries for concurrency, some things are missing
04:54:02<dons>Jicksta: yeah, but its more experimental, and not as pervasive as erlangs
04:54:07<dancor>dolio: i thought (f . g) x was the same as f (g x), e.g. http://www.cs.arizona.edu/~collberg/Teaching/372/2005/Html/Html-12/index.html
04:54:10<lambdabot>Title: CSc 372 - Comparative Programming Languages 12 : Haskell -- Composing Functions, http://tinyurl.com/36kn42
04:54:12<dons>siti, oh, what kinds of things?
04:54:15<shachaf>dancor: It is.
04:54:28<shachaf>dancor: But (f . g) x y isn't the same as f (g x y)
04:54:32<dolio>dancor: Yes, but (f . g) x y /= f (g x y)
04:54:42<dons>erlang doesn't support large strings and binary files very well, we found out last week
04:54:50<dons>while ghc haskell can process terabytes happily.
04:55:04<Jicksta>hehe. I saw that on Dzone too
04:55:05<siti>dons: e.g. splitting a job in to many threads with load balancing etc.
04:55:10<shachaf>ACTION was under the impression Erlang had good support for binary files.
04:55:14<siti>I will try and get some code to show you an example
04:55:15<dolio>Essentially, you need a (.) for each argument of g, I think.
04:55:16<shachaf>I thought I'd heard that somewhere.
04:55:21<dons>shachaf: it has good support for pattern matching on binary
04:55:23<Jicksta>and someone actually retorted, claiming Erlang actually did handle those well
04:55:30<Jicksta>not one to call the shot -- it's not an issue I'd deal with often
04:55:32<dons>but loading large binary files into memory seemed to bang out at 300M on a recent thread
04:55:51<dons>its certainly has bit patterns, which are more flexible that pattern guards and Data.Binary
04:56:11<dons>I suspect Data.Binary is faster than erlang though, for streaming binary data
04:56:25<dolio>dancor: I've seen something that will let you do (f `comp` g) for g of more than one argument, but it involves some serious type hackery.
04:56:50<Jicksta>it seems to also depend on the algorithm (and knowledge of Erlang under the covers)
04:56:56<dons>definitely
04:57:19<dons>here's a generic speed benchmark, http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=ghc&lang2=hipe
04:57:21<hpaste> siti pasted "nice thread function" at http://hpaste.org/1707
04:57:21<lambdabot>Title: Haskell GHC benchmarks | Gentoo : Intel&#174; Pentium&#174;&nbsp;4 Computer Lang ..., http://tinyurl.com/28d6h2
04:57:27<dons>so you can pretty much expect ghc to always be faster.
04:57:29<Jicksta>for example, it's more efficient to store bytes into an array, and then reverse and convert it to binary at the very end...
04:57:36<dolio>dancor: That is, the same 'comp' works for gs of various number of arguments. You can, of course, make comp1 comp2 ... without type hackery.
04:57:38<dons>but whether its as easy to reload code, distribute across many cluster nodes and so on
04:57:57<Jicksta>instead of composing binary objects together...
04:58:07<Cale>For shared-memory concurrency, GHC is getting quite good.
04:58:42<dons>so HIPE erlang is around the speed of GHC on concurrent stuff , for sequential stuff its far behind, is probably what we could conclude from the shootout
04:58:47<Cale>It'll be interesting to see how the data parallelism stuff goes if/when they end up adding support for distributed computation.
04:58:49<dons>i think that would be fairly uncontroversial
04:59:05<dons>Cale, yeah, there's other distributoin stuff already (e.g. the `ports' library)
04:59:30<dons>we've written a few things to run on the linux cluster here, a parallel monte carlo simulator, made up of tiny haskell nodes, for example
04:59:46<dons>Jicksta: so what particular things were you looking at?
04:59:54<Cale>dons: heh, I see you updated it just today?
05:00:00<dons>yesterday, yep
05:00:31<Jicksta>well, I have a hackery project coming up that requires dumbfounding speed...
05:00:43<dons>do you have a lot of cores to play with?
05:00:47<Jicksta>basically serving as a TCP proxy for a certain VoIP-related protocol
05:01:04<dons>doesn't erlang only run in SMP on x86 too?
05:01:06<Jicksta>not immediately...
05:01:32<Jicksta>Erlang doesn't require SMP to my knowledge
05:01:36<dons>so you need low level protocol parsing, binary data streaming
05:01:41<Jicksta>nope
05:01:44<Jicksta>plain text protocol
05:01:52<dons>yeah, they tend to distribute separate erlang nodes
05:01:53<Jicksta>proxying lines of text, actually
05:02:04<Jicksta>the command delimiter is \n
05:02:09<dons>so just fast strings? with the optoin to do things concurrently in the future?
05:02:32<dons>Haskell bytestrings are much much faster than strings in erlang, if that's relevant.
05:02:35<Jicksta>right... the idea is the switch/PBX connects to the proxy at localhost...
05:02:51<Jicksta>the proxy then tries to find the best candidate to proxy the call handling to...
05:03:03<dons>you might have libraries for some of the telecoms stuff already in erlang though, not sure.
05:03:06<Jicksta>if the thing to which it's proxying goes down, it recovers cleanly and connects elsewhere
05:03:31<Jicksta>well, there is a LGPL package that's similar to what I'm describing
05:03:38<dons>it does sound like an erlangy job then : fault tolerant reloading, that kind of thing.
05:03:39<Jicksta>not so much a proxy -- more like a full app server
05:04:02<dons>you probably could get a faster system in ghc haskell, though. so its a matter of how much you like haskell, i suspect :)
05:04:10<Jicksta>hehe
05:04:18<Jicksta>well, I certainly respect Haskell... never used it before
05:04:30<Jicksta>I've been dabbling with Erlang and do enjoy it
05:04:41<dons>well, its similar to erlang, nicer syntax, native code compilation, good concurrency
05:04:45<Jicksta>though, if Haskell makes that case that it's 50% faster or something it'd justify using it instead
05:05:01<dons>I think 50% faster for string processing would be not unreasonable
05:05:05<dons>if the strings were big enough
05:05:06<Jicksta>Erlang is compiled too by the way...
05:05:10<Jicksta>not sure if it's native code or bytecode
05:05:23<dons>yeah, i know, (see the benchmark link i posted)
05:05:38<dons>but these dyamically typed languages suffer since they're hard to compile efficiently
05:05:46<dons>and you insert all these runtime checks into the code, slowing things down
05:05:55<Jicksta>yeah
05:05:59<Jicksta>though look at smalltalk :)
05:06:08<dons>smalltalk and SBCL are rather good, yeah
05:06:09<Jicksta>something like 40% the speed of Java.
05:06:17<Jicksta>and five times faster than Python
05:06:18<dons>java's slow though :)
05:06:24<dons>pythons really slow :)
05:06:27<siti>dons: that's what I was about to say ;)
05:06:40<Jicksta>well, I'm a Ruby developer -- I know what slow code's like :)
05:06:42<dons>we tend to compare Haskell against C, for some reason
05:06:49<Jicksta>sometimes it just doesn't f'ing matter, honestly :)
05:06:54<dons>yeah
05:06:56<Jicksta>except in cases when you're making a proxy, for example :)
05:07:03<dons>but you think performance will be important for this project?
05:07:12<Jicksta>yeah, definitely
05:07:17<siti>ghc is much much faster (will in my testing) when the minimum heap size is increased for the GC
05:07:43<dons>avoiding GC is always good
05:07:43<Jicksta>what does Haskell concurrency look like?
05:07:52<dons>there's several forms
05:07:57<siti>forkIO ;)
05:07:57<Jicksta>in Erlang we just spawn a process, giving it a function
05:08:01<dons>explicit threads, implicit threads, transactoinal memory
05:08:04<dons>yeah, that's the basic form
05:08:07<dons>:t forkIO
05:08:09<lambdabot>Not in scope: `forkIO'
05:08:12<dons>:t Control.Concurent.forkIO
05:08:14<lambdabot>Couldn't find qualified module.
05:08:20<Cale>:t Control.Concurrent.forkIO
05:08:21<siti>ACTION hits lambdabot
05:08:21<dons>:t Control.Concurent.forkIO
05:08:23<lambdabot>Couldn't find qualified module.
05:08:23<lambdabot>IO () -> IO GHC.Conc.ThreadId
05:08:25<Jicksta>does Haskell have green threads?
05:08:33<Cale>*cough* two r's :)
05:08:36<dons>lightweight threads, that will use other cores if you have them
05:08:49<Jicksta>cool
05:09:24<dons>see haskell versus erlang benchmarks here: http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=ghc&lang2=hipe
05:09:26<lambdabot>Title: Haskell GHC benchmarks | Gentoo : Intel&#174; Pentium&#174;&nbsp;4 Computer Lang ..., http://tinyurl.com/28d6h2
05:10:01<Jicksta>looking at that now...
05:10:03<Cale>To go along with that basic form of concurrency, there are two systems for thread communication which are currently in GHC.
05:10:04<dons>?docs Control.Concurrent
05:10:04<lambdabot>http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent.html
05:10:17<dons>is the low level concurrency layer, good to get the best performance
05:10:37<Jicksta>hmmm
05:10:49<Cale>The first, which is simpler, is based on something called an MVar, which is a mutable cell that can be empty or full. Reading from an empty MVar or writing to a full one blocks.
05:10:59<dons>there's lots of concurrency demos and so on haskell.org too, fwiw
05:11:21<Cale>In terms of that, there are various simple structures like channels, quantity semaphores and so on
05:11:35<Cale>Then there's a transactional thread communication library called STM
05:11:57<Cale>STM actions mutate shared thread variables and act as if they occur atomically.
05:12:01<Cale>and you can compose them
05:12:22<Jicksta>well, since I've no immediate use for concurrency, perhaps the best solution would be to implement a very efficient Haskell proxy and, in the future as necessary, implement the concurrency
05:12:30<Jicksta>so, I have to ask...
05:12:48<Jicksta>are there any other languages that you may recommend that're faster than Haskell?
05:12:53<dons>if you're just reading text data off a socket, yeah, i'd expect ghc to win.
05:13:03<dons>hmm, ocaml is a good one, otherwise you're down to C or C++
05:13:11<Cale>Or Clean, perhaps?
05:13:19<dons>pretty dead project though
05:13:22<Cale>hmm
05:13:25<Jicksta>well, I'm staying away from C/C++
05:13:31<Jicksta>not my idea of a high level language :)
05:14:03<dibblego>I know someone who is *convinced* that C is a high level language
05:14:09<dons>right. Haskell or OCaml then. for text processing off sockets, I'd probably go with Haskell, because of bytestrings.
05:14:11<Jicksta>oh, me too
05:14:19<siti>well "high" is relative
05:14:25<Figs>C and C++ are mid-level languages
05:14:33<Jicksta>I was with Mark Spencer once and he exclaimed to me seriously "You know what I love about C? It's just so simple"
05:14:40<dibblego>siti, that's my point as well, to no avail
05:14:40<Cale>If you're going to use Haskell, you probably want to give yourself at least a little time to get accustomed. :) Even though lots of stuff should be familiar from Erlang, there will also be quite a lot of new ideas, I suspect.
05:15:03<Adamant>using C is pretty simple. being correct with C is a fair bit harder
05:15:13<Jicksta>right
05:15:21<dons>that's true. you would want to learn it , write other programs, before betting the company on your haskell skillz :)
05:15:23<Jicksta>well, at any rate I won't be doing much of the coding myself...
05:15:25<siti>Jicksta: is he the guy that wrote asterisk? or am I getting confused?
05:15:25<weitzman>Jicksta: SML compiled with MLton is pretty fast
05:15:31<shachaf>Cale: Is Clean generally faster than Haskell?
05:15:39<Jicksta>likely be pulling in a developer from the community for consulting work
05:15:48<dons>shachaf: the Clean compiler seems to be rather good, yep.
05:15:52<Cale>shachaf: It has a rather fast IO system, from what I've seen.
05:15:54<Jicksta>siti: author of Asterisk, Gaim, L2TP, and others
05:15:58<siti>ok
05:15:59<Jicksta>CTO of Digium
05:16:04<dons>shachaf: there is also a haskell to clean translator, but its about half and half there. some things get faster, others get slower
05:16:11<Jicksta>"creator" I should say
05:16:30<Cale>shachaf: unfortunately, not a very abstract IO system -- you pass the 'world' around explicitly.
05:16:31<Jicksta>looking at the OCaml benchmarks
05:16:37<siti>Jicksta: I have heard rather bad things about the asterisk code :p I have had a look at some modules and well... it's crazy
05:16:39<shachaf>dons: Are the languages that close?
05:16:53<dons>Jicksta: that's a good idea. if you're looking to do this stuff commercially, talk to the Haskell companies (like Galois) or seek consultants on the mailing list
05:16:56<shachaf>Cale: Yes, that's about all I know about it. :-)
05:17:01<dons>shachaf: indeed, clean is really a `fork' of haskell
05:17:16<dons>well, its a fork that never merged back in. and then the community around it died
05:17:27<weitzman>Jicksta: Plus MLton supports continuations, if you're into that kind of thing
05:17:29<shachaf>dons: So they forked Haskell and took monadic IO out?
05:17:34<shachaf>dons: Why?
05:17:46<shachaf>dons: Just for performance, or for other reasons too?
05:17:49<Jicksta>weitzman: no need whatsoever for continuations for this project...
05:17:54<shachaf>dons: (Or is this an earlier Haskell?)
05:18:10<dons>its earlier. it didn't get merged into haskell , when all the other lazy pure research languages did
05:18:22<dons>though the authors were on the original haskell comittee
05:18:38<dons>its about 5 years older than ghc
05:18:39<Cale>Haskell 1.0 didn't have monadic IO yet, iirc.
05:18:46<Jicksta>found an interesting comparison... D is even faster than OCaml
05:18:59<dons>oh, D yes, that's another option. C++ improved
05:19:14<weitzman>Jicksta: Some people like having "cool" theoretical features around even if they serve no purpose
05:19:16<dons>not really the same kind of language as erlang, haskell or ocaml though. so depends on what you like
05:19:29<Jicksta>right
05:19:44<shachaf>Isn't D a much lower level than O'Caml?
05:19:49<dons>yes.
05:19:51<shachaf>ACTION has not looked much into it.
05:19:59<dons>its a C++-ish
05:20:16<Jicksta>yeah. kinda takes features from C++ and Objective C
05:20:18<dons>but designed, rather than growing in a bucket of primordial language soup
05:20:33<Jicksta>though, they have the most retarded marketing... they say they match the productivity of Ruby
05:20:42<dons>heh
05:20:45<Jicksta>clearly they have NO IDEA what Ruby is beyond its name...
05:20:52<glguy>lol, the productivity of ruby
05:22:09<dons>Jicksta: do let us know how you go, and what you decide upon.
05:22:20<Jicksta>I have a few months to make any decisions
05:22:21<dons>if you pick haskell, there's people around here who'll happily help, or point you to consultants.
05:22:33<dons>ah good. so you can get a feel for the design space
05:22:34<Cale>Jicksta: and make sure you hang around here lots if you're learning Haskell, since we like beginners :)
05:22:42<Jicksta>hehe :)
05:22:48<Jicksta>glad to see Haskell community is so supportive :)
05:22:50<Heffalump>especially with sugar on ;-)
05:23:06<bos>the guy behind D has an ... interesting personality.
05:23:42<Korollary>and almost a total lack of familiarity with non-algol syntax languages
05:24:15<bos>well, that could describe about 99.5% of programmers :-)
05:24:31<Korollary>it shouldnt describe language designers
05:25:22<Cale>"Note: all D users agree that by downloading and using D, or reading the D specs, they will explicitly identify any claims to intellectual property rights with a copyright or patent notice in any posted or emailed feedback sent to Digital Mars."
05:25:24<weitzman>D has some language design ideas that are pretty interesting regardless
05:25:35<Cale>That's a confusing remark :)
05:25:51<dancor>in general is something like mapM_ putStrLn ls or putStrLn $ unlines ls better
05:26:05<dancor>do you pay per io start
05:26:19<dancor>or are they the same
05:26:20<Cale>dancor: I'd expect them to be similar.
05:26:35<shachaf>dancor: (You'd use putStr in this case, though that doesn't answer your question.)
05:27:16<shachaf>dancor: How big is the list?
05:28:06<dancor>shachaf: no matter, for any particular case i can just test it. i was just wondering about paying per io
05:28:59<dancor>another q: "why" can't i have (++ " " ++) for (\ x y -> x ++ " " ++ y)
05:29:05<dancor>but e.g. (*) is ok
05:29:10<Cale>dancor: Well, mapM_ has a little more structure to it than just a plain putStr, so it's possible that you pay a little more.
05:30:11<bos>dancor: the syntax for (*) is special.
05:30:22<bos>to write what you want, you'd need to do this.
05:30:29<bos>@pl (\ x y -> x ++ " " ++ y
05:30:30<lambdabot>(line 1, column 25):
05:30:30<lambdabot>unexpected end of input
05:30:30<lambdabot>expecting letter or digit, variable, "(", operator, ":", "++" or ")"
05:30:30<Cale>@pl (\ x y -> x ++ " " ++ y)
05:30:30<lambdabot>(. (" " ++)) . (++)
05:30:33<bos>@pl \ x y -> x ++ " " ++ y
05:30:33<lambdabot>(. (" " ++)) . (++)
05:30:40<bos>@quote stereo
05:30:40<lambdabot>Cale says: Welcome to #haskell where your questions are answered in majestic stereo!
05:31:18<bos>dancor: writing something like ("foo"++) or (++"foo") is called a section, and it's special, too.
05:31:19<dancor>lolbdabot
05:31:54<dancor>we should add ++"a"++ to the special things
05:31:59<Figs>bbl
05:32:05<bos>so (++) by itself is special, and ("foo"++) and (++"foo") are special, but those are the only special building blocks you get for this purpose. it doesn't generalise.
05:32:29<bos>dancor: but the specialness isn't limited to the (++) operator.
05:32:32<dancor>> (++"a"++"b") "c"
05:32:34<lambdabot> "cab"
05:32:46<Cale>heh
05:32:53<shachaf>> ("a"++"b"++) "c"
05:32:54<lambdabot> The operator `++' [infixr 5] of a section
05:32:54<lambdabot> must have lower preced...
05:33:00<bos>you can have a section with a missing parameter on the left, or on the right, but not both.
05:33:03<dancor>omg
05:33:05<shachaf>It's just because ++ is infixr.
05:33:24<dancor>how dare ("a"++"b"++) not work
05:33:29<Cale>(++"a"++"b") = (++("a"++"b"))
05:33:39<Cale>because ++ is right associative
05:33:49<opqdonut>and (++) is not a section but a "functionized" version of ++ in essence
05:34:16<Cale>You have to write (("a"++"b")++) if you want that
05:34:21<dancor>is this a case where the arbitrarity of the result to the uninitiated is important for some coding safety
05:34:26<dancor>or is it just completely insane
05:34:35<dancor>and now all of you are too for being like "this is fine"
05:35:10<Cale>Well, sections are hard to read when they get too complicated anyway
05:35:57<shachaf>dancor: It makes sense, because the "new parens" in (++"a"++"b") are added as (++{"a"++"b"}), but in ("a"++"b"++) They're added as ("a"++{"b"++)}.
05:35:58<Cale>(++) is deceptive too, because it's an associative operator
05:36:35<dancor>shachaf: oh have no doubt that it makes sense, but so does perl
05:36:43<Cale>> (3/7/) 5
05:36:45<lambdabot> 8.571428571428572e-2
05:37:09<shachaf>> ((3/7)/5)
05:37:10<lambdabot> 8.571428571428572e-2
05:37:11<Cale>> (3/7/) 1 :: Rational
05:37:12<lambdabot> 3%7
05:37:30<Cale>> (3/(7/1)) :: Rational
05:37:31<lambdabot> 3%7
05:37:36<Cale>heh, bad example
05:37:43<Cale>> (3/(7/2)) :: Rational
05:37:45<lambdabot> 6%7
05:37:58<Cale>> (3/7/) 2 :: Rational
05:37:59<lambdabot> 3%14
05:38:06<shachaf>> (/7/2) 3
05:38:07<lambdabot> The operator `/' [infixl 7] of a section
05:38:07<lambdabot> must have lower precede...
05:38:21<shachaf>> (\x -> x/7/2) 3
05:38:22<lambdabot> 0.21428571428571427
05:38:25<Cale>> (/(7/2)) 3
05:38:27<lambdabot> 0.8571428571428571
05:39:06<Cale>Which one would you expect (/7/2) 3 to mean? 3/7/2 or 3/(7/2) ?
05:39:30<bos>march the 7th 2002!
05:39:40<dancor>:: unsafeDateCoerce
05:39:41<shachaf>Cale: It's infixl, so I'd say the first one.
05:39:41<bos>ahem. sorry.
05:40:15<shachaf>bos: No, 2nd of July, year 3.
05:40:16<Cale>It would be doable, but I think it's sort of tricky to the point where it's worth making people write a lambda.
05:40:55<shachaf>@pl \x -> x/7/2
05:40:56<lambdabot>(/ 2) . (/ 7)
05:41:03<shachaf>That's also pretty clear.
05:41:20<Cale>People have also wanted funny syntax with "blanks" to avoid lambdas, but I don't think it's worth it.
05:41:44<Cale>Like, lambda is there for a reason, after all :)
05:41:52<shachaf>Cale: You mean in that "burn" language?
05:42:40<shachaf>Cale: The "Business Objects Gem Cutter" email on -cafe is the only one I've seen.
05:42:43<Cale>I mean like (foldr (:) _ xs) to mean (\z -> foldr (:) z xs)
05:43:16<shachaf>Cale: That's quite ambiguous.
05:43:33<shachaf>ACTION would probably not like that.
05:43:36<Cale>yeah, there are lots of problems with stuff like that
05:44:02<edward2>cale: do you think that rebinding Eq, And, Or, etc. so that you can say things like filter (isAlpha || isDigit) "foo12" would be too scary to end users? I already let you add functions etc, so it seems like the next logical step
05:44:30<Cale>There were long discussions about things like that on -cafe a while back and the consensus was basically that they're too tricky.
05:44:34<shachaf>filter (liftM2 (||) isAlpha isDigit) ['a','1',' ']
05:44:37<shachaf>> filter (liftM2 (||) isAlpha isDigit) ['a','1',' ']
05:44:39<lambdabot> "a1"
05:44:41<edward2>cale: =/
05:44:54<Cale>edward2: sorry, that wasn't to you
05:44:55<edward2>shachaf: yeah i know
05:44:59<edward2>cale: whew =)
05:45:17<edward2>shachaf: its just in my toy prelude i'm going with the most general type signatures for everything =)
05:45:40<Cale>edward2: Well, go for it and see :)
05:45:57<Cale>edwardk: Your monad stuff is already pretty scary :)
05:46:03<edwardk>its already in, i just thought i'd check and see if there was some great moral reason others could think of against it ;)
05:46:06<edwardk>heh
05:46:17<shachaf>Cale: Which "monad stuff"?
05:46:20<edwardk>the version i'm currently inclined to include is just generalized, not parameterized
05:46:26<edwardk>shachaf: http://comonad.com/reader
05:46:40<lambdabot>Title: The Comonad.Reader
05:46:41<Cale>The strange join :: m (m' a) -> m'' a thing
05:46:44<edwardk>type-parameterized monads by just letting the monad type vary
05:47:12<edwardk>class ... => Bind m m' m'' where (>>=) :: m a -> (a -> m' b) -> m'' b
05:47:54<edwardk>my current prelude just uses the oleg trick though, because it preserves type inference while the type-parameterized version requires the occasional 'go' to be inserted
05:48:36<edwardk>that and mixing type-parameterized and generalized monads yields a LOT of typeclasses. to the point where you'd need template haskell to practical define an instance =)
05:48:59<edwardk>which i'm actually kind of considering at this point given where my numerical type hierarchy has gone
05:49:10<Cale>Hehe, I have the small satisfaction that I actually came up with Oleg's trick a while before him, but I didn't post it, because I thought it was too ugly.
05:49:21<edwardk>fair enough
05:49:34<Cale>Well, depending on whether he posted his trick immediately, of course :)
05:49:52<edwardk>i just wish GHC's do sugar wasn't monomorphic in the monad type
05:50:22<Cale>mm... I kind of think it makes sense for it to be
05:50:34<edwardk>given the current implementations, sure =)
05:51:15<Cale>You want to permit things like using STM actions as IO actions, right?
05:51:24<edwardk>it kind of mucks up my examples like do x <- [1..]; y <- if even x then Just x else Nothing mixing monad cases
05:51:38<shachaf>edwardk: On that post, you have:
05:51:39<shachaf>class Bind m m' m'' | m m' -> m'' where (>>=) :: m p a -> (a -> m' a) -> m'' a
05:51:45<edwardk>er
05:51:57<edwardk>i mucked up that version, it should be p p' p'' | p p' -> p''
05:52:11<edwardk>i backed into it from the actual version, i'll fix
05:52:23<edwardk>and whoa that one is messed
05:52:27<Cale>Perhaps it would be better to have a class that defined how to lift one monad to another, and allow do-notation to insert lifts when appropriate instances of that class were available?
05:52:52<Cale>The open-class problem is a little unsettling in that regard though.
05:53:09<edwardk>what i'm currently using for my security monads which i'll blog up in a day or two as soon as i get all the lattice product stuff done is class Rebind m m' m'' ... so that the normal monad sugar is untouched.
05:53:33<edwardk>its not as fun, but it has the right properties and doesn't need ghc's behavior to change to be useful
05:53:52<Cale>How does that work?
05:54:00<edwardk>the rebind stuff?
05:54:43<edwardk>one sec
05:54:49<edwardk>i'll clean something up and you can peek
05:55:45<edwardk>http://comonad.com/haskell/security-policy/src/Control/Monad/Security.hs
05:55:47<lambdabot>http://tinyurl.com/3atx79
05:55:53<edwardk>its not quite ready to check out
05:56:07<edwardk>'SecurityLattice' is the 'Rebind' in question
05:56:55<edwardk>where I treat monads as security levels, with a meet-semilattice between different monads in a policy, and rely on the control over the export of the policy type to keep people from extending and subverting the policy
05:57:34<edwardk>http://comonad.com/haskell/security-policy/test/Policy.hs shows the current version in practice
05:58:02<edwardk>what i'm doing now is defining various semilattice products to make it easier to actually define policies
05:58:31<Cale>Who are you working for? :)
05:58:31<edwardk>no one, its my own toy
05:58:38<Cale>ah, "If I told you, I'd have to kill you", would be more interesting :)
05:58:53<edwardk>I do work for a Raytheon subcontractor doing defense work though during the day though =)
05:58:59<Cale>:)
05:59:08<Cale>canHasStdio :)
05:59:13<edwardk>=)
05:59:35<edwardk>http://comonad.com/haskell/security-policy/test/Main.hs shows the actual kind of code that would use that policy
05:59:55<edwardk>i was planning on blogging this up this weekend, but i haven't had time to resolve all of the 'how-to-cut-down-boilerplate' issues yet
06:00:29<edwardk>so it'll probably be Tuesday before i get a nice writeup
06:00:50<Cale>I wonder how well class aliases would help.
06:01:04<Cale>Someone really really ought to implement them already :)
06:01:24<edwardk>well, its one reason why my prelude is so much easier in my language than haskell
06:01:39<edwardk>because dictionaries there are just polymorphic records, so you can define them all in one go usually
06:01:50<edwardk>here it gets piecemealed when i break them apart
06:03:05<edwardk>anyways, the basic idea is you can dump the policy into one module or package and never expose it, then the way the rest of the system is designed without cheating with unsafe tricks you can't access the data in a higher security level, so you get a form of security monad, except with compile time checks using the parameterization trick from the other day
06:03:30<Cale>Speaking of potential defence contracts for Raytheon, have you seen that google video presentation on electrostatic containment fusion reactors?
06:03:33<bos>i wonder where ABC got its use of the offside rule from. none of the original ABC papers is online, so i can't see if ISWIM is cited.
06:04:30<edwardk>the only worries I can think of are Bjorn's standalone deriving clauses since i use newtypes everywhere so all the monads self-erase, various IO cast hackery, and the unsoundness of data families and newtypes. In the absence of those it appears to be impossible to subvert the type system to get at the data.
06:04:39<edwardk>not yet
06:04:57<shachaf>Why do people call ((->) e) the Reader monad, instead of the ((->) e) monad?
06:05:07<shachaf>Isn't Reader the Reader monad?
06:05:09<Cale>shachaf: they're isomorphic
06:05:30<bos>because ((->) e) is hard to pronounce, and the two are the same thing.
06:05:54<shachaf>Cale, bos: OK, it makes sense.
06:06:08<shachaf>(Why can't it be called the (e ->) monad, by the way?)
06:06:20<Cale>We should really allow sections for infix type constructors
06:06:34<Cale>But that's something which was left out of the syntax
06:06:40<edwardk>er and that version there won't compile because the test is broken, as it was written before i transformed policies into monads themselves in order to define lattice sums.
06:06:58<edwardk>you can't construct partial infix applications at the type level shachaf, thats basically why
06:07:26<shachaf>edwardk: It's just a matter of syntax, though.
06:07:36<edwardk>not entirely because its not symmetric
06:07:51<shachaf>edwardk: What do you mean?
06:08:00<edwardk>you can define the functor (e->) but not the contrafunctor (->a)
06:08:22<edwardk>because the latter isn't just 'partially' applied, its applied to a later argument.
06:08:40<edwardk>so fully supporting it, would extend what the type system can do
06:08:52<shachaf>ACTION also wants flip and friends on the type level, though. :-)
06:09:12<Cale>shachaf: You probably want type lambdas, but they really make type inference hard.
06:09:19<edwardk>sure, one of the things i want in my toy language, the problem is they play hell with type inference and typeclasses, etc.
06:09:32<shachaf>Cale: Yes, I do, and yes, I'd guess they would. :-)
06:09:50<edwardk>basically you lose a lot of the benefits of haskell typeclasses with them =/
06:09:53<dblhelix>shachaf: be careful what you ask for: we do not want to find ourselves lost in a system that requires higher-order unification ;-)
06:10:02<edwardk>i can't seem to figure out how to get MPTCs to survive in their presence
06:10:52<edwardk>actually there was a good paper on a limited form of them by neubauer and thiemann i think
06:11:02<edwardk>http://citeseer.ist.psu.edu/neubauer02type.html <-- ahh there it is
06:11:04<lambdabot>Title: Type Classes With More Higher-Order Polymorphism - Neubauer, Thiemann (ResearchI ...
06:11:27<Cale>Basically, the Haskell approach has been to extend things in ways which are mostly conservative, but which allow for fancy types, with an attempt to minimise the additional type signatures you have to use to get them.
06:11:34<edwardk>showing how to deal with a limited form of inference by making a deterministic choice for flex-flex.
06:11:35<dblhelix>edwardk: the problem with introducing a limited form of type lambdas is that you have to be very careful to keep the language understandable
06:11:40<edwardk>yep
06:12:24<shachaf>Why limited? Let's have a full Haskell on the type level! :-)
06:12:38<edwardk>in my case i kind of let the type-level functions have their wicked way then build up typeclasses off of the fully reduced forms
06:12:40<Cale>shachaf: I think Cayenne might do that
06:12:49<dons>shachaf: makes the types too hard
06:12:52<edwardk>shachaf: again, my goal more or less
06:12:54<dons>and you can't do inference anymore
06:13:03<dblhelix>there are nights that I don't sleep too well wondering if a language with gadts, mptcs with fds etc. is still suitable for novice programmers
06:13:16<dons>fds, no.
06:13:27<dons>gadts don't seem too bad
06:13:28<edwardk>you can do inference, but its tricky to get the staging right and you need a form of pointedness in the type checker to guarantee termination
06:13:30<Cale>gadt's aren't so bad
06:13:39<dblhelix>ASTs are a lot better indeed, especially for novices
06:14:07<dons>i suspect associated types will be newbie friendly, in comparison to FDs
06:14:12<dblhelix>still, what I like about Haskell 98 is that is can still envision it as the first programming language one learns
06:14:23<dons>since its obvious how to add extra types to your class, and have themvary on a per-instance basis
06:14:36<shachaf>ACTION definitely counts as a novice. :-)
06:14:37<Cale>dblhelix: Well, novices manage to learn perl.
06:14:50<Cale>(somehow)
06:14:55<dons>what novices don't know won't hurt them more than once a week, eh? :)
06:14:58<dblhelix>Cale: why are you trying to depress me? ;-)
06:15:19<Cale>hehe
06:15:19<edwardk>My current approach is if the function is unpointed then you can use it at the type level, if it isn't the typechecker will give it a window in which to run speculatively to a normal form, and if it fails I give up Cayenne style.
06:15:21<dblhelix>dons: I used to think that too... and maybe I still do
06:15:33<dons>dblhelix: seen the hackathon page yet? (or did i mention that already?)
06:15:38<dons>http://haskell.org/haskellwiki/Hac_2007_II
06:15:39<lambdabot>Title: Hac 2007 II - HaskellWiki
06:15:53<Cale>dblhelix: What do you think of the idea of 'language levels'?
06:15:57<dblhelix>dons: I've seen it... still can't make it though
06:16:14<dblhelix>Cale: we've been seriously considering it to be incorporated in helium
06:16:14<edwardk>where polymorphic unpointed total functions can in general be used in what i would have to call a "poly-sorted" fashion.
06:16:19<dons>we need someone from Utrecht ! :)
06:16:29<edwardk>problem is i lose phantom types =(
06:16:31<dons>you guys still write haskell, right? :)
06:16:41<dons>can't let chalmers take over everything
06:16:42<dblhelix>dons: afaik all the utrecht guys are leaving after cufp
06:17:04<dblhelix>most of us arrive before ifl already, you know
06:17:05<shachaf>ACTION wishes more (any) Haskell-ish events were around here.
06:17:07<dons>yeah
06:17:17<shachaf>I guess Oregon counts as pretty close.
06:17:22<Cale>I think it might be worthwhile have a -101 flag in GHC. While we're at it, let's provide for multiple base libraries, so that progress can be made while retaining compatibility.
06:17:28<Cale>to*
06:17:40<dblhelix>dons: we still write haskell, indeed
06:18:03<dons>just teasing. ;)
06:18:11<dblhelix>I know
06:18:12<Cale>Southern Ontario needs more Haskell events :)
06:18:12<dblhelix>:-)
06:18:28<shachaf>Cale: Are you sure having separate libraries is a good idea?
06:18:41<bos>heck, we can't even manage any haskell events in the san francisco area, and we have about a dozen haskellers here.
06:18:54<Cale>shachaf: Well, it's better than being stuck with the Haskell 98 prelude forever.
06:18:56<dons>we'll have to do something about that, bos.
06:19:01<shachaf>Cale: A "learning mode" is one thing, but actually using Haskell with two very different libraries is another.
06:19:02<dblhelix>shachaf: helium already has two preludes: one with overloading, one without
06:19:25<dblhelix>but admittedly, in some cases having two preludes also adds to the confusing
06:19:32<dblhelix>it's really hard to get these things right
06:19:33<shachaf>Cale: For example, if fmap was called map in one but not the other, it would break a lot of code.
06:19:43<shachaf>Cale: And that's just a simple example.
06:19:50<Cale>There's a fundamental conflict of interest between providing compatibility and developing the language.
06:19:59<Cale>shachaf: Of course, that's the point.
06:20:09<Cale>shachaf: Provide compiler flags to choose.
06:20:15<dblhelix>jurriaan is sliding towards empirical research more and more... just to find out what is effective and what is not when teaching haskell to undergraduates
06:20:27<shachaf>Cale: But what if one piece of code does one thing and another does another?
06:20:51<shachaf>It'd be like working with multiple browsers...
06:21:14<Cale>Well, you just agree to version things.
06:21:36<shachaf>Cale: (I do think it's a good idea, though, if it can be made to work.)
06:21:54<Cale>If I want to write in Haskell 2 and you want to write in Haskell '98, then maybe we can't load each other's modules.
06:22:05<Cale>But then again, perhaps something could be made to work.
06:22:22<Cale>Still, kind of doubtful that the classes would work out.
06:23:14<Cale>We'll likely need something soon along these lines anyway if Haskell 98 is going to co-exist with Haskell'.
06:23:46<shachaf>How big a change is Haskell'?
06:24:13<Cale>Not big relative to stuff already in GHC, but I'm fairly sure some breakage is being considered.
06:24:25<Cale>It's supposed to mostly be a subset of what's already in GHC.
06:24:38<shachaf>Will it have MonadZero/monad comprehensions?
06:24:52<Cale>So no new fancy untested record system, for instance.
06:24:58<Cale>I don't think that's been decided.
06:25:07<Cale>But it would be nice.
06:25:16<Cale>I really hope it has MonadZero.
06:26:08<Cale>Personally, I think we should do one major world-breaking change and not too far into the future, because Haskell is getting more popular, and this sort of thing only gets harder and harder to do.
06:26:11<opqdonut>monad comprehensions <3
06:26:11<shachaf>Will map/fmap/(.)/mapMaybe/(<$>)/etc. be consolidated?
06:26:35<opqdonut>shachaf: consolidated how?
06:26:44<shachaf>opqdonut: They're all the same function.
06:26:49<Cale>Then again, major world-breaking changes might be just the thing to bring popularity down ;)
06:27:00<opqdonut>shachaf: yeah they're all fmap :)
06:27:09<opqdonut>i think the multiple names aren't a problem
06:27:22<Cale>I think we should keep (.) and map, but have them both mean fmap.
06:27:28<shachaf>opqdonut: Will they all have type (Functor f) =>, at least?
06:27:42<Cale>Simply because sometimes you want infix and sometimes you want prefix.
06:28:06<shachaf>Will the class hierarchy be Functor => Applicative => Monad?
06:28:19<Cale>shachaf: I think these are all unresolved questions.
06:28:22<opqdonut>that'd be nice
06:28:45<shachaf>Cale: These are just various changes I've heard rumors of, that would be nice to see.
06:29:13<Cale>In the current draft, it looks like the Monad class hasn't been touched.
06:29:32<Cale>neither has Functor
06:29:40<opqdonut>where is the current draft?
06:29:47<Cale>http://darcs.haskell.org/haskell-prime-report/report/haskell-report-html/index.html
06:29:49<lambdabot>Title: The Haskell Prime Language Report, http://tinyurl.com/2pdmj9
06:30:50<shachaf>Hmm, are all the modules still flat (Monad instead of Control.Monad)?
06:31:40<sjanssen>I don't think the report has been changed much at all
06:32:47<Cale>aha
06:32:50<Cale>http://hackage.haskell.org/trac/haskell-prime/wiki/Status%27
06:32:51<lambdabot>Title: Status' - Haskell Prime - Trac
06:33:05<Cale>That lists the Definitely-in and Probably-in changes.
06:33:17<Cale>Mostly pretty uncontroversial stuff :)
06:33:36<edwardk>cale: i'm currently just using (.) in my toy prelude
06:34:10<edwardk>@type <$>
06:34:10<Cale>edwardk: The trouble comes when you want to write map f in the middle of a chain of compositions
06:34:12<lambdabot>parse error on input `<$>'
06:34:16<shachaf>@ty (<$>)
06:34:18<lambdabot>forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b
06:34:23<shachaf>(<$>) = fmap
06:34:35<edwardk>er yeah =)
06:34:37<Cale>stuff . (f .) . otherStuff looks kind of strange
06:34:40<shachaf>@src (<$>)
06:34:40<lambdabot>f <$> a = fmap f a
06:34:47<Cale>or you could do (.) f
06:34:51<Cale>but that's also ugly
06:34:55<edwardk>ok, i can accept map as a prefix .
06:34:58<Cale>Sometimes you really want the prefix one.
06:35:40<shachaf>ACTION sees how code could get confusing if (.) is fmap. You'd have to be careful...
06:35:52<edwardk>i rather like the resulting code though
06:36:11<shachaf>edwardk: Yes, it's nice.
06:36:47<edwardk>ok, map is in my toy prelude but its explicitly defined outside of the Map typeclass so it has to mean the same as (.)
06:37:26<shachaf>edwardk: Map = Functor?
06:37:52<edwardk>(Map and Functor are currently separate) Map is the restricted version class Map f a b where (.) :: (a -> b) -> f a -> f b
06:38:03<edwardk>so you can do restricted-functor tricks
06:38:56<Cale>There are also very strange things which can happen due to associativity.
06:39:00<edwardk>i may roll it back together
06:39:20<Cale>But it is a cool thing. :)
06:39:23<shachaf>Cale: I hadn't thought of that. fmap isn't associative, is it?
06:39:33<Cale>shachaf: not at all
06:39:39<edwardk>thats what parens are for =)
06:39:48<Cale>But (.) for the (e ->) functor is.
06:39:51<shachaf>Cale: Yes, that wouldn't make any sense. :-)
06:40:42<edwardk>the lack of associativity for fmap is the first good reason against joining everything that looks like it together that i've seen.
06:41:02<Cale>yeah, it's the only one I could come up with
06:41:08<shachaf>edwardk: I'd agree.
06:41:34<Cale>Certainly at *least* map should be functor application
06:41:57<dolio>@quote bulat
06:41:57<lambdabot>No quotes match. Have you considered trying to match wits with a rutabaga?
06:42:00<Cale>Function composition and functor application are basically the two most important operations in functional programming.
06:42:14<opqdonut>and they can be viewed as the same operation, right?
06:42:22<edwardk>yeah
06:42:23<Cale>While it's *really* nice that they can be seen as the same thing, one wonders if they're too important to be unified.
06:42:31<edwardk>right now i think i'll leave them conflated though
06:42:36<opqdonut>Cale: yeah it could be confusing
06:42:37<dolio>@remember bulat instances are standard answer. they are as viruses, imperceptibly filtering through any import lists :)
06:42:37<lambdabot>Done.
06:42:57<opqdonut>> fmap (+1) (+2) $ 0
06:42:59<lambdabot> 3
06:43:35<opqdonut>ghci throws me a No instance for (Functor ((->) a))
06:43:49<edwardk>opqdonut :m + Control.Monad.Reader
06:44:06<opqdonut>ah, Reader defines all those ((->) r) instances?
06:44:10<shachaf>edwardk: Not Control.Monad.Instances?
06:44:28<edwardk>er. oh yeah did it move?
06:45:12<edwardk>looks like its there now
06:45:22<shachaf>Can someone give me an example of a mostly-trivial comonad (Identity is completely trivial, but anything else, like the [] or Maybe monads)?
06:45:35<edwardk>shachaf ((,)e)
06:45:53<edwardk>extract (e,a) = a
06:46:03<edwardk>duplicate (e,a) = (e,(e,a))
06:46:16<dons>shachaf: http://www.eyrie.org/~zednenem/2004/hsce/Control.Comonad.html
06:46:35<dons>some here too http://www.cs.helsinki.fi/u/ekarttun/comonad/
06:46:35<lambdabot>Title: Comonads and Haskell
06:46:44<edwardk>extend ea@(e,a) f = (e,f ea)
06:47:34<Cale>Oh, one thing I should point out to everyone about monad comprehensions. If they get added, I think they really ought to have a new kind of defaulting, like that for the Num class.
06:47:47<shachaf>Cale: For lists?
06:47:51<Cale>Right.
06:47:53<Figs>hi
06:47:54<Figs>me again
06:47:59<shachaf>Cale: That makes sense.
06:48:19<edwardk>if monad comprehensions go in, i think the same flag should let you use more general [foo..bar] enums for arbitrary MonadPlus instances ;)
06:48:20<Cale>Their removal last time was due to the fact that students would type in monad comprehensions which you couldn't actually tell were list comprehensions and get confusing errors.
06:48:32<Figs>I have more weird left-recursion
06:48:40<Cale>edwardk: This is something that I'm actually not too keen on, for some reason.
06:48:45<Nopik>hi there..
06:48:53<Nopik>i have small problem installing libraries
06:48:55<shachaf>Figs: When will you rewrite all this in Haskell? :-)
06:49:03<Cale>edwardk: Lists are very very special in a way that MonadPlus instances aren't necessarily.
06:49:04<Figs>when I understand haskell
06:49:04<edwardk>its consistent with the changing of [...] to support arbitrary monads
06:49:16<Cale>edwardk: That's true.
06:49:20<Nopik>i wanted to use gd library.. its setup says that DAta.Binary.Base cannot be found.. i figured out that fps library do have this...
06:49:23<Figs>believe me, it's not much fun writing this in C++ :)
06:49:31<Figs>but I need to make progress
06:49:35<Nopik>then i setup configure/build/install fps library, all of it went correctly
06:49:36<shachaf>@where binary
06:49:36<lambdabot>http://www.cse.unsw.edu.au/~dons/binary.html
06:49:47<Nopik>now gd still says that Data.ByteString.Base cannot be found
06:49:48<edwardk>and could make for some really nice Set comprehensions =)
06:49:49<Cale>edwardk: However, it's easy enough to write option = msum . map return and use that :)
06:49:55<edwardk>when you add in restricted monads
06:50:13<Cale>edwardk: I really wish there was a better way to do restricted monads.
06:50:15<Nopik>run setup with -v reveals the ghc command which it is using
06:50:19<Figs>I think I might have a weird scheme that would allow me to switch what type of parser I am using
06:50:28<Figs>basically, let's say I have a pattern like
06:50:30<Cale>edwardk: Without the loss of naturality guarantees.
06:50:37<edwardk>well, one reason why i like the excessively general versions of things is they don't require a degree in advanced mathematics to understand what they do when they work =)
06:50:37<shachaf>ACTION wonders if monad comprehensions should use some other syntax than [], which feels like lists.
06:50:39<Figs>M = ref(M)|E >> T
06:50:39<Nopik>when i run the command manually, i get the same error.. but it includes -hide-all-packages argument.. when i remove it, it works
06:50:43<Nopik>but not from setup
06:50:51<Figs>err
06:50:54<Nopik>any ideas?
06:50:56<Figs>M = (ref(M)|E) >> T
06:50:58<Figs>make it more clear
06:51:02<Nopik>or should i use the binary library?
06:51:22<edwardk>shachaf: everything else is taken =/
06:51:29<shachaf>Nopik: What program are you using, that depends on the library? (And which version of GHC?)
06:51:34<Cale>edwardk: Er, except that, let's say you have a monad instance which doesn't obey the monad laws -- those can be *really* confusing.
06:51:37<Figs>if you were trying to do ETTTTT.... it would basically fail
06:51:46<Figs>it'd just match ET
06:51:53<edwardk>shachaf: i ran into the same issue in my toy language. i had no symbols left in the ascii character set, so i started having to reuse notations
06:52:08<shachaf>edwardk: Unicode to the rescue!
06:52:10<Nopik>shachaf: i am trying to install gd library (as i want to use it in my own programs), ghc 6.4.2
06:52:26<shachaf>Nopik: GHC 6.6 might make it easier, if you can do that.
06:52:29<Cale>edwardk: To see this, you only need to consider what happens when the monad laws fail. :)
06:52:29<edwardk>cale: well the writer should be shot, then strung up as an example to all those who profane the monad laws =)
06:52:34<Figs>but you could say, enable for that pattern a specific type of rearrangement
06:52:40<Figs>like
06:52:45<Cale>edwardk: I think losing naturality could be even worse.
06:52:51<Figs>check_left( sequential_pattern )
06:52:55<edwardk>unless it breaks it only in minor ways like Data.Set ;)
06:53:01<Cale>edwardk: Imagine a 'bind' that did something different for Integers :)
06:53:09<Nopik>shachaf: i'll see if my distro includes it ;p
06:53:14<Figs>that would start from the end of the string working <--- to match the string in reverse
06:53:16<shachaf>Nopik: Which distribution?
06:53:24<edwardk>cale: data families probably already have that for you ;)
06:53:32<Figs>until it gets one that goes to the start of the string or fails
06:53:50<Nopik>shachaf: gentoo
06:54:00<Figs>shachaf, does that make sense?
06:54:13<shachaf>Nopik: I'm sure you'll fine it.
06:54:22<shachaf>Nopik: Might take a while to compile, though.
06:54:25<Cale>edwardk: hmm... I somehow doubt it's possible to write an instance of Monad for data families as it stands
06:54:38<shachaf>s/fine/find/ -- I find it surprising that I did that.
06:54:58<Figs>the alternative is to check right recursion first
06:55:03<Figs>and then check left recursion after
06:55:12<edwardk>even so if its imposible to write directly, i think its possible for it to delegate some aspect of a computation to something that involves them
06:55:12<Nopik>shachaf: yeah, i tried to compile ghc 6.4.2, but given up and installed precompiled version.. now i see that precompiled is available for 6.4.2 only, and 6.6.1 is available in sources, but marked as unstable.. lets try
06:55:16<Figs>or pray I can think of a way to translate one into another
06:55:16<Figs>:)
06:55:31<shachaf>Figs: Why are you asking me?
06:55:56<Figs>I thought you knew?
06:56:13<shachaf>Figs: Knew what?
06:56:20<Figs>what I'm doing :P
06:56:57<shachaf>Figs: Probably not... Do you have a latest-and-greatest @paste?
06:57:17<Figs>I don't have any recent pastes
06:57:20<Cale>edwardk: data instances are always monomorphic applications of the type constructor, right?
06:57:31<Figs>unless you want me to call up my math example from earlier
06:58:06<shachaf>Figs: What are you trying to do now?
06:58:26<Figs>I'm trying to figure out how I can make things like
06:58:32<Figs>M = (M|E) >> T
06:58:33<Figs>work
06:58:41<quicksilver>Cale: is it right that a given 'Applicative', if it is in fact a monad, is uniquely so? I.e. at most one bind definition can be compatible with a given <*> definition?
06:58:42<edwardk>i'm not so well acquainted with them, i just remember some weirdness about using them to delegate out special handling of different particular cases
06:58:51<Figs>which is equivalent to E >> T*
06:58:53<Figs>err *T
06:59:12<edwardk>quicksilver: there are multiple valid applicative instances for list
06:59:18<Cale>quicksilver: I doubt it, but it might take me a minute to come up with an example :)
06:59:29<Figs>except that left recursion tends to produce associations to the left
06:59:38<Figs>which causes other issues if it's expected...
06:59:39<edwardk>check the original applicative paper it makes the case for why you might want different applicative and monad behavior
06:59:54<Figs>I can't just translate left-recursion into right recursion automatically (even if I knew how)
06:59:59<quicksilver>edwardk: that wasn't quite my conjecture, though
07:00:09<Cale>edwardk: Yeah, but only one of those is induced by a monad
07:00:13<edwardk>hrmm
07:00:14<quicksilver>edwardk: my conjecture was once you have fixed the appliciative..
07:00:21<quicksilver>edwardk: there is (at most) one monad
07:00:35<edwardk>@type ap
07:00:37<lambdabot>forall (m :: * -> *) a b. (Monad m) => m (a -> b) -> m a -> m b
07:00:38<edwardk>hrmm
07:00:45<shachaf>@src Applicative
07:00:46<lambdabot>class Functor f => Applicative f where
07:00:46<lambdabot> pure :: a -> f a
07:00:46<lambdabot> (<*>) :: f (a -> b) -> f a -> f b
07:01:10<edwardk>thanks for reminding me that i'd forgotten ap =)
07:01:18<quicksilver>it seems to me (arguing purely intruitively) that for a generic 'container' structure, working how to define <*> is much like working out how to make it a monad
07:01:21<Figs>even though xpressive doesn't really do what I want... maybe the boost people will have an answer...
07:02:03<shachaf>Figs: I wonder where you got the idea that I can help you. :-)
07:02:11<shachaf>ACTION is no expert on this.
07:02:17<Figs>you responded to me :)
07:02:25<Figs>10[23:48:58] shachaf: 01Figs: When will you rewrite all this in Haskell? :-)
07:02:26<shachaf>Figs: Oh.
07:02:36<quicksilver>it's equivalent to saying that a monad is defined by its liftMn, for all n
07:02:40<shachaf>Does someone else feel like responding?
07:02:47<shachaf>quicksilver: And its return.
07:02:50<Figs>lol, it's ok...
07:02:50<edwardk>so, each bind gives rise to a natural notion of ap, but you want to know does the converse hold when the notion of bind exists?
07:02:57<Figs>although, if anyone knows... :)
07:03:13<quicksilver>shachaf: yes, indeed
07:03:22<Cale>Figs: I don't actually have any idea what you're doing, but from the bits that were happening in between the other conversations I was having, it has something to do with left-recursive grammars?
07:03:37<Figs>sort of
07:03:45<Figs>I'm writing a C++ regex library
07:04:10<Cale>okay
07:04:14<Figs>I came here earlier and someone (I think it was ddarius) pointed out that my system had a flaw where left-recursion would screw it up since I was doing recursive descent
07:04:41<Figs>simply finding infinite loops in my code isn't too hard, I think
07:04:49<Figs>except in a few cases
07:05:00<Cale>how do you write a recursive regex?
07:05:10<Figs>some thing like...
07:05:28<Cale>(hint: it should be impossible)
07:05:29<Figs>foo = term( "(" ) >> by_ref(foo)|middle >> term( ")");
07:05:50<Cale>that's not a regular language
07:05:57<Figs>it's at least context free, probably context sensitive
07:06:12<Figs>but if I said cfxp
07:06:14<Figs>of csxp
07:06:22<Figs>no one would have a clue wtf I was talking about
07:06:27<Cale>Yeah, it looks more like a PEG
07:06:33<Figs>PEG?
07:06:42<Cale>parsing expression grammar
07:06:46<mm_freak>where's the (^) operator?
07:06:48<edwardk>@src ap
07:06:48<lambdabot>ap = liftM2 id
07:06:49<Figs>that might be a better term, yes
07:07:05<Figs>I haven't heard that one
07:07:19<Figs>anyway, right now, it does recursive descent
07:07:41<edwardk>well, if ap and return would uniquely define a monad, thats a much stronger statement than the earlier one about LiftMn and return, no?
07:08:01<edwardk>since then effectively LiftM2 and return would define the monad
07:08:02<mm_freak>@src (^)
07:08:02<lambdabot>Source not found. I've seen penguins that can type better than that.
07:08:11<mm_freak>@help
07:08:12<lambdabot>help <command>. Ask for help for <command>. Try 'list' for all commands
07:08:12<Figs>I can do a lot of unusual things with the system so far, for example...
07:08:17<Cale>Figs: I think that's fine, so long as you provide some other mechanism to handle those cases where you seem to need left-recursion.
07:08:18<mm_freak>@help list
07:08:18<lambdabot>list [module|command]
07:08:19<lambdabot>show all commands or command for [module]. http://www.cse.unsw.edu.au/~dons/lambdabot/COMMANDS
07:08:19<shachaf>@src liftA2
07:08:20<lambdabot>liftA2 f a b = f <$> a <*> b
07:08:37<Figs>foo = (S[0] << +A) >> replace(S[0],A,B);
07:08:37<edwardk>(^) : (MulMonoid a, EuclideanNearRig b, Eq b) -> a -> b -> a; a ^ b = expT (b .* (Log a))
07:08:40<shachaf>That's the same as liftM2, isn't it?
07:08:43<edwardk>woops, wrong Prelude =)
07:08:47<opqdonut>liftA?
07:08:48<Figs>or
07:09:09<mm_freak>does anyone know, in which class (^) is defined?
07:09:13<edwardk>er s/expT/exp/
07:09:17<Cale>Figs: oh, it has mutation? :)
07:09:23<shachaf>@info (^)
07:09:23<lambdabot>(^)
07:09:27<opqdonut>Prelude.(^):: (Num a, Integral b) => a -> b -> a
07:09:29<edwardk>its Num
07:09:30<Figs>basically it's extensible
07:09:33<edwardk>and Integral
07:09:44<Figs>you can write new pattern matches pretty easily
07:09:47<Figs>or, that's the hope
07:10:00<mm_freak>edwardk: nope, it's neither Num, nor Integral
07:10:06<Figs>the regular operators will serve for most purposes, but if you wanted say to do
07:10:11<Cale>mm_freak: it's not a class member
07:10:13<Figs>A^n B^n C^n D^n ...
07:10:15<mm_freak>seems to be a classless function
07:10:18<mm_freak>yeah
07:10:19<Figs>it would be easy
07:10:29<mm_freak>that sucks
07:10:30<edwardk>well, it uses them, but doesn't get defined in either yeah
07:10:36<edwardk>same as in my version =)
07:10:40<Figs>just take s[0] by reference and write a function to generate the part to match against
07:10:52<shachaf>@help info
07:10:52<lambdabot>help <command>. Ask for help for <command>. Try 'list' for all commands
07:11:05<Cale>mm_freak: What, were you going to define it somehow differently than the Num and Integral instances would make it?
07:11:05<opqdonut>:i (^)
07:11:14<opqdonut>?i (^)
07:11:15<lambdabot>Maybe you meant: id ignore index instances instances-importing irc-connect . v
07:11:22<opqdonut>?info (^)
07:11:23<lambdabot>(^)
07:11:25<edwardk>btw, speaking of which
07:11:25<opqdonut>yep, broken :)
07:11:26<edwardk>@hpaste
07:11:26<Cale>(**) is a class member
07:11:27<lambdabot>Haskell pastebin: http://hpaste.org/new
07:11:46<mm_freak>cale: i'm writing a Mod type for modular arithmetic… the basics are done, now i just need modular exponentiation
07:11:52<Figs>if I wanted to reverse something, I could write a reverse function that took the S object by reference and returned a parser for the reverse pattern
07:11:57<Figs>and do
07:12:01<Cale>mm_freak: oh, so you wanted to write a more efficient version
07:12:09<Figs>foo = (S[0] << A) >> reverse(S[0]);
07:12:09<mm_freak>cale: yes
07:12:19<Figs>Hello!!olleH
07:12:26<mm_freak>but i guess, i'll drop it all and implement it as a monad
07:12:30<Figs>>>><<< etc
07:12:32<opqdonut>?src (^)
07:12:33<lambdabot>Source not found. Maybe if you used more than just two fingers...
07:12:50<mm_freak>looks like that's going to be the easiest
07:13:02<Figs>if you wanted to write a module to search a dictionary, you could do
07:13:12<Cale>mm_freak: er, you could just give your new operator the same name and not import the prelude one, if you wanted
07:13:18<hpaste> edwardk pasted "are these too strange?" at http://hpaste.org/1708
07:13:26<mm_freak>cale: IMO that's bad style
07:13:26<Cale>Or else you could give it a completely new name :)
07:13:28<opqdonut>mm_freak: huh? monad? modular arithmetic?
07:13:41<edwardk>using those as a way to convert between multiplicative and additive monoids, etc.
07:13:43<Figs>foo = (S[0] << A) >> dictionary_begins_with(S[0]);
07:13:44<opqdonut>can't see how that'd work
07:13:53<mm_freak>opqdonut: yes… the monad could just apply the modulo after each computation
07:13:58<ski>edwardk : EuclideanNearRig ?
07:14:15<opqdonut>mm_freak: but that'd place restraints on the type parameter?
07:14:17<edwardk>mm_freak: have you seen Oleg's modular arithmetic typeclass styff?
07:14:19<edwardk>er stuff
07:14:23<mm_freak>such that the type does not hold any ring member anymore, but solely the modulus
07:14:33<mm_freak>edwardk: nope
07:14:33<edwardk>stefan: eucliean algorithm works, but almost everything else isn't guaranteed basically
07:14:44<mm_freak>opqdonut: the type parameter has to be Integral anyway
07:15:00<mm_freak>and since i'm not gonna work with small numbers, i've even speciailized it to Integer
07:15:01<ski>(edwardk : was that to me ?)
07:15:01<Figs>what you can't do though is something like ...
07:15:04<Cale>mm_freak: how would it do that? The value being operated on is a state parameter?
07:15:19<Figs>(S[0] << A) >> lookup(S[1]) >> (S[1] << B);
07:15:24<mm_freak>cale: the modulus being the state
07:15:29<edwardk>ski: an example would be the Naturals. i lack additive inverses, but i can divmod in it.
07:15:33<Figs>because it's recursive descent
07:15:38<Figs>left to right
07:15:41<edwardk>ski: er yeah
07:16:07<Figs>well meh
07:16:09<Figs>I need to go
07:16:14<Figs>I'll bb tomorrow though ;)
07:16:18<Figs>g'night
07:16:26<Cale>Figs: at some point, I'll show you how this sort of thing might be done in Haskell
07:16:33<Figs>cool
07:16:34<Figs>:)
07:16:44<Figs>I'll hold you to it ;)
07:16:49<Figs>cya
07:16:53<Cale>later
07:17:06<edwardk>ski: the typeclasses underlying are a little more general than normal, but the ideas there can be applied to Num with some hackery.
07:17:24<mm_freak>cale: like: (>>=) (Mod a n) f = f (mod a n)
07:17:43<ski>ACTION just doen't have a good picture of how all variants of ring, etc fits together
07:17:59<Cale>mm_freak: I don't see how that works type-wise.
07:18:16<opqdonut>yeah, me neither
07:18:36<Cale>Remember that n could be of any type at all.
07:18:37<mm_freak>dunno… hold on, i'll try it out
07:18:44<Cale>n could be a String
07:18:45<Cale>or ()
07:18:49<Cale>or an IO action
07:18:51<Cale>or a function :)
07:18:59<opqdonut>or ur mom, even
07:19:07<opqdonut>:)
07:19:10<Cale>yep, even your mom
07:19:13<ski>or 'RealWorld'
07:19:13<edwardk>ski: basically its an euclidean domain, with the guarantee of the lack of zero divisors removed (so you can use it over Ints rather than Integers, and the guarantee of additive inverses removed
07:19:16<mm_freak>cale: well, i'll need to restrict that somehow
07:19:27<mm_freak>unfortunately Monad needs * -> *
07:19:31<opqdonut>restricted monads don't work
07:19:31<Cale>right
07:19:32<opqdonut>yep
07:19:52<mm_freak>hmm
07:19:58<ski>edwardk : euclidean domain ? :)
07:20:24<mm_freak>cale: but the idea could actually work
07:20:46<edwardk>mm_freak: http://www.cs.rutgers.edu/~ccshan/prepose/prepose.pdf is the paper I was mentioning about how Oleg and CC Shan encoded moduli in types, very nice trick
07:20:57<edwardk>ski: a euclidean domain is basically something with 'divMod' =)
07:21:10<ski>a ring with some extra things ?
07:21:32<dolio>Using type-level naturals is the way to go for modular arithmetic, if you ask me.
07:21:42<mm_freak>edwardk: thanks
07:21:57<dolio>(^) will automatically be the standard good algorithm, that way.
07:22:15<edwardk>divMod :: { x : a } -> { y : non-zero a } -> { (q,r) : x = y*q + r && valuation r < valuation y || valuation y == 0 }
07:22:28<edwardk>where valuation maps from your domain into the naturals
07:22:34<edwardk>and acts as sort of a measure
07:22:49<edwardk>quotRem and divMod are artifacts of different valuations over the integers.
07:23:35<mm_freak>dolio: you're right… it performs pretty well
07:23:46<Cale>If you really want a fast powerMod operation, you probably want to work with the binary representation of the exponent directly.
07:23:47<mm_freak>ok, no need to write an own function =)
07:23:59<mm_freak>cale: that's what i'm doing
07:24:10<mm_freak>modexp (!b) !e !p !n | (e == 0) = p | (even e) = modexp (mod (b*b) n) (shiftR e 1) p n | otherwise = modexp b (e-1) (mod (p*b) n) n
07:24:14<mm_freak>aaaaaah
07:24:16<mm_freak>damned
07:24:30<mm_freak>but you get the point =)
07:24:37<ski>edwardk : hm, shouldn't 'r' be an element of a quotient type ?
07:24:43<Cale>That's fine.
07:24:53<edwardk>er { (q,r) : (a,a) | x = ... }
07:24:58<Cale>mm_freak: That should all parse as one line, I think.
07:25:02<mm_freak>cale: (^) seems to work the same way
07:25:11<edwardk>would be the concrete syntax
07:25:13<Cale>Oh, interesting.
07:25:22<Cale>I suppose that's why it needs an Integral :)
07:25:25<mm_freak>cale: it's actually multiple lines, but i've configured my client to join indented lines
07:25:45<mm_freak>cale: yeah… Floating provides a separate function, which doesn't use Integrals
07:26:29<Cale>mm_freak: right, because it provides a completely different kind of exponentiation :)
07:26:54<mm_freak>not different, but generalized =)
07:27:05<edwardk>ski: the (q,r) pair is in a subset type, not a quotient type as you can check correctness of subsets and i'm not sure what the quotient would be in this case, grouping them by valuation isn't the right answer because divmod gives back a particular r not the equivalence class =)
07:27:24<Cale>mm_freak: Also, de-generalised
07:27:24<mm_freak>actually both generalized (to arbitrary exponents) and specialized (to numbers)
07:27:31<Cale>right
07:27:35<ski>edwardk : i wanted 'r' to be in a quotient
07:27:51<edwardk>the problem is if you take a quotient over it, you can't compute with it concretely
07:27:55<ski>(and then '(q,r)' could be in a subtype, as well)
07:28:13<mm_freak>now my Mod type is an instance of (Eq, Show, Num, Fractional)
07:28:47<edwardk>so i'm not sure how a quotient over a of all values with the same valuation (which i presume is the quotient you mean) helps
07:28:54<ski>edwardk : hm .. why do you express this property in the result type of the function at all ? to be able to take inverse of the function ?
07:29:05<mm_freak>is there a predefined extended GCD function? i've written it myself, but probably someone has already written a more optimized version
07:29:38<ski>edwardk : an example quotient would be Z/5Z
07:29:49<ski>(for division by '5')
07:30:15<ski>Z ~= Z * Z/5Z
07:30:44<edwardk>well, in this case, the definition that says how a euclidean domain extends a ring is it adds a valuation and divMod function where the divMod function satisfies that law. if it doesn't, then it isn't a euclidean domain. that gives the compiler the ability to try to prove the correctness of your instance
07:31:47<edwardk>ski: the problem i have with that is if i'm using divMod its not because i want to change rings, its because i want to know the remainder in the ring i have. [4]_Z/5Z means a very different thing when projected back into Z.
07:31:56<ski>ok .. so you just wanted to shorten and make it neater, by folding the function and the property into the same "thing"
07:31:59<ski>?
07:32:12<edwardk>yeah more or less
07:32:27<ski>(i don't complain about that :)
07:32:54<Cale>edwardk: [4]_Z ?
07:32:54<edwardk>and it keeps you from implementing a fake version of the class that doesn't satisfy the laws without the compiler complaining at you =)
07:33:04<ski>'[4]_Z/5Z' ?
07:33:17<edwardk>4 in Z/5Z i should have said
07:33:38<ski>edwardk : but you could have made a separate property member in the class, yes ?
07:33:52<Cale>4 + 5Z :)
07:33:53<edwardk>the law?
07:33:56<edwardk>yeah
07:34:00<edwardk>er
07:34:06<edwardk>the yeah was to Cale =)
07:34:31<ski>"means a very different thing when projected back into Z" ?
07:34:44<edwardk>the 'separate property in the class' is awkward because its best for me to check laws about results in the subset type system because then they are flow directed.
07:35:20<ski>ah .. the run-time checking
07:35:25<edwardk>9 `divMod` 5 = (1,4) the 4 is intended as an actual member of the euclidean domain D, not of some equivalence class formed over it.
07:35:48<ski>do you need that ?
07:35:49<edwardk>well, actually its compile time checked by default, the flow in question is the abstract interpretation =)
07:36:01<edwardk>http://en.wikipedia.org/wiki/Euclidean_domain read the definition =)
07:36:02<lambdabot>Title: Euclidean domain - Wikipedia, the free encyclopedia
07:36:09<ski>(ok, compile-time run-time :)
07:37:30<edwardk>we are interested in 4 not all the other things that happen to have the same remainder modulo our particular divisor. your version would cost us trivial invertability and require an explicit projection back into the original ring in order to continue to use it for GCDs, etc.
07:37:47<edwardk>so the utility of the notion of divMod would be compromised
07:39:11<edwardk>i'm perfectly ok with another mod operator that does something like that, but I don't think they are the same
07:39:46<iakovz>hello
07:40:59<shachaf>iakovz: Hello.
07:43:31<ski>edwardk : does 'valuation' only map '0' to '0' ?
07:43:42<ski>s/only map/map only/
07:44:02<moritz>hi
07:44:07<ski>hello there
07:44:15<moritz>I have some problems with installing ghc 6.6.1 on debian...
07:44:43<moritz>I have debian etch (aka stable), and recompiled 6.6.1 from the testing sources
07:44:59<Cale>That would have taken a while :)
07:45:07<moritz>and these are the problems I get when installing ghc6-doc: http://sial.org/pbot/26329
07:45:08<lambdabot>Title: Paste #26329 from "moritz" at 84.148.35.162
07:45:15<Cale>I'd have probably just installed the generic binary
07:45:30<edwardk>ski: not sure about that, some euclideandomains could be a little weird. the practical ones i can think of do
07:45:44<Cale>moritz: Which version of haddock do you have installed?
07:45:48<moritz>Cale: but can I get that as a debian packages?
07:45:59<moritz>Cale: 0.8-2
07:46:08<moritz>Cale: recompiled from testing sources as well
07:46:16<Cale>oh, hmm
07:46:49<moritz>and I had some problems deisntalling two of the libghc6-*-dev packages due to broken prerm-packages ;)
07:47:06<ski>edwardk : i parse 'a = bq + r and either r = 0 or v(r) < v(b)' as 'a = b*q + r /\ (r = 0 \/ v r < v b)' .. how do 'x = y*q + r && valuation r < valuation y || valuation y == 0' parse ?
07:47:34<edwardk>hrmm, i wonder if it could actually be beneficial to define some form of template haskell type hackery that understood how to unravel a bunch of [d| |] blocks into their appropriate typeclasses and built the right instances when you said 'Field' and gave the definitions for the operators
07:48:13<Cale>I don't think I've ever successfully recompiled a package from a newer version of debian, but that could just be bad luck on my part.
07:48:17<edwardk>that was just rattled off my cuff, you got the right interpretation =)
07:48:30<Cale>The generic linux binary would work, but it wouldn't be a debian package.
07:48:40<quicksilver>edwardk: no, I don't think it's any stronger
07:49:01<shachaf>moritz: Can't you use the generic binary with checkinstall or similar?
07:49:04<quicksilver>edwardk: return is liftM0, fmap is liftM1, and ap is (definable using) liftM2
07:49:05<Cale>You could also possibly just move to testing.
07:49:13<moritz>Cale: normally it works... I'd install the binaries from testing, but that is compiled against a newer libc6 :(
07:49:23<quicksilver>edwardk: so the liftMi claim is the same as the 'ap' claim
07:49:25<edwardk>quicksilver: then doesn't your question devolve to if liftM2 and return can uniquely define the bind operation?
07:49:39<edwardk>since you can define ap in terms of liftM2?
07:49:39<quicksilver>edwardk: yes
07:49:49<ski>edwardk : actually, i'm wondering why the domain of 'v' is restricted to not include '0' (e.g. in that WP article)
07:49:55<edwardk>thats all i was saying, the other claim was that if you knew liftMn for all n, no?
07:50:03<quicksilver>yes
07:50:07<mm_freak>edwardk: that paper is very interesting, thank you
07:50:12<quicksilver>that was just a more elegant way of expressing it
07:50:13<moritz>shachaf: I'll try that
07:50:17<quicksilver>I agree it's no more minimal
07:50:50<edwardk>mm_freak: no problem. i found it to be a really neat trick myself =)
07:50:51<moritz>Cale: moving to testing is not an option... I have to keep my system as close as possible to an existing server (that runs stable)
07:51:00<Cale>moritz: ah
07:51:17<shachaf>moritz: I know someone who used the generic binary on Ubuntu before they had 6.6, and it worked.
07:51:29<shachaf>moritz: I'd guess this would be similar.
07:51:29<mm_freak>edwardk: yeah… i don't understand it fully from the first example, but i guess, it'll clarify things later =)
07:51:32<Cale>I've used the generic binary on Ubuntu.
07:52:47<shachaf>mm_freak: "yeah⦠" -- is this on my side or on yours?
07:52:59<edwardk>mm_freak: the basic trick is you abuse polymorphism to carry around a term value reified into a type, then they show you can encode anything in haskell into a type that way, to get a form of implicit parameter passing with a way to enforce the same terms are being used in different locations. i.e. that you are always computing w.r.t the same modulus
07:53:08<ski>quicksilver : are you arguing that '(>>=)' is definable by the 'liftM' functions ?
07:53:19<shachaf>mm_freak: I've been wondering, this isn't my regular terminal.
07:53:28<quicksilver>ski: I was speculating, yes
07:53:37<moritz>if I do a "runghc Setup.hs install" of a cabal package, can I do an unistall in the same way?
07:53:50<mm_freak>shachaf: on your side… i'm using UTF-8
07:53:54<shachaf>quicksilver: Are you saying every Applicative is a Monad?
07:53:55<quicksilver>ski: more precisely, my conjecture was that any Applicative instance is compatible with at most one Monad instance
07:54:03<mm_freak>those weird characters should actually be an ellipse ("...")
07:54:06<quicksilver>shachaf: no no. 'at most one'.
07:54:11<shachaf>quicksilver: Yes, that's what I understood before.
07:54:17<shachaf>mm_freak: Oh.
07:54:18<edwardk>ski: the speculation in question as i understand it is if given a definition for ap and return, if there is only one definition of bind that is compatible. i.e. one way to transform an applicative into a monad.
07:54:33<edwardk>er at most one
07:54:43<shachaf>ACTION wishes his computer worked, so he could use urxvt again.
07:54:54<Cale>I really really doubt that, but I don't have a counterexample on hand :)
07:54:56<mm_freak>edwardk: i've understood the semantics, but i couldn't do it myself yet
07:55:41<Cale>At least, it would be extremely surprising to me if there weren't some applicative functor that was a monad in two different ways.
07:55:57<edwardk>mm_freak: i toyed with using that to pass around command-line flags in my compiler
07:57:23<edwardk>ACTION is striding down a slippery slope very fast
07:57:51<shachaf>moritz: I don't think so.
07:58:24<shachaf>moritz: There's unregister, but I've always deleted the files manually when necessary (probably a bad idea).
07:58:55<moritz>shachaf: I noticed it installs to /usr/local/*, so I don't mind ;)
07:58:56<mm_freak>edwardk: yeah, command line flags are my current problem
07:58:57<edwardk>ok, so i accepted that if 'a' is a monoid/magma/etc it should also be the case that (b -> a) is a monoid/magma. similarly if (==) :: a -> a -> b for some a and b, then (==) :: (c -> a) -> (c -> a) -> (c -> b) should also be allowed
07:59:10<mm_freak>it already starts with a simple "verbosity" value, which i really need to pass almost everywhere
07:59:12<edwardk>similarly for (&&), (||), etc.
07:59:28<ski>edwardk : environment ?
07:59:34<edwardk>yeah
07:59:42<edwardk>trivially lifting them into the reader monad basically
07:59:52<ski>hm, that latter '(==)' looks a bit strange :)
07:59:54<edwardk>since it is unambiguous
08:00:09<edwardk>it does give some nice things like
08:00:16<edwardk>filter (isAlpha || isDigit)
08:01:05<ski>possibly one can think of it as a construct where objects are carriers^c
08:01:15<edwardk>and I went and said that my main goal is to preserve type inference, so i'll allow class ExpOp a b | a -> b, b -> a where exp :: a -> b sort of things, so i can use Log and Exp type classes to map additive foo to multiplicative foo
08:02:32<edwardk>which i thought was particularly clean, and can similarly handle the environment. but then when you get to things like fst and snd, they start to call out to lift as well ;)
08:04:14<edwardk>(f `divMod` g) given f :: b -> a, g :: b -> a, EuclideanNearRig a returns a pair of functions to be consistent with the rest of the numerical hierarchy, which then says i should allow myself to apply fst and snd to functions ;)
08:04:30<edwardk>just not quite sure where this ends =)
08:04:44<ski>what if 'b' is 'Bool' ?
08:05:03<ski>do you get point-wise application over tuples ?
08:05:18<moritz>Cale, shachaf: thanks for your help
08:05:27<shachaf>moritz: It works?
08:05:33<edwardk>(f + g) True = f True + g True right now
08:05:50<edwardk>divMod is the one i'm not sure of the right semantics for
08:05:53<ski>fst (f + g) = fst f + fst g
08:06:17<ski>(a,b) + (c,d) = (a + c,b+d) -- i.e.
08:06:17<moritz>shachaf: sadly not. the generic binary needs readline 4, which I can't find
08:06:33<moritz>shachaf: I decided to live without ghc6-doc for the moment
08:06:39<shachaf>moritz: Oh, I remember reading about people who had that problem.
08:06:42<edwardk>i have lifting of magmas etc over tuples already
08:06:45<edwardk>so the latter works
08:06:55<edwardk>the fst case i haven't got implemented yet
08:07:25<shachaf>moritz: Does Debian not have a readline4 package?
08:07:32<edwardk>fst f = fst . f ?
08:07:38<mm_freak>what confuses me all the time… what is a "first-class object"?
08:07:41<ski>no
08:07:51<ski>edwardk : 'f' was a pair there .. i.e. a function from 'Bool'
08:07:59<moritz>shachaf: not in stable. I haven't looked at oldstable
08:08:02<quicksilver>mm_freak: something which can be passed around the language as a 'normal value'
08:08:19<mm_freak>quicksilver: an example of a non-first-class object?
08:08:23<edwardk>where in that the assumption is i'm using f to refer to a function
08:08:23<ski>f : (b : Bool) -> if b then a1 else a0
08:08:35<quicksilver>mm_freak: in C or Java, functions are not first-class
08:08:45<mm_freak>ah k
08:08:46<quicksilver>mm_freak: in haskell, patterns are not first class
08:08:53<quicksilver>or modules
08:08:54<edwardk>not sure where you are going with the bool thing
08:08:55<mm_freak>thank you
08:09:03<shachaf>moritz: Yes, it's in oldstable.
08:09:09<shachaf>(According to debian.org.)
08:09:16<mm_freak>what is a higher-order function? a function, that returns another function?
08:09:19<edwardk>you want (a,a) to be sort of indexed by True,False?
08:09:22<ski>in C "functions" are first-class
08:09:32<mm_freak>ski: function pointers are, not functions themselves
08:09:49<ski>edwardk : as an example .. needn't be exactly 'Bool', though
08:09:54<quicksilver>mm_freak: typically a higher order function is a function that takes a function as a parameter
08:10:06<edwardk>doesn't fit really well with the rest of my system i think
08:10:14<ski>mm_freak : just terminology :)
08:10:14<edwardk>this is actually haskell code right now =)
08:10:44<mm_freak>ski: nope, there is a technical difference between the two =)
08:10:47<ski>edwardk : the exponential above, too ?
08:10:59<edwardk>the ExpOp case?
08:11:15<edwardk>yeah using a toy prelude i've been porting over from my compiler and working on as i go
08:11:25<mm_freak>calls via function pointers are translated to indirect calls in opcode
08:11:34<ski>(mm_freak : yeah .. which was why i said "\"functions\"" ..)
08:11:53<ski>(mm_freak : and how does 'map' call its argument ?)
08:11:54<edwardk>i just break out each operator separately into a typeclass
08:11:59<edwardk>its making for instance hell
08:12:02<edwardk>but its not all that bad
08:12:35<edwardk>i'm kind of tempted right now to put together some template haskell magic for stringing together the right instances given the definitions of all the functions that go into them
08:12:38<ski>istr Clean had more separated numeric classes
08:12:41<mm_freak>ski: let's call them procedures =)
08:12:44<ski>s/had/has/
08:13:30<ski>mm_freak : (i can't recall the term rn, but) let's call them first-order procedures, then
08:13:58<mm_freak>ski: most likely via indirect calls, but that's not so easy to predict
08:14:01<edwardk>@hpaste
08:14:01<lambdabot>Haskell pastebin: http://hpaste.org/new
08:14:36<mm_freak>now what is a first-order function? a function that takes only values?
08:15:09<JKnecht>same as 1st order formula I would guess
08:15:31<ski>what i wanted to express, but can't recall term for was : not being able to use local variables defined outside a function .. i.e. no closures
08:15:32<hpaste> edwardk pasted "misc. algebraic classes" at http://hpaste.org/1709
08:16:09<ski>the type being '[](a -> b)' with '[]' being a "neccisity" modal operator
08:16:18<quicksilver>mm_freak: yes, first order means it takes only values as parameters
08:17:00<mm_freak>quicksilver: what's the difference between second-order and third-order?
08:17:21<edwardk>as you can see to define a Num takes like 7 typeclasses now, hence why i'm thinking the TH wizardry might not be a bad idea
08:17:32<dolio>secondOrder :: (a -> b) -> c, thirdOrder :: ((a -> b) -> c) -> d
08:17:42<ski>(n+1)th-order things can take nth-order things as arguments
08:18:01<ski>(0-order things doesn't take arguments)
08:18:19<mm_freak>ok, thanks
08:18:57<edwardk>$(additiveGroup [ [d|zero = ...|], [d|(+) = ... |], [d|negate = ...|] ])
08:19:04<ski>ACTION had some omega-order functions in a project
08:22:02<edwardk>at present i'm using a lot of CPP stuff to prepopulate those from the traditional prelude
08:22:05<edwardk>which isn't ideal
08:22:35<edwardk>though it does have the advantage that things can be defined and used in the same file
08:25:08<edwardk>so, next question
08:25:32<edwardk>I implicitly lift (+) , etc into the reader monad. these also make sense lifted into other monads. would that be too weird?
08:25:50<edwardk>@hpaste
08:25:50<lambdabot>Haskell pastebin: http://hpaste.org/new
08:28:27<dolio>I've seen it suggested before.
08:29:21<hpaste> edwardk pasted "monadic math" at http://hpaste.org/1710
08:29:44<edwardk>in my case its a little easier coz i don't have spurious Show and Eq requirements everywhere
08:30:01<dolio>Indeed.
08:31:13<hpaste> edwardk annotated "monadic math" with "fixed typos" at http://hpaste.org/1710#a1
08:31:28<shachaf>Hmm. Would something similar to "instance Monad a where x >>= f = f x; return = id" be possible/a good idea?
08:31:49<ski>(edwardk : hm .. you don't have loops or moups ?)
08:32:02<edwardk>shachaf: it doesn't work at last check
08:32:07<quicksilver>shachaf: http://haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-Identity.html ?
08:32:09<lambdabot>http://tinyurl.com/ydy84p
08:32:16<dolio>'a' isn't a type constructor there.
08:32:27<shachaf>quicksilver: Yes, except without thee Identity part.
08:32:30<shachaf>dolio: Hmm.
08:32:33<edwardk>ski: i stuck to defining the points in the hierarchy that have operational meaning to haskell. where a new operator was introduced basically.
08:32:48<ski>instance Monad (\a -> a) -- not allowed by haskell
08:32:59<quicksilver>shachaf: without the identity part it isn't a type constructor any more, so it can't be a monad?
08:33:00<shachaf>Well, you know what I mean, anyway. Is something similar possible, at all?
08:33:11<ski>edwardk : ok
08:33:19<shachaf>quicksilver: I guess.
08:33:22<edwardk>shachaf: you need the Identity constructor in there
08:33:46<shachaf>ACTION wonders what he means, exactly. :-)
08:33:57<shachaf>ACTION should go to sleep.
08:34:28<edwardk>shachaf: Monad m expects m :: * -> * your a has kind *
08:35:08<shachaf>edwardk: Yes, I know.
08:35:12<edwardk>to get something of kind * -> * you'd need a type, newtype or data declaration that took an argument, the type thing would appear to work at first glance, except you can't use 'type's as arguments to typeclasses.
08:35:41<shachaf>edwardk: Why not, by the way?
08:35:53<edwardk>because they reduce themselves to normal form silently on you, so they aren't there for the typeclass or instance to look at
08:36:19<edwardk>type Foo a b = a -> b when used as Foo a b is indistinguishable from a -> b
08:36:48<edwardk>so type MyIdentity a = a seems at first like it might work, but when the compiler gets around to looking at it its already an a, no longer a 'MyIdentity a'
08:37:12<shachaf>OK, that makes sense.
08:37:34<edwardk>I have kind of wondered if a much much lazier compiler could keep those around longer =)
08:38:04<edwardk>but i don't think its practical and it would rely on letting the compiler redo a lot of work to get consistent semantics, etc.
08:38:14<quicksilver>edwardk: but it might be a bit surprising, you could accidently 'erase' a type by passing through 'id'
08:38:19<edwardk>yep
08:38:31<quicksilver>id :: [Char] -> [Char] would 'anonymise' a String
08:38:35<quicksilver>e.g.
08:39:37<edwardk>yeah, i played with it, but couldn't come up with any sort of consistent semantics
08:40:41<edwardk>hrmm, wondering what weird effects you get from the monadic math stuff now that i'm looking at now just readers and writers, etc.
08:40:42<dolio>You could do some crazy stuff that way.
08:41:10<dolio>type ComposeT f g m a = f (g m) a
08:41:45<dolio>instance (MonadTrans f, MonadTrans g) => MonadTrans (ComposeT f g) where lift = lift . lift
08:42:07<ski>edwardk : istr ghc allows type-synonyms in instance heads .. not partially applied, though
08:42:42<ski>s/not partially/only fully/
08:42:50<kolmodin>@yarr! -- morning
08:42:50<lambdabot>Swab the deck!
08:42:59<ski>indeed!
08:43:25<edwardk>ski: sure, because then they know they can reduce them fully, and won't wind up with any weird 'holes' in the middle of the type
08:43:38<ski>right. no lambda types
08:43:45<edwardk>> liftM2 (*) [1,2,3] [4,5,6]
08:43:46<lambdabot> [4,5,6,8,10,12,12,15,18]
08:43:49<edwardk>hrmm
08:44:02<edwardk>is that the semantics we'd want a [1,2,3] * [4,5,6] to have?
08:44:22<ski>> liftM2 (+) [100,200,300] [4,5,6]
08:44:24<lambdabot> [104,105,106,204,205,206,304,305,306]
08:44:38<ski>if we want left-to-right evaluation of the effects, yes
08:44:55<quicksilver>> zipWith (*) [1,2,3] [4,5,6]
08:44:56<lambdabot> [4,10,18]
08:44:58<dolio>You could define it for arbitrary Applicatives.
08:45:06<ski>(in the list monad, i forgot to say :)
08:45:08<quicksilver>anand then again, maybe I'd ratehr have that one :)
08:45:10<edwardk>i'd kind of hoped to use + for the natural list append monoid. that hope appears to be gone =)
08:45:11<dolio>Then you could choose between [] and ZipList.
08:45:17<edwardk>but this is more consistent
08:45:19<quicksilver>as dolio says
08:46:41<edwardk>well, the reader monad is natural, writer, state, and blech even IO works, its just list that sticks in my craw a bit
08:47:39<edwardk>and of course that becomes rather funny when mixed with the parameterized monad stuff from the other day =)
08:47:49<edwardk>Just 2 * [1,2,3] etc =)
08:48:31<edwardk>though that doesn't work =(
08:48:37<edwardk>it would cost us type inference for *
08:50:18<edwardk>it does work nicely for the set and bag restricted monads though, giving a proper everything-to-everything operation
08:51:14<ClaudiusMaximus>@hoogle finalizer
08:51:15<lambdabot>Foreign.Marshal.Alloc.finalizerFree :: FinalizerPtr a
08:51:15<lambdabot>Foreign.ForeignPtr.FinalizerPtr :: type FinalizerPtr a
08:51:15<lambdabot>Foreign.Concurrent.addForeignPtrFinalizer :: ForeignPtr a -> IO () -> IO ()
08:51:36<edwardk>but it changes the meaning of (==) in a weird way, (==) for the reader monad lacks an alternative interpretation, but when you talk about lists or sets or bags it has a clear interpretation
08:51:45<edwardk>=(
08:52:05<quicksilver>yes
08:52:20<quicksilver>that's why we (sometimes) want to distinguish between foo and liftM2 foo :)
08:52:36<edwardk>heh
08:52:52<quicksilver>distinguishing between ++ and liftM2 ++, too....
08:53:00<edwardk>i realize, but until i moved from Reader to a general monad i didn't have a good counter example =)
08:53:32<quicksilver>you're doing some really cool magic, but sometimes cool magic can become confusin
08:54:03<edwardk>so, one answer might be to define a class Monad m => MonadMath m
08:54:09<edwardk>then use the magic math stuff that way
08:54:44<edwardk>i.e. iff there is no reasonable interpretation of the mathematical operators in another way lift them
08:55:01<edwardk>but if you have something like lists etc, don't lift them by default
08:55:07<wli>edwardk: sounds interesting; what's going on here?
08:55:20<edwardk>playing with the stuff from my toy prelude some more
08:55:33<quicksilver>edwardk is pushing back the boundaries of sugar
08:55:40<edwardk>wli: the current question has to do with automatic lifting of mathematical operations into various monads.
08:55:48<wli>edwardk: Seen Oleg's BinaryNumber.hs?
08:56:13<edwardk>i already accepted the notion that given say a Monoid instance for 'a' then you should get a Monoid for b -> a, which is the reader monad
08:56:33<edwardk>so the question arose if it just make sense to define (+) = LiftM2 (+) for all monads
08:56:50<edwardk>similarly (==), (&&), (||), etc lift nicely
08:57:03<edwardk>but then it compromises the notion of equality comparison directly on lists
08:57:09<wli>edwardk: Built-in syntactic sugar or Oleg's BinaryNumber.hs would be very spiffy.
08:57:10<edwardk>even though it works nicely in the reader monad
08:57:17<edwardk>which one is that?
08:57:21<wli>s/sugar or/sugar for/
08:57:40<edwardk>wli: heh, have you seen my version of that sort of thing?
08:57:49<wli>edwardk: no
08:58:14<quicksilver>edwardk: your pain would be allayed, somewhat, by syntax for choosing among alternative instances
08:58:21<edwardk>http://comonad.com/haskell/type-int/src/Data/Type/
08:58:22<lambdabot>Title: Index of /haskell/type-int/src/Data/Type
08:58:41<quicksilver>edwardk: then it wouldn't matter that there were two instances for Eq [a], etc
08:58:42<edwardk>the Binary/ directory is the one of interest in the current discussion
08:58:46<edwardk>yeah
08:59:23<edwardk>in my toy compiler i allow dictionary passing by name, which plays some weird games with the semantics for dictionaries and typeclass inference i'm not QUITE sure i like yet
08:59:54<edwardk>sort .by anotherordinstance ...
09:00:25<wli>ACTION sees
09:00:38<wli>good stuff in the numbers
09:00:39<quicksilver>edwardk: yes. Have you seen the paper on that?
09:00:43<edwardk>sort :: (.by : Ord a) => [a] -> (result : [a] | sorted result)
09:00:44<edwardk>yeah
09:00:46<quicksilver>edwardk: they used the syntax '#' for application
09:00:49<edwardk>wli: thanks
09:00:57<edwardk>wli: the hex one is the scary part
09:01:01<wli>Totally reasonable.
09:01:08<edwardk>derives about 5 megs of haskell =)
09:01:20<quicksilver>although I favour some kind of lexical approach myself
09:01:46<wli>edwardk: Does it boil down to decently small programs despite 5M of source?
09:02:10<edwardk>quicksilver: yeah, what i'm using is .foo for named field dereference, and i've conflated the notion of functions and records so that accessing a named argument is looking up a named field in the function, which returns a new function pushing that argument to the front
09:02:33<edwardk>wli: they don't seem to be any worse than normal haskell programs
09:02:40<edwardk>wli: its just a huge library in the middle
09:03:50<edwardk>quicksilver: then i just allow the implicit dictionaries to be made explicit by passing them by name, requires a few more type annotations to be able to pass one in by name, which i'm not happy with but i think it may be the way i have to go
09:04:03<quicksilver>ACTION nods
09:04:17<quicksilver>edwardk: I like the idea of a language construct
09:04:34<quicksilver>using MonoidFromMonadPlus { ... expr ... }
09:04:48<quicksilver>edwardk: then, inside that scope, the notion of 'default' dictionary is changed
09:04:56<edwardk>thought about it, but the syntax is horrible =)
09:05:14<edwardk>and what is inside the scope, everything written in the scope or everything called by anything written in the scope
09:05:26<edwardk>what if i call into that scope is it dynamically of lexically bound, etc.
09:05:59<edwardk>to steal a quote from dan friedman 'scope is everything' =)
09:06:19<quicksilver>edwardk: lexical, not dynamic, obviously
09:06:27<quicksilver>edwardk: dynamic scopes are the work of the devil
09:07:37<edwardk>well, thats somewhat problematic still, because what if the compiler elides the dictionary for a few calls of depth knowing it can rederive it later? so now this interferes with optimizations? =) this is actually a spurious argument becausse i currently require myself to compile two versions, one optimized one for explicit calls ;)
09:08:30<edwardk>dynamic scopes have their place. i never thought i'd say it but i think oleg won me over with some of the dynamic binding + delimited control use cases.
09:08:32<quicksilver>edwardk: well obviously it can't elide dictionaries if they have been explicitly chosen as a non-default
09:08:49<quicksilver>edwardk: at least, it can't do that upfront
09:08:51<dolio>Yeah, I thought that was an interesting paper, too.
09:09:08<quicksilver>edwardk: after it's parsed + type checked everthing, then it can elide all kinds of dictionaries, cos they're mostly compile-time-constant
09:09:11<dolio>I hadn't thought of Reader as dynamic scoping before, but I suppose you can look at it like that.
09:09:24<edwardk>yeah
09:09:28<quicksilver>dolio: I would look at it as 'dynamic scoping done right', though
09:09:38<vincenz>moin
09:09:43<wli>I'm much stodgier about these things.
09:09:44<dolio>His dynamically scoped variables are different than you see in, say, old lisps, though.
09:09:45<quicksilver>dolio: dynamic scoping but 'explicit' in the types so you can see what's happening
09:10:21<dolio>Since you need to get a name for the scoped variable from someone. You can't just use an arbitrary name that happens to change depending on where you're called.
09:10:23<edwardk>wli: anyways the type integers there are largely inspired by oleg tricks, i just needed some that actually were fully fleshed out
09:10:50<wli>edwardk: I presume they're sugared in the source language?
09:11:09<edwardk>because while Oleg is brilliant, the man doesn't exactly spend his time polishing his ideas beyond a point before he goes off to do something else =)
09:11:22<dolio>Heh.
09:11:57<edwardk>wli: there are sugared witnesses for them, tAdd foo bar. and $(hexE 123) gives you a compile time generated numeric term.
09:13:04<edwardk>show (tAdd $(hexE 123) $(hexE (-123))) should output "$(hexE 0)"
09:13:34<edwardk>and the witnesses type infer values in all possible directions
09:14:38<edwardk>i mostly did it because i wanted to think through infinite precision 2s complement arithmetic
09:14:54<edwardk>i find the adder becomes amazingly symmetrical in that setting, etc.
09:15:20<wli>witnesses?
09:16:10<edwardk>well, the idea of type level arithmetic is you usually don't have members of your types, right? other than undefined that is. so you supply term-level functions for passing around those differently typed undefineds to perform calculations at the type level
09:16:48<edwardk>those term-level functions that reify the type-level calculations down from typeclasses to the term syntax are what I was calling witnesses.
09:17:16<wli>You could have a single member for each.
09:19:04<edwardk>result = tAdd $(hexE 3) $(hexE 64) is a fancy way of saying the constraint result :: TAdd (X3 F) (X4 (XF F)) z => z; result = undefined
09:19:47<edwardk>wli: you COULD, but then the compiler can't fully erase the types and then you have to deal with the implicit bottom member as opposed to the explicit member etc.
09:20:04<edwardk>its generally better form to not allow a singleton member in a witness if you can get away with it
09:20:15<edwardk>empty data declarations state intent to erase quite nicely =)
09:21:01<wli>edwardk: What's a witness?
09:21:06<roconnor>@where monad laws
09:21:07<lambdabot>I know nothing about monad.
09:21:27<edwardk>a witness is just a term level function like tOdd :: TOdd a b => a -> b; tOdd = undefined
09:21:47<edwardk>for a type level relation like: class TOdd a b | a -> b; instance (LSB a b c, TNot b b') => TOdd a b'
09:22:53<edwardk>tOdd takes one argument and returns its answer, its argument's value is never looked at just its type, and it generates an answer whose type is purely dependent on the type of the argument through the functional dependency in TOdd's definition
09:23:33<edwardk>tOdd 'witnesses' the relationship that TOdd creates between a number and a boolean value, by allowing you to write it at the term level rather than the type level.
09:23:48<wli>okay
09:24:05<edwardk>they are the sugar you mentioned =)
09:24:08<wli>I didn't know there was a name for that.
09:24:34<edwardk>the only problem is that you can't overload the normal (+) to manipulate the type level terms or you lose type inference for the normal use cases =(
09:25:09<edwardk>ideally i'd go back and make a consistent convention, like (+:) or something
09:25:12<wli>edwardk: I was thinking more of the compiler/interpreter translating type names written with decimal digits to the binary/whatever strings.
09:25:45<edwardk>wli: thats what the template haskell $(hexE 123891) expressions are for
09:26:32<dblhelix>are there any standard arrows implemented in the hierarchical libraries? reader arrows, writer arrows, state arrows, etc.?
09:26:53<wli>dblhelix: I wish. I've not seen anything of the sort.
09:26:54<edwardk>$(hexE 255) returns the equivalent of having written (undefined :: XF (XF F))
09:27:17<edwardk>and $(hexT 255) returns the type itself XF (XF F) for use in type-level expressions
09:27:18<dblhelix>we need an arrow template library!
09:27:30<wli>edwardk: Some sort of lexical construct that expands to that would be nice.
09:28:09<wli>TypeNat123 etc.
09:28:19<edwardk>wli: $(hexE 123) _is_ that lexical construct =) thats the only escape we can get right now.
09:28:36<dblhelix>wli: what about http://hackage.haskell.org/cgi-bin/hackage-scripts/package/arrows-0.2
09:28:39<lambdabot>http://tinyurl.com/2z6ftm
09:29:13<wli>dblhelix: Looks interesting.
09:30:31<wli>edwardk: Punching a hole in the type namespace for it and generating that from the name string shouldn't be hard.
09:30:59<edwardk>robert dockins also has a typenat library, though his has fewer directions of inference (because his is naturals, not integers, not so many things are closed) in his case the naming sugar is the kind of scary 'two `hundred` sixty four'
09:31:37<opqdonut>:D
09:31:39<opqdonut>nice
09:32:27<edwardk>wli: an interesting problem, GHC doesn't offer that sort of user directed name management at the moment. i've thought about something in the same general sphere to allow for user-managed int syntax, etc for my own use but i haven't found a good way to let the library hook into the parser
09:32:38<wli>edwardk: Naturals and integers are easy. Primes, polynomials (esp. irreducible ones), etc.
09:33:16<edwardk>heh, i just needed them to check array bounds at compile time, etc.
09:34:08<edwardk>ints and nats are more than sufficient for those needs. =) i'm actually in the process of defining arbitrary type-level meet-semilattices, and their products, sums, disjoint unions, etc. for another project though. so maybe i'll drift back towards that =)
09:34:09<wli>GF(p^n), Q_p, Z[a] for algebraic integers a, etc.
09:35:24<wli>I'm not sure how to do primes yet. Irreducible polynomials look even hairier.
09:36:13<edwardk>anyways i can catch about an hour and a half nap before work, so i'm going to wander off.
09:36:23<quicksilver>@localtime edwardk
09:36:32<wli>If you can get a large enough fragment of logic going within your types to check those sorts of things I think you can still be decidable.
09:37:31<edwardk>wli: right now i just need a logical ^ meet operator for security levels, not in a hurry to do RSA at the type level =)
09:46:27<oerjan>@bot
09:46:27<lambdabot>:)
09:53:04<Nopik>damn.. ghc was compiling for 2 hours and it failed due to lack of disk space ;(
09:53:36<dons>oops
09:53:39<dons>can you just use a binary?
09:55:15<Nopik>yeah, i would like to.. though my distro somehow refuses to notice the fact that ghc-bin 6.6 exists and forces 6.4.2..
10:13:52<mm_freak>nopik: gentoo?
10:38:43<dons>?users
10:38:43<lambdabot>Maximum users seen in #haskell: 355, currently: 319 (89.9%), active: 5 (1.6%)
10:39:33<quicksilver>ooh :(
10:39:39<quicksilver>dropping
10:40:46<dozer>is there a cleaner way to write this: flip (foldl (flip $ uncurry M.insert)) assocList
10:41:05<dozer>where assocList is [(k, v)]
10:42:00<Nopik>mm_freak: yeah
10:42:07<quicksilver>fromList?
10:42:17<mm_freak>nopik: GHC 6.6 is masked in gentoo… you need to unmask it
10:42:19<quicksilver>dozer: is that M.fromList?
10:42:31<Nopik>mm_freak: i've unmasked 6.6.1 sources and remerging them once again (after freeing 500mb of disk space ;d)
10:42:45<dozer>well, it is a functio that adds all the things in assocList to its argument
10:42:47<Nopik>mm_freak: yes, but there is no ebuild for ghc-bin 6.6.x
10:43:21<mm_freak>oh, i see
10:43:22<dozer>quicksilver: it's still waiting for a map to add all those things to
10:43:42<quicksilver>dozer: M.union (M.fromList assocList)
10:44:10<mm_freak>ok, then you'll need to merge ghc-bin-6.4.2, then ghc-6.6.1, then unmerge ghc-6.4.2 and finally remerge ghc-6.6.1 =)
10:44:35<mm_freak>the point is compiler performance… compiling GHC using GHC 6.6.1 makes it run a lot faster
10:44:46<quicksilver>dozer: and isn't flip ( foldl ( flip just foldr?
10:45:23<dozer>quicksilver: that union/fromlist thing is probably what I was after
10:45:41<wli>flip . foldr . flip == foldl?
10:47:01<DRMacIver>Wrong type signature isn't it?
10:47:08<DRMacIver>@type flip . foldr . flip
10:47:10<lambdabot>forall b c. (c -> b -> c) -> [b] -> c -> c
10:47:11<DRMacIver>@type foldl
10:47:13<lambdabot>forall a b. (a -> b -> a) -> a -> [b] -> a
10:47:27<quicksilver>well you don't necessarily need that last flip
10:47:34<DRMacIver>@type foldr . flip
10:47:35<quicksilver>it does all depend what you're trying to acheive, exactly
10:47:36<lambdabot>forall b c. (c -> b -> c) -> c -> [b] -> c
10:47:49<DRMacIver>Hm. I guess not.
10:47:57<quicksilver>of course, they're not the same, in the sense that they do the calculation in a different order
10:48:18<quicksilver>you need to add a 'reverse' in to get the same ordering
10:48:20<quicksilver>if that matters
10:48:31<wli>looks like it yeah
10:48:44<quicksilver>the guideline is to use foldr if in doubt, though
10:51:57<DRMacIver>I'm never entirely clear how lazy Data.Map manages to be.
10:52:20<wli>Me neither.
10:52:54<wli>Maybe there should be a Data.RadixTree as they're obvious to make fully lazy.
10:52:56<DRMacIver>I mean, I can see the potential for some opportunities for laziness, but most of them look like "Only if you're lucky in the data you try to use".
10:53:00<oerjan>DRMacIver: someone said it is strict in the spine of the map
10:53:40<DRMacIver>Hm. I'm not totally sure what that means. :)
10:53:46<DRMacIver>What's the spine of the map?
10:53:58<oerjan>the shape of the tree
10:54:37<DRMacIver>Ah
10:56:02<quicksilver>DRMacIver: totally lazy in values, I'm sure
10:56:07<quicksilver>DRMacIver: it would be daft to be any other way
10:56:20<wli>How would it do comparisons if so?
10:56:24<quicksilver>DRMacIver: most Ord instances you can imagine would make it strict in the keys
10:56:42<quicksilver>DRMacIver: although you can imagine an Ord instance which falls short of completely strict
10:56:55<quicksilver>> 'a' : undefined < 'b' : undefined
10:57:01<oerjan>quicksilver: keys that are lists
10:57:03<lambdabot> True
10:57:06<wli>Ord on a record only comparing some fields.
10:57:08<quicksilver>including that one :)
10:57:09<quicksilver>right
10:57:23<quicksilver>however it's always going to be 'somewhat' strict in the keys
10:57:39<oerjan>(but then you probably want a trie)
10:57:41<DRMacIver>quicksilver: Yeah, I realised it was always lazy in the values. I was wondering about key strictness.
10:57:52<kolmodin>dons: you've got mail
10:58:38<DRMacIver>But you're right that some strictness is obviously neccessary. I was just curious how much. :)
10:58:40<wli>ACTION ponders composition/chaining of Mealy machines.
10:59:20<quicksilver>DRMacIver: I believe it is maximally lazy, in practice
10:59:25<DRMacIver>What on earth is a Mealy machine?
10:59:36<quicksilver>DRMacIver: the only strictness is that which is implied by your choice of Ord instance
10:59:46<DRMacIver>ok
10:59:48<dozer>DRMaclvier: it's an inside-out more machine
11:00:13<DRMacIver>What on earth is a more machine? :)
11:00:25<quicksilver>DRMacIver: an inside-out mealy machine
11:00:26<wli>DRMacIver: A Mealy machine is a finite automaton that produces output during state transitions.
11:00:26<blackdog_>it's an outside-in mealy machine...
11:00:32<oerjan>quicksilver: that is not what i heard. i heard it computed the entire shape of the tree (and was translated from Ocaml)
11:00:38<quicksilver>oerjan: that's true too
11:00:40<DRMacIver>quicksilver: I new you would say that. :)
11:00:45<quicksilver>DRMacIver: sorry :P
11:00:48<DRMacIver>knew
11:00:55<wli>DRMacIver: A Moore machine is a finite automaton that produces output on entering states.
11:01:00<quicksilver>oerjan: well, 'insert' doesn't force the spine AFAIk
11:01:02<DRMacIver>ok
11:01:05<quicksilver>oerjan: but accessing an element does
11:01:59<quicksilver>oerjan: so in practice the spine gets forced fairly 'soon'
11:02:18<quicksilver>I don't know for sure if it forces the whole spine, though
11:02:29<wli>It shouldn't.
11:02:33<quicksilver>if you head down the left branch, the other thunks might just get pushed right
11:02:40<wli>Just what's required in the lookup path.
11:02:41<quicksilver>and not evaluated further than needed to push them right
11:03:08<DRMacIver>Hm. Any good functional programming related podcasts?
11:03:14<oerjan>forcing the whole spine may help against space leaks, i suspect
11:03:22<DRMacIver>(Otherwise good podcasts are also welcome :) )
11:03:40<quicksilver>oerjan: I could imagine that, but I don't see any explicit forcing in the code
11:03:54<quicksilver>oerjan: so I think it's just demand-driven
11:03:57<ekidd>Good morning.
11:05:24<oerjan>oh, it's actually obvious: there are strictness tags on the Map data definition
11:06:55<quicksilver>oerjan: oh. stupid me :)
11:07:20<quicksilver>oerjan: didn't think to look there :)
11:07:30<oerjan>easy to do :)
11:07:46<quicksilver>I searched the file for 'seq' and Iread the source for insert and balance
11:09:05<kjdf>could someone give me some pointers on how to do dynamic programming in haskell?
11:09:13<kjdf>(and/or memoization)
11:09:21<quicksilver>oerjan: I don't understand the algorithm in detail, but I *think* that the !Size annotation is enough to strictify the whole spine
11:09:29<|Steve|>I just wrote a macro in scheme that will memoize any function.
11:09:34<quicksilver>oerjan: since that forces all the sizes everywhere and that forces the whole shape?
11:21:42<malcolmw>dcoutts, dcoutts_: ping?
11:22:17<fasta>Is there free software which implements a propositional logic simplifier?
11:22:56<oerjan>quicksilver: i think rebalancing can be lazy in some of the shape even while calculating the total sizes.
11:24:00<oerjan>(in principle)
11:24:25<malcolmw>fasta: clausify? (in the nofib suite)
11:24:52<malcolmw>fasta: I think ndm has a propositional simplifier as well
11:24:55<fasta>malcolmw: I prefer something which is an actual apt-gettable program.
11:26:16<wli>fasta: You want something like a command interpreter that accepts propositional logic expressions as input and produces simplified expressions as replies?
11:26:24<fasta>wli: right
11:26:37<fasta>Probably coq does that
11:26:41<wli>Sounds like a fun project.
11:26:50<wli>coq probably does everything.
11:27:26<fasta>wli: It's just that it's easy to let the machine do the simplifications then to do by hand, although I rarely write redundant logic.
11:28:37<wli>Sort of like a reducer for Prolog.
11:30:32<quicksilver>or, sort of like prolog itself :)
11:30:37<quicksilver>sort of like a prolog engine
11:30:54<quicksilver>I'm not aware of an out-of-the-box solution myself
11:31:01<quicksilver>although surely all the decent CA packages can do it
11:31:10<quicksilver>and ndm did write something like that you're right
11:33:03<malcolmw>http://www-users.cs.york.ac.uk/~ndm/proposition/
11:33:05<lambdabot>Title: Neil Mitchell - Proposition
11:38:36<fasta>Another program I would love to see is a compiler from Haskell to a boolean circuit.
11:39:06<fasta>Or rather a boolean formula.
11:39:17<fasta>(to be more precise)
11:44:02<profmakx>hmm
11:46:15<dons>would an FPGA compiler do?
11:46:36<profmakx>i thought of something like that too, fasta :)
11:48:36<Nopik>i have a question about monad types.. i am a beginner haskeller, so most likely i confuse some ideas here.. but, on a tutorials about a monads, they says that monad typing convention is seamlessly using existing haskell syntax, so things like "IO String" are already in the language.. but how to understand the "IO String" or "MyType OtherType" syntax?
11:49:16<quicksilver>"IO String" means : computation, which probably involves some I/O or other interaction with the outside world, and finally produces a result of type String
11:49:18<Nopik>I can write data Point a b = Point Double Double for example (or something like this :D).. which seems the same syntax to me
11:49:29<earthy>nopik: exactly so.
11:49:29<mauke>Nopik: it is
11:49:31<quicksilver>it is the same syntax
11:49:40<quicksilver>there is nothing spcial about them, in that sense
11:49:44<quicksilver>they're just another data type
11:49:50<quicksilver>their meaning is the interesting part
11:49:52<Nopik>ok, then, I cannot write method of type IO String -> String, right?
11:50:00<quicksilver>you can, in fact
11:50:07<quicksilver>but you can't write the method you wanted to write :)
11:50:08<mauke>right, because you don't know how IO looks internally
11:50:11<earthy>but we like to hide that fact. :)
11:50:11<Nopik>but I can write method Point Double Double -> (Double, Double)
11:50:17<quicksilver>correct
11:50:29<quicksilver>because 'IO String' doesn't actually *include* that value of type String
11:50:36<quicksilver>rather, it contains the instructions on how to calculate it
11:50:45<quicksilver>until that calculation/computation is carried out
11:50:49<quicksilver>the String result doesn't exist
11:50:58<Nopik>ok, but if IO internals were exposed to me, I would be able to extract String from IO String and export it without IO monad.. is that right?
11:51:05<mauke>not really
11:51:06<quicksilver>and you can't know in advance what the answer is going to be
11:51:12<mauke>you'd still have to actually do the I/O somehow
11:51:18<quicksilver>well computing the answer might involve connecting to another computer over the internet
11:51:22<quicksilver>or asking for user input
11:51:26<quicksilver>or various other things
11:51:26<Nopik>yeah
11:51:47<roconnor>or formating your hard drive
11:51:59<Nopik>but once one function returns something of type IO String to me, I should be able to extract plain String from it?
11:52:23<mauke>there is no plain string there
11:52:30<mauke>consider data Spork a b = Spork (a -> b -> Ordering)
11:52:38<mauke>then I hand you Spork Double Double
11:52:46<mauke>can you extract (Double, Double) from that?
11:52:55<Nopik>hm, ok
11:52:57<Nopik>good point
11:53:32<Nopik>so it is more like c++ template argument
11:53:44<roconnor>indeed.
11:53:44<mauke>right
11:54:06<Nopik>ok, thanks for explaination
11:54:14<mauke>in fact, there is no requirement that a data type actually uses the type parameters it gets
11:54:25<mauke>data Wtf a = Wtf String -- valid
11:54:32<Nopik>yeah, i know
11:55:33<quicksilver>even if the type is there in the type, it may not be there in every value, too
11:55:40<quicksilver>'Nothing' is a valid value of type 'Maybe Int'
11:55:47<quicksilver>but there really isn't an integer in there, to get out :)
11:55:48<fasta>A program-simplifier could also have some value.
11:55:58<Nopik>;)
11:56:02<quicksilver>Nopik: this is actually a good example, since Maybe is also a monad
11:56:03<fasta>E.g. if a < b then a else b should be min a b
11:56:12<Nopik>quicksilver: indeed
11:56:30<quicksilver>Nopik: the analogy with IO is that an action of type IO String might actually throw an exception
11:56:36<quicksilver>Nopik: so it might never return a string after all
11:56:51<Nopik>ACTION did not read about exceptions yet ;p
11:57:21<mauke>fail "zomg" :: IO String
11:57:37<fasta>dons: I just want an AST consisting of NOT, AND and OR gates taking respectively 1, 2 and 2 arguments.
11:57:49<Nopik>yeah, i have seen 'fail' usage few times, but no comprehensive text about them
11:57:53<fasta>dons: if an FPGA can do that, I would be most happy.
11:57:59<quicksilver>malcolmw: interesting. ndm's Data.Proposition abuses Show.
11:58:10<quicksilver>malcolmw: I wonder if this is still considered abuse, or if it's become acceptable
11:58:13<fasta>dons: FPGA compiler*
11:58:19<mauke>Nopik: that's probably because 'fail' is a hack :-)
11:58:27<Nopik>mauke: :)
11:58:36<kjdf>RWS monad is just a combined reader, writer and state?
11:58:43<mauke>yes
11:58:56<quicksilver>kjdf: yes. I believe it's intended more as an instructive example than a useful thing in itself
11:58:57<Nopik>i'll write my first 'real' program first, then i'll know what i need to read about on the next stage ;p
11:59:27<mauke>maybe it predates monad transformers
11:59:33<roconnor>quicksilver: I used the RWS monad.
11:59:38<dons>quicksilver: how is it abused, the Show instance?
11:59:45<dons>to wrap IO and render it harmless?
11:59:51<roconnor>Monad tranformers confuse me a bit.
11:59:52<scook0>RWST is a great way to accidentally introduce space leaks :/
12:00:12<quicksilver>dons: No. It's just he makes an instance for a 'convenient human readble display'
12:00:17<quicksilver>dons: but it doesn't produce parseable haskell
12:00:23<roconnor>I never know if i want ListT State or StateT List.
12:00:27<quicksilver>dons: which is the unofficial Show invariant :)
12:00:32<dons>oh, i guess its ok outside of the base lib
12:00:58<quicksilver>dons: I find that very annoying, during debugging
12:01:02<dons>yeah, read . show is supposed to work. as is pasting code into src
12:01:14<quicksilver>dons: I often generate counter-examples in ghci
12:01:20<roconnor>scook0: how does RWST introduce space leaks?
12:01:21<quicksilver>dons: and copy them into code from my terminal, to make a test
12:01:31<dons>yeah
12:01:48<quicksilver>dons: show the Show -> copy/paste -> .hs file loop is very important to me
12:01:54<dons>tell him to use a Pretty class for that, not Show :)
12:01:55<quicksilver>s/show the/so the/
12:01:57<quicksilver>ACTION nods
12:02:02<scook0>roconnor: a lazy writer part accumulates thunks like mad
12:02:08<quicksilver>I've tried to bring this up with him once
12:02:11<scook0>even if you aren't using it
12:02:14<quicksilver>he didn't understand my point, I don't think
12:02:22<quicksilver>I probably didn't explain it well
12:02:40<quicksilver>dons: but I wonder if this invariant should be better documented or discussed
12:02:56<earthy>really the point is that there's 'moderately readable serialisation, acceptable to the GHC parser' and 'pretty printing'
12:03:23<roconnor>scook0: does that apply equally to the WriterT?
12:03:33<earthy>where the latter may degenerate into calls to the former
12:03:36<quicksilver>earthy: absolutely
12:03:38<earthy>but not the other way 'round
12:03:39<scook0>roconnor: if it's lazy, I presume so
12:03:44<quicksilver>earthy: well said
12:04:05<roconnor>@type runWriter
12:04:07<lambdabot>forall w a. Writer w a -> (a, w)
12:04:08<earthy>unfortunately, the distinction isn't available in the prelude
12:04:16<scook0>actually, I have no idea whether either is *guaranteed* to leak space
12:04:38<roconnor>scook0: If uses the list Monoid, then the size of the thunks is about the size of the resulting list?
12:04:40<earthy>which makes the new prelude goals laudable. :)
12:05:48<scook0>after upgrading to ghc 6.6 I spent ages tracking down a space leak caused by a lazy RWST making heaps of 'mappend' thunks on ()
12:05:51<quicksilver>@src Writer (>>=)
12:05:51<lambdabot>Source not found. My mind is going. I can feel it.
12:06:04<quicksilver>the problem, as I see it, is there in Writer
12:06:15<quicksilver>@src (Writer w) (>>=)
12:06:15<lambdabot>Source not found. Just what do you think you're doing Dave?
12:06:24<quicksilver> m >>= k = Writer $ let
12:06:24<quicksilver> (a, w) = runWriter m
12:06:24<quicksilver> (b, w') = runWriter (k a)
12:06:24<quicksilver> in (b, w `mappend` w')
12:06:40<quicksilver>note the `mappend` is "always" called
12:06:48<quicksilver>even if the action 'm' generated no output
12:07:06<quicksilver>so for a long writer action, which generates no output at all
12:07:27<quicksilver>you get this silly thunk mempty `mappend` mempty `mappend` mempty `mappend` ....
12:07:46<quicksilver>scook0: is that your understanding of the problem?
12:07:51<scook0>quicksilver: pretty much
12:08:15<scook0>the worst thing was that my space profiling gave totally misleading results
12:08:21<scook0>since the leak was in the monad itself
12:08:46<quicksilver>seems to be true even of Writer.Strict
12:08:50<quicksilver>unless I'm misreading the code
12:09:22<chessguy>so who's got the cryptic messages about ICFP07 figured out?
12:09:23<scook0>well, in my case I just ditched the writer, since I wasn't using it
12:10:08<mauke>@source Control.Monad.Writer
12:10:09<lambdabot>http://darcs.haskell.org/packages/mtl/Control/Monad/Writer.hs
12:10:55<quicksilver>seems that let w'' = w `mappend` w' in w'' `seq` (b,w'') might be better
12:10:58<quicksilver>but I'm not sure
12:11:14<mauke>wtf
12:11:15<quicksilver>given a monad instance which has a fairly simple instance for 'mempty'
12:11:25<mauke>is Writer.Strict identical to Writer.Lazy?
12:11:43<quicksilver>mauke: no, it's strict in the typle
12:11:47<quicksilver>mauke: tuple
12:12:05<mauke>meh
12:12:20<wli>I've not gotten the hang of what writers are used for.
12:12:26<quicksilver>wli: logging
12:12:35<mauke>table building
12:12:37<wli>Examples?
12:12:41<quicksilver>wli: like sprinkling 'putStrLns' through your code
12:12:47<quicksilver>only they aren't actually putStrLns really
12:12:52<quicksilver>just log messages collected in a big list
12:12:53<mauke>I've used it in an interpreter
12:13:09<wli>mauke: How did you use it there?
12:13:23<mauke>I wanted to transform a parse tree into an easier interpretable form
12:13:29<wli>quicksilver: I'm looking for things more like mauke is talking about.
12:13:40<roconnor>quicksilver: ugh, that's terrible.
12:13:40<quicksilver>ACTION nods
12:13:41<mauke>specifically, I wanted to resolve function calls
12:13:42<wli>mauke: What sort of form was that?
12:14:23<wli>Well, I already have an example where I output the various row operations used in Gaussian elimination.
12:15:00<wli>It seems vastly more general than outputting mere sequences so I've something of a failure of imagination as to how it's used more generally.
12:15:28<quicksilver>wli: well, think of more exciting monoids, then
12:15:29<mauke>the original version used runtime table lookups because all function calls were done on strings
12:15:40<quicksilver>wli: 'accumulating summary data'
12:16:01<mauke>the improved "compiler" had to immediately resolve symbols while compiling them
12:16:14<roconnor>maybe my RWS monad code worked well because I demaned the results of my writer monad in the middle of using it.
12:16:20<mauke>i.e. it had to resolve symbols that weren't even compiled yet
12:16:23<quicksilver>roconnor: that will stop the leak, yes
12:16:30<wli>quicksilver: So it could, in principle, be used to sum numbers.
12:16:36<quicksilver>roconnor: just keep demanding the write from time to time
12:16:51<quicksilver>@instances Monoid
12:16:55<lambdabot>(), (a -> b), (a, b), (a, b, c), All, Any, Dual a, Endo a, Ordering, Product a, Sum a, [a]
12:17:02<wli>mauke: IOW single-pass compilation?
12:17:13<mauke>right
12:17:40<roconnor>Ordering is a Monoid?
12:17:48<wli>mauke: So you built up a forward reference table of symbols to be resolved once encountered?
12:17:52<roconnor>> Lt `mappend` Gt
12:17:53<lambdabot> Not in scope: data constructor `Gt'
12:17:57<roconnor>> LT `mappend` GT
12:17:59<lambdabot> LT
12:18:05<roconnor>?
12:18:44<mauke>everytime it encountered a function, it would compile it and 'write' it (the name and compiled code) to the log
12:19:07<Botje>@pl \v m -> M.insert k v m
12:19:07<lambdabot>((M .) .) . insert k
12:19:11<mauke>hmm
12:19:14<Botje>@pl \v m -> insert k v m
12:19:14<lambdabot>insert k
12:19:20<Botje>doh
12:19:21<Nopik>yeah... ghc 6.6.1 finally compiled, after 2h20m and 1GB of disk space ;p
12:19:23<Botje>that was silly.
12:19:43<mauke>am I misreading this code?
12:20:01<quicksilver>> runWriter . sequence_ . map (tell . Sum) $ [1..5]
12:20:02<lambdabot> ((),Sum {getSum = 15})
12:20:04<chessguy>-- lexicographical ordering
12:20:04<chessguy>instance Monoid Ordering where
12:20:04<chessguy> mempty = EQ
12:20:04<chessguy> LT `mappend` _ = LT
12:20:04<chessguy> EQ `mappend` y = y
12:20:05<chessguy> GT `mappend` _ = GT
12:20:08<quicksilver>wli: like that ^^
12:20:09<chessguy>roconnor, ^^
12:20:51<quicksilver>wli: or, if you prefer to multiply the numbers, take a different Monoid instance
12:20:58<quicksilver>> runWriter . sequence_ . map (tell . Prouct) $ [1..5]
12:20:59<lambdabot> Not in scope: data constructor `Prouct'
12:21:02<quicksilver>> runWriter . sequence_ . map (tell . Product) $ [1..5]
12:21:03<lambdabot> ((),Product {getProduct = 120})
12:21:36<Nopik>do anyone here happen to have simple/small examples of using gd library?
12:21:45<chessguy>gd?
12:22:12<wli>Not sure what lambdabot command to look up Sum
12:22:20<quicksilver>it's just a newtype over numbers
12:22:23<Nopik>chessguy: this is library for manipulating images
12:22:31<fasta>gd is an image library, popular with PHP programmers.
12:22:33<quicksilver>to give it the obvious Monoid instance using (+)
12:22:42<wli>quicksilver: Where is it?
12:22:50<quicksilver>not sure
12:23:03<fasta>Nopik: what makes you think this library has Haskell bindings?
12:23:10<quicksilver>http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html
12:23:12<lambdabot>http://tinyurl.com/y5qk9n
12:23:15<quicksilver>wli: there ^^
12:23:36<quicksilver>'IntSet' is another interesting Monoid instance
12:23:42<quicksilver>you can accumulate sets of stuff
12:23:50<wli>Endo hmm.
12:23:51<quicksilver>this has obvious applications for things like 'privileges'
12:23:55<Nopik>fasta: because i have downloaded the bindings from haskell.org and runghc Setup.hs configure/build/install worked?
12:23:59<mauke>wli: apparently I misremembered my own code. the "log" is just a set of strings (symbol names)
12:24:11<fasta>Nopik: URL?
12:24:19<fasta>And define:
12:24:22<fasta>@where gd
12:24:22<lambdabot>I know nothing about gd.
12:25:00<Nopik>fasta: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/gd-3000.3.0
12:25:02<lambdabot>http://tinyurl.com/2wuz44
12:25:24<fasta>@where+ gd http://hackage.haskell.org/cgi-bin/hackage-scripts/package/gd-3000.3.0
12:25:24<lambdabot>Done.
12:25:35<mauke>wli: the magic is in the compiler functions that use this set to build a symbol map that is then returned and so it can be passed in as a reader environment for the compiler functions
12:25:53<Nopik>though bindings are quite badly documented :(
12:26:09<fasta>Nopik: if you just look at the module interface, it's quite clear.
12:26:18<fasta> loadJpegFile, loadJpegData, loadJpegByteString,
12:26:18<fasta> -- ** PNG
12:26:18<fasta> loadPngFile, loadPngData, loadPngByteString,
12:26:18<fasta> -- ** GIF
12:26:20<fasta> loadGifFile, loadGifData, loadGifByteString,
12:26:23<fasta>Etc
12:26:32<fasta>That seem pretty sane names.
12:26:57<dons>looks nice. what lib is that?
12:27:04<dons>gd-3000 ?
12:27:05<fasta>@where gd
12:27:06<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/gd-3000.3.0
12:27:08<fasta>dons: yes
12:27:18<dons>cool, must recommend that when people come looking for .png loading libs
12:27:20<Nopik>fasta: yeah.. though i am extremely new at haskell, so even such things leave a little puzzlement for me :) but well, lets get some experience ;)
12:27:24<fasta>I wasn't aware of its existence.
12:27:43<fasta>Nopik: I only touched really simple libraries written by other people.
12:27:58<Nopik>i was looking for image manipulation library, this is the only library listed on haskell.org to claim to be able to do such thing ;p
12:27:59<fasta>Nopik: partly, because everything I need doesn't exist yet.
12:28:27<Nopik>fasta: yeah, tell me about it ;p
12:28:29<wli>Sum/Product are really just biendomorphism instances.
12:28:42<fasta>Nopik: GTK2HS also contains an image manupulation monad.
12:28:57<kjdf>and what do you need, fasta?
12:29:06<fasta>manipulation*
12:29:11<quicksilver>dons: is it possible for hacakge to automatically put the haddock online?
12:29:23<fasta>kjdf: are you asking for suggestions?
12:29:24<quicksilver>dons: that's what CPAN does, and I suspect that's one of the most important features
12:29:36<Botje>ACTION is writing a small webserver in haskell
12:29:37<Botje>it's nice :)
12:29:41<wli>You probably need instances on higher kinds.
12:29:52<HairyDude>is it intentional in GHC that Ord defaults to ()?
12:29:58<kjdf>fasta: yes
12:30:09<quicksilver>> () < ()
12:30:11<lambdabot> False
12:30:23<HairyDude>> () <= ()
12:30:24<lambdabot> True
12:30:32<fasta>kjdf: I am interested in a program that given a program written in Haskell transforms that to an abstract syntax tree consisting of boolean nodes(NOT, AND, OR).
12:30:51<wli>A biendomorphism is a function f : X x X -> X
12:30:54<Nopik>heh.. it seems that gd have load image, save image, set pixel, but no get pixel function ;p
12:30:54<fasta>kjdf: it should of course be easy to extend to other programming languages.
12:31:18<quicksilver>wli: I'm not sure that your observation is all that interesting
12:31:18<HairyDude>it seems useless and counterintuitive
12:31:34<quicksilver>wli: isn't monoid multiplication always a bi-endomorphism
12:31:41<HairyDude>this is ghc 6.7 btw
12:31:43<roconnor>@check (<=)
12:31:45<lambdabot> Add a type signature
12:31:51<mauke>HairyDude: what do you mean?
12:31:53<roconnor>@check (<=)::(() -> () -> Bool)
12:31:54<lambdabot> OK, passed 500 tests.
12:31:59<fasta>kjdf: does that keep you busy for the next month?
12:31:59<roconnor>@scheck (<=)::(() -> () -> Bool)
12:32:01<lambdabot> Completed 1 test(s) without failure.
12:32:13<wli>quicksilver: The thought was to be able to somehow parametrize over the biendomorphism.
12:32:32<kjdf>I don't think so. It's not my league yet :)
12:32:33<fasta>Is there also a triendomorphism?
12:32:51<wli>fasta: n-endomorphisms even, of course.
12:33:06<scsibug>Nopik: it should be fairly straightforward to add getPixel to GD (I added setPixel awhile back when the wrapper didn't even have that..)
12:33:07<fasta>Those words are great with Scrabble!
12:33:31<quicksilver>wli: I just don't really think the jargon adds much
12:33:34<fasta>morph -> morphism -> endomorphism -> nendomorphism
12:33:40<quicksilver>wli: normally we call these binary operations
12:33:51<quicksilver>wli: and all you've done is re-stated what Monoid is
12:34:02<hpaste> HairyDude pasted "Ord defaults to () in ghc 6.7" at http://hpaste.org/1711
12:34:03<quicksilver>(Monoid is a class with an identity and a binary operation, such that...)
12:34:15<mauke>@seen augustss
12:34:15<lambdabot>I saw augustss leaving #haskell 2d 1h 45m 17s ago, and .
12:34:32<wli>quikcksilver: The thought was to cast it in a more general context.
12:34:51<HairyDude>oddly 'insert' is fully polymorphic but 'isort' isn't
12:35:01<wli>quicksilver: So the restatement is deliberate.
12:36:15<oerjan>HairyDude: perhaps () is just the first default for anything it fits
12:36:30<oerjan>it _does_ seem intuitive for that
12:37:30<HairyDude>well I believe it goes against the Report, since that says defaulting only happens for numeric types
12:37:39<oerjan>> let isort = foldr insert [] in isort
12:37:41<lambdabot> <[Integer] -> [Integer]>
12:37:54<HairyDude>yes, in ghc 6 it default to Integer
12:37:55<kilimanjaro>A Java programmer and a Haskell programmer are handed the same project. The Java programmer spends 5 days working on the project, and is at least successful in getting it handed off to somebody else. The Haskell programmer finishes up a prototype in 30 minutes, argues with his boss over a bit of vocabulary, and then listens to Mozart while surfing IRC
12:38:06<oerjan>HairyDude: ghc has an "extended defaulting" mechanism?
12:38:27<HairyDude>I'd only expect that to be turned on with -fglasgow-exts
12:38:35<wli>kilimanjaro: You don't even want to think about what the C programmer goes through.
12:38:35<HairyDude>or some other switch
12:38:43<mauke>maybe it's a bug
12:38:48<oerjan>HairyDude: report a bug then
12:40:56<ddarius>magma
12:41:42<HairyDude>ah, it seems the defaulting is turned on in GHCi for convenience... but I would expect it to default to something numeric instead of ()
12:42:16<ddarius>Anyone do Claus' Mux exercise from the list?
12:44:23<|Steve|>kilimanjaro: Funny. I've been a TA for classes that taught Java for the first time and I've been a TA for classes that taught Haskell and now Scheme for the first time. By the end of the quarter, the Java students could write little programs. By the end of the quarter, the functional programming students could do small math calculations and _maybe_, just maybe map a function over a list.
12:44:49<|Steve|>Well, I'm not at the end of the Scheme quarter yet, so I'll let you know in 3 weeks.
12:44:58<quicksilver>that sounds a bit odd?
12:45:04<integral>Are the classes teaching as fast as possible?
12:45:09<quicksilver>surely you can do small math calculations at the end of your first 10 minutes?
12:45:14<quicksilver>how does that take a quarter?
12:45:14<scook0>hmm, if I have [a->b] and [a], and I want a list of all the possible results,
12:45:20<scook0>that's just "ap" in [], right?
12:45:21<quicksilver>> 1 + 2 * 5
12:45:24<quicksilver>scook0: right
12:45:29<|Steve|>quicksilver: Yeah, but there isn't a whole lot of progression after that.
12:45:29<lambdabot> 11
12:45:30<integral>sturgeon's law applies to students I guess
12:45:55<kilimanjaro>|Steve|, so they are no longer a risk to the health of themselves and others around them. Really I'd say that's a success
12:46:28<|Steve|>Writing a tail-recursive version of log-time exponentiation was more than many of them could handle. It's less than 10 lines of scheme.
12:46:45<kilimanjaro>You go from sticking forks into outlets all the way to sitting down, dressed, typing math calculations. That's like a complete transformation
12:47:42<|Steve|>And this scheme class is supposedly upper division. The java class was the slow java class for freshman who've never programmed anything before.
12:47:57<Saizan>is haskell the first programming course? or they have to unlearn all that OO and imperativeness?
12:48:18<Nopik>scsibug: yeah, i was looking at the source code and indeed it is mostly a wrapper to foreign call
12:48:19<|Steve|>Haskell was actually a bit of an experiment (a failed one, I might add) to combine haskell and discrete math.
12:48:23<matt__r>steve: I have to say my experience is the opposite
12:48:30<Nopik>scsibug: do you happen to have any small program using gd in haskell?
12:48:41<quicksilver>certainly |Steve|'s experience doesn't conform with my knowledge of the Imperial first term Miranda course
12:48:46<|Steve|>I was hoping to hear about matt's experience...
12:48:47<earthy>nopik: doesn't the gd lib binding have examples?
12:48:55<Nopik>earthy: unfortunately, not ;(
12:49:01<kilimanjaro>|Steve|, haha yea, that sounds like something a professor would find cool. Take two classes that, on their own, most students would have trouble with, and blend them into one orgy of confusion
12:49:02<quicksilver>admittedly I didn't teach or take that course, but I spoke to people who did
12:49:18<earthy>hm.
12:49:30<earthy>the exif lib also suffers that fate.
12:49:31<scsibug>there should be a few example programs included with GD, if that is what you mean
12:49:46<quicksilver>kilimanjaro: I could see an argument for teaching haskell in your first term, then discrete math in your second. And using haskell for the discrete maths labs.
12:49:56<scsibug>nopik: http://scsibug.com/2007/04/21/mandelbrot-hs/
12:49:57<lambdabot>Title: scsibug.com » Fractal-hs
12:50:02<kilimanjaro>What's a math lab?
12:50:10<quicksilver>kilimanjaro: if you did that right then (a) the haskell would make the abstract stuff in discrete math seem more concrete
12:50:22<quicksilver>and (b) it would be an example of 'stuff you can do' with haskell
12:50:27<quicksilver>which might stop them forgetting it all :)
12:50:32<scsibug>http://www.scsibug.com/haskell-gd/examples/
12:50:33<lambdabot>Title: Index of /haskell-gd/examples
12:50:35<quicksilver>kilimanjaro: exercise classes or whatever secondary tuition there is
12:50:42<quicksilver>kilimanjaro: to back up the lectures
12:50:46<Philippa_>kilimanjaro: and no doubt in half the time...
12:50:56<|Steve|>I can't see any argument for using haskell to teach math.
12:51:03<kilimanjaro>I personally think Scheme is a better first language than Haskell, there are less things to think about
12:51:06<earthy>quicksilver: you mean much like http://homepages.cwi.nl/~jve/HR/
12:51:08<lambdabot>Title: The Haskell Road
12:51:13<mauke>I can
12:51:34<|Steve|>I could see teaching people to program in a functional language for their first language. I'd like to give that a shot like Berkeley or MIT do.
12:51:39<kilimanjaro>Like half of an intro to programming class is getting students to understand syntax
12:51:47<|Steve|>Right.
12:51:48<quicksilver>earthy: probably, yes
12:51:53<quicksilver>earthy: along those lines, at least
12:51:57<ddarius>kilimanjaro: I agree but not for that reason.
12:52:16<kilimanjaro>ddarius, for what reason then?
12:52:25<quicksilver>I think haskell is a better language than scheme for a first language, because I think type inference is very valuable pedagogically
12:52:26<matt__r>steve: http://journals.cambridge.org/action/displayAbstract;jsessionid=D9E3845B38ED3F5E88511B049D7314E3.tomcat1?fromPage=online&aid=192401
12:52:29<lambdabot>Title: CJO - Abstract - The risks and benefits of teaching purely functional programmin ..., http://tinyurl.com/33fnmo
12:52:47<ddarius>It has much more and better introductory material. Learning to deal with unbounded side-effects is also important.
12:52:48<quicksilver>having a good instinct for typing is really important in becoming a good programmer
12:52:59<mauke>one of our assignments was about deciding whether various symbolic statements were true or not
12:53:00<earthy>uhuh
12:53:00<kilimanjaro>If it's your first time programming, type inference is 100% magic and it will probably cause you strife
12:53:08<mauke>like ø \elem N
12:53:19<mauke>about 80% of them were "type errors" :-)
12:53:42<quicksilver>anyhow, speculating about teaching styles is terribly easy. Actually designing a good course and giving it is not ;(
12:53:46<Philippa_>type inference is magic anyway unless you've already met unification
12:54:15<ddarius>So teach Prolog as an introduction to Haskell.
12:54:15<quicksilver>to be clear, what i mean really is that strong typing is valuable pedagogically
12:54:23<HairyDude>http://hackage.haskell.org/trac/ghc/ticket/1539
12:54:24<MyCatSchemes>Philippa_: whut? How so?
12:54:25<lambdabot>Title: #1539 (Ord should not default to ()) - GHC - Trac
12:54:25<|Steve|>matt__r: Looks interesting, but I'm not paying $20 for it.
12:54:29<quicksilver>but type inference is a very helpful tool for coping with strong typing
12:54:47<|Steve|>But you can write the Z combinator in scheme!
12:54:51<matt__r>steve: there should be copies all over the joint and most unis will have access to the journal
12:54:55<Philippa_>MyCatSchemes: because unless you've already met at least an instance of unification, you're being handed something you've no idea how it works. You don't know how to follow the inference process
12:54:59<ddarius>Z, not Y.
12:55:07<|Steve|>matt__r: Okay, I'll grab it in my office tomorrow.
12:55:15<matt__r>I think it is about the only work on teaching functional programming to anyone, let alone first years
12:55:17<quicksilver>|Steve|: there's a preprint at http://www.cse.unsw.edu.au/~chak/papers/CK02a.html
12:55:17<lambdabot>Title: Research Papers of Manuel Chakravarty
12:55:30<kilimanjaro>The ones who want to learn will learn, the ones who don't care will end up writing Java code anyways
12:55:35<matt__r>dons: I don't suppose you were ever one of those first years were you?
12:55:36<MyCatSchemes>Philippa_: the basic idea would seem simple enough even without knowing Prolog. Students can quite happily imagine the compiler walking the parse tree of a piece of code and assigning tags to everything unlabelled.
12:55:48<Philippa_>MyCatSchemes: I didn't mention Prolog
12:56:03<|Steve|>matt__r: I'd be surprised if it were the only one. I've spoken to other people about this and they said that it's been studied before.
12:56:05<Philippa_>and "walking the parse tree" is definitely not a good concept for someone who's only just started programming
12:56:28<MyCatSchemes>Philippa_: oh, my bad. But still, anyway. Haskell's type inference was my first introduction to unification and I don't think I've ever had any problem with it, is all.
12:56:29<matt__r>|Steve|: yeah - I could be wrong.
12:56:50<|Steve|>quicksilver: Oh, thanks.
12:57:06<matt__r>|Steve|: I have been interested in it though - why did it click so well with me, but is such an uphill struggle with many otherwise wonderful computing students/practitioners?
12:57:19<quicksilver>googling for 'teaching functional programming' shows quite a lot of study og it
12:57:22<MyCatSchemes>Philippa_: true, but it's just chasing pointers recursively. That should be, like, practically instinctive by the time you're halfway through a CS introductory unit.
12:57:31<matt__r>|Steve|: I think the bottom line is the person teaching you :)
12:57:53<matt__r>|Steve|: I was rather lucky in that regard
12:57:58<|Steve|>matt__r: Could be. But I've learned every language I know (except for Java I suppose...) on my own.
12:58:15<MyCatSchemes>matt__r: your theory breaks down when applied to autodictats. ;)
12:58:29<Philippa_>MyCatSchemes: Hahahaha. No.
12:58:37<|Steve|>I was introduced to scheme and haskell during my ugrad PL class, but what I know now, I know from my own study of the language.
12:58:46<quicksilver>|Steve|: that unfortunately disqualifies you as a useful example, I fear :)
12:58:55<Philippa_>I mean yeah, it should in a magic world where everyone clicks with the concepts first time and doesn't need any time to internalise...
12:58:59<Syzygy->quicksilver: Example of what, exactly?
12:59:08<quicksilver>|Steve|: you're in the "would have learnt it anyway" category
12:59:13<matt__r>MyCatSchemes: then you are your own teacher - or the text writer is your teacher
12:59:19<|Steve|>Oh, I lied. I learned MIPS entirely in school.
12:59:21<MyCatSchemes>Philippa_: ah, I see what you mean there.
12:59:33<ddarius>Perhaps I'm a good teacher for myself...
12:59:34<|Steve|>(But I don't think assembly counts since I don't program in it, ever.)
12:59:40<quicksilver>Syzygy-: example of what programming languages are good or bad as first languages.
12:59:43<kilimanjaro>I figure your education is too important to be left entirely in the hands of others
12:59:44<Syzygy->Ah.
12:59:44<MyCatSchemes>matt__r: hence the need for damn good text books. (Three, nay, four cheers for Sussman.)
12:59:49<Syzygy->I started with GWBasic - does that count?
13:00:07<MyCatSchemes>kilimanjaro: that's an interesting way of putting it. :)
13:00:11<Syzygy->I also started with 11, so I may be an exception as well.
13:00:23<Philippa_>I learned Java in a few hours when it was going to be the first module at UoN
13:00:26<ddarius>Philippa_: Pictures!
13:00:26<wli>I started with C.
13:00:27<MyCatSchemes>Syzygy-: BASIC does teach a few useful things.
13:00:33<matt__r>MyCatSchemes: I am with you on that one
13:00:44<ddarius>MyCatSchemes: Like what spaghetti code looks like.
13:00:53<Philippa_>ddarius: *cough*
13:00:55<|Steve|>Philippa_: Java was my fourth language and after C, C++, and Objective-C, it was pretty easy to pick up.
13:00:56<matt__r>I started with Pascal :)
13:01:01<MyCatSchemes>Syzygy-: like, when you start using C later, it'll let you realise *immediately* how painful memory management by hand is, instead of a few years down the line when you later start trying better programming languages.
13:01:17<Philippa_>yeah, I already knew C and was making my way through C++
13:01:33<quicksilver>Syzygy-: yes, you're an exception too. I imagine most people in the channel are, really
13:01:37<kilimanjaro>The nice thing about BASIC is that you don't have to do things the right way, you just get started and through trial and error you can do fun stuff (that's where I got my start as a kid)
13:01:38<MyCatSchemes>|Steve|: I'm curious as to whether you've ever tried Smalltalk?
13:01:42<quicksilver>Syzygy-: the question was about 'typical' first year undergrads
13:01:44<|Steve|>You know, everyone bitches about memory management in C, but it's really not that hard. And in C++, it's even easier.
13:01:50<wli>I didn't find the language to be particularly interesting. I wrote programs to do parallel Runge-Kutta diffeq solving my first week in college.
13:01:57<ddarius>MyCatSchemes: I started on QBASIC and went to a Cish C++ and eventually C++.
13:01:57<|Steve|>MyCatSchemes: You know, I never have. I know it was a precursor to objective-c.
13:02:13<quicksilver>Syzygy-: I.e. you've done no programming before, you turn up at university. What do they teach you in your firs tterm?
13:02:28<MyCatSchemes>|Steve|: it's not impossible, no, but it's still work that isn't actually neccessary for you to tackle by hand outside of a few well defined domains.
13:02:29<quicksilver>|Steve|: I think that just says something about the kinds of programs you have written in C and C++
13:02:36<Philippa_>of course, I'm talking about Java back in 2000, and minimal library knowledge (I kept bashing out singly-linked list classes in exams too, although at least one was for a module where we were using Java only because not enough people knew C)
13:02:52<quicksilver>|Steve|: memory management is a real pain for a large class of problems.
13:02:54<Syzygy->quicksilver: Have you ever seen a typical first year undergrad?
13:02:56<Syzygy->o.O
13:03:01<quicksilver>Syzygy-: yes, a very large number of them.
13:03:08<Philippa_>Smalltalk is well worth some exposure to
13:03:08<quicksilver>Syzygy-: I've both been one, and taught some :)
13:03:14<MyCatSchemes>ddarius: spaghetti code... if you want to see spaghetti code, you need to start looking at peoples' PIC programs. ;)
13:03:16<Syzygy->Oh dear. ;)
13:03:16<quicksilver>Syzygy-: I even married one...
13:03:34<|Steve|>quicksilver: I've worked as a programmer on an arcade game in C++.
13:03:36<ddarius>quicksilver: A "typical" one?
13:03:39<quicksilver>|Steve|: *ALL* commercially deployed C and C++ programs contain memory leaks.
13:03:40<MyCatSchemes>Then I guess you've probably seen more of them that most. ;_
13:03:47<|Steve|>It's not like I've been confined to small programs.
13:03:48<MyCatSchemes>;)
13:03:49<quicksilver>|Steve|: now tell me memory management is easy :)
13:04:07<quicksilver>ddarius: no, I suppose she wasn't very typical ;)
13:04:23<|Steve|>You have memory leaks in Java too. I suspect you get them in Haskell as well.
13:04:28<quicksilver>of course
13:04:37<ddarius>Even computers find it hard.
13:04:38<MyCatSchemes>|Steve|: except that we call 'em "space leaks" instead. ;)
13:04:38<quicksilver>for different kinds of reasons, though :)
13:04:45<Nopik>scsibug: thanks
13:04:47<matt__r>|Steve|: damn right you can (in Haskell and they are probably more insidious that in C++
13:04:59<|Steve|>Fine, relabel it all you want.
13:05:10<matt__r>perhaps I can ask the wisdom of the list
13:05:12<MyCatSchemes>And yes, but references that're being held on to unneccessarily can be tracked down more easily than memory that's not referred to but still left un-freed.
13:05:14<wli>quicksilver: They also contain buffer overflow exploits, NULL and wild pointer dereferences, and more.
13:05:22<|Steve|>When my c++ program is leaking, I run leaks on it and track'em down.
13:05:26<ddarius>Actually in the nexus of a Haskell program space itself starts growing.
13:05:34<Philippa_>you can get memory leaks in any GCed language if you're careless about references. Haskell has a further bunch of problems due to laziness though - it's not as well understood how to handle that
13:05:59<matt__r>are haskellers ignoring the "space leak" elephant in the room when we evangelise our language.
13:05:59<matt__r>?
13:06:06<|Steve|>I don't think it matters, you're not really getting the word out about haskell.
13:06:14<wli>You have to program in something without dynamic memory allocation for the space problem to be solvable.
13:06:21<|Steve|>Every time I say I've written something in haskell, or I like haskell, people think I'm saying pascal.
13:06:37<kilimanjaro>Haha
13:06:41<Philippa_>if haskell suddenly gained perl-level "success" we'd rapidly lose what makes the community (and to a large extent the language) worthwhile under a flood of crap libs though
13:06:48<ddarius>matt__r: Programming in a lazy language is more different than programming in an eager language than most people are aware of.
13:06:50<wli>Fortran comes to mind.
13:07:02<|Steve|>Philippa_: That's an...interesting POV.
13:07:09<quicksilver>wli: yeah, they're probably more important
13:07:19<MyCatSchemes>matt__r: no, 'cuz a) the Java crowd have it too and b) space leaks are rather less nasty to track down.
13:07:23<matt__r>ddarius: agreed
13:07:25<Philippa_>|Steve|: it's not commonly stated as directly, but there's a reason "avoid success at all costs" became a catchphrase
13:07:30<|Steve|>I kind of liked programming in ocaml. I only did a tiny bit for my grad pl class.
13:07:41<Philippa_>haskell is what it is partly because we're all picky
13:07:43<|Steve|>Funny, I've never heard that catchphrase...
13:07:51<MyCatSchemes>It's a good one, though.
13:07:53<|Steve|>And I can't wait for Haskell'.
13:07:54<kilimanjaro>|Steve|, sure, just don't tell anyone in #haskell that you like... ohh wait
13:07:59<Philippa_>sure. How long have you been around here?
13:08:03<matt__r>MyCatSchemes: how does the java version manifest itself?
13:08:17<|Steve|>Philippa_: Me?
13:08:20<ddarius>@google "Haskell retrospective"
13:08:22<wli>I'm not remotely interested in language evangelism. Haskell is merely useful to me.
13:08:22<lambdabot>http://research.microsoft.com/~simonpj/papers/haskell-retrospective/index.htm
13:08:22<lambdabot>Title: Wearing the hair shirt: a retrospective on Haskell
13:08:22<Philippa_>(it comes from a retrospective written by Simon Peyton-Jones, btw)
13:08:33<ddarius>|Steve|: Read that, it's entertaining.
13:08:39<MyCatSchemes>matt__r: exactly the same way. Data structures containing references to other data structures and people forgetting to clean up references to them.
13:08:43<|Steve|>ddarius: Will do.
13:09:16<MyCatSchemes>matt__r: apparently a common one is hash tables used for memoization whose references are kept in scope for the whole length of the program when they're only actually used for part of it.
13:09:26<|Steve|>Alas, it's 6 am and I need some sleep. This is by far the best programming language channel I've even been in, so I can't argue with the community aspect.
13:09:40<Philippa_>|Steve|: there isn't a perl-sized user base currently that's picky enough about correctness, good factoring and type-safety. So if we suddenly gained that many users, the haskell community would undergo a radical shift in values
13:10:01<matt__r>MyCatSchemes: aha
13:10:05<|Steve|>I like perl. It's fun.
13:10:11<MyCatSchemes>|Steve|: I concur. Only channels I've tried that hold a candle to this are #scheme and, uh, possibly #nethack.
13:10:31<|Steve|>I haven't tried #scheme. ##c and ##c++ were terrible for the week I spent in them.
13:10:40<quicksilver>Philippa_: which makes me worry, sometimes, about how easy it is to write type-unsafe and/or semantic destroying GHC libraries
13:10:41<MyCatSchemes>|Steve|: though the latter will occasionally merrily tell me to eat Medusa's corpse in order to point and laugh at my YASD message.
13:10:41<ddarius>I've never been to #scheme, thought about it now and again.
13:10:48<quicksilver>Philippa_: using unsafeFOO or RULES
13:11:02<quicksilver>MyCatSchemes: that's part of the charm, though
13:11:05<MyCatSchemes>ddarius: I just tried it once offhand to see what it was like. I got the impression it was pretty similar to here.
13:11:12<Philippa_>quicksilver: yup, and that you won't get /any/ warning that they're being used. A warning flag for 'em would be nice
13:11:36<ddarius>Philippa_: We could easily make "safe" modules and such.
13:11:40<MyCatSchemes>quicksilver: oh yes, of the game, too. It wouldn't be NetHack if my characters ever survived for more than five consecutive minutes.
13:12:47<MyCatSchemes>matt__r: but of course, the thing about space leaks is... those unneccessary references are still hanging around. You can run a debugger over and manually audit all the references in your program, if neccessary. ;)
13:13:13<quicksilver>we may trust dons and dcoutts to write such dangerous code (do we?) but can we trust Random.Hackage.uploader?
13:13:53<|Steve|>Wait, there's a Haskell debugger?
13:13:56<ddarius>quicksilver: No we don't (re dons and dcoutts). We bash their libraries and see what bugs pop out.
13:14:01<matt__r>quicksilver: you always have to trust your lib writer
13:14:10<fasta>|Steve|: there is a broken debugger in 6.7
13:14:11<Philippa_>matt__r: no, no you don't
13:14:12<ddarius>|Steve|: For several values of "debugger", there're many.
13:14:21<wli>page 54, type classes as logic programs
13:14:27<fasta>ddarius: many? Name 2
13:14:44<quicksilver>matt__r: in an ideal world you wouldn't, no
13:14:45<|Steve|>And you can't even add print statements. I've never figured out how to debug a haskell program.
13:14:45<ddarius>Buddha, Freya, Hat, HOOD, the GHCi debugger
13:14:57<|Steve|>basically, I just assume that if I can sneak it past the type system, I'm right.
13:14:57<matt__r>Philippa_: so what are the practical techniques for using safe but untrustworty code
13:14:57<quicksilver>|Steve|: by using the REPL
13:15:11<quicksilver>|Steve|: and trying out your component functions one by one
13:15:12<|Steve|>REPL = read eval print loop?
13:15:15<matt__r>ddaruis: is hat working on the latest GHC?
13:15:16<quicksilver>|Steve|: understading hte errors
13:15:17<quicksilver>yeah
13:15:20<fasta>ddarius: ok, two that work for Haskell + all common libraries
13:15:20<Philippa_>matt__r: sufficiently strong typing, sandboxing
13:15:30<quicksilver>I don't find "imperative-style" debuggers a good match fo haskell debugging problems
13:15:35<|Steve|>One cannot always write such modules.
13:15:37<ddarius>matt__r: I don't think Hat ever worked for GHC. It was an NHC thing.
13:15:38<quicksilver>I much rather derive Show instances for my data types
13:15:44<quicksilver>Hat does work for GHC
13:15:52<matt__r>Philippa_: yeah - but you need to bypass the safe typing for just about any working program
13:15:53<quicksilver>malcolmw demonstrated it recently to me
13:15:53<fasta>ddarius: Hat did work at some point
13:15:58<quicksilver>I've not used that
13:16:08<Philippa_>matt__r: no, no you don't
13:16:08<wli>Nice, talking about ML functors vs. Haskell modules, too.
13:16:09<malcolmw>there's an SoC project to rehabilitate Hat with modern ghc + libraries + etc
13:16:11<ddarius>fasta: I was out of the community for a good while.
13:16:11<quicksilver>matt__r: I've written many haskell programs and not once bypassed any of the safety
13:16:12<matt__r>Philippa_: unless you rewrite all hte c librarries we rely on
13:16:15<fasta>ddarius: severly limited to H98, though.
13:16:26<wli>Philippa: This retrospective is awesome. It talks about a bunch of things I think about all the time.
13:16:40<quicksilver>matt__r: well that last is a fair point
13:16:43<Philippa_>that depends how you define "trust". You can ensure that the C libraries are the source of any untrustworthiness, for example
13:16:48<quicksilver>matt__r: but as long as the C libraries don't actually segfault
13:16:51<|Steve|>Okay, I said I was going to sleep and this time I mean it. Goodnight. (I'll read those papers/links when I wake up.)
13:16:55<quicksilver>matt__r: they don't upset the semantics of the haskell code
13:16:57<malcolmw>fasta: Hat is not limited to haskell'98
13:17:08<quicksilver>(unless someone made a pure binding for a function which isn't really pure)
13:17:09<Philippa_>quicksilver: strictly speaking, even if they do so long as they're in the IO monad
13:17:16<matt__r>just think how to write a safe HDBC, or readline or networking, etc
13:17:17<fasta>malcolmw: or it didn't include all libraries?
13:17:17<quicksilver>but that's the binding author's fault not the libraries
13:17:27<quicksilver>Philippa_: good point
13:17:35<fasta>malcolmw: or I am confusing two tools
13:17:43<malcolmw>fasta: yup, the hierarchical libraries all arrived after the Hat implementation was finished
13:17:46<matt__r>when you are part of a larger stack and you don't know how the code is working, you have to "trust" the library writer
13:17:53<ddarius>Auf wiedersehen.
13:18:04<Philippa_>matt__r: yes. That's a notably weaker statement than your original one though
13:18:28<quicksilver>matt__r: in a strongly typed system, you can be precise about how much trust that is
13:18:28<Philippa_>"you have to trust the substrate system" just isn't the same as "you have to trust libs in your own language"
13:18:41<quicksilver>certainly you have to trust him to write code which terminates
13:18:49<quicksilver>but often it's not much more than that
13:18:56<Philippa_>actually, that can be eliminated with the right type system too
13:19:01<quicksilver>ACTION nods
13:19:23<matt__r>Philippa_: well yeah - so we need to have unsafeperformIO propagate up from where it is used
13:19:39<matt__r>then we can always know when code calls out to something unsafe
13:19:58<Philippa_>matt__r: funny, that's already been proposed in here today
13:20:26<matt__r>Philippa_: I just means losing one or two functions that go IO a -> a right?
13:21:01<Philippa_>it just means knowing when they're called. Whether you then trust them's up to you
13:21:25<Philippa_>I can certainly build useful systems that don't need unsafePerformIO, YMMV
13:22:42<tanuk>Hello, I'm having problems. Stdin seems to be buffered even though I set it to NoBuffering in the start of the program.
13:22:43<matt__r>Philippa_: I am with you on that, but I find myself constantly using code (libs) that does use unsafePerformIO
13:23:13<matt__r>tanuk: hpaste your code
13:23:39<Philippa_>sure. There're some classic uses that can be avoided with a more powerful language though...
13:24:00<wli>Philippa: Which uses and what sort of power?
13:24:16<hpaste> (anonymous) pasted "(no title)" at http://hpaste.org/1712
13:24:37<tanuk>Uh, I should have given my nick to that...
13:24:39<Philippa_>wli: faking global mutable variables is one that comes to mind - a more powerful module system can handle it
13:25:04<hkBst>does the Haskell code in http://blogs.nubgames.com/code/?p=15 get displayed correctly for anyone? Both in konqueror and firefox it is too wide for the box it is in and not displayed fully.
13:25:06<lambdabot>Title: Nub Games » Haskell &#8212; First Impressions
13:25:23<Philippa_>a number of other uses involve mutability too, and could be dealt with via linear types. Yet more could be dealt with if we took a different approach to monadic programming...
13:25:26<tanuk>The program removes parts from the input that comes in stdin and prints it to stdout.
13:26:14<nopcode>how do remove duplicate elements from a list?
13:26:17<fasta>hkBst: drop the italics
13:26:29<opqdonut>nopcode: nub
13:26:52<hkBst>fasta: how can I do that?
13:26:56<nopcode>is that an insult or the name of a function? ;P
13:27:07<fasta>hkBst: is it your webpage?
13:27:09<opqdonut>> nub . take 1000 $ cycle [1,2,3]
13:27:09<tanuk>Every line is examined and if it fulfills the requirement (contains "System exclusive") a part of it is printed. Otherwise it is ignored.
13:27:11<lambdabot> [1,2,3]
13:27:12<hkBst>fasta: no
13:27:26<opqdonut>nopcode: name of the function as you can see :)
13:27:31<fasta>hkBst: oh, it is displayed here fully
13:27:43<fasta>hkBst: the italics are very ugly however(Firefox)
13:27:46<Lemmih>hkBst: It looks fine to me.
13:27:48<fasta>hkBst: Iceweasel*
13:27:57<matt__r>tanuk: sorry - it must be too late for me, I can't get my head around it well enough to give you useful advice.
13:28:12<nopcode>opqdonut: ok thx *G*
13:28:33<hkBst>fasta: histories = takeWhile ((> 0) . length) . unfoldr history . li <rest cutoff>
13:28:41<tanuk>matt__r: Thanks for trying anyway.
13:28:48<hkBst>Lemmih: what browser?
13:28:51<tuukkah>tanuk, did you try with a simple cat?
13:28:55<Lemmih>hkBst: Firefox.
13:29:04<fasta>hkBst: I see lines are last word
13:29:05<matt__r>tanuk: hFlush might helo :0
13:29:08<matt__r>:)
13:29:11<fasta>hkBst: as*
13:29:41<tanuk>matt__r: I tried to insert hFlush after every putStrLn, but it didn't help.
13:30:12<tanuk>tuukkah: What do you mean.
13:30:14<tanuk>?
13:30:18<hkBst>fasta: it only gets worse as I increase font size and I seem to be at the minimum :(
13:30:47<quicksilver>tanuk: what OK, and which makes you think the turning off the buffering isn't working?
13:30:49<fasta>hkBst: use no page style or complain to author
13:30:51<tuukkah>tanuk, you can try to make the program as simple as possible and see whether it still has the problem
13:31:08<quicksilver>tanuk: don't you want to turn buffering off on stdout
13:31:14<hkBst>fasta: I would if I could find his email...
13:32:07<tanuk>quicksilver: Yes I want... Thanks for pointing out.
13:32:08<tuukkah>tanuk, besides, please don't make Ctrl-C not exit the program :-)
13:32:15<fasta>hkBst: leave a comment in his commenting system
13:32:43<tuukkah>Ctrl-D doesn't work either but that's a problem in ghc i suppose
13:33:25<tanuk>tuukkah: It still exits, without the handler the buffered part would be discarded, this way at least on exit everything gets written.
13:34:03<tuukkah>doesn't exit here using runghc version 6.6
13:35:48<Lemmih>tanuk: It seems to do exactly what it's supposed to.
13:36:29<Lemmih>Entering " System exclusive This is a test" gives "This is a test".
13:37:05<bringert>dcoutts: you here?
13:38:02<liber>what exactly do I get if I use "return True" in an application? It isnt a Bool, at least
13:38:09<liber>I get a type error
13:38:25<tuukkah>@ type return True
13:38:27<tanuk>Lemmih: Yeah, it seems to print it fine when getting input from keyboard...
13:38:29<tuukkah>@type return True
13:38:38<lambdabot>forall (m :: * -> *). (Monad m) => m Bool
13:38:39<liber>return True :: (Monad m) => m Bool
13:39:02<liber>Is there a way to typeset that?
13:39:20<tuukkah>you get a Bool in a monad
13:39:38<liber>And I have not gotten to the chapter about Monads yet :)
13:39:47<mauke>liber: then why are you using return?
13:40:04<Igloo>tanuk: What's the problem?
13:40:05<quicksilver>liber: think of it just as a 'structure'
13:40:10<quicksilver>liber: in quite an abstract sense
13:40:19<quicksilver>liber: "return True" returns true embedded in some kind of structure
13:40:20<Lemmih>tanuk: Piping the text with 'echo' gives exactly the same response.
13:40:39<EvilTerran>> (return :: a -> Maybe a) True
13:40:40<lambdabot> Just True
13:40:46<EvilTerran>> (return :: a -> [a]) True
13:40:47<lambdabot> [True]
13:40:59<Lemmih>tanuk: Same with piping it from a file.
13:41:13<liber>mauke: because I want to return a bool from a function
13:41:18<tanuk>Lemmih: The program that the data runs continuously, so EOF doesn't come before ctrl-c.
13:41:21<mauke>liber: that has nothing to do with 'return'
13:41:24<opqdonut>?src (\\)
13:41:25<lambdabot>(\\) = foldl (flip delete)
13:41:37<tanuk>"the data runs" -> "the data comes from runs"
13:41:40<EvilTerran>liber, ah. you've got completely the wrong end of the stick, i'm afraid.
13:41:41<mauke>liber: think of return x as new Monad(x)
13:41:51<liber>alright
13:41:53<vincenz>mauke++ for proper color usage
13:41:56<mauke>i.e. a constructor call
13:42:02<scook0>liber: to return a value, just write the value ... 'return' is used for something different in Haskell
13:42:14<liber>I havent gotten to that part of the tutorial yet. Just experimenting a bit on my own :
13:42:15<liber>)
13:42:25<quicksilver>liber: just thiis, is all it takes:
13:42:25<dozer>how do I do this: data Baz (bar foo) foo = ...
13:42:28<quicksilver>my_fun = True
13:42:36<quicksilver>liber: no special keyword for return, in that sense
13:42:47<SamB_XP>dozer: you can't do *that*
13:42:48<dozer>I want Baz parameterised over two types, but the first type must be itself parameterised over the seccond type
13:42:49<EvilTerran>liber, think of the body of a function as an expression, rather than a code block
13:43:03<dozer>SamB_XP: can I get close?
13:43:08<liber>quicksilver: but if I have alot more things, like in a "do"-"block"
13:43:13<ski>dozer : maybe 'data Baz bar foo = ...' is what you want ?
13:43:21<SamB_XP>you could do data Baz bar foo = ...
13:43:22<liber>Do i stull just end the "block" with "True"
13:43:24<liber>?
13:43:32<SamB_XP>and, in ..., write (bar foo)
13:43:33<tuukkah>or "data (Baz (Bar foo)) = ..."
13:43:41<EvilTerran>"foo x = <expression involving x>" means "whenever you see 'foo <something>', replace that with <expression involving x> except with <something> in place of x"
13:43:44<edwardk>hrmm. so if i have * as multiplication, .* as left scalar multiplication, *. as right scalar multiplication with generalized signatures a -> a -> a, a -> b -> b and b -> a -> b, respectively does having .*. with a -> b -> c | a b -> c seem too specific? with the idea being that the . tells you where type inference will break over the general signature.
13:43:46<tanuk>Lemmih: Do you think if it is possible that the input program checks if the output goes to a terminal, and in that case uses less buffering?
13:43:58<scook0>liber: if you aren't up to monads, you probably shouldn't be using do
13:44:01<ski>liber : if you're in a do-block, then if you just want to return a value at the end, you use 'return'
13:44:03<quicksilver>liber: you need to be a bit more precise about 'other things'
13:44:10<dozer>ah, so in each place I currently use bar in the declaration, actually write (bar foo) instead
13:44:12<quicksilver>liber: you don't want to use 'do' unless you're using monads
13:44:18<MyCatSchemes>scook0: hhgh?
13:44:31<liber>quicksilver: aigtt :) Ill just keep reading the tutorial. Thx guys
13:44:31<dozer>like: data Baz bar foo = BZ (bar foo) foo
13:44:37<EvilTerran>liber, what i just said there is a good way of thinking about things, even tho it's not quite a perfect description of how it really works ;]
13:44:42<scook0>MyCatSchemes: unless you're cargo-culting monadic IO or something
13:44:49<quicksilver>liber: and, from what you're saying, you don't waht to use monads :)
13:45:00<quicksilver>SamB_XP: that' won't work
13:45:00<liber>:D
13:45:00<MyCatSchemes>scook0: jah, precisely. ^^
13:45:08<SamB_XP>edwardk: that does seem a bit more specifc than needed...
13:45:10<quicksilver>SamB_XP: data types can't have higher-kinded fields
13:45:15<quicksilver>SamB_XP: 'bar' is a type constructor
13:45:21<quicksilver>SamB_XP: if I'm following dozer corectly
13:45:27<SamB_XP>quicksilver: what the heck are you talking about?
13:45:34<SamB_XP>@src StateT
13:45:34<lambdabot>Source not found. Sorry about this, I know it's a bit silly.
13:45:37<SamB_XP>arg.
13:45:43<quicksilver>data Bar (bar foo) foo
13:45:48<quicksilver>bar is a type constructor, I presume
13:45:52<quicksilver>erm
13:45:55<SamB_XP>quasisane: so?
13:45:56<SamB_XP>er.
13:45:56<dozer>quicksilver: yes it is
13:45:57<quicksilver>data Baz (bar foo) foo
13:46:00<SamB_XP>quicksilver: so?
13:46:07<quicksilver>well you can't say 'data Baz bar foo' then
13:46:12<quicksilver>because then bar is a type constructor
13:46:15<SamB_XP>yeah you can...
13:46:29<quicksilver>you can't have higher kinded fields...
13:46:41<SamB_XP>haven't you heard of kinds like (* -> *) -> * -> * before?
13:46:51<edwardk>samb: well, the .* for scalar multiplication gives you things like multiplication by the naturals for peasant multiplication over any semigroup. .*. gives a limited form of type inference to the result, and lets you use that same type to witness type level multiplication
13:46:54<quicksilver>oh hang on
13:47:00<quicksilver>on the left of the = not the right of the =?
13:47:18<edwardk>samb: then typeints, could offer up witnesses in the form (.+.) (.*.), etc.
13:47:18<quicksilver>I thought we were on the right of =
13:47:19<quicksilver>sorry :)
13:47:35<SamB_XP>quicksilver: oh ;-)
13:47:44<sieni>'
13:48:13<SamB_XP>quicksilver: it's very true that you can't have data of types whose kinds have arrows in them ;-)
13:49:11<SamB_XP>edwardk: well, will it hurt anything for you to add it?
13:49:16<edwardk>samb: though in the case of (.+.) i'd really like to make the inference tridirectional a b -> c, a c -> b, b c -> a, but perhaps thats a bit overzealous, or rather maybe thats best used as the type for (+) with most instances setting them to the same
13:50:08<edwardk>(+) : a -> b -> c | a b -> c, b c -> a, a c -> b (.*) : a -> b -> b (*.) : b -> a -> a (.*.) : a -> b -> c | a b -> c
13:50:23<edwardk>er (*)
13:50:48<SamB_XP>edwardk: hmm, I'm a bit curious. do you use a dictionary-passing or a typecase implementation?
13:51:11<edwardk>then we have the case where type inference always works, probably fails on the left, probably fails on the right, and where it probably fails on both arguments.
13:51:33<edwardk>ironically a bit of both, i have the worst case issues of each =)
13:52:03<edwardk>typecase determines which dictionary to pass around in the event the dictionary wasn't explicitly passed
13:52:05<SamB_XP>what, it's as slow as dictionary passing but has the whole-program-compilation of typecases?
13:52:25<edwardk>and i'm already whole program compiling anyways
13:52:25<tanuk>tuukkah: You asked to try with plain cat, I think I now understood that. I replaced my program with cat and that too doesn't print everything immediately. Is there anything that can be done, or is this completely the source program writer's fault?
13:52:44<SamB_XP>do you do existentials?
13:53:00<edwardk>not yet, they are on the 'would-be-cool' feature list
13:53:13<SamB_XP>hmm. I guess my next question is inapplicable then ;-)
13:53:26<edwardk>i had a version back when it was a simple PTS
13:53:31<quicksilver>SamB_XP: sensible dictionary passing manages to optimise out the dictionary in most cases, though
13:53:33<edwardk>but they got dropped when things got more complicated
13:53:41<quicksilver>SamB_XP: so practical dictionary passing isn't that slow, is it?
13:54:03<SamB_XP>quicksilver: you'd be surprised
13:54:30<quicksilver>SamB_XP: what makes it slow, then?
13:54:34<SamB_XP>sure, when you use >>= and >> and return at statically known types
13:54:37<SamB_XP>that's fine
13:55:15<SamB_XP>quicksilver: as far as I know, GHC doesn't know that there is only one dictionary for each type
13:55:25<quicksilver>I believe it does
13:55:29<SamB_XP>(for a given dictionary constructor)
13:55:45<edwardk>ok, i'll go with the 4 signatures above i think and see if i can use them uniformly used across all binary operators in the prelude (modulo the ==, &&, etc) ones that go a -> a -> b,
13:56:11<SamB_XP>I mean, afaik, it doesn't optimize Core based on that assumption
13:56:21<fasta>A 140 line function, what will the fanboys say to that!
13:56:24<quicksilver>well most methods are inlineable
13:56:38<quicksilver>which means the optimiser can remove the case on the dictionary
13:56:39<ski>fasta : fie on you :)
13:56:41<edwardk>and in my case i can have a lot of dictionaries for a given type =/
13:57:09<edwardk>since you can pass them by name
13:57:11<SamB_XP>quicksilver: if it knows which dictionary to use, sure
13:57:20<dozer>ok - what about if I wanted to instead say something like: data Baz foo bar | foo -> bar = ...
13:57:43<quicksilver>that's what associated types are for, I believe?
13:58:11<SamB_XP>dozer: hmm.
13:58:15<fasta>I find the associated types less natural to read than fundeps
13:58:36<quicksilver>fasta: this isn't a class, thouh
13:58:43<quicksilver>fasta: it's a data declaration
13:58:50<SamB_XP>dozer: data BazClass foo bar => Baz foo bar = ... ?
13:59:36<quicksilver>SamB_XP: I think you may be underestimating the dictionary passing approach, in the presence of a good optimiser
13:59:47<SamB_XP>fasta: associated type synonyms are nice when you truly just want an associated type...
13:59:47<quicksilver>SamB_XP: have a look at the core generated by -O2
13:59:48<fasta>quicksilver: oh, I wasn't paying attention and I guess I wanted to say that regardless of it ;)
14:00:23<SamB_XP>fasta: especially if you have already written some code using a class before you added one
14:00:57<SamB_XP>quicksilver: have they recently improved it?
14:01:51<hpaste> tuukkah annotated "(no title)" with "Still buffered..." at http://hpaste.org/1712#a1
14:02:21<tuukkah>tanuk, could be a problem with getLine
14:03:12<tuukkah>tanuk, if i change that paste to use getChar and putChar, it isn't line-buffered anymore
14:03:37<MyCatSchemes>Philippa: eh, I thought the underscore kinda suited you. ;)
14:03:39<SamB>quicksilver: does it now realize that the Fractional a field in a RealFrac a has the same value as the one in a Floating a?
14:04:03<shapr>Good morning #haskell!
14:04:17<SamB>what does 39 do?
14:04:17<blackdog_>shapr: only by seven minutes
14:04:24<tuukkah>shapr, good evening shapr :-)
14:04:39<shapr>heippa hei tuukkah
14:04:40<tanuk>tuukkah: Maybe I'll try with getChar. It's just that line buffering would be good enough, but the input seems to be buffered more than that.
14:04:42<shapr>g'day blackdog_
14:04:48<Igloo>tanuk: getLine doesn't return anything until it finds a newline
14:05:04<SamB>quicksilver: well? does it?
14:05:08<MyCatSchemes>shapr: cannot construct contradictory type (EarlyInDay, Doesn'tSuck) at line 1, arising from expression "good morning"
14:05:26<blackdog_>shapr: am writing stupid postgres db code. the filthy, disgusting things i do for money... tell me you're doing something more interesting
14:05:31<quicksilver>SamB: I don't know. I thought it did.
14:05:46<tanuk>Igloo: Sorry for giving code that doesn't accurately tell my intentions. I tried with NoBuffering after LineBuffering didn't work (it should work).
14:06:06<Igloo>tanuk: What should work?
14:06:11<tanuk>Line buffering.
14:06:31<shapr>MyCatSchemes: Try going to sleep earlier ;-)
14:06:33<Philippa>SamB: 39 is basically full ophood
14:06:43<Igloo>ACTION can't work out exactly what program doesn't do what
14:06:47<shapr>blackdog_: Yeah, about to do some HAppS hacking.
14:06:47<tuukkah>tanuk, so can you see the line buffering not working with the simpler program i pasted?
14:06:52<MyCatSchemes>shapr: I do go to sleep early. Early in the morning.
14:07:02<shapr>heh
14:07:17<tanuk>tuukkah: I missed your paste, I'll look it up, one moment.
14:07:47<SamB>wow, standard Haskell has so few types...
14:08:30<ski>SamB : countably infinite isn't enough for you ?
14:08:43<SamB>ski: I meant in the library
14:08:59<SamB>or at least so few class instances for those types
14:09:09<mauke>there's [()], [[()]], [[[()]]], ...
14:09:24<SamB>type constructors, if you will...
14:09:25<ski>mayhaps you mean s/type/type constructor/ ?
14:09:28<ski>(:
14:11:26<tanuk>tuukkah: That's block buffered too.
14:12:03<tuukkah>tanuk, and did you try with both getLine and getChar?
14:12:29<tanuk>tuukkah: No... I'll try.
14:12:33<blackdog_>aurynn: you wouldn't stripe the data?
14:12:46<blackdog_>oops, sorry
14:14:29<tanuk>tuukkah: Output comes still in blocks when piping aseqdump's output to Test. Typing the input from keyboard works.
14:14:52<quicksilver>tanuk: oh, well that's the output sides fault then
14:15:18<quicksilver>tanuk: if aseqdump is block buffering then there is nothing you can do at your end
14:16:48<tanuk>quicksilver: If I don't pipe aseqdump's output, so that it is printed in the terminal, output comes immediately.
14:16:59<quicksilver>again, that's aseqdump's fault
14:17:11<quicksilver>programs which use the stdio C bindings
14:17:19<quicksilver>will exhibit line buffering if stdout is a TTY
14:17:34<quicksilver>but block buffering otherwise
14:17:46<quicksilver>(unless they explicitly choose a different buffering style)
14:17:47<tanuk>quicksilver: Ok, the cause is now clear, thank you.
14:18:33<quicksilver>this is, essentially, an optimisation
14:18:40<quicksilver>it's notably confusing until you understand it though :)
14:18:50<tanuk>quicksilver: Can this be altered externally, or do I have to modify aseqdump's source?
14:18:58<SamB>it can be really annoying at times
14:19:13<quicksilver>if you're really lucky, aseqdump has an option to control it
14:19:22<tanuk>I'm not lucky.
14:19:40<SamB>I wish GHC's RTS would flush it's output buffers at the end of a heap sample...
14:19:57<quicksilver>you could foold aseqdump into thinking it's talking to a tty
14:20:11<quicksilver>by using ioctls possibly?
14:20:15<tuukkah>tanuk, there are gdb scripts for changing the stdout of a running program. you can probably make one that changes the buffering mode too
14:20:17<zbrown>Has anyone had trouble with ghci on Debian etch? Its telling me ghci wasn't built with interactive use?
14:20:23<SamB>quicksilver: or actually hook it up to a TTY
14:20:29<quicksilver>SamB: yes, or that :)
14:20:41<SamB>I don't know if ioctls would work or not
14:20:52<SamB>I don't know much about them
14:21:38<tanuk>With open source there is always the patching way, which seems to be the easiest way this time.
14:22:17<Igloo>zbrown: ghci isn't enabled for arches other than x86 and amd64
14:22:34<benny99>|Steve|: hey, just found this one here http://en.wikibooks.org/wiki/Haskell/Understanding_monads, maybe you want to try that
14:22:37<lambdabot>Title: Haskell/Understanding monads - Wikibooks, collection of open-content textbooks
14:22:43<zbrown>Igloo: oh. I didn't know that.
14:23:15<benny99>bye again
14:23:17<Philippa>Igloo: could I crib some stuff to try porting to a non-debian linux on arm at some point, btw?
14:23:29<Philippa>still want to get a proper native build on my zaurus sometime
14:24:34<crazy_coder>Hello everyone
14:24:52<crazy_coder>Is it possible to produce multiple side effects in a function ?
14:25:21<quicksilver>yes
14:25:27<Lemmih>crazy_coder: Multiple side-effects?
14:25:36<Igloo>Philippa: How do you mean, "crib some stuff"?
14:25:37<quicksilver>twosideffects = putStrLn "hello" >> putStrLn "world"
14:25:43<quicksilver>that has two side effects
14:25:45<crazy_coder>Like I take in a list and produce another list (by manipulating the given list) and also actually return something
14:25:50<quicksilver>first it prints hello, then it prints world
14:26:12<crazy_coder>What I return is permanent, but the list I modified isn't
14:26:21<quicksilver>crazy_coder: why not just return two things?
14:26:27<quicksilver>crazy_coder: that's the simplest way to do that
14:26:28<crazy_coder>Can we do that ?
14:26:30<quicksilver>sure
14:26:33<Philippa>Igloo: take a poke at the debian arm build, I guess
14:26:36<crazy_coder>How to do it ?
14:26:36<SamB>> (1, 2)
14:26:39<lambdabot> (1,2)
14:26:44<SamB>that's two things
14:26:46<mauke>crazy_coder: return a value composed of two other values
14:26:48<crazy_coder>returning as a tuple ?
14:26:51<quicksilver>yup
14:26:52<mauke>for example
14:26:56<crazy_coder>Oh Ok
14:26:58<earthy>mumblegrumble hat grumble
14:27:05<crazy_coder>But it complicated the code , isn;t it?
14:27:09<crazy_coder>*complicates
14:27:11<quicksilver>I don't think so
14:27:21<quicksilver>just a question of what you're used to, perhaps
14:27:23<crazy_coder>You then have to apply fst, etc
14:27:24<malcolmw>earthy? tell me your Hat woes
14:27:27<quicksilver>no you don't
14:27:31<crazy_coder>To get back the stuff you put in
14:27:34<quicksilver>nope
14:27:38<quicksilver>you pattern match
14:27:39<crazy_coder>How not ?
14:27:47<mauke>> let (x, y) = (1, 2) in x * 10 + y
14:27:49<lambdabot> 12
14:27:50<quicksilver>let (x,l) = my_cool_fun m
14:28:48<earthy>malcolmw: it won't accept existential types
14:28:56<crazy_coder>Ok , I'll try, but if i use let as above, the x and y are local and not useful outside hte function
14:28:58<crazy_coder>*the
14:28:59<earthy>not even if I want to compile the module containing them as trusted
14:29:00<Igloo>Philippa: I'm still not sure exactly what you want from me. If you mean "what goes in mk/build.mk", then http://hpaste.org/1713
14:29:16<earthy>(as in: the code I want to trace doesn't contain the existentials explicitly)
14:29:27<mauke>crazy_coder: yes, like all return values
14:29:29<crazy_coder>Oh ok
14:29:32<crazy_coder>I got it
14:29:33<malcolmw>earthy: I'm pretty sure it should accept tham
14:29:53<crazy_coder>something like (x,y) <- Some_function_which_returns_tuples
14:29:59<wli>Are there anything like higher-order classes?
14:30:01<crazy_coder>and then use x and y right ?
14:30:05<quicksilver>crazy_coder: not <-, no
14:30:07<malcolmw>earthy: the Hat parser is ripped from nhc98, which supported existentials since 1996
14:30:11<quicksilver>crazy_coder: just let (x,y) =
14:30:15<crazy_coder>quicksilver: Its a monad
14:30:22<quicksilver>crazy_coder: ah, well then yes :)
14:30:23<crazy_coder>IO (Int,Int) say
14:30:29<earthy>class Applicable rule term where
14:30:29<earthy> apply :: rule -> term -> term
14:30:29<earthy> -- apply' :: forall m . (Monad m) => rule -> term -> m term
14:30:29<earthy> applicable :: rule -> term -> Bool
14:30:30<quicksilver>exactly
14:30:35<earthy>the commented line wasn't accepted
14:30:36<crazy_coder>Thanks
14:31:00<malcolmw>earthy: that's not an existential in the classic sense
14:31:03<Philippa>Igloo: I wasn't actually asking anything right this moment, but yeah, that's a good start
14:31:05<crazy_coder>actually i am trying to write a stack class
14:31:13<earthy>nope, true.
14:31:22<crazy_coder>which has pop and push functions
14:31:30<mauke>crazy_coder: that's just a linked list
14:31:37<mauke>push is (:), pop is tail
14:31:45<Philippa>but basically, give you a yell when I know what I'm after?
14:31:46<crazy_coder>So in pop I have to return an element as well as modify the lsit
14:31:53<malcolmw>earthy: and I'll bet that ghc has only supported that since GADTs were added
14:31:58<quicksilver>mauke: but maybe it's interesting for crazy_coder to write it his way? :)
14:32:10<crazy_coder>Thanks quicksilver
14:32:11<quicksilver>crazy_coder: yes, returning a tuple of the two would be a common idiom
14:32:35<crazy_coder>Also one thing more
14:32:45<crazy_coder>When I write class Stack a where ....
14:32:47<mauke>if you're doing it in IO, you can use data Stack a = Stack (IORef [a])
14:33:02<crazy_coder>Then I have to define all instances of Class manually
14:33:10<earthy>malcolmw: I could do without that btw.
14:33:13<earthy>what I can't do without is
14:33:13<earthy>newtype RealParser state s p a = P(forall r' r'' . (a -> r'' -> r') ->
14:33:16<earthy> (state -> Steps r'' s p) -> state -> Steps r' s p)
14:33:19<crazy_coder>Is there something like derive which will do it automatically ?
14:33:21<mauke>crazy_coder: whoa. how many instances do you need?
14:33:39<crazy_coder>Char,String, anything should go it
14:33:41<earthy>it doesn't grok the ( before the forall somehow
14:33:42<crazy_coder>*in it
14:33:53<mauke>crazy_coder: that has nothing to do with classes
14:33:59<mauke>just make a parametrized type
14:33:59<earthy>and that, IIRC, is existential in the classic sense.
14:34:11<shapr>ACTION boings cheerfully
14:34:29<malcolmw>earthy: not an existential, that is rank-2 polymorphism
14:34:38<crazy_coder>mauke: you mean when I declare it like class Stack a where....... , I don't have to define all instances for it ?
14:34:52<earthy>uhm. yah.
14:34:57<mauke>no, you shouldn't make it a class at all
14:35:05<earthy>ACTION is not awake *at*all* either
14:35:17<earthy>which makes me even more grumbly. sorry for that.
14:35:29<earthy>but the unfortunate issue is I can't use hat
14:35:30<crazy_coder>mauke: why not ?
14:35:45<earthy>even though I think I should be able to when I want to trust this code
14:35:50<malcolmw>earthy: so, if you move the forall outside the constructor, does it still mean the same thing? `cos then you could get it through Hat
14:36:08<mauke>crazy_coder: what's the point?
14:36:55<crazy_coder>mauke: I can store it in a module called Stack and use it whenever I want to use a stack
14:36:56<earthy>you mean RealParser state s p a = forall r' r'' . P ((a -> r'' -> r') -> (state -> Steps r'' s p) -> state -> Steps r' s p) ?
14:37:02<mauke>crazy_coder: no, you can't
14:37:07<mauke>crazy_coder: a class is just an interface
14:37:07<earthy>lemme think about that one for a bit
14:37:15<malcolmw>earthy: yep
14:37:16<mauke>crazy_coder: you'd still have to write a concrete stack
14:37:49<quicksilver>crazy_coder: yeah, this doesn't need to be a class
14:37:51<tuukkah>crazy_coder, you know tail? it works for any type of list since its type is [a] -> [a]
14:37:59<quicksilver>crazy_coder: a class is for when the instances are different, for different a
14:38:06<quicksilver>crazy_coder: you can use the same code for any a
14:38:16<quicksilver>crazy_coder: so this is just a plain old polymorphic function
14:38:31<quicksilver>crazy_coder: from what you've told me so far, your stack doesn't need to be in IO, either
14:38:35<quicksilver>crazy_coder: sounds like it is pure code
14:38:53<crazy_coder>When do we use a class ?
14:39:08<quicksilver>when you need to write different code for different types
14:39:09<crazy_coder>To put all methods together
14:39:30<mauke>crazy_coder: when you need a common interface to different types
14:39:37<quicksilver>you'd use a class if you had a completely different way to implement a stack of ints, from a stack of strings
14:39:51<quicksilver>but for this case, the same implementation works for all, and that's nice
14:39:57<crazy_coder>How would push and pop be associated with stack
14:40:03<pharm>I've always seens classes in Haskell as more like Java interfaces.
14:40:04<crazy_coder>If i use just functions
14:40:12<mauke>crazy_coder: they wouldn't
14:40:18<quicksilver>by their types perhaps
14:40:18<mauke>what do you mean by "associated"?
14:40:22<quicksilver>or by the module they were in
14:40:26<quicksilver>or by their documentation
14:40:28<quicksilver>(or all three)\
14:41:21<crazy_coder>I mean when I should be able to use pop and push only on certain lists(which are actually stacks) and not all
14:41:40<mauke>but all lists are stacks
14:41:44<tuukkah>in object-oriented programming data and methods are contained in object. but haskell isn't object-oriented and haskell doesn't have objects
14:42:09<quicksilver>crazy_coder: if you want to do that, you'd make a 'newtype' for Stack
14:42:10<mauke>you could make a new Stack type that doesn't support list operations
14:42:22<quicksilver>crazy_coder: underneath it would actually be a list
14:42:23<Toxaris>crazy_coder: you could use data Stack a = Stack [a], but why should you?
14:42:31<quicksilver>crazy_coder: but the newtype would tag it as a stack
14:42:42<quicksilver>so that you can only pass it to functions that want stacks
14:42:55<crazy_coder>Oh I see, Now I get some important stuff
14:42:59<quicksilver>but, as mauke and Toxaris say, why would you do that? all lists are stacks.
14:43:14<quicksilver>seems unnecessary to restrict your instance
14:43:17<quicksilver>erm
14:43:18<crazy_coder>I really was confused with when to use what..
14:43:21<quicksilver>restrict your types
14:43:21<quicksilver>:)
14:43:22<crazy_coder>hmm
14:43:28<crazy_coder>I see the point
14:43:40<mauke>class Stack s where {empty :: s a; push :: a -> s a -> s a; nstruct :: b -> (a -> s a -> b) -> s a -> b} -- just because I can
14:44:15<jedai>quicksilver: He could want to be really sure his 'stack' is never used as a list as it would invalidate some invariant he would like to have in his application
14:44:23<crazy_coder>Ok one more thing, If I want to produce a side effect, I suppose one doesn;t have to return IO type right ?
14:44:34<mauke>yes, you do
14:44:43<quicksilver>well that depends what kind of side-effect
14:44:50<mauke>(ignoring ST)
14:45:00<jedai>crazy_coder: You don't want to produce a side effect
14:45:10<quicksilver>there are other monads which are designed to encapsulate particular styles of effectful programming
14:45:17<crazy_coder>If I just want to modify a list permanently , how to do it without IO ?
14:45:18<Toxaris>jedai: but a stack is isomorphic to a list?
14:45:22<jedai>crazy_coder: If you really want to though you need to return a IO or cheat
14:45:39<quicksilver>crazy_coder: it is totally impossible to modify a list permanently. You never want to do that :)
14:45:49<mauke>crazy_coder: you can't modify lists anyway
14:46:39<crazy_coder>like thats my side effect .. change the list (function takes in a list and gives another) . But I want to actually call the function in a do block
14:46:57<mauke>that doesn't change the list, it just returns a different list
14:47:04<mauke>and you can call anything from a do block
14:47:19<quicksilver>crazy_coder: call it in a do block or not, you still can't (and don't want to) modify the list
14:47:33<Toxaris>crazy_coder: do {x; y; let newlist = fun oldlist; z }
14:47:34<jedai>Toxaris: Yes it is, but his functions could add an invariant, for example never get over a certain length (well it isn't a canonical stack anymore but you get my point)
14:47:51<crazy_coder>Ok
14:48:42<crazy_coder>Sometimes its a bit complicated. Do requires you to have return type IO x of every statement, if the last expression is IO () say Right ?
14:48:50<Toxaris>jedai: ok, if he want an ADT, he could use newtype or data :)
14:49:02<quicksilver>crazy_coder: do requires every statement to be in the same monad yes
14:49:02<mauke>crazy_coder: yes
14:49:16<quicksilver>crazy_coder: I don't think you want 'do' at all, though, for the program you're describing
14:49:20<mauke>crazy_coder: except not :-)
14:49:33<mauke>crazy_coder: you can use let statements of any type
14:49:43<jedai>Toxaris: That was my point, but I think we agree anyway, it was just to say "restricting a type" is a valid need.
14:49:55<crazy_coder>Then in this case if I have my function x :: [Int]->[Int] and if I call it in a do block without let, I am going to get some errors Right ?
14:50:28<quicksilver>nope
14:50:30<quicksilver>yes
14:50:31<mauke>if that is the whole statement, yes
14:50:32<quicksilver>sorry that's right
14:50:42<crazy_coder>No these are the general conceptual problems I face :)
14:50:54<crazy_coder>Nothing to do with my stack program
14:51:04<mauke>crazy_coder: it might be easier to learn >>, return and >>= first, just for IO
14:51:08<jedai>crazy_coder: Yes, but why would you call it without let ? If it hasn't side-effects then without a let or a return it won't serve any purpose anyway ?
14:51:08<earthy>right. drat.
14:51:12<quicksilver>each 'statement' in a do block must be in the same monad
14:51:25<quicksilver>however each 'statement' is, actually, just a haskell expression
14:51:25<mauke>then 'do' can be explained in terms of >>=
14:51:36<quicksilver>as such it can contain all kinds of components (sub expressions)
14:51:42<quicksilver>and there is no such constraint on their type
14:51:46<crazy_coder>Was not really understanding it, sometimes one has to change the return type of a function to make it fit in the whole scheme of things
14:52:00<quicksilver>they, simply, must be the right type for the function they're being used in
14:52:01<mauke>crazy_coder: really?
14:52:47<crazy_coder>like to incorporate a function , i had to change a functions return type and then that caused errors somewhere else, then i had to fix that too !
14:52:48<earthy>malcolmw: any chance that simply adding support for the syntax of rank-n polymorphism would allow generation of 'trusted' trace library code?
14:53:08<mauke>crazy_coder: how did you change the return type?
14:53:17<earthy>or is there a fundamental problem that makes that A Hard Thing?
14:53:18<malcolmw>earthy: yes, I think that would be quite a reasonable expectation
14:53:21<crazy_coder>using return ;)
14:53:36<mauke>crazy_coder: no point in changing the original function, then
14:53:38<crazy_coder>maybe I am doing it wrong
14:53:43<earthy>magic words, malcolm, magic words. /me dives into hat's sources
14:54:00<mauke>crazy_coder: you could always say return (f x) when calling it
14:54:03<Toxaris>jedai: all needs are valid. "If any one of you is without needs, let him be the first to say 'you don't want that'"
14:54:03<tuxplore1>is there any CMS written in HAppS?
14:54:06<malcolmw>earthy: most of the type system extensions are purely a matter of leaving them to the underlying compiler, since Hat does not do much with types itself
14:54:08<mauke>and that shouldn't be very common
14:54:15<earthy>ACTION nods
14:54:15<tuxplore1>or using any other haskell technology?
14:54:16<Toxaris>jedai: but yes, we agree
14:54:23<earthy>harlan:/usr/local/src/hat-2.05/src/compiler98 arthurvl$ pwd
14:54:24<crazy_coder>mauke: ok Thanks
14:54:33<crazy_coder>mauke: where do you learn all that ?
14:54:47<malcolmw>earthy: src/compiler98/Syntax.hs
14:54:50<mauke>crazy_coder: remember, "return" doesn't actually return from a function or anything. it's just a constructor call
14:54:53<vincenz>dons: ping
14:54:58<vincenz>@localtime dons
14:54:59<lambdabot>Local time for dons is Tue Jul 17 00:54:58 2007
14:55:01<malcolmw>earthy: and src/compiler98/Parse.hs
14:55:07<mauke>crazy_coder: I don't remember. tutorials, trying stuff?
14:55:15<fberthold>Hi I have libraries question, is anyone aware of a lightweight time library, or a constructor for teh standard CallendarTime type that does not require advanced knowledge of things like "day of week"?
14:55:20<crazy_coder>mauke: how much time ;)
14:55:23<earthy>thanks, hacking
14:55:33<crazy_coder>@localtime crazy_coder
14:56:08<thoughtpolice>tuxplore1: http://hope.bringert.net/about
14:56:13<malcolmw>earthy: plus, there will be some plumbing needed to ensure that any new syntax gets all the way through and back out the other side
14:56:36<malcolmw>earthy: src/compiler98/Pretty.hs is the "other side"
14:56:46<crazy_coder>@localtime mauke
14:56:47<jedai>crazy_coder: a week ? a month ? several years ? it depends on what you want to know...
14:56:48<lambdabot>Local time for mauke is Mon Jul 16 16:56:48 2007
14:57:35<jedai>crazy_coder: To learn the base of haskell and most of its syntax I didn't need more than a few days, but I had prior experiences
14:57:59<quicksilver>crazy_coder: would it be helpful to you if I told you that the special function 'return' has nothing at all to do with return types?
14:58:02<jedai>crazy_coder: and I'm far from mastering Haskell (very very far...)
14:58:02<tuxplore1>thoughtpolice: Thanks. would check it out
14:58:12<quicksilver>the two are quite independent
14:58:33<quicksilver>crazy_coder: I haven't actually seen your code but I have a feeling you're using monads in most of your functions when actually only a very small number really need them
14:58:59<crazy_coder>jedai: 'and I'm far from mastering Haskell (very very far...)' I don't believe it ;)
14:59:58<crazy_coder>quicksilver: whenever I start a do block , i convert all functions to monads ;) Not all, some, many ? dont know
15:00:00<jedai>crazy_coder: You better believe it since I began a few months ago and there's still concept I didn't explore
15:00:20<crazy_coder>:)
15:00:31<shapr>jedai: I'm still there after six years.
15:00:42<quicksilver>crazy_coder: (a) only start a do block because you have genuinely monadic stuff to do
15:00:48<quicksilver>(b) don't convert any functions
15:00:52<crazy_coder>Its going to take me years when i'll start helping people on IRC
15:00:52<edwardk>haskell is crazy huge =)
15:00:56<shapr>Truly
15:01:02<quicksilver>just inline the expressions straight into the statements
15:01:04<quicksilver>or use a let
15:01:10<shapr>Haskell is the most nifty language I've ever seen!
15:01:19<quicksilver>crazy_coder: it would be easier to explain if you gave me an example of the kind of conversion you have done
15:01:36<shapr>crazy_coder: Nah, you'll be able to start helping others very soon, but there's still lots of cool stuff to learn!
15:02:00<Nafai>Morning!
15:02:05<jedai>shapr: Yeah, and I expect I'll still be there in a few years too, but I don't even know now the existence of what I'll be trying to understand then (or so I hope)
15:02:42<crazy_coder>quicksilver: i will show you my code, when i get it working ;)
15:03:37<shapr>Good morning Nafai!
15:03:42<Nafai>How are you?
15:03:44<shapr>jedai: Yeah, there's lots of cool stuff.
15:03:55<shapr>Nafai: I'm getting paid to code, life is good! What about you?
15:03:57<quicksilver>the nice thing about shapr is how positive he always is
15:04:01<quicksilver>shapr++
15:04:04<quicksilver>(even more so now, I guess)
15:04:19<Nafai>Getting paid to code, possibly not as fun as yours, but still life is good!
15:04:51<shapr>quicksilver: I have perspective, I've worked at Subway and various other places.
15:05:46<Nafai>shapr: I got lambdabot running on my local system this weekend!
15:05:48<jedai>crazy_coder: Did you read http://web.cecs.pdx.edu/~antoy/Courses/TPFLP/lectures/MONADS/Noel/research/monads.html , it's pretty good to understand why monads are simple things after all
15:05:50<lambdabot>Title: Online Tutorial: What the hell are Monads?, http://tinyurl.com/n8bqd
15:06:07<crazy_coder>no
15:06:11<crazy_coder>let me check
15:06:16<crazy_coder>jedai: Thanks
15:06:17<crazy_coder>:)
15:06:49<crazy_coder>I read many different tutorials, But I hardly read other peoples code
15:06:52<shapr>Nafai: Cool, any ideas how it could be easier?
15:06:56<crazy_coder>I think it is cheating :p
15:07:05<crazy_coder>But I should learn to do it
15:07:28<sjanssen>@yow!
15:07:28<lambdabot>UH-OH!! I think KEN is OVER-DUE on his R.V. PAYMENTS and HE'S having a
15:07:28<lambdabot>NERVOUS BREAKDOWN too!! Ha ha.
15:07:46<mauke>@quote
15:07:46<lambdabot>AdamPeacock says: Once I looked at the source code, 25000 lines of ASP, I reckoned it would be easier to rewrite it in a real language.
15:08:24<crazy_coder>I actually find it boring too , to read other peoples code....
15:08:25<sjanssen>that'd a good one
15:08:33<crazy_coder>Maybe I am talking bullshit
15:08:43<crazy_coder>I need some coffee
15:09:51<dozer>Ive gone 3 weeks now without drinking coke while coding!!!
15:10:15<mauke>dude, you should go to sleep immediately!!
15:10:48<crazy_coder>mauke: me ?
15:11:02<mauke>no, dozer
15:11:18<_Nucleo>@src fromJust
15:11:18<lambdabot>fromJust Nothing = undefined
15:11:18<lambdabot>fromJust (Just x) = x
15:11:21<crazy_coder>heh :) Same for me
15:13:01<crazy_coder>btw, is the tuple idea to return for than two things, actually a concept of state transformation ?
15:13:25<dozer>mauke: It hurt for the first week - I had no idea a litre of sugar, phosphoric acid and caffeene could have hooked my body like that
15:13:34<crazy_coder>*return two or more things
15:13:54<mauke>@src State
15:13:55<lambdabot>Source not found. stty: unknown mode: doofus
15:14:14<mauke>blargh
15:14:32<mauke>transform :: state -> (x, state)
15:15:35<vincenz>mauke: stateT
15:17:06<crazy_coder>Anyways, thanks everyone mauke, quicksilver, jedai, shapr
15:18:24<earthy>ACTION has obviously gotten spoiled by parser combinator libraries
15:18:51<earthy>damn. that parser in hat is not easy to read. :)
15:19:20<malcolmw>earthy: it _is_ written using combinators :-)
15:19:28<earthy>malcolmw: I know. :)
15:19:35<wli>I wonder if there are parser combinator libraries that build up state machines from combinatory expressions.
15:19:37<earthy>but the combinators are not the combinators I'm used to. :)
15:19:49<earthy>so I've gotten spoiled by the libraries I'm used to :)
15:20:12<earthy>at least it's a reasonably clear continuation-base combinator lib :)
15:20:15<earthy>+d
15:20:20<malcolmw>ACTION wants to rewrite the parser using polyparse combinators at some point
15:20:34<wli>malcomw: What are polyparse combinators?
15:21:00<malcolmw>earthy: the Hat parser combinators are acutally monadic, believe it or not
15:21:26<malcolmw>wli: http://www.cs.york.ac.uk/cs/fp/polyparse
15:21:42<shapr>malcolmw: Ever tried the http://www.cs.helsinki.fi/u/ekarttun/PArrows/ ?
15:21:44<lambdabot>Title: PArrows
15:21:52<wli>malcomw: 404
15:21:56<quicksilver>the thing about combinator libraries is that they are, of course, new languages
15:22:06<malcolmw>wli: correction, http://www.cs.york.ac.uk/fp/polyparse
15:22:08<lambdabot>Title: polyparse: alternative parser combinator libraries
15:22:08<quicksilver>OK, they're quite small languages in the grand scheme of things
15:22:18<quicksilver>but still, they need 'learning'
15:22:29<earthy>malcolmw: I'd already gathered that much
15:22:34<earthy>with `into` being >>=
15:22:39<quicksilver>until you learn them, they look a bit mystifying, especially if you're used to a similar one which uses a different form
15:23:04<quicksilver>c.f. the difference between Parsec/ReadP/polyparse
15:23:37<wli>malcolmw: The haddock is a bit sparse.
15:24:04<earthy>but hell, learning a new parser combinator lib in what, 25 minutes, with no docs but source is not trivial
15:24:18<quicksilver>earthy: agreed
15:24:31<quicksilver>earthy: although plenty of examples would help
15:24:42<earthy>well, the only example is a parser for haskell. :P
15:24:52<earthy>at least I've got a clear view by now :)
15:25:05<sjanssen>the combinator is monadic but not 'instance Monad'?
15:25:13<earthy>parseAp =~= <$>
15:25:20<sjanssen>s/combinator/combinator library
15:25:23<malcolmw>wli: polyparse kind of assumes you are familiar with hutton-meijer-style combinators I'm afriad
15:25:24<earthy>parseChk =~= $>
15:25:25<wli>type Parser = String -> [(Tree, String)] hmm. Shouldn't that be a DAG vs. a tree?
15:25:30<earthy>oh, no, <$
15:25:33<earthy>and so on and so forth
15:25:40<SamB>malcolmw: a strange assumption indeed
15:26:11<SamB>why, dons isn't even familiar with Parsec!
15:26:31<malcolmw>SamB: I don't see the point in replicating the best monadic parsing tutorial in the world...
15:26:57<SamB>malcolmw: maybe you should instead link to it?
15:27:03<malcolmw>but I do agree more documentation is needed.
15:27:32<malcolmw>SamB: there is a link to it?
15:27:34<SamB>with a more attractive link text
15:27:36<SamB>perhaps
15:27:46<SamB>NOTTCS-TR-96-4 isn't very attractive ;-)
15:29:10<earthy>gotcha.!
15:29:15<wli>ACTION barfs on left factoring.
15:29:25<earthy>the forall parser needs to move to the parseContext rule
15:30:05<earthy>but that's for tomorrow
15:30:14<earthy>now to make dinner for the girl
15:33:27<SamB>malcolmw: btw, have you seen my parsely library?
15:33:47<wli>SamB: I want to see it.
15:33:54<SamB>@hackage parsely
15:33:55<lambdabot>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/parsely
15:34:06<earthy>ACTION wonders why chk is not implemented as chk x = parse const `ap` x `ap`
15:34:22<earthy>ACTION wonders why chk is not implemented as chk x y = parse const `ap` x `ap` y
15:34:25<earthy>that is
15:35:26<malcolmw>earthy: probably something to do with precedence of operators
15:35:30<earthy>interesting.
15:35:51<earthy>parsers do seem to suffer from NIH-syndrome a bit in haskell. :)
15:36:06<cedricshock>Can libraries provide Deriving things for Classes?
15:36:32<SamB>cedricshock: no. maybe ten or twenty years from now they will be able to...
15:37:08<cedricshock>SamB: Aww. I hate when the language gets to do something I don't.
15:37:56<SamB>cedricshock: also, probably if that ever happens the "deriving" syntax will work a bit differently -- i.e. there will most likely be a way to say which of several derivings you want to use.
15:38:54<SamB>cedricshock: I don't think there is anyone who specifically doesn't want something like what you describe
15:39:52<wli>ACTION wonders if it'd be possible to shoehorn the happy-GLR back-end behind Hutton-Meijer combinators.
15:40:05<SamB>wli: what the heck?
15:40:22<mrd>what about Drift and Data.Derive?
15:41:00<wli>SamB: Have the parsers build up a GLR state machine etc. instead of whatever LL(1) stuff they now use.
15:42:02<SamB>hey, malcolmw, HuttonMeijerWallace doesn't seem to have a State Transformer in it... besides which, oughtn't that to be an implementation detail?
15:42:30<malcolmw>SamB: HMW predates monad transformers
15:42:52<cedricshock>SamB: That'd be nice to. The derivations I want are pretty much just functions from types to code for functions...
15:43:17<SamB>malcolmw: oh, you mean that meant something else back then?
15:44:07<malcolmw>SamB: a state transformer is a function (s->s) for some state s, that is all
15:44:11<wli>I think it should be possible to do something on the order of building up a grammar from combinators and then doing all the standard parser generator state machine crud "on the fly" (more likely via partial evaluation).
15:44:14<SamB>malcolmw: oh.
15:44:35<malcolmw>then there is the State Transformer monad (the ST monad)
15:44:51<malcolmw>and finally, the StateT monad transformer
15:45:01<malcolmw>which is different again :-)
15:45:12<SamB>malcolmw: perhaps you should change the module description to be less confusing?
15:46:25<malcolmw>SamB: perhaps I cold
15:46:36<malcolmw>s/cold/could
15:46:51<SamB>malcolmw: are you sure HuttonMeijerWallace predates monad transformers?
15:47:01<wli>malcolmw: I get the impression that what the parser combinator libraries end up constructing is typically recursive descent.
15:47:25<SamB>because I see something suspiciously like StateT and ReaderT here...
15:47:30<malcolmw>wli: exactly so
15:47:49<SamB>though for some reason they're called StateM and ReaderM...
15:48:39<wli>malcolmw: Does it make sense to think about building up a grammar and doing the sort of state machine machinations that parser generators like happy/etc. more typically do?
15:48:41<malcolmw>SamB: when did the mtl first appear?
15:49:17<malcolmw>wli: I believe that's what the Utrecht parser combinators do
15:49:29<wli>malcolmw: Very interesting. Googling.
15:49:45<quicksilver>wli: I did on-the-fly-parser generation, almost combinator like, in lua
15:50:09<quicksilver>wli: I used an array of arrays to model the grammar (inner level - concatenation, outer-level alternation)
15:50:25<quicksilver>wli: and then did factoring and left-recursion elimination
15:50:33<quicksilver>and, I think, first-token shortcut table generation
15:51:45<SamB>malcolmw: well, the paper it was inspired by is from 1995
15:52:02<wli>"The basic parsing technique used follows closely the conventional recursive descent, top-down parsing method."
15:52:34<wli>"Caveat: All parsers must correspond to non-left recursive grammars."
15:52:47<malcolmw>SamB: and the Hutton Meijer combinators date from 1994, but that tells us nothing.
15:53:05<wli>malcolmw: Are you sure it was the Utrecht parser combinators?
15:53:09<SamB>malcolmw: this paper you linked too is for 1996
15:53:22<SamB>and I see in it what look like monad transformers to me
15:53:35<malcolmw>SamB: it took them a while to get it published
15:53:35<cedricshock>I'm interested in making a derived or template library that does something like darcs on many haskell data types. Anyone know of existing things I should look at, other than darcs itself?
15:53:37<SamB>er. s/too/to/.
15:53:41<wli>That was from http://www.cs.uu.nl/groups/ST/Software/UU_Parsing/Run-OnlyPC.pdf
15:54:05<quicksilver>cedricshock: calculation of 'diffs' and the ability to mix and match versions?
15:54:08<malcolmw>wli: no, I'm not certain. just a vague recollection
15:54:11<quicksilver>cedricshock: that is very interesting
15:54:17<quicksilver>cedricshock: I'm not aware of anything personally
15:54:38<wli>malcolmw: Okay, so it makes sense and has been done before, we're just not entirely sure when.
15:54:45<wli>Or by whom.
15:54:50<malcolmw>wli: in the same way that I recall manuel chakravarty having self-optimising lexer combinators, in the same vein
15:55:19<quicksilver>many people end up not using their parsers in speed-critical situations
15:55:28<quicksilver>especially with the speed of today's machines
15:55:47<malcolmw>wli: table-driven parsing is not necessarily faster than other techniques anyway
15:55:48<quicksilver>so parser performance isn't a priority (for many people)
15:55:59<quicksilver>of course, when it is, it is
15:56:02<quicksilver>to state the obvious
15:56:03<cedricshock>quicksilver: I'd love to be able to do it on types or tuples by field, union types (full replacement), and some of the Data library type things, like lists and sets. This would be the basis for a user interface paradigm.
15:56:07<malcolmw>SamB:
15:56:14<wli>malcolmw: Oh, I'm not interested in performance, but expressiveness. I don't really want to left factor grammars.
15:56:15<quicksilver>cedricshock: yes, that would be lovely
15:56:19<quicksilver>cedricshock: I'm not aware of that
15:56:30<quicksilver>cedricshock: I wrote something recently for a perl application, along those lines
15:56:35<wli>malcolmw: I'd be just as happy with Earley or CYK as GLR.
15:56:35<quicksilver>cedricshock: diff for nested maps, basically
15:56:43<quicksilver>cedricshock: turns out to be quite subtle :)
15:56:50<SamB>malcolmw: how very interesting
15:57:15<wli>er, s/malcolmw/quicksilver/
15:57:25<quicksilver>:)
15:57:35<quicksilver>SamB: what bit was interesting?
15:57:51<SamB>quicksilver: the part where he said my name with nothing after it ;-)
15:58:03<wli>quicksilver: As table-driven parsers go, things like Earley, CYK, and GLR are dogslow vs. LALR(1) etc.
15:58:06<quicksilver>SamB: ah ;)
15:58:09<malcolmw>SamB: oops, mistyped
15:58:40<wli>quicksilver: We're talking asymptotically inequivalent even, O(n^3) worst-case.
15:58:53<malcolmw>SamB: in any case, the concept of monad transformers has only really gained traction in the last two years, AFAICT
15:58:59<cedricshock>quicksilver: I'm perfectly willing to write it... I think many of the simpler patch types can achieve orthogonality over nested structures, but some of the more interesting operations (like updating everything element in a set) could be a mess.
15:59:29<quicksilver>wli: yes, yes
15:59:36<quicksilver>wli: I had actual, real performance issues
15:59:40<quicksilver>wli: that's what drove me to do it
15:59:47<quicksilver>wli: I didn't do it for the kicks :)
15:59:56<quicksilver>wli: I was doing incremental parsing after every keypress, in a LUA shell
16:00:05<quicksilver>in order to do syntax colouring and auto-complete
16:00:12<quicksilver>(context-sensitive auto-complete)
16:00:18<malcolmw>SamB: and I extended HM to HMW back in 1999, in the days when everyone rolled their own monad, rather than composing them from smaller monads
16:00:30<quicksilver>the table-factoring made it feasible, with naive rec descent it was not viable
16:01:33<wli>quicksilver: I don't have any essential use for Haskell. It could be exchanged for any of a number of scripting languages where I use it for any essential task.
16:02:00<SamB>malcolmw: apparantly Hutton and Meijer were not aware of this back in 1996
16:03:07<malcolmw>SamB: back then, it was widely recognised that monads were not composable, and that this was a problem yet to be solved adequately
16:03:18<wli>quicksilver: The hope for GLR/etc. is that I can use them on super dirty nasty ultra-ambiguous languages where I throw out possibilities via higher-level semantics.
16:03:23<SamB>malcolmw: that doesn't seem to have stopped them...
16:03:32<SamB>perhaps they were not well-enough read to know that ;-)
16:05:17<quicksilver>It's still not clear to me that monad transformers are very magical
16:05:30<SamB>quicksilver: they aren't magical
16:05:34<quicksilver>well I know
16:05:34<SamB>they're merely convenient
16:05:37<quicksilver>poor choice of words
16:05:40<wli>I'm starting to get the idea behind monads.
16:05:47<quicksilver>it's not even clear to me that they are all *that* convenient
16:05:54<quicksilver>the best part is the MonadFoo instances
16:05:57<quicksilver>now *those* are useful
16:06:03<SamB>yeah.
16:06:05<quicksilver>dispensed with all that nasty lifting crap
16:06:09<SamB>that's the convenient part...
16:06:21<wli>How about arrows?
16:06:29<SamB>wli: how about them/
16:06:38<SamB>s|/|?|
16:07:00<shapr>Arrows are more general than monads, but lots more trouble to use.
16:07:12<SamB>that pretty much sums it up ;-)
16:08:08<wli>shapr: The automaton arrows look very interesting to me.
16:08:09<shapr>Arrow advantages can be powerful, but you lose those advantages when you need to lift normal functions into an arrow. Arrows only stay powerful when you use them only with other arrows.
16:08:15<SamB>ACTION wants a ProtoArrow class, with no arr/pure method...
16:09:00<tuukkah>tanuk, in case you still need to set line buffering, here's a script using gdb: http://tuukka.iki.fi/tmp/linebuf
16:09:27<shapr>wli: It's worth learning.
16:09:27<wli>shapr: Well, suppose one has parsing automata and wants to compose them...
16:09:54<quicksilver>SamB: that's interesting
16:10:00<quicksilver>SamB: I *think* that's what I want, too
16:10:23<quicksilver>SamB: were you around the other day when I was musing about eDSLs for code generation?
16:10:26<shapr>wli: Parsing was the original motivation for arrows. Arrow-style parsers can short-circuit, monads must either succeed or fail.
16:10:29<SamB>I'm not sure what would happen if you tried to use it for anything useful though
16:10:31<Philippa>SamB: YA me a few years ago AICM5UKP
16:10:34<jfincher>I've got a non-haskell-related question that I can't think of a better place to ask, where more knowledgeable language-oriented people hang out and discuss things :)
16:10:43<SamB>quicksilver: probably not
16:10:57<SamB>Philippa: huh?
16:10:59<int-e>SamB: hmm. but then you'll need extra functions for all the useful isomorphisms between objects (like (A + B) x C = A x C + B x C)
16:11:14<wli>shapr: Interesting. What were the Arrow-based parsersdoing?
16:11:18<SamB>Philippa: is that a game genie code?
16:11:29<quicksilver>SamB: I want an 'm' such that 'm a' means "generate bytecode which calculates a result of type a'
16:11:43<int-e>SamB: in particular desugaring arrow notation will be much harder.
16:11:58<SamB>int-e: so?
16:12:00<quicksilver>SamB: but that definitely isn't an arrow, because I can't turn an arbitrary haskell function (a->b) into one of these
16:12:03<Philippa>SamB: "You Are ... And I Claim My Five Pounds"
16:12:22<SamB>Philippa: I haven't got any pounds
16:12:24<quicksilver>SamB: but that implies I can 'unpick' my haskell function and turn it into bytecode
16:12:30<quicksilver>SamB: which I certainly can't do
16:12:43<jfincher>It seems self-evident to me that given a string of symbols connected according to some grammar, that more than one semantics for the language consisting of that sentence can be defined. Does anyone know of any papers/etc. that might relate to that idea?
16:12:51<SyntaxNinja>y0
16:13:02<SamB>quicksilver: simililarly, you can't reverse the direction of a function, which a biarrow would need to be able to do...
16:13:13<quicksilver>SamB: yes, agreed
16:13:21<Philippa>jfincher: lisp?
16:13:23<int-e>SamB: it'd be nice to have an ArrowProto class but it wouldn't make arrows easier to use; it'd make it harder.
16:13:29<jfincher>Philippa: any language
16:13:29<Philippa>as in, the entire community?
16:13:51<SamB>int-e: it ought to make them useful for more things though...
16:13:51<quicksilver>SamB: I think I want: Code a b meaning a recipe for generating Code which expects values of type a {on the stack/in predetermined registers}
16:13:52<Philippa>basically, it's trivial - any interpretation is a valid one
16:14:04<Philippa>you might find reading up on abstract interpretation interesting though
16:14:07<quicksilver>SamB: and then you can obviously write compose :: Code a b -> Code b c -> Code a c
16:14:34<shapr>wli: The only way to see if a monadic parser will succeed or fail is to execute it. Arrow-style parsers can hold static properties, so you can factor out common traversals, and/or short circuit around things that will not be parsed.
16:14:37<quicksilver>SamB: and, furthermore, you might hope to be able to write an 'optimising' version of the compose function
16:14:44<quicksilver>SamB: which can eliminate unused registers,e tc
16:15:03<int-e>SamB: yes, I'd have an application for that actually: invertible computations. (they come with an operation invert :: (b ~> c) -> (c ~> b) and have pure :: (b -> c) -> (c -> b) -> (b ~> c)
16:15:18<SamB>int-e: yeah, that's what I meant by "biarrows"
16:15:22<int-e>ah
16:15:33<quicksilver>int-e: my version would come with some 'axioms' :: b ~> c
16:15:40<quicksilver>int-e: but nothing like 'pure' at all
16:15:58<quicksilver>perhaps you'd have 'CodePlus' :: Int ~> Int
16:15:59<int-e>quicksilver: I used pure mostly to define the axioms (as helper functions)
16:16:02<quicksilver>ACTION nods
16:16:05<shapr>wli: In monadic form string "one" <|> string "two" <|> string "three" must go through every alternative before it can fail, and it checks twice whether the string starts with (char 't').
16:16:20<quicksilver>or mayb you wouldn't use Int, maybe you'd use QSInt
16:16:28<quicksilver>I'm not sure if I want different types or not
16:16:47<wli>sapr: Yeah, that doesn't sound so good.
16:16:53<SamB>quicksilver: perhaps CInt ;-)
16:16:59<quicksilver>SamB: well yes, perhaps
16:17:07<wli>shapr: Sounds awesome. Where do I pick up these arrow parsers?
16:17:29<shapr>wli: http://www.cs.helsinki.fi/u/ekarttun/PArrows/
16:17:30<lambdabot>Title: PArrows
16:17:34<SyntaxNinja>I uploaded darcs to debian yesterday. folks should try it out and let me know of any problems.
16:17:49<wli>shapr: Ultraspiffitude.
16:20:35<olsner>it'd be awesome to make a [GS]?(LA)?LR(\([0-9]+\))? parser generator working with parser combinators
16:20:59<malcolmw>SyntaxNinja: the wanderer returns!
16:21:01<wli>olsner: GLR interests me most.
16:21:22<wli>olsner: There's a GLR variant of happy.
16:21:41<vincenz>GLR is the only way forward
16:21:44<shapr>y0 SyntaxNinja!
16:21:47<olsner>if the framework is there, it should be easy to generate all kinds of parser from a single specification
16:21:50<vincenz>though I admit I haven't played with GLR of happy yet
16:21:52<psykotic>wli: the original paper on arrows basically just computes FIRST sets and combines them, in parallel to the usual composition of parsing functions.
16:21:57<ski>wli : istr an hughes arrow paper mentioned an arrow(izable ?) parser library .. someone and duponschel or something
16:22:01<wli>olsner: So basically get parser combinators to build up enough crap to feed to whatever the engine behind that is and blow the doors off them.
16:22:09<psykotic>wli: so the FIRST sets function as a static approximation to the dynamic behavior of the parsing functions.
16:22:16<wli>ski: shapr pointed me at it.
16:22:18<SyntaxNinja>heya malcolmw, sha
16:22:20<SyntaxNinja>shapr:
16:22:27<ski>wli : no, not that one
16:22:28<SyntaxNinja>I climbed a mountain the other day. it was high.
16:22:34<SyntaxNinja>but not that high for a mountain
16:22:35<shapr>ski: Swierstra & Duponcheel
16:22:37<wli>ski: Oh, interesting then.
16:22:40<ski>shapr : ty
16:22:44<SyntaxNinja>ACTION will climb St. Helens next week.
16:22:51<wli>psykotic: I think nondeterminism + LR(1) suffices.
16:22:51<malcolmw>SyntaxNinja: got my PM?
16:22:57<wli>psykotic: I think nondeterminism + LR(1) == GLR.
16:23:14<ski>SyntaxNinja : into the caldera ?
16:23:14<psykotic>wli: you don't even need LR(1). i think you can do LR(0).
16:23:33<psykotic>wli: since the nondeterminism makes lookahead needless (efficiency aside).
16:23:41<wli>psykotic: I'm not sure. I think you need LR(1) so the deterministic cases work.
16:24:04<SyntaxNinja>ski: to the edge.
16:24:07<wli>psykotic: Never mind. You're right, though I suspect LR(1) is used anyway.
16:24:18<psykotic>right, it would be silly not to.
16:24:35<ski>ACTION has no idea if there's still any activity there ..
16:24:53<psykotic>last time i implemented GLR i used LR(0) though, since it's a good deal simpler conceptually and in implementation.
16:24:55<wli>psykotic: The tricky part of GLR is of course the resulting expression DAG.
16:25:07<ski>SyntaxNinja : bring back pics ! :)
16:25:28<psykotic>wli: i don't think it's very tricky, is it? it's just dynamic programming/memoization.
16:25:36<wli>psykotic: I don't think the LR(1) vs. LR(0) bits are where one feels the pain in GLR, but anyway.
16:25:40<ski>'GLR' ?
16:25:44<psykotic>generalized LR
16:25:57<wli>psykotic: Maybe you're right.
16:26:12<psykotic>it essentially just covers the technique of "resolving" conflicts in the LR tables by exploring alternatives in parallel, and sharing structure and parse results using dynamic programming.
16:26:41<wli>psykotic: The same principle as CYK and Earley, except applied to LR parsers instead of chart parsers.
16:26:56<ski>ACTION recalls a breadth-first parse monad claessen showed
16:27:00<olsner>the devil's in the details as usual... I think the trouble with GLR parsers in practice is the number of potential parses you may have to keep track of
16:27:07<psykotic>well, in that those things are dynamic programming, but it's bottom up rather than top down (unlike CYK and earley).
16:27:32<wli>olsner: That's where the dynamic programming and representing the result as a multirooted DAG comes in.
16:27:45<wli>olsner: Common sub-parses are all shared in the DAG.
16:27:57<psykotic>a simple implementation isn't very tricky at all. it really is a textbook application of DP.
16:27:59<tanuk>tuukkah: Thanks. Unfortunately I'm having problems with using the script. Could you provide a quick how-to?
16:28:22<edwardk>@seen mnislaih
16:28:22<lambdabot>mnislaih is in #haskell and #ghc. I last heard mnislaih speak 33m 12s ago.
16:28:25<wli>psykotic: Where does it get complicated?
16:28:37<psykotic>it doesn't, in a simple implementation.
16:28:52<wli>psykotic: Where do implementations get un-simple?
16:28:59<vincenz>why do you need dynamic programming?
16:29:08<vincenz>you just (lazily) duplicate your stack
16:29:09<psykotic>vincenz, to prevent exponential explosion.
16:29:24<psykotic>basically the divergent parses can reconverge
16:29:29<mnislaih>hi edwardk
16:29:30<psykotic>and you don't want them to duplicate work from that point on
16:29:34<vincenz>ah
16:29:38<wli>vincenz: The parser's results can be huge. You have to share ultra-aggressively between different possible parse trees.
16:29:40<edwardk>heya mnislaih. neat stuff
16:29:41<vincenz>yeah, that's when you re-unify your stacks
16:29:51<vincenz>psykotic: looked at elkhound?
16:29:51<psykotic>well, that's what DP is here.
16:30:07<vincenz>they do it both in O'Caml and C++
16:30:19<vincenz>(they have a c++ parser using the c++ code generated from the GLR-framework elkhound)
16:30:29<wli>vincenz: This would be constructed on the fly by parser combinators, not a parser generator.
16:30:48<vincenz>wli: oic
16:30:51<vincenz>wli: why?
16:30:57<psykotic>wli: as for complexities, i haven't looked at "serious implementations" like elkhound in detail, but i imagine it's the same thing that afflits all "serious implementations": they want to squeeze out as much performance as possible, so they apply every trick in the book.
16:31:05<tuukkah>tanuk, for example: linebuf sed "s/foo/bar/g" | linebuf sed "s/baz/blum/g"
16:31:05<vincenz>"on the fly" and "parser-generator" barely differ
16:31:06<wli>vincenz: Since no one gives a damn how fast their parsers run it would make more sense to be as general as possible.
16:31:25<vincenz>the only difference is that one has a 'language' while the other has a set of 'combinators', again the distinction is subtl
16:32:25<wli>vincenz: Yeah, that's why ripping the front and back ends off happy-GLR (http://www.dur.ac.uk/p.c.callaghan/happy-glr/) and shoving it under the hood of some parsing combinators sounds good to me.
16:32:27<lambdabot>Title: GLR parsing with Happy
16:32:37<vincenz>wli: sounds like a good idea :)
16:32:42<vincenz>wli: though I admit I rather like happy
16:32:52<wli>vincenz: As general as possible wrt. grammars handled, that is.
16:32:54<vincenz>wli: (especially cause it does -not- deal with lexers)
16:33:33<vincenz>wli: btw, if you plan on doing that, something that would be useful is a combinator-generator
16:33:46<vincenz>wli: that would take the input that the frontend of happy takes and produces the code that uses the combinato
16:34:40<psi>i'm getting: 'Symbol's function definition is void: inferior-haskell-load-file' when i go C-c C-l in a haskell-mode buffer.
16:35:05<psi>any clues? i'm using carbon emacs.
16:35:14<wli>vincenz: I'm not sure what you mean there.
16:35:16<quicksilver>psi: you haven't got inf-haskell loaded
16:35:33<wli>vincenz: Anyway I think I found a "project" to learn stuff.
16:35:54<vincenz>wli: well currently happy is a parser-generator, so it takes some nput file (which is close to std yacc stuff). It'd be good that if you moved to combinator to have something that generates the combinator code from the nput that would be used by the parser-generator
16:35:59<psi>quicksilver: woops, I forgot to add the load to my .emacs.
16:36:08<quicksilver>I use this: (autoload 'run-haskell "inf-haskell" "Run interactive haskell interpreter." t)
16:36:20<quicksilver>I think I still have to remmber to do a run-haskell myself, thouh
16:38:46<wli>vincenz: I'll see what I can do about generating parsers on the fly using it.
16:39:58<psi>quicksilver: thanks
16:42:13<tanuk>tuukkah: The problem is that the data source doesn't use line buffering. I tried to change CMDPID=$$ to CMDPID=`pidof aseqdump`, and then running in one terminal "aseqdump -p 20:0 | Sysextract" and in another "./linebuf", that didn't work. aseqdump exits without a message.
16:42:21<psi>quicksilver: here's what i came up with: (add-hook 'haskell-mode-hook (lambda () (load "inf-haskell")))
16:42:21<wli>vincenz: I've got a bad feeling it just slings around Haskell code as strings.
16:42:29<psi>quicksilver: you don't have to do it manually then.
16:44:53<quicksilver>psi: yeah, that works too
16:45:53<tuukkah>tanuk, if Sysextract is your unbuffered haskell application, this could work: ./linebuf aseqdump -p 20:0 | Sysextract
16:48:02<tanuk>tuukkah: It doesn't work, because CMDPID doesn't get any value.
16:51:13<tuukkah>in bash, $$ should be the pid of the current shell
16:53:14<tanuk>tuukkah: Yeah, but it's aseqdump's pid that we're interested in, if I understand correctly. The script could maybe work this way: first it starts the program (aseqdump) in a separate thread, takes it's pid, then does the gdb magic and then attaches to the program's thread. I don't know how to do this.
16:53:56<tuukkah>tanuk, as aseqdump is started using exec, it gets the same pid as the shell had
16:54:34<tuukkah>on your machine, doesn't it work even with my sed example?
16:55:21<tanuk>tuukkah: The sed example works, but I think that's because the input comes from the shell, therefore CMDPID is assigned the right pid.
16:56:33<tuukkah>if you think that, you can test by adding a third sed in the middle which doesn't receive input from nor produce output for a shell
16:57:52<tuukkah>but anyway, if it doesn't work then it doesn't work and you need some other hack :-(
16:59:43<tanuk>tuukkah: The ./linebuf aseqdump -p 20:0 | Sysextract
17:00:02<tanuk>line exits after a couple of seconds.
17:00:53<tanuk>I'll modify aseqdump.
17:02:00<SimonRC>why aren't fudgets based on arrows?
17:02:04<tanuk>tuukkah: Thanks for your efforts anyway.
17:02:10<ddarius>SimonRC: Because it was made way way before arrows.
17:02:11<EvilTerran>ACTION notes that "let ... = ... in ..." is slightly longer than "| ... <- ... ="
17:02:27<tuukkah>tanuk, nevermind, the gdb script was something i wanted to test some time :-)
17:02:41<EvilTerran>(terseness FTW!)
17:02:53<monochrom>EvilTerran: they also behave different.
17:03:02<ski>SimonRC : probably because the former were invented before the latter
17:03:14<SimonRC>ddarius: I can see that arrows my help; the fudget law feels "wrong" to me
17:03:43<EvilTerran>monochrom, i know pattern guards cause fallthough on pattern match failure, but is there any difference in the case when the thing you're matching against only has one constructor?
17:04:14<EvilTerran>("foo x = let (y,z) = bar x in ..." versus "foo x | (y,z) <- bar x = ...")
17:04:44<monochrom>> let (y,z) = undefined in "hey"
17:04:45<lambdabot> "hey"
17:04:55<monochrom>That shows the difference.
17:05:25<ddarius>~(y,z)
17:05:27<EvilTerran>ah. let doesn't HNF the things being bound
17:05:44<quicksilver>WHNF
17:05:48<EvilTerran>yes, that one.
17:05:52<quicksilver>but it's a bit more than that
17:05:54<EvilTerran>@where WHNF
17:05:54<lambdabot>I know nothing about whnf.
17:05:59<quicksilver>a let binding doesn't just WHNF
17:06:06<quicksilver>a let binding reduces it 'as much as it needed to bind'
17:06:13<quicksilver>so let ((x,y),z) = ...
17:06:14<monochrom>Somehow WHNF feels like a swear word to me, up there with WTF and RTFM :)
17:06:27<quicksilver>is going a bit beyond WHNF, because it forces the constructor inside the left side
17:06:32<quicksilver>erm sorry
17:06:35<EvilTerran>yes, i thought of that just after i said it.
17:06:37<quicksilver>pattern binding I meant of course
17:06:45<EvilTerran>but let _doesn't_, pattern binding _does_
17:06:48<quicksilver>right :)
17:07:01<EvilTerran>because control flow doesn't depend on a let binding successfully, it doesn't try
17:07:09<therp>isn't let lazy per default?
17:07:21<quicksilver>therp: yes
17:07:24<ddarius>therp: It's an irrefutable binding, yes.
17:07:25<quicksilver>therp: what I said was wrong
17:07:26<EvilTerran>therp, that's what we just concluded
17:07:33<monochrom>Control.Monad.State.Lazy and Control.Monad.State.Strict exploit the difference. The former uses let, the later uses case.
17:07:43<therp>ah sorry /me should read the whole discussion before dropping comments
17:07:49<EvilTerran>so "foo x = let (y,z) = bar x in ..." is like "foo x | ~(y,z) <- bar x = ..."?
17:07:58<monochrom>Yeah.
17:08:08<quicksilver>modulo the difference about falling through
17:08:18<quicksilver>ah, no, I'm wrong again
17:08:20<quicksilver>damn I'm on form
17:08:24<monochrom>Hehehehe
17:08:26<quicksilver>a ~ <- binding can't fall through :)
17:08:29<quicksilver>it's irrefutable
17:08:38<EvilTerran>but if the expression is strict in y or z, there's no difference anyway, right?
17:08:57<monochrom>I agree with that one.
17:09:02<EvilTerran>with or without twiddles
17:09:21<ddarius>tilde takes less typing
17:09:36<EvilTerran>"foo (x,y) = x+y" is effectively indistinguishable from "foo ~(x,y) = x+y", i mean
17:10:03<Igloo>For Int etc, yes, but not necessarily for types you define yourself
17:10:06<monochrom>Heh pattern guard still more compact :)
17:10:27<ddarius>Hmm... is foo !(~(Just x)) = 5 valid?
17:10:37<Igloo>Yes
17:10:43<ddarius>What happens?
17:10:45<mauke>does it semant?
17:10:46<Igloo>There was a discussion on the mailing list about what it means recently
17:11:02<Igloo>ACTION can't remember the answer OTTOMH
17:12:02<ddarius>GHC must have fun with things like ~(x,!y)
17:13:17<monochrom>> let ~(x,!y) = (5, undefined) in x
17:13:18<lambdabot> Parse error
17:13:51<monochrom>> let f ~(x,!y) = x in f (5, undefined)
17:13:51<lambdabot> Parse error
17:14:00<monochrom>It not know bangs?
17:14:09<sjanssen>monochrom: correct
17:14:26<monochrom>Anyway, that example shows what happens.
17:14:48<ddarius>There is a fairly "obvious" thing that should happen in all of these cases.
17:14:56<quicksilver>I would expect the semantics to be 'whenever the tuple gets forced at all, y gets forced'
17:14:58<ddarius>I'm not sure if there are "unobvious" cases.
17:15:11<quicksilver>but the tuple itself doesn't get forced immediately cos its irrefutable
17:15:14<quicksilver>is that right?
17:15:25<mauke>seems like it
17:16:03<edwardk>gah, i wish there was a way to say that Foo m is a class iff Bar m a is defined forall a. class Bar m a => Foo m complains about the absence of a in the type, and I can't make instance Foo m => Bar m a without tagging m with a way to keep me from being able to implement Bar m a in other ways.
17:16:27<quicksilver>I would expect (a,(b,!c)) to mean that c gets forced (only) when the inner tuple which directly contains c gets forced
17:16:35<edwardk>er s/keep me from/keep me so I can/
17:16:51<ddarius>Use those type level predicates?
17:17:11<edwardk>ddarius: the Fc things?
17:18:57<_Nucleo>@src elem
17:18:58<lambdabot>elem x = any (== x)
17:19:06<_Nucleo>@src any
17:19:06<lambdabot>any p = or . map p
17:19:39<wli>vincenz: Hmm. Looks like Alex is nasty enough I'm better off rolling my own.
17:19:52<wli>vincez: s/alex/happy/
17:20:05<wli>It's Monday. I'm jacking around.
17:20:22<SamB_XP>wli: you don't like the way you have to specify grammars?
17:20:22<wli>Rolling my own would be better exercise anyway.
17:20:37<wli>SamB_XP: No idea what you mean.
17:20:41<ski>edwardk : you want 'instance (forall a. Bar m a) => Foo m' .. (not supported)
17:20:54<SamB_XP>wli: what about happy do you not like?
17:21:24<edwardk>yeah
17:21:52<wli>SamB_XP: I like it well enough. It's that the state machine code is all done up as Haskell code it writes out to a file, which makes it rather tough to interpret some representation of a state machine in-core using any of its code.
17:22:14<SamB_XP>wli: hmm?
17:22:16<edwardk>it'd make it possible to define convenience classes for Monad m, despite implementing monads with a set of restricted monad classes, like Oleg's version.
17:22:26<SamB_XP>oh, you mean you were trying to adapt it's code to do something else?
17:22:32<wli>SamB_XP: Yes.
17:22:40<wli>SamB_XP: Or looking at doing so.
17:22:41<edwardk>I can build monad convenience classes over the parameterized monad stuff, but not over the restricted monads
17:22:49<ski>edwardk : 'instance (forall a. Show a => Show (f a)) => Show (Foo f)' would be handy sometimes, too
17:23:20<ski>(though in that case there is a workaround)
17:23:27<SamB_XP>ski: something's not being supported probably doesn't bother edwardk so much
17:23:48<edwardk>which means that i may have to drop restricted monads from the toy prelude, since they prevent me from having usable mapMs, sequences, etc.
17:23:58<edwardk>they obviously weren't tested beyond the basic idea
17:24:13<edwardk>samb: =)
17:24:39<ski>SamB_XP : well .. it would be interesting if one could get a usable ssystem supporting these things
17:25:49<edwardk>and i don't want to do anything of this sort with explicit rank-n polymorphism because then i have to plumb around a bunch of dictionary-like objects and its not pretty
17:26:25<ski>edwardk : mayhaps you could do an 'class BarForall m','instance BarForall m => Bar m a',etc ..
17:27:12<edwardk>ski: thought about it, but then I can't do instance SomethingElse m => Bar m a kind of things without ghc complaining about the conflict
17:27:25<edwardk>the moment there is a diamond in the inheritance hierarchy all is lost
17:27:37<ski>instance SomethingElse m => BarForall m -- then ?
17:27:51<edwardk>you get one the moment you allow Monad, ParameterizedMonad, RestrictedMonad and ParameterizedRestrictedMonad
17:28:09<ski>ok :/
17:28:09<SamB_XP>edwardk: I thought you had a toy language ?
17:28:51<edwardk>samb: i do, i started porting a good portion of the standard library over to haskell to get more eyes, and to work out the issues i was running into in my compiler to see if it was the language or the library at fault.
17:29:02<SamB_XP>ah
17:29:53<edwardk>my current goal is a painfully abstract prelude that unifies as many things as possible. backwards compatibility is not a priority, learnability is not a priority. useful or educational unification of ideas is
17:30:04<shapr>ACTION cheers
17:30:29<wli>Equivalence for DPDA's is decidable if and only if it's decidable for "monadic recursion schemes." (Friedman 1977, as cited by Hopcroft and Ullman).
17:30:35<SamB_XP>edwardk: obviously when you make a new Prelude you have to throw most compatibility out the window...
17:30:53<edwardk>minimizing typeclasses is not a priority, current thought is to $(mkMonad "MyMonad" [d| return = ...; m >>= k = ... |]) to recover usable syntax for definitions
17:30:58<wli>What are the odds that this is somehow connected to monadic parsing?
17:31:17<wli>edwardk: Is this a new Prelude or a new language you're working on?
17:31:21<edwardk>wli: yes =)
17:31:26<SamB_XP>wli: both apparantly
17:31:44<edwardk>wli: the prelude is a projection of features for the one i want for my language into haskell.
17:31:46<ski>wli : DPDA ?
17:31:54<edwardk>wli: the language is the things i'd never get haskell to adopt
17:32:04<wli>edwardk: Could you extend the module system so that modules can be parametrized by other modules?
17:32:18<wli>ski: Deterministic Push Down Automaton
17:32:41<edwardk>wli: well, in haskell the idea is that a ML module maps onto a typeclass
17:32:55<ski>not quite
17:33:02<shapr>ACTION makes a t-shirt "DPDAs against Oppression"
17:33:04<wli>edwardk: Doesn't really work out.
17:33:14<edwardk>well, based on the manuel chakravarty paper on modular type classes
17:33:18<shapr>For too long have we been pushed down!
17:33:29<wli>edwardk: Mostly because you want to switch out implementations behind things.
17:33:48<ski>should we push up instead ?
17:33:52<edwardk>anyways, in my setting they are stagedly dependently typed records, but the inference for them is a nightmare because i don't explicitly annotate what is a type and what is a term.
17:34:08<edwardk>wli: i understand =)
17:34:12<wli>ski: It just means that the finite control manipulates a stack.
17:34:28<ski>wli : i know
17:35:16<ski>ACTION implemented function calls on a DPDA sometime ago
17:35:28<laz0r>hi there, its me again... whenever i use 'do x <- something; ...' the something must be of type (a -> b), right?
17:36:05<ski>laz0r : 'something' must be of type 'm a' for any type 'a', and any type 'm' in the class 'Monad'
17:36:09<shachaf>laz0r: The something must be of type (Monad m) => m a
17:36:12<edwardk>laz0r: something can be of type (m a) for any monad type m
17:36:17<ski>@stereo
17:36:18<lambdabot>Unknown command, try @list
17:36:22<ski>@quote stereo
17:36:22<lambdabot>Cale says: Welcome to #haskell where your questions are answered in majestic stereo!
17:36:50<glguy>@quote stereo
17:36:50<lambdabot>Cale says: Welcome to #haskell where your questions are answered in majestic stereo!
17:36:52<glguy>:)
17:37:11<SamB_XP>edwardk: couldn't you just use -fno-implicit-prelude?
17:37:19<SamB_XP>rather than bothering with TH?
17:37:23<edwardk>wli: at present my module system just hands you back a record with some types embedded in it, using the same mechanism i use for objects
17:37:29<ski>dons : we need '@stereo' .. and possibly whatever the corresponding term is for three !
17:37:30<edwardk>samb: the problem is sheer number of instances
17:37:31<kpreid>laz0r: and note that m can be (b ->), in which case m a *is* b -> a
17:37:47<SamB_XP>edwardk: for do-notation
17:37:48<shachaf>ski: Yes, and one that doesn't beep Cale's IRC client.
17:37:53<ski>indeed
17:38:07<glguy>@quote
17:38:07<lambdabot>joelr says: the learning curve is far steeper with Haskell but it is far more elegant and readable
17:38:08<edwardk>samb: ideally to express things right a Field would take 30-40 =)
17:38:10<shachaf>kpreid: But it's not likely to be.
17:38:25<shachaf>kpreid: In this case.
17:39:07<shachaf>Is there any reason to use Reader instead of the (e ->) monad?
17:39:19<ski>> (do {x <- (*200); y <- (+8); return (x+y)}) 10
17:39:23<lambdabot> 2018
17:39:51<kpreid>when you've got a lot of function arrows and the newtype helps make your type errors less baffling?
17:39:54<ski>shachaf : more explicit distictions between working abstractly in the monad, and concretely applying and abstracting actions
17:39:58<olsner>springerlink wants $32 for the paper on monadic recursion schemes though
17:40:01<edwardk>the current thought is to go through and define a redundant set of operators for the more restricted class of actions, and to build a manual set of instance of the more restricted type, but i still can't say that having something implies the existence of the more specific version
17:40:04<edwardk>in general mixing restricted and unrestricted monads seems to force one to become a really bad second class citizen
17:40:07<shachaf>> liftM2 (+) (*200) (+8) 10
17:40:08<lambdabot> 2018
17:40:24<SamB_XP>shachaf: ... it's easier to say and harder to mess up the typing?
17:40:53<ski>and also more tedious to type 'Reader' and 'runReader' all the time :)
17:41:06<edwardk>heh i like the Abstract version ((*200) + (+8)) 10
17:41:40<shachaf>> do { x <- ask; return (x+1) } $ 5
17:41:42<lambdabot> 6
17:41:45<glguy>where a -> a is an instance of Num?
17:42:09<ski>`(,(*200) + ,(+8)) 10
17:42:10<edwardk>glguy: where b -> a is an instance of AddMagma and MulMagma if a is
17:42:50<edwardk>er AddOp and MulOp now, since Magma is scary and would otherwise be all over the place inconsistently
17:42:57<SamB_XP>heh
17:43:04<ski>scary ?
17:43:32<edwardk>well, the problem is this, do I call every binary operator's overarching class a FooMagma?
17:43:50<ski>not if it isn't associative
17:44:03<edwardk>MeetMagma, JoinMagma, etc.
17:44:13<ski>take octonion multiplication, e.g.
17:44:15<edwardk>SemiGroup is associative =)
17:44:21<edwardk>Magma implies no such thing ;)
17:44:36<edwardk>the free magma is a binary tree with labeled leaves
17:44:38<ski>oh, sorry .. i can never remember what magma is :)
17:45:39<oerjan>edwardk: i recall that in Clean, the class corresponding to an operator has the same name as it
17:45:43<edwardk>thats one reason for the explosion of typeclasses to define it right, it'd be nice to be able to say that hey for this op to work the underlying operation you are using it over has to be associative and to give a SemiGroup constraint
17:46:03<edwardk>oerjan: i started there, but Add seemed like a weird typeclass. i may go back to it though
17:46:40<edwardk>especially now that i'm thinking that class Add a b c | a b -> c, b c -> a, a c -> b where (+) :: a -> b -> c
17:46:49<edwardk>which works for type level and term level math
17:47:00<edwardk>er
17:47:07<oerjan>edwardk: i mean the class of (+) is (+)
17:47:10<edwardk>yeah thats right
17:47:14<edwardk>ah
17:47:18<edwardk>can't do that in haskell =)
17:47:25<SamB_XP>yeah.
17:47:34<SamB_XP>you can't use variable names for classes in Haskell
17:48:03<edwardk>and there is no ability to use :+ either since that is only type and data constructors no?
17:48:11<wli>Higher-order classes would be nice.
17:48:24<SamB_XP>edwardk: what?
17:48:26<edwardk>wli: in a haskell setting the problem is type inference
17:48:31<roconnor>ACTION has a Mult class defining a mult operator like that
17:48:33<wli>edwardk: Point.
17:48:34<SamB_XP>I'm fairly certain that :+ is fair game in Haskell
17:48:44<SamB_XP>if it isn't, report a bug!
17:48:46<edwardk>samb: not for a class or instance name though
17:48:48<oerjan>edwardk: i thought you had already abolished the capitalization rules?
17:49:02<SamB_XP>oerjan: not in Haskell
17:49:05<edwardk>oerjan: two distinct settings, my language vs. this current prelude =)
17:49:09<edwardk>the prelude is haskell
17:49:12<edwardk>the language is not
17:49:22<oerjan>oh
17:49:27<edwardk>its a context thing =)
17:49:36<edwardk>you missed the context
17:49:59<SamB_XP>edwardk: yeah, you'd already established the my-new-language context ;-)
17:50:03<wli>edwardk: I really like the idea of formally including laws for classes in the language.
17:50:31<edwardk>samb: anyways even if :+ was legal for a type class name it'd be useless since you want a typeclass for that to be ternary anyways
17:50:58<EvilTerran>"(a :+ b) c" would be clear enough for me
17:51:01<olsner>heh, someone should write a device driver in VB - just for the evil of it!
17:51:03<oerjan>edwardk: i am reminded of Smalltalk syntax...
17:51:05<SamB_XP>I'm fairly certain (:+) supports >=2 args at least
17:51:15<edwardk>samb: can it be used as a typeclass name?
17:51:28<SamB_XP>edwardk: if it can't...
17:51:29<SamB_XP>@bug
17:51:29<olsner>@quote evil
17:51:30<lambdabot>http://hackage.haskell.org/trac/ghc/newticket?type=bug
17:51:30<lambdabot>Philippa says: <TomMD> Cale: I was wondering if something was wrong with the constructor "Red" :-) <Philippa> TomMD: it's supposed to be written EvilCommieBastard, duh
17:52:16<oerjan>allowing operators to be split into several words
17:52:18<EvilTerran>much like writing "container `get` key" leads naturally, imo, to writing "container `put` key $ value"
17:52:25<wli>Ternary operators are usually of the form "x & y @ z" etc.
17:52:27<psykotic>edwardk, i recall that fortress has support for specifying such laws as parts of interfaces/traits. it leaves unspecified how (or if) they are checked--a naive implementation could use some kind of randomized testing, a more sophisticated one could use theorem proving. but even having it there as a purely unchecked form of documentation/heads up would be nice.
17:52:35<edwardk>oerjan: yeah like (a + b = c) ?
17:52:40<wli>Or "(x, y, z)"
17:52:45<SamB_XP>olsner: can VB export functions with sufficiently arbitrary calling conventions and argument types?
17:52:55<edwardk>psykotic: thats actually what I do now more or less
17:52:57<wli>I suppose you could call that an outfix ternary operator.
17:53:25<oerjan>edwardk: words starting with : are continuations of the previous message
17:53:28<edwardk>psykotic: sort :: [a] -> { xs : [a] | sorted xs } the latter subset type is a proof obligation
17:53:32<wli>kind of like "(x, y)" is an outfix binary operator.
17:53:44<opqdonut>hehe outfix
17:53:45<olsner>not sure actually... but I guess you could make some glue code in a C/C++ dll (although that's cheating)
17:53:47<SamB_XP>wli: or you could call it special syntax
17:54:06<olsner>wli: circumfix
17:54:19<wli>SamB_XP: Then the problem of classifying special syntax arises.
17:54:30<olsner>the Vulcan language has circumfix verb conjugations
17:54:39<SamB_XP>olsner: also, I don't think the kernel has the vbvm dlls
17:54:39<edwardk>psykotic: or semigroup+ a = magma+ a with (+) :: a -> a -> a | associative (+)
17:55:12<EvilTerran>class l := r; data l :+ r; instance (a :+ b) := c where ... --?
17:55:37<wli>olsner: Russian has something of that sort, except the prefix is related to something called the "aspect," which is perfective vs. imperfective as opposed to being related to the actor.
17:55:42<SamB_XP>EvilTerran: hahaha
17:55:54<EvilTerran>>:]
17:56:03<edwardk>where associative f = forall a b c. (a + b) + c <%> a + (b + c) (forgive the horrible <%> syntax, but its what i currently have), the associative law can only really be checked randomly right now, but the <%> says this is a rewrite rule that the compiler can use
17:56:19<edwardk>er s/f/(+)/
17:56:20<wli>olsner: And it is more of a change to the verb's word stem as opposed to a prefix per se.
17:56:31<olsner>SamB_XP: it'll certainly be a challenge ;-)
17:56:37<SamB_XP>edwardk: was <=> taken?
17:56:42<edwardk>evilterran: hrmm, that works
17:57:05<edwardk>samb: yeah ternary comparison in a total order witnessing trichotomy ala perl. =)
17:57:06<EvilTerran>edwardk, aside from that extraneous "where" and probably needing some fundeps, yeah, i think so
17:57:17<SamB_XP>edwardk: what was wrong with `compare`
17:57:29<edwardk>the perl version is clearer =)
17:57:40<SamB_XP>how about <==>
17:57:45<EvilTerran>the intuitive definition of "greater than, equal to, or less than" is amusing ;]
17:58:08<SamB_XP>EvilTerran: you mean x <=> y = True ?
17:58:08<edwardk>and in my case there are two notions of rewrite permissability <%> allows interconversion for unification purposes and %> is a GHC-like one way confluent rewrite rule.
17:58:22<SamB_XP>edwardk: you could use ==> for the other one
17:58:31<edwardk>==> is implication =)
17:58:47<SamB_XP>--> and <--> ?
17:58:51<edwardk>like i said forgive the horrible notation, it just got crowded into an ugly corner =)
17:58:59<edwardk>that might wind up being the one i use
17:59:21<edwardk>i like those
17:59:23<EvilTerran>SamB, well, x <=> y IFF x < y | x = y | x > y, so it's not always true if the ordering isn't total
18:00:07<EvilTerran>apparently the unicode consortium considered this a sufficiently likely occurance to include "≶" in the maths bit
18:00:42<EvilTerran>I'm not sure how it differs from "≷", tho.
18:01:00<Cale>⋚
18:01:14<EvilTerran>sorry, yes, those two omitted equality. I wanted ⋚ and ⋛.
18:01:29<opqdonut>ahh
18:01:36<opqdonut>unicode :)
18:01:44<opqdonut>i just saw question marks and got flummoxed
18:01:51<edwardk>right now i have preorders with <~ >~ and ~, /~, partial orders with <= >= = /=with induced strict orders < and >, and an as yet unsymbolicized incomparable notion, so that pcompare returns something like Maybe Ordering, and total orders which give a trichotomy law <=> where it just returns Ordering
18:02:05<EvilTerran>there's some really funny operators in there... "⋇" aka "divison times" anyone?
18:02:30<Cale>I can't say I've ever needed that one.
18:02:44<edwardk>heh, i could just revert to the unicode operators but reading code with &ltgt; or whatever the long form is would get weird.
18:03:27<EvilTerran>...can you use unicode symbols as haskell operators?
18:03:40<edwardk>i believe ghc allows it now
18:03:41<edwardk>hrmm
18:03:49<edwardk>hey i have a new toy for my prelude =)
18:03:52<puusorsa>hooray!
18:04:07<edwardk>not sure its a GOOD idea, but hey
18:04:10<Cale>∔ -- this one is actually useful occasionally (when you want to talk about both plus and times at the same time)
18:04:29<edwardk>fmap = &cdot; =)
18:04:33<EvilTerran>ACTION wouldn't mind (≤) = (<=), (≠) = (/=), (×) = (*), etc
18:04:43<EvilTerran>ACTION wanders off for a bit
18:04:43<Cale>f∘g
18:04:46<edwardk>yeah
18:05:05<Cale>∘
18:05:09<Cale>\circ
18:05:19<edwardk>would finally get me out of using vim over the network to edit source files
18:05:37<EvilTerran>(i'd have to train my editor with the appropriate keyboard shortcuts, mind)
18:05:46<Cale>edwardk: why's that?
18:06:06<Cale>I just install SCIM.
18:06:07<EvilTerran>edwardk, with a suitably modern terminal, it should work fine. or with gvim.
18:06:15<EvilTerran>anyway. away!
18:06:19<Cale>(and the latex table)
18:06:28<edwardk>evilterran: yeah, my terminal is just not suitably modern for some reason =)
18:06:34<EvilTerran>heh.
18:07:00<Cale>However, I think composition is common enough to warrant having something that's one keypress to type.
18:07:14<edwardk>so in the interest of full obfuscation should i just start throwing unicode operators at problems then? =)
18:07:47<shapr>sure!
18:08:14<shapr>edwardk: But, doesn't ghc explode on unicode?
18:08:30<glguy>ghc 6.6 handles unicode in .hs files
18:08:58<edwardk>one thing i do find missing in haskell is the ability to define an overloaded application when the lhs isn't a function type. i still can't define that [1,2,3] 0 = 1 thats one piece of my prelude i can't port over
18:09:19<edwardk>or similarly for indexing arrays, etc.
18:09:39<opqdonut>yeah overloaded application would be cool
18:09:47<opqdonut>though i guess it could be horribly misused
18:09:52<edwardk>sure
18:10:01<edwardk>and its a pain to figure out how to type infer i'll confess =)
18:10:11<glguy>m
18:11:47<edwardk>i think i tried at one point changing $ for it, but ran afoul of type inference problems
18:12:31<edwardk>oh yeah way back when on ##logic with cale and dons when we came up with the (.) trick
18:12:46<wli>edwardk: Which (.) trick is this?
18:13:03<edwardk>class Functor f where (.) :: (a -> b) -> f a -> f b
18:14:02<edwardk>it started with me trying to come up with really really general signatures for ($) and (.) before i realized my stupidly general signatures weren't inferrable.
18:14:14<edwardk>at the time i was mixing in arbitrary arrows as well.
18:14:25<mnislaih>fwiw, <$> works wonders
18:14:34<glguy>?where shootout
18:14:35<lambdabot>http://shootout.alioth.debian.org/
18:15:21<glguy>:-( dylan isn't on the shootout
18:15:56<edwardk>because looking at (.) above one wonders why its a -> on the outside and not an Arrow c a b => c a b -> c (f a) (f b) since functors map arrows after all, then of course they map arrows to arrows so the truly general signature is worse, etc. =)
18:16:30<edwardk>its a very slippery slope that leads to madness
18:17:03<_Nucleo>@src genericTake
18:17:03<lambdabot>Source not found. BOB says: You seem to have forgotten your passwd, enter another!
18:18:04<oerjan>genericTake 0 _ = []
18:18:04<oerjan>genericTake _ [] = []
18:18:04<oerjan>genericTake n (x:xs) | n > 0 = x : genericTake (n-1) xs
18:18:04<oerjan>genericTake _ _ = error "List.genericTake: negative argument"
18:18:31<Botje>:t genericTake
18:18:34<lambdabot>forall i a. (Integral i) => i -> [a] -> [a]
18:18:53<edwardk>at the time i was new to haskell and was still kind of obsessed with removing the injective nature of a lot of things. the abuse of type constructors as tags in haskell still bugs me, but i have to admit that the inference it gives rocks.
18:19:24<ski>injective ?
18:19:30<_Nucleo>oerjan: thanks
18:20:19<edwardk>the fact that functors in haskell aren't truly all endofunctors on the category of types, they only act as endofunctors from the 'larger' category of all types into a smaller subset delimited by the typeconstructor of the functor.
18:20:27<oerjan>edwardk: i think of type constructors as all being in essence newtypes, with the main purpose of creating a new type
18:20:54<oerjan>everything else can be desugared to functions :)
18:21:11<edwardk>so in addition to fmap :: (a -> b) -> f a -> f b one would like (g a -> g b) -> a -> b and (f a -> f b) -> g a -> g b at least, or to move to the painfully general arrow notations above that are even less productive
18:22:08<opqdonut>well you could just have some sort of "switch functor" function
18:22:12<edwardk>in the end i came around to the haskell way of thinking but it was a long road =)
18:22:29<opqdonut>those are all it's specializations
18:22:39<opqdonut>*specialisations
18:22:39<shapr>edwardk: Sounds like a good blog post to me.
18:22:46<edwardk>opqdonut: the issue i had at the time is that a functor isn't a fully general functor =)
18:23:13<oerjan>edwardk: missing a lot of categories too...
18:23:14<edwardk>its just the Hom map of an endofunctor into a subset of the category of all types.
18:23:37<edwardk>the Ob map is entirely missing as return isn't part of functor
18:24:22<edwardk>i got used to it though
18:24:54<edwardk>the asymmetry led me to drive cale to distraction I think for a while though when i first showed up here though =)
18:25:43<Cale>edwardk: the Object map isn't missing at all
18:25:50<edwardk>?
18:25:50<Cale>It's the type constructor.
18:26:06<Cale>That is, the thing which you're making an instance of Functor :)
18:28:02<edwardk>i think calling it the type constructor is conflating two notions though. return seems to me to be really an object map. mapping objects into the same place as you map arrows, you can't move objects with just the type constructor like you can move arrows with map, you can just name what they should move to
18:28:37<Cale>return is a natural transformation from the identity functor to your functor
18:29:14<Cale>Objects are types, the object map of a functor sends types to other types
18:29:59<Cale>Of course, in Haskell, you don't have complete control over what the object map is -- you have to pick something which is in some sense natural.
18:30:13<edwardk>my main issue is ideally i'd like to be able to define a real 'identity functor' and the forced existence of a tag kind of keeps that from happening, but thats the whole haskell mindset of using tags to break apart cases so it can't really be worked around in the context of the system. I agree that in haskell the answer that haskell uses is the right one. in the presence of the ability to pass an explicit dictionary and use type level funct
18:30:15<ski>a functor 'F' from 'C' to 'D' consists of a map 'F.mapObj : C.Obj -> D.Obj' and a map 'F.mapMor : forall A,B :: C.Obj . C.Mor (A,B) -> D.Mor (F.mapObj A,F.mapObj B)' (together with the requirement that those respects identities and composition)
18:31:06<Cale>Hehe, OO syntax :)
18:31:19<ski>just record syntax, yes
18:31:56<edwardk>thats what i use in my toy compiler more or less for them, or rather whats lurking in the prelude waiting for the compiler to successfully parse it ;)
18:35:04<ski>ACTION has been pondering a way to think of morphisms as effectful things (and objects being effectless) ..
18:35:32<edwardk>ski: a tofte and talpin style type and effect system basically?
18:36:20<ski>hm .. maybe a little bit like that .. more related to my ideas about quotation
18:37:41<edwardk>i've been trying to figure out the right way to reflect an effect into a monad and reify the monad back out into an effect, so you can treat the monad as a value, and run the monad to get the effect as an effectful computation, but i haven't come up with anything clean
18:38:16<edwardk>http://www.comp.mq.edu.au/~asloane/pmwiki.php/SAPLING/SAPLING071?action=download&upname=lippmeier-slides071.pdf was a good paper and i'm amused he takes the same kitchen sink approach to features i do (largely the same features even)
18:38:18<lambdabot>http://tinyurl.com/3y7tb7
18:38:18<ski>e.g. if 'F,G : C -> D', 'eta : F -> G', 'A,B : C' and 'f : A -> B', then '`(,eta ,f) : F A -> G B' which strikes me as a nice way of denoting that diagonal morphism
18:38:45<edwardk>er not paper, presentation i guess
18:38:59<ski>ty for link
18:39:58<edwardk>in that setting note the -(effects)> on the arrows. what i'd like to do is be able to reflect those into a monad parameterized by the effects in question so that the monad when later invoked causes those effects to happen.
18:40:08<edwardk>rather than have the effects happen when crossing the arrow
18:40:19<ski>(more common ways of denoting that diagonal is as 'eta_B . F f' or alternatively (and symmetrically) as 'G f . eta_A')
18:41:19<ski>edwardk : hehe .. that is what i'm doing in my (not completed) monad effect system :)
18:43:07<ski>(if you want elaboration on the diagonal above, just ask)
18:45:11<edwardk>ski: so what i want is something like reify :: m effects a -(effects)> a, and a metalinguistic form of reflect that can capture actions leading to effects, then you can get haskell like separation of evaluation and execution
18:46:17<ski>ACTION gets separation of evaluation and execution in his system .. that being one of the design goals
18:46:56<edwardk>because it seems that ben's system above has the problem that a lot of those sorts of systems have, that they conflate reduction to normal form with running the effects involved.
18:47:12<ski>ACTION nods
18:47:15<edwardk>its one of the more elegant points in haskell's and forsythe's design that people often over look =)
18:47:54<ski>i'd say its one of the main point of bothering with monads
18:48:23<edwardk>i find it funny that you were talking about this a few months ago, and I largely ignored you because I couldn't figure out what you were rambling on about until I encountered the same problem and puzzled it out for myself =P
18:48:36<ski>ACTION smiles
18:50:38<edwardk>btw- i still want to find a practical way to exploit some of the ideas of the hoare type theory separation logic monad in a practical language though.
18:51:08<ski>ACTION attempts to recall what that was .. again
18:51:09<edwardk>seems like a lot of the 'is this monad commutative' questions can be answered by an approach like that
18:51:19<shapr>Is it better than nanevski's stuff?
18:51:23<edwardk>{ P } t { Q}
18:51:31<edwardk>it kind of half-is nanevski's stuff =)
18:51:47<edwardk>since at last check he was doing a post-doc or something working with greg morrisett at harvard on it
18:51:56<ski>(>>=) :: m o p a -> (a -> m p q b) -> M o q b -- ?
18:52:00<mattam>what would be the other half ?
18:52:21<shapr>salut mattam
18:52:24<edwardk>well, iirc amal ahmed, and greg morrisett were working on it, not sure who else
18:52:33<ski>shapr : good evening
18:52:40<shapr>tjenare ski!
18:52:58<mattam>yep the Y_0 team
18:53:04<shapr>ski: Hej Herr Stefan!
18:53:12<edwardk>heh, i moved out here to within about 3 miles of harvard and I've yet to actually have an excuse to set foot on the campus.
18:53:22<ski>ACTION feels a bit too excited .. even though he ought to go to sleep
18:54:22<edwardk>hrmm actually closer to a mile
18:54:24<mattam>Hmm, it seems there's a good team of plt people there, aren't you acquainted with anyone there ?
18:55:03<edwardk>I met Fluet, Ahmed and Nanevski briefly at the ICFP last year, but I doubt they remember be beyond me being the 'crazy comonad guy' =)
18:55:10<edwardk>er remember me
18:55:28<mattam>hehe
18:55:34<edwardk>and at last check all but nanevski had fled the area to go to TTI in chicago
18:55:55<chrisamaphone>anyone here know anything about type theory/logic schools that aren't in the u.s.?
18:56:07<ski>(oh, right .. i think my system can be applied to comonads, maybe arrows, .. and also in a way to equality proofs :)
18:56:47<chrisamaphone>(i'm currently an undergrad in cs at cmu.)
18:56:52<ski>chrisamaphone : Chalmers/Gothenburg University has Haskell research
18:57:24<chrisamaphone>ski: ok, i've been meaning to look into chalmers.
18:57:33<ski>ACTION is currently an undergrad at chalmers/GU
18:57:44<mattam>chrisamaphone: There's a good master program in Paris
18:57:56<chrisamaphone>inria?
18:58:09<edwardk>ski: anyways the pre and post conditions in those hoare type theory monads just specify the pre and post conditions for the heap in which they can run, so you get sort of runs of things that can happen in parallel rather than a purely sequential composition.
18:58:12<chrisamaphone>i've actually found a bunch of interesting stuff in sweden.
18:58:19<mattam>http://mpri.master.univ-paris7.fr/english/index.html
18:58:19<shapr>Me too!
18:58:31<chrisamaphone>i just don't know anyone with firsthand experience with any of it.
18:58:37<mattam>They even have an english translation :)
18:58:41<shapr>Chalmers is awesome, if you can get in.
18:58:44<ski>edwardk : was my '(>>=)' type signature related to that or not ?
18:59:22<quicksilver>edwardk: I have some vague ideas about using seperation logic to optimise query languages
18:59:27<chrisamaphone>mattam: i'd ideally go into a phd program, but this does look interesting.
18:59:39<edwardk>ski: close, but think of two actions {P} x : t {Q} and {P'} y : t2 {Q'} as being able to operate in parallel as long as their conditions don't conflict.
18:59:53<edwardk>i.e. if they mention different portions of the heap
18:59:57<mattam>There are links to most doctoral studies schools around
18:59:57<quicksilver>edwardk: help you find out how to divide a query between threads or indeed machine, safely
19:00:26<ski>edwardk : ok .. more arrowic, then ?
19:01:14<mattam>well, the separation logic stuff can be separated from the Hoare type theory somehow.
19:01:55<edwardk>well, if two actions are disjoint they can be run in parallel. that reminds me I need to slap together that Par monad.
19:02:50<ski>?
19:02:55<ski>resumptions ?
19:03:20<jameysharp>sjanssen: ping?
19:03:51<ski>data Resumption a = Return a | Yield (Resumption a)
19:03:56<edwardk>given something :: { P } x : t { Q}; somethingelse :: { P' } y : t' { Q'}, something >> somethingelse can just both be executed in parallel if the operation { P } x : t {Q} doesn't mention the same stuff in the heap as { P'} y : t' {Q'}
19:04:47<edwardk>resumptions being the Par monad thing?
19:04:49<glguy>STRef IORef MVar TVar TMVar, am I missing any?
19:05:04<ski>edwardk : that was supposed to be my query, yes
19:05:16<edwardk>the Par monad was just a stupid newtype Par a = Par { runPar :: a }; with Par m >>= k = m `par` k m
19:05:32<ski>glguy : 'SampleVar' ?
19:05:35<edwardk>an identity monad that sparks speculation
19:05:36<glguy>oh yeah
19:05:58<edwardk>glguy: building a MonadRef kind of library?
19:06:03<oerjan>@index SampleVar
19:06:03<lambdabot>Control.Concurrent.SampleVar, Control.Concurrent
19:06:09<glguy>ACTION is tired of not having a modifyRef
19:06:13<edwardk>heh
19:06:13<glguy>swapRef
19:06:45<ski>should there be any fundeps in it, if so, which direction ?
19:07:01<edwardk>yeah, though i admit the big three of IO/IORef, ST/STRef STM/TVar would be good enough for me, and it gives fundeps
19:07:19<edwardk>and fundeps are problem.
19:07:27<glguy>fundeps wouldn't be needed if you use newIORef
19:07:31<glguy>and then switch to the generic functiosn
19:07:55<edwardk>yeah but then i can't parameterize my hash table off of the type of monad its designed for =)
19:07:56<ski>'newRef' !
19:08:03<edwardk>not so easily
19:08:17<SamB>ACTION just joined facebook for some reason
19:08:27<glguy>myspacebook?
19:08:34<SamB>facebook!
19:08:42<ski>ACTION built a 'LogVar' parameterized over an arbitrary 'ref' in 'MonadRef'
19:08:55<glguy>previous attempts at a Data.Ref were killed because people couldn't agree on how to do it
19:09:05<glguy>so I'm thinking that I'd rather have it than not
19:10:08<SamB>how can it work if you don't parameterize the datastructure
19:10:11<edwardk>so would the right answer on a fresh slate be to newtype IO, etc. so that under the correct newtype you got the MVar version of things for instance?
19:10:40<edwardk>samb: type family, one parameter of the monad thats it
19:11:09<edwardk>or a fundepped MonadRef kind of class
19:11:49<ski>exists :: (Quantifiable ref a,MonadRef ref m) => (a -> Logic m b) -> Logic m b
19:11:49<edwardk>withMVarRefs $ do ...
19:12:19<ski>bound :: MonadRef ref m => a -> Logic m (LogVar ref a)
19:12:22<ski>(etc)
19:12:41<quicksilver>edwardk: if you newtype IO aren't you in lifting hell every time you try to do any other IO operation?
19:12:59<quicksilver>edwardk: (until the *entire* standard library is rewritten with MonadIO primitives instead of IO ones)
19:13:11<edwardk>quicksilver: the setting being a new prelude in which IO is modular and all methods in it lift somehow
19:13:20<quicksilver>oh, I see
19:13:34<quicksilver>right, sounds plausible to me :)
19:13:38<ski>it'd be nice to have someting a bit like hugs restricted type synonyms .. but openable at will later
19:14:20<edwardk>quicksilver: well, i';m thinking a huge chunk of template haskell =)
19:14:35<ski>('newtype f Foo = MkF (f Bar)' could be nice, as well)
19:14:39<edwardk>and a preprocessing job to pull in a good chunk of the library
19:15:04<edwardk>right now i do something like that to steal numeric types
19:17:00<edwardk>foreign imports would be second class citizens without some form of template magic as well though =(
19:17:51<edwardk>gah the IO monad is really cemented into Haskell's worldview isn't it
19:18:20<ski>the sin-bin
19:18:24<edwardk>yeah
19:18:53<edwardk>its just bolted in there good though
19:18:59<Cale>I don't see it as a sin-bin, personally.
19:19:15<Cale>Of course, perhaps at present, it might have a few things in it which it shouldn't.
19:20:02<Cale>But generally, I think using some form of combinator library to deal with IO is the right way to go, and if that combinator library happens to be a monad, there's no reason not to make it one.
19:20:10<shapr>SamB: What's your facebook email?
19:20:23<edwardk>so the trick would have to be something like $(importForeign ...) where that automatically made the wrapper that took an arbitrary MonadIO instance and made it able to run this
19:20:24<ski>what is "IO" ?
19:21:15<edwardk>and that would leave the ugly side effect that you couldn't use the action you just imported in the same module you just imported it into unless you dealt with lift hell.
19:26:07<Nopik>hi again
19:26:50<Nopik>heh, the topic should say: "The Haskell programming language: fit infinite lists into few bytes" :D
19:27:09<Nopik>.. just as linux is doing infinite loops in 5 seconds :D
19:27:22<shapr>BogoLists?
19:29:50<glguy>there really can't be a functional dependency in "MonadRef" since things like TVar can be created in multiple monads (IO and STM) and muliple Ref Types can be created in a single monad (MVar IORef) so that makes it easy to decide
19:33:08<ihope>Nopik: Haskell can do that too!
19:33:11<ihope>> last (repeat ())
19:33:16<lambdabot>Terminated
19:33:20<ihope>Okay, maybe it can't.
19:33:23<ihope>> let x = x in x
19:33:24<Nopik>hehe :)
19:33:24<lambdabot> Exception: <<loop>>
19:34:43<_Nucleo>@src LiftM2
19:34:43<lambdabot>Source not found. It can only be attributed to human error.
19:34:46<quicksilver>> concat . repeat $ []
19:34:47<lambdabot> Exception: <<loop>>
19:34:47<_Nucleo>@src liftM2
19:34:47<lambdabot>liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) }
19:35:15<glguy>liftM2 f x y = return f `ap` x `ap` y
19:35:28<_Nucleo>@src ap
19:35:28<lambdabot>ap = liftM2 id
19:35:33<_Nucleo>heh
19:35:43<Nopik>damn.. i have installed gd library, but when I try to import Graphics.GD in my code, runghc says: can't load .so/.DLL for: pthread (/usr/lib64/libpthread.so: invalid ELF header)
19:37:08<Nopik>i tried to run plain ghc, but it throws bunch of undefined references.. any ideas what option i should add to ghc to add proper library to link with?
19:37:14<EvilTerran>have you got the pthreads dynamic library files (in a place GHC can find 'em)?
19:38:05<EvilTerran>s/can/should be able to/
19:38:58<_Nucleo>@undo do { x1 <- m1; x2 <- m2; return (f x1 x2) }
19:38:58<lambdabot>m1 >>= \ x1 -> m2 >>= \ x2 -> return (f x1 x2)
19:39:38<Nopik>well, my system uses pthread all the time, and i did not moved them at all :)
19:39:59<oerjan>m1 >>= \ x1 -> m2 >>= \ x2 -> return (f x1 x2)
19:40:46<quicksilver>EvilTerran: that wasn't file not found
19:40:50<quicksilver>EvilTerran: it was invalid ELF header
19:41:05<quicksilver>Nopik: I think you have a mixed 64bit/32bit system and something has gone awry?
19:41:08<oerjan>@pl m1 >>= \ x1 -> m2 >>= \ x2 -> return (f x1 x2)
19:41:08<lambdabot>(`fmap` m2) . f =<< m1
19:41:37<Nopik>quicksilver: well, i am working on amd64, everything should be 64bit
19:41:41<Nopik>unless something is not :D
19:41:42<oerjan>@pl \m1 m2 -> m1 >>= \ x1 -> m2 >>= \ x2 -> return (f x1 x2)
19:41:42<lambdabot>liftM2 f
19:41:43<EvilTerran>huh. well, it was just a thought. i don't know what an ELF header
19:41:47<EvilTerran>is
19:41:53<quicksilver>could be the GD library wasn't 64 bit clean
19:42:02<Nopik>linux executables are in ELF format
19:42:08<quicksilver>or the FFI bindings used by the haskel-gd binding aren't 64 bit clean
19:42:11<Nopik>quicksilver: maybe.. though i just compiled it minute ago
19:42:23<ski>@redo m1 >>= \ x1 -> m2 >>= \ x2 -> return (f x1 x2)
19:42:23<lambdabot>do { x1 <- m1; x2 <- m2; return (f x1 x2)}
19:42:54<msouth>but isn't it saying that the .so has something it isn't expecting? like it's for wrong architecture?
19:43:44<Nopik>heh, but when i run ghc -v option, it displays gcc command.. if i copy/paste, add proper -L -l, it works
19:44:16<Nopik>but manually running gcc is not what user is meant to do, i bet ;p
19:46:21<Nopik>ok, managed to run via ghc using the same -L -l options
19:46:33<Nopik>now, the question is how to run the same thing using runghc ;p
19:56:35<Nopik>ok, next bit in this pthread puzzle: /usr/lib64/libpthread.so is a ld script on my system.. strace shows that runghc looks at /usr/local/lib/gd-3000.3.0/ghc-6.6.1/libpthread.so before going into /usr/lib*, so i copied /lib64/libpthread.so.0 (which is proper ELF file) into /usr/local/lib/gd-3000.3.0/ghc-6.6.1/libpthread.so and it works
19:56:59<SamB>Nopik: what? no symlinks?
19:57:15<Nopik>SamB: yeah ;P
19:57:43<EvilTerran>ACTION meditates on unsafeCoerce#
19:58:07<Nopik>http://hpaste.org/1717
19:58:52<fasta>It seems the popularity of unsafe operations is on the rise...
19:59:23<EvilTerran>wow. nice name there -- GHC.Prim.reallyUnsafePtrEquality#
20:00:01<Cale>EvilTerran: Yeah, just 'unsafe' wasn't discouraging enough, I suppose.
20:00:03<EvilTerran>fasta, i'm merely thinking about it, not seriously intending to use it. i'm sure i'm missing something, and that probably wouldn't fix it
20:00:46<fasta>EvilTerran: I do unsafe things all the time, and my machine didn't explode :)
20:01:02<fasta>EvilTerran: although, some stuff did break between 6.6 and 6.7
20:01:23<fasta>I don't recommend unsafe for nuclear reactors, though.
20:01:31<EvilTerran>okay. well, as i said, i don't intend to really use it. best stay safe if at all possible, eh.
20:02:46<glguy>is the next adjective: dangerous, as in dangerousPtrEquality#
20:02:52<glguy>or maybe disasterous
20:03:13<glguy>unwise?
20:03:46<EvilTerran>hazardous?
20:03:51<oerjan>wmd
20:03:55<EvilTerran>omg?
20:03:57<SamB>dasasterous probably
20:04:07<SamB>for that particular one
20:04:08<fasta>How about "tryme"?
20:04:23<SamB>probablyWrongPtrEquality#?
20:04:33<EvilTerran>bigRedButtonPtrEquality#
20:04:39<fasta>Nice and short, just like people who like shooting themselves in the foot like.
20:04:46<glguy>notReallyPtrEquality
20:04:48<ski>willMakeYouInsanePointerEquality#
20:04:51<SamB>seqFirstIfYouWantInterestingResultsPtrEquality#?
20:05:00<EvilTerran>iahIahCthulhuPtrEquality#
20:05:06<ski>;)
20:05:15<wli>Try pointer inequalities.
20:05:17<fasta>"used_as_source_of_randomness_by_some"
20:05:40<wli>p - q <= 2*(p' - q') etc.
20:05:45<EvilTerran>schrödingerPtrEquality#, complete with umlaut to really be difficult.
20:05:50<SamB>wli: those are positively wrong
20:06:08<wli>Don't forget screwed up pointer differencing semantics.
20:06:09<newsham>so icfp contest is run by a bunch of haskell zealots this year?
20:06:10<SamB>wrongPtrGTE
20:06:12<newsham>that should bode well
20:06:28<fasta>newsham: nice troll
20:06:34<newsham>no troll intended.
20:06:49<ski>haskell libs should have more really long identifiers
20:06:53<newsham>I'm not a haskell zealot, but i'm 50% of the way there.
20:07:02<ski>(like 'call-with-current-continuation' in scheme)
20:07:05<wli>I have no idea how people can get so worked up about languages as to be zealots about them, but I've seen it happen.
20:07:24<fasta>newsham: I think it were run by Scheme "zealots" last year.
20:07:38<SamB>fasta: hah
20:07:42<newsham>wli: some people are prone to zealotry, in other situations its a reflection of the competition more than the language itself ;-)
20:07:49<Cale>'CentralizerInAssociativeGaussianMatrixAlgebra'
20:07:51<SamB>then why did they use an ML variant to write the codex?
20:08:01<newsham>fasta: it was a good set of problems, though.
20:08:09<fasta>SamB: that's a diversion
20:08:12<Cale>'AbelianNumberFieldByReducedGaloisStabilizerInfo'
20:08:22<ski>Cale : ty
20:08:28<Cale>I love GAPs long identifiers :)
20:08:30<SamB>fasta: do you think this because they never parodied scheme?
20:08:34<wli>That hair shirt retrospective thing said the next version of ML was going to adopt typeclasses.
20:08:45<wli>Or was it monadic IO?
20:08:57<SamB>wli: how do you take one without the other?
20:09:12<SamB>where "one" is monadic IO
20:09:17<wli>SamB: I'm not sure. It only said one and I'm inferring the other.
20:09:42<fasta>Type classes... is that like Jaaavaaa?
20:10:08<SamB>fasta: stop it before I call you a 2d lover!
20:10:10<opqdonut>no, that's like haskell :)
20:10:25<wli>fasta: I wish they'd have been called something else like "qualified types" or "type qualifiers" or "modal types" or something.
20:10:31<SamB>or... worse... an o'cult lover!
20:10:54<newsham>a rose by any other name would smell as sweet
20:11:15<SamB>wli: but then what would we call "methods"?
20:11:55<wli>SamB: Something else. Domain-restricted polymorphic functions?
20:12:22<SamB>wli: and *that* is as good a reason as any to call typeclasses that ;-)
20:12:32<ski>SamB : "qualified-type-properties" ?
20:12:44<opqdonut>interfaces?
20:12:46<opqdonut>;)
20:12:54<SamB>also it doesn't distinguish methods from functions that *use* methods
20:13:00<EvilTerran>i've got it! interestingPtrEquality# !
20:13:12<SamB>EvilTerran: how about boringPtrEquality#
20:13:13<EvilTerran>oh, wait... the conversation's moved on. ignore me. ;]
20:13:23<SamB>since it usually returns False
20:13:35<glguy>it usually returns an Int#
20:13:38<opqdonut>how about totallySafeAndEntirelyHarmleePtrRquality#
20:13:41<SamB>glguy: oh.
20:13:44<opqdonut>*Harmless
20:14:11<EvilTerran>samb, it's a reference (to PTerry, iirc); allegedly a traditional curse is "may you live in interesting times!"
20:14:28<ski>safePtrEquality :: Execution a -> Execution b -> Possibly (Equal a b)
20:14:53<ski>('Possibly' being a monad a bit like 'Maybe')
20:15:13<opqdonut>Remotely (Possibly (Equal a b))
20:15:44<newsham>data PLZ a = AWSUM_THX a | O_NOES String
20:15:45<dozer>EvilTerran: usually people under that curse say something like: "It was never booring" after their third wisky
20:16:00<EvilTerran>hehe
20:16:01<ski>runPossibly :: Possibly a -> Nondet (Maybe a)
20:16:09<newsham>http://www.haskell.org/pipermail/haskell-cafe/2007-May/026142.html
20:16:11<lambdabot>Title: [Haskell-cafe] data PLZ a, http://tinyurl.com/2my4vu
20:16:57<ski>runNondet :: Nondet a -> IO a
20:17:17<ski>unsafePeekExecution# :: a -> Execution a
20:17:37<newsham>unsafeGuessAtAnswer
20:17:51<Nopik>ok, there is: mapM_ (\x -> setPixel (x, 10) red pic) [0..w] how to make it work over 2 dimensional array (like [0..w] [0..h])?
20:17:55<opqdonut>unsafeOptimize
20:17:57<newsham>stand back, I'm going to try SCIENCE
20:18:00<Nopik>should i make mapM_ nested?
20:18:09<Nopik>or, there is simpler way?
20:18:12<ski>(where 'Execution a' is a representation of a thunk, or something like that .. so you can check if it's been forced yet, e.g.)
20:18:18<SamB>ACTION tries to figure out how JHC treats Bool as being "data Bool = Bool# Bool__" (or something like that) when it is declared "data Bool = False | True"
20:18:22<opqdonut>Nopik: well, nested mapM_ would work
20:18:42<mattam>newsham: you're not too far from being a geek if not a zealot anyway :)
20:18:49<ski>@index forM_
20:18:49<lambdabot>bzzt
20:18:56<newsham>mapM_ func [(w,h) | w<-[0..w], h<-[0..h]]
20:18:57<Nopik>i just want nested for loop :P
20:19:15<ski>forM_ = flip mapM_
20:19:20<ski>do ...
20:19:21<newsham>yes, forM_ superior
20:19:35<Nopik>why superior?
20:19:40<ski> forM [0..w] $ \w ->
20:19:41<newsham>why nest loops when you can cross-product
20:19:46<ski> forM [0..h] $ \h -> do
20:19:59<Nopik>hm, let me try
20:19:59<newsham>nopik: because I program in #python, and forM is like my imperative friend
20:20:00<ski> func (w,h)
20:20:42<ski>(s/forM /forM_ /)
20:21:07<EvilTerran>Nopik, if mapM_ does what i think it does, i'd be tempted to do a list comprehension over the two lists, and then sequence_ it
20:21:09<Nopik>not in scope forM_ ?
20:21:25<Nopik>EvilTerran: yeah, i'm trying to do so
20:21:29<newsham>import Control.Monad
20:21:32<EvilTerran>?type sequence [setPixel (x, y) red pic | x <- [0..w], y <- [0..h]]
20:21:34<lambdabot>Not in scope: `setPixel'
20:21:34<lambdabot>
20:21:34<lambdabot><interactive>:1:26: Not in scope: `red'
20:21:45<EvilTerran>hm
20:21:47<ski>ACTION once made a monad so he could say 'do {w <- for_list [0..w]; h <- for_list [0..h]; func (w,h)}' :)
20:21:57<Cale>?type sequence [?setPixel (x, y) ?red ?pic | x <- [0..w], y <- [0..h]]
20:21:58<lambdabot>Not in scope: `w'
20:21:59<lambdabot>
20:21:59<lambdabot><interactive>:1:61: Not in scope: `h'
20:22:03<Cale>?type sequence [?setPixel (x, y) ?red ?pic | x <- [0..?w], y <- [0..?h]]
20:22:05<lambdabot>Not in scope: `..?'
20:22:05<lambdabot>
20:22:05<lambdabot><interactive>:1:49: Not in scope: `w'
20:22:09<Cale>er, right
20:22:12<Cale>?type sequence [?setPixel (x, y) ?red ?pic | x <- [0.. ?w], y <- [0.. ?h]]
20:22:14<lambdabot>forall t t1 (m :: * -> *) a t2 t3. (Num t2, ?w::t2, Enum t2, Num t3, ?h::t3, Enum t3, ?setPixel::(t2, t3) -> t -> t1 -> m a, ?red::t, ?pic::t1, Monad m) => m [a]
20:22:17<Cale>hehe
20:22:33<ski>(but for some strange reason the laboration examiner thought it was overkill for solving sudoku ...)
20:22:34<EvilTerran>the significant component of that being the thoroughly uninteresting "m [a]"
20:22:43<Nopik>hm, now i have forM_, list comprehension etc. it compiles, but i see no result ;p
20:22:48<Nopik>just like iterating over empty list
20:22:50<newsham>> do { w <- [0..2]; h <- [0..2]; return (show w ++ " " ++ show h) }
20:22:50<EvilTerran>ski, does that differ from the list monad?
20:22:51<lambdabot> ["0 0","0 1","0 2","1 0","1 1","1 2","2 0","2 1","2 2"]
20:22:55<ski>I HAD so much FUN !
20:23:15<ski>EvilTerran : it was based on a continuation monad (transformer) with shift/reset
20:23:18<Nopik>ok, my mystake ;p
20:23:37<EvilTerran>Nopik, the _ indicates it shouldn't return a result
20:23:39<ski>Nopik : now do IO in the body
20:24:00<Nopik>EvilTerran: no, i had \x -> setPixel (w,h) while i should have \(w,h) -> ...
20:24:03<glguy>> sequence ["012"," ","012"]
20:24:04<lambdabot> ["0 0","0 1","0 2","1 0","1 1","1 2","2 0","2 1","2 2"]
20:24:05<EvilTerran>ahh
20:24:12<Nopik>works now
20:24:21<Nopik>my first nested for in haskell :)
20:24:42<oerjan>:t forM
20:24:44<lambdabot>forall a (m :: * -> *) b. (Monad m) => [a] -> (a -> m b) -> m [b]
20:24:48<Nopik>though it iterates 500x500 for 1.5 sec ;p
20:25:13<ski>actually .. to say the truth i couldn't use the 'do' syntax but instead 'bindC' and 'returnC', since i had more general types ..
20:26:26<SamB>ski: -fno-implicit-prelude
20:26:27<SamB>;-P
20:27:11<Nopik>ok, how to write thing like [0..(w/2)] ?
20:27:31<SamB>> 25 `div` 2
20:27:32<Nopik>div w 2 ;)
20:27:33<lambdabot> 12
20:27:36<newsham>"my first nested for in haskell" is amusing cause most idiomatic haskell coders dont use nested fors
20:27:47<hpaste> (anonymous) pasted "Imperative Hoare" at http://hpaste.org/1718
20:27:57<Nopik>newsham: my first nested for equivalent? :)
20:28:21<newsham>what i mean is -- you're probably doing things "the imperative way" when you could do it nicer "the haskell way"
20:28:25<newsham>(I do that all the time myself)
20:28:39<Nopik>newsham: maybe
20:28:49<SamB>newsham: what's a nicer way to do a cross product?
20:28:49<ski>loopCT :: (QuantifiableCollection f,Monad m) => f a -> Cont2T (f b) b m a -- this appears to have been my general looping construct
20:29:15<Nopik>newsham: so, how to iterate function over 2 dimensional array in 'haskel way'?
20:29:35<SamB>Nopik: the other way is list comprehensions, I guess...
20:29:41<quicksilver>Nopik: 2 dimensional array or 2d list?
20:29:43<ski>Haskell is the worlds finest imperative language !
20:29:43<newsham>you could use sequence, as above
20:29:46<Nopik>SamB: i am using list comprehension now
20:29:47<quicksilver>Nopik: 2d list is just map.map
20:29:52<quicksilver>:t map.map
20:29:54<lambdabot>forall a b. (a -> b) -> [[a]] -> [[b]]
20:30:00<newsham>ski: so how come you have to manually select monads?
20:30:09<newsham>my other imperative languages pick my monads for me
20:30:24<quicksilver>no, your other imperative languages only have 1 monad
20:30:24<Nopik>yeah, i was considering map.map, though this way felt better for me ;p
20:30:25<newsham>no lifting
20:30:27<SamB>newsham: most languages have at most one usable monad
20:30:30<quicksilver>and they use that for everything
20:30:38<ski>newsham : yes, you can't decide yourself which monad you want .. e.g. a parsing monad
20:30:38<quicksilver>haskell lets you give more precise types to your functions/actions
20:30:45<bulio|>would haskell be advisable for a new programmer to learn?
20:30:59<quicksilver>so you can understand what kinds of computational effect they have
20:30:59<ski>bulio| : i believe so
20:31:13<quicksilver>bulio|: it's a controversial point, but I also think it is, like ski
20:31:21<xsdnyd>hi, how can i compute the number: 2^(1/3) in haskell? the ^ operator only allows integers as second parameter... :-\
20:31:33<quicksilver>> 2 ** (1/3)
20:31:34<lambdabot> 1.2599210498948732
20:31:39<quicksilver>xsdnyd: comme ca
20:31:52<SamB>bulio|: some are of the opinion that it might discourage further study (they say something like "who would want to learn another language after haskell?"). I don't see how it could work that way though ;-)
20:31:59<newsham>right, which is why when I want to add debugging printfs into my program in most imperative languages I don thave to reengineer my code.
20:32:05<glguy>xsdnyd: actually, the ^ operator only allows non-negative integrals :)
20:32:05<xsdnyd>quicksilver, i need the number as Rational
20:32:09<newsham>I love haskell, but I strongly disagree with "best imperative language"
20:32:26<quicksilver>xsdnyd: well, in the first place, cube roots aren't normally rational :)
20:32:26<SamB>newsham: Debug.Trace is your friend
20:32:31<glguy>xsdnyd: fractional exponents don't generate rationals :)
20:32:31<Nopik>bulio|: haskell is quite hard, and not directed toward newbie programmers
20:32:33<newsham>i know debug trace.
20:32:38<newsham>that was just one of many examples
20:32:41<ihope>Is sum strict?
20:32:41<caust1c>hi
20:32:42<newsham>debug.trace does not generalize
20:32:46<ski>(newsham : note btw that that above was a quote :)
20:32:50<SamB>newsham: so?
20:32:53<xsdnyd>glguy, yeah, i only want the third root of 2...
20:32:56<EvilTerran>ihope, could it not be strict?
20:32:59<newsham>what if I want to keep statistics in my code that wasnt designed to keep state?
20:33:02<caust1c>does ghc always produce C code from haskell code and compiles it?
20:33:09<EvilTerran>@src sum
20:33:10<lambdabot>sum = foldl (+) 0
20:33:11<newsham>there's no "debug.trace" like thing for that
20:33:12<SamB>newsham: you should have newtyped your monad
20:33:12<quicksilver>xs xs
20:33:18<opqdonut>yep
20:33:20<ihope>foldl isn't strict, is it?
20:33:22<glguy>xsdnyd: that isn't a rational
20:33:23<oerjan>ihope: no
20:33:30<opqdonut>ihope: foldl' is
20:33:31<ihope>Why isn't it strict?
20:33:35<newsham>samb: i'm aware of how to do this. its just not a trivial modification.
20:33:38<ihope>sum, I mean.
20:33:38<xsdnyd>quicksilver, how do i calculate a cube root, even as float or double?
20:33:40<quicksilver>xsdnyd: syou can get an approximate answer, of course
20:33:47<quicksilver>xsdnyd: I just showed you
20:33:48<quicksilver>> 2 ** (1/3)
20:33:50<lambdabot> 1.2599210498948732
20:33:51<newsham>where as coding imperative style in other languages makes this a trivial operation
20:33:56<sjanssen>ihope: I call it an oversight
20:33:59<quicksilver>if you want that as an approximation Rational, then:
20:34:01<SamB>newsham: or at least made a type synonym for it...
20:34:02<newsham>coding in an imperative style in haskell leaves something to be desired
20:34:04<quicksilver>> toRational (2 ** (1/3))
20:34:05<lambdabot> 5674179970822795%4503599627370496
20:34:09<SamB>hmm.
20:34:11<SamB>this is true.
20:34:14<EvilTerran>ihope, the foldl forces it to be a non-bottom list, and then the (+) forces each element to be a non-bottom number
20:34:16<newsham>(but it has other strengths that more than compensate)
20:34:18<quicksilver>but that's not very pretty
20:34:32<SamB>it does, indeed, leave something to be desired
20:34:35<ski>newsham : yes .. i agree some things could be better on that front
20:34:48<SamB>however I must point out that this does not mean that it is not the world's finest imperative language
20:34:51<xsdnyd>quicksilver, thanks that fit my needs :)
20:34:55<MarcWeber>Do you think the haskell community is interested in links such as www.noooxml.org ( open standards etc ) ?
20:35:04<SamB>... it just means that there is probably room for improvement
20:35:10<ihope>Noooooxml?
20:35:11<EvilTerran>i imagine it's possible to write a Num instance in which (+) is non-strict in one argument, but it would not follow the laws of most numbers
20:35:13<wli>You can always represent elements of algebraic number fields by indices into roots of their minimal polynomials and linear combinations with rational coefficients thereof.
20:35:32<ihope>EvilTerran: easier to write one in which (*) is non-strict in one argument :-)
20:35:43<ski>> "N" ++ repeat 'o' ++ "xml" -- ?
20:35:44<lambdabot> "Noooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo...
20:35:45<EvilTerran>0 * _ = 0
20:36:03<SamB>EvilTerran: how about signed magnitude based on Nats?
20:36:06<EvilTerran>(Inf + _) = Inf ? =P
20:36:32<wli>Significant nonstrictness can occur in the case of multiplying sparse elements of GL_n(R) for various rings R.
20:36:36<EvilTerran>SamB, i don't know what you mean
20:36:55<Nopik>ok, next question.. i have setPixel :: Point -> Color -> Image -> IO() and getPixel :: Point -> Image -> IO Color now i want to copy pixel: setPixel (10,10) (getPixel (20, 20) image) image and it says that IO Color do not match Color... how to fix that?
20:36:56<SamB>data Nat = Zero | Succ Nat
20:36:56<newsham>sequence (do {x <- [0..w]; y <- [0..h]; setPixel x y red pic})
20:37:34<newsham>sequence [setPixel x y red pic| x <- [0..w], y <- [0..h]]
20:37:35<SamB>data NatAndSign = Negative Nat | Positive Nat
20:37:46<SamB>well, obviously that leaves you with tow kinds of zero...
20:37:51<Nopik>@src sequence
20:37:52<lambdabot>sequence ms = foldr k (return []) ms
20:37:52<lambdabot> where
20:37:52<lambdabot> k m m' = do { x <- m; xs <- m'; return (x:xs) }
20:37:53<quicksilver>Nopik: setPixel (10,10) =<< getPixel (20,20) image
20:38:07<SamB>but if you don't make that observable you're fine
20:38:08<ski>Nopik : do color <- getPixel (20, 20) image; setPixel (10,10) color image
20:38:12<opqdonut>Nopik: getPixel (20,20) image >>= \x -> setPixel (10,10) x image
20:38:14<quicksilver>Nopik: because getPixel is monadic you have to 'bind' the value in place
20:38:22<Nopik>ok, thanks
20:38:30<quicksilver>ACTION thinks his answer is the prettiest
20:38:36<quicksilver>although perhaps the least easily generalised
20:38:55<oerjan>quicksilver: it is also wrong, alas
20:38:56<Nopik>quicksilver: i was just going to ask about >>= version :)
20:39:03<quicksilver>oerjan: is it?
20:39:11<MarcWeber>ihope, ski: This page reveals some bad things about the office open XML format which Microsoft wants to make an ISO standard.
20:39:13<quicksilver>:t (=<<)
20:39:13<ski>quicksilver : missing 'image'
20:39:16<lambdabot>forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> m a -> m b
20:39:25<quicksilver>ski: ah. good point
20:39:27<quicksilver>ACTION cries
20:39:35<quicksilver>beauty does not always prevail, alas :(
20:39:35<EvilTerran>SamB, data Nat = One | Succ Nat; data Int' = Negative Nat | Zero | Positive Nat --?
20:40:04<ihope>MarcWeber: well, if it's not Haskell-related...
20:40:08<ski>MarcWeber : ok (hm, i didn't know *Microsoft* wanted to make OpenOffice things standard ..)
20:40:19<ihope>Not to say that people who are interested in Haskell are interested only in Haskell.
20:40:25<ski>quicksilver : maybe with 'ReaderT' ?
20:40:41<EvilTerran>still, even with that aside, addition must surely be strict in both arguments for it to continue to be "addition" in any intuitive sense?
20:40:49<wli>EvilTerran: data PositiveNat = One } TwoN PositiveNat | TwoNPlusOne PositiveNat please.
20:41:00<ski>EvilTerran : why ?
20:41:12<quicksilver>ski: yeah, although I find readerT is only worth the effort in rather special circumstances
20:41:19<EvilTerran>well... because addition depends on both arguments... =/
20:41:32<ski>quicksilver : .. yes
20:41:32<quicksilver>ski: because lifting all the non-readerT-parts is annoying...
20:41:38<ski>(indeed)
20:41:40<SamB>wli: isn't that significantly less lazy?
20:41:43<MarcWeber>ihope, ski You are propably right
20:41:44<newsham>zero not natural?
20:42:01<EvilTerran>addition on any field or vector space does, anyway, if i'm not completely confused.
20:42:08<wli>SamB: Not sure how so.
20:42:09<SamB>EvilTerran: but if you had fix (Succ) for the first argument...
20:42:10<Nopik>heh, the only good thing from exposing newbie programmer to haskell is that he will find all other languages very easy ;)
20:42:20<Nopik>very limited, too, perhaps ;p
20:42:38<EvilTerran>SamB, then how would you tell that this were the case without running forever?
20:42:40<SamB>but he will have a toolkit with which to design his own language...
20:42:49<newsham>nopik: depends. if you show newbie pure functional stuff (ie. two dozen short lessons in haskell), its all quite easy and makes more sense than most programming languages
20:42:50<xsdnyd>i get an "No instance for (Floating Rational)" error, when using this code: "target :: Rational -> Rational" and "target x = toRational (x ** (1/3))"... i don't know how to fix this :-\ may someone give me a hint? ;)
20:42:53<SamB>EvilTerran: you wouldn't.
20:42:57<newsham>its just all this wacky real-world stuff like doing IO :)
20:42:59<ski>Zero + y = y; Succ x + y = Succ (y + x)
20:43:02<EvilTerran>i mentioned Inf + _ = Inf earlier, anyway.
20:43:04<quicksilver>ski: I often think about the kind of implicit lifting you'd need to make ReaderT reduce noise rather than adding it
20:43:06<SamB>but you also would never notice if you tried to add it to _|_
20:43:17<quicksilver>ski: but I can't think of anything sane
20:43:20<EvilTerran>...because the answer would be _|_
20:43:26<SamB>uh, no
20:43:28<Nopik>SamB: btw. any good example (tutorial-like) about writing own languages like this? i have seen few tutorials describe that this is possible, but none of them explained how ;P
20:43:36<EvilTerran>"const undefined" is strict, etc
20:43:38<SamB>because you'd never get to the _|_
20:43:38<wli>EvilTerran: Direct sums of various sorts are partially lazy depending on how you represent them.
20:43:47<newsham>?google two dozen haskell
20:43:49<Nopik>SamB: i suppose that monads do offer easy way to construct your own dsl..
20:43:50<lambdabot>http://www.cs.ou.edu/cs1323h/textbook/haskell.shtml
20:43:50<lambdabot>Title: Two Dozen Short Lessons in Haskell
20:44:06<ski>@type (**)
20:44:08<lambdabot>forall a. (Floating a) => a -> a -> a
20:44:14<SamB>Nopik: we have parsers. we have algebraic datatypes. we have numerous language implementations to look at...
20:44:18<EvilTerran>ohhh, i see. (fix Succ) + undefined could still be (fix Succ), if addition were appropriately defined.
20:44:19<EvilTerran>i get it now.
20:44:20<Heffalump>does hsql have a darcs repo?
20:44:23<wli>EvilTerran: Sparse vectors, for instance, don't need to examine anything more than indices except where they collide in the elements being summed.
20:44:26<newsham>nopik: there's "build scheme in 48 hrs"
20:44:27<EvilTerran>**facepalm**
20:44:43<Nopik>yeah, but this is just a parser
20:44:45<EvilTerran>ACTION hides.
20:44:46<Heffalump>ah, google finds it, ask a silly question..
20:44:53<Nopik>c++ also have parsers ;)
20:45:01<SamB>we have *nice* parsers
20:45:10<Nopik>;)
20:45:10<SamB>and algebraic datatypes to use for the results
20:45:15<ski>xsdnyd : maybe .. s/x **/fromRational x **/
20:45:24<Nopik>SamB: what is algebraic datatype?
20:45:27<wli>EvilTerran: Addition of things like power series is also necessarily lazy.
20:45:31<ski>@src Bool
20:45:31<lambdabot>data Bool = False | True deriving (Eq, Ord)
20:45:36<ski>@src Maybe
20:45:36<lambdabot>data Maybe a = Nothing | Just a
20:45:38<ski>@src []
20:45:38<lambdabot>data [] a = [] | a : [a]
20:45:45<SamB>@src HsExpr
20:45:46<lambdabot>Source not found. This mission is too important for me to allow you to jeopardize it.
20:45:46<newsham>you can make nice ASTs with "data"
20:45:52<SamB>@hoogle HsExpr
20:45:52<lambdabot>No matches found
20:45:54<Nopik>newsham: ok
20:45:55<SamB>@hoogle Expr
20:45:56<lambdabot>Text.ParserCombinators.Parsec.Expr :: module
20:45:56<lambdabot>Text.ParserCombinators.Parsec.Expr.buildExpressionParser :: OperatorTable tok st a -> GenParser tok st a -> GenParser tok st a
20:45:58<SamB>aww.
20:46:06<newsham>blah, use a real parser generator.
20:46:16<newsham>?where happy
20:46:17<lambdabot>http://www.haskell.org/happy/
20:46:20<EvilTerran>wli, i have already acknowledged that i was talking rubbish. jeez. ;]
20:46:28<SamB>newsham: I was looking for an example of an AST :-(
20:46:34<oerjan>xsdnyd: http://en.wikipedia.org/wiki/Gelfond-Schneider_theorem
20:46:36<_Nucleo>> Nothing >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1) )
20:46:36<lambdabot>Title: Gelfond–Schneider theorem - Wikipedia, the free encyclopedia
20:46:37<lambdabot> Nothing
20:46:40<oerjan>;)
20:46:57<oerjan>(in other words, 2^(1/3) is _not_ rational)
20:47:02<Nopik>newsham: ok
20:47:22<newsham>data If = If Expr Stmt Stmt
20:47:25<oerjan>oh wait
20:48:20<newsham>data Expr = Plus Expr Expr | ... | Var String | Val Integer
20:48:24<oerjan>:t fromRational
20:48:26<lambdabot>forall a. (Fractional a) => Rational -> a
20:48:31<ski>data Expr = Var String | Lam String Expr | App Expr Expr
20:48:44<oerjan>xsdnyd: you need to use fromRational x
20:49:29<xsdnyd>oerjan, thanks that solved it!!
20:49:46<wli>data RadicalNumber = Sum [(Rational {- linear coefficient -}, Rational {- exponent it's raised to -}, RadicalNumber)] | JustRational Rational ?
20:50:11<newsham>stmt = If (Gte (Var "x") (Val 5)) (Print (Var x)) (Print (Val 2))
20:50:41<newsham>(assuming Print is a Stmt)
20:52:34<psi>anyone got this on os x? /usr/bin/ld: can't locate framework for: -framework GMP
20:52:44<psi>i have it in ~/Library/Frameworks
20:52:57<psi>oh, when using ghc.
20:54:47<Nopik>newsham: nice
20:54:59<psi>ok, /Library/Frameworks worked. although the installation instruction said both would be ok...
20:57:40<newsham>nopik: as you can imagine, its really easy to build those up during parsing.
20:58:03<newsham>and with pattern matching, really easy to deconstruct and walk over the results
20:58:29<newsham>eval (Plus e1 e2) = eval e1 + eval e2
20:58:33<newsham>eval (Val x) = x
20:58:34<newsham>etc..
20:59:09<_Sketch_>Any recommended projects to learn haskell with?
20:59:22<wli>_Sketch: Write an interpreter.
20:59:29<newsham>sketch: the problems in two dozen short lessons?
20:59:53<Nopik>newsham: yeah, quite powerfull
21:00:35<ski>http://www.haskell.org/~pairwise/intro/intro.html -- might be useful if you know C
21:00:35<lambdabot>Title: Haskell for C Programmers
21:00:47<shapr>SamB: Want to be my facebook friend? What address are you using?
21:00:47<Nopik>_Sketch_: i have just gone through 2-3 tutorials, found them quite handy
21:00:52<ski>@where yaht
21:00:52<lambdabot>http://darcs.haskell.org/yaht/yaht.pdf
21:00:56<kaol>how do I output arbitrary debug output in the middle of code? (ie. I want to do some printf debugging)
21:01:02<_Sketch_>Wow, so much attention! :) Thank you all.
21:01:08<Nopik>_Sketch_: yaht and 'gentle introduction to haskell' (in that order)
21:01:16<SamB>shapr: naesten at gmail dot com
21:01:18<ski>_Sketch_ : yaht above people say is quite good
21:01:35<_Sketch_>ski: is there a non-PDF..?
21:01:51<Nopik>_Sketch_: and when you will stuck at monads, try reading 'you could have invented monads' tutorial ;)
21:01:52<ski>_Sketch_ : i'm not sure .. :/
21:02:06<ski>@google you could have invented monads
21:02:06<newsham>kaol: Debug.Trace
21:02:08<lambdabot>http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html
21:02:08<lambdabot>Title: A Neighborhood of Infinity: You Could Have Invented Monads! (And Maybe You Alrea ...
21:02:35<ski>ACTION thinks http://web.cecs.pdx.edu/~antoy/Courses/TPFLP/lectures/MONADS/Noel/research/monads.html is not so bad for monads, either
21:02:37<lambdabot>Title: Online Tutorial: What the hell are Monads?, http://tinyurl.com/n8bqd
21:03:06<ski>_Sketch_ : but one thing at a time ! monads *after* handling the basics
21:03:59<shapr>Binkley: That was fast
21:04:09<Binkley>heh
21:04:18<ski>kaol : 'Debug.Trace.trace' ?
21:06:51<wli>pdx.edu? I live in pdx.
21:06:56<jedai>Could we use a "data" definition in GHCi
21:07:08<jedai>??
21:07:11<shapr>jedai: hs-plugins?
21:07:13<Binkley>wli: are you looking for an ICFP contest team, by chance? :-)
21:07:41<jedai>shapr: You mean there's no way actually but it could be added ?
21:08:10<newsham>jedai: :load ? :)
21:08:11<wli>Binkley: No, I'm not likely to participate. I'm also not all that good a programmer.
21:08:17<shapr>wli: I disagree.
21:08:36<newsham>shapr: what's your team?
21:08:37<SamB>wli: do you by any chance mean that *fast* a programmer?
21:08:48<glguy>is a + in a URI always a space? or only after the '?' ?
21:08:53<shapr>ICFP is next weekend, right?
21:08:59<SamB>shapr: indeed
21:09:03<jedai>newsham: Of course, but I'm searching for a way to define it directly in GHCi
21:09:06<newsham>http://www.kingsrook.com/icfp/countdown.html
21:09:37<Heffalump>ACTION has no time for the contest :-(
21:09:55<wli>SamB: No. As in capable of putting together larger programs, working with other people's code, code review, finding bugs, etc. Just shitting out code is not very meaningful.
21:09:58<shapr>I've sacrificed my ICFP weekend to spend time with my Swedish girlfriend. I won't get to spend more than a few days with her for the next six months.
21:10:05<jedai>newsham: It's not really a preoccupation for me (I use haskell-mode in emacs), but some have others idea
21:10:09<SamB>wli: ah.
21:10:24<SamB>wli: how do you even know this is going to be a "larger programs" contest"
21:10:27<SamB>s/"//
21:10:32<SamB>last one wasn't really
21:10:47<shapr>wli: If I were part of a team, I'd gladly invite you :-)
21:10:55<shapr>newsham: What team are you on?
21:10:58<wli>SamB: That aspect of being a good programmer isn't necessarily pertinent to ICFP. The others are more so.
21:11:05<Nafai>When is the ICFP contest?
21:11:09<shapr>Nafai: Upcoming weekend.
21:11:14<Nafai>Ah
21:11:51<SamB>wli: perhaps you should join my team?
21:12:07<SamB>ACTION is thinking of trying to attack the contest problem after the contest is ofver
21:12:09<newsham>shapr: flying solo (unless some of my friends decide to help out)
21:12:10<wli>SamB: I don't think it's a good idea.
21:12:19<newsham>also gotta help someone move half of saturday,s o i my not complete
21:12:29<Nopik>lets assume that there is image, and you have getPixel :: Point -> Image -> IO Color is it possible to write findPixel :: Color -> Point without any IO infection?
21:12:33<wli>newsham: Is what you're doing an interpreter assignment somewhere?
21:12:53<newsham>wli: no, talking with nopik about ASTs in haskell
21:13:01<scsibug>Nopik: did you ever implement getPixel for GD?
21:13:04<Nafai>wli: Why isn't it a good idea to try it later?
21:13:10<Nopik>scsibug: yeah, it was straightforward
21:13:20<SamB>wli: with what I just /me'd in mind, do you still think it sounds like a bad idea?
21:13:38<Nopik>scsibug: just copy/paste from setPixel and slightly modify argument list
21:13:45<scsibug>Nopik: make sure you darcs send your changes to bringert
21:14:01<wli>SamB: My day job is demanding enough I can't really focus on anything, though right now I'm just letting compiles spin.
21:14:05<Nopik>scsibug: i would need to setup darcs first ;p
21:14:24<wli>SamB: (and, of course, partially blowing things off)
21:14:29<SamB>last contest I think I had my UM working maybe an hour after the contest was over (I started beforre it was ove ;-)
21:14:37<scsibug>Nopik: just sending a simple patch would probably be fine
21:14:45<Nopik>scsibug: yeah, i think so
21:15:05<Nopik>scsibug: going back to my problem.. do i need to infect all my functions with IO?
21:15:31<scsibug>Nopik: not sure what your problem was (just got back from work), but if you are talking about GD, then yes, most likely
21:15:36<ski>Nopik : what should 'findPixel :: Color -> Point' do ?
21:15:45<scsibug>anything that directly messes with images
21:16:19<SamB>scsibug: so why would anyone want ot use GD then??
21:16:27<Nopik>ski: just find any pixel with given color and return its position (ok, Maybe Point as return could do)
21:16:51<ski>Nopik : any pixel in which image ?
21:16:56<Nopik>ski: actually it doesnt matter, i was just asking if i can get rid of IO in function
21:17:06<Nopik>ski: of given color, if such exists
21:17:21<ski>(sorry .. in *which*image* ?)
21:17:39<Nopik>ah, findPixel :: Color -> Image -> Maybe Point
21:17:56<Nopik>ski: though it is not related to my question :D
21:18:00<SamB>Nopik: wouldn't it be far cleaner to just return an Image Bool?
21:18:10<scsibug>SamB: I'm not sure what you mean...
21:18:13<Nopik>Image Bool ?
21:18:13<msouth>_Sketch_: didn't see if anyone got you this: http://en.wikibooks.org/wiki/Haskell/YAHT
21:18:13<ski>Nopik : ok .. well, in case the underlying image referred to by 'Image' is immutable, then yes, otherwise no. i think
21:18:15<lambdabot>Title: Haskell/YAHT - Wikibooks, collection of open-content textbooks
21:18:46<Nopik>ski: i just want to read image, do not need to mutate it
21:19:06<ski>Nopik : ok, if you never mutate the image, then it should be ok
21:19:32<SamB>ACTION is making things up
21:20:20<scsibug>ACTION is a bit lost too... Nopik, is there a specific question you had that you could repeat?
21:20:52<Nopik>scsibug: yeah.. i was just asking if i can write functions operating on plain Color instead of IO Color
21:21:04<Nopik>which probably is true as i can always lift those
21:21:09<scsibug>indeed
21:21:24<scsibug>I've got functions in my fractal program which work on Color types
21:21:39<Nopik>hm, let me see
21:22:06<scsibug>http://scsibug.com/fractal-hs/burning_ship.hs
21:22:19<scsibug>there are a couple pure functions in there involving color
21:24:18<Nopik>scsibug: though most probably drawPlot accepts plain Color and draws it
21:24:55<scsibug>drawPlot takes a function mapping coordinates to colors (which is pure)
21:25:18<Nopik>scsibug: yeah, though this is simpler case than mine
21:25:18<scsibug>so drawPlot does handle all the nasty IO interaction with GD
21:25:47<Nopik>anyway i'll try do my way, at the worst i will have just more questions :)
21:26:03<Nopik>though most likely i will do it tomorrow - as it is time to sleep for me ;p
21:26:11<scsibug>ok, take care, and good luck
21:26:31<Souwh>Hello
21:26:40<scsibug>howdy
21:26:42<shapr>hi Souwh
21:28:37<hpaste> ski pasted "not safe for program" at http://hpaste.org/1719
21:28:53<ski>Nopik : ^
21:31:19<shapr>Souwh: Written any Haskell code lately?
21:32:48<scsibug>has anyone successfully gotten wxWidgets/wxHaskell working on OS X lately?
21:33:43<scsibug>I can get everything to compile, but I get unresolved symbols when I actually try to run a program :(
21:39:14<_Nucleo>did the old wiki just disappear?
21:42:36<monochrom>The old wiki cannot disappear yet. But it's no longer updated.
21:42:55<Figs>hi
21:43:12<_Nucleo>for some reason I get 404s, e.g. here: http://haskell.org/hawiki/TailRecursive
21:43:45<SamB>if i has disappered, some mainmiogns are in order
21:43:50<SamB>s/i/it/
21:44:01<Figs>does anyone understand left-recursion well?
21:45:02<shapr>Looks like someone got rid of the old hawiki entirely.
21:45:08<shapr>"The requested URL /hawiki/ was not found on this server."
21:45:13<_Nucleo>yeah, that's not good.
21:45:16<SamB>maimings!
21:45:43<shapr>kolmodin: I'm confused about this whole "you have been a member of haskell since year X" bit on Facebook.
21:45:46<monochrom>Hrm! All of hawiki has 404ed!
21:45:46<SamB>unless it was an accident
21:45:50<Igloo>We had 2 people getting confused by old, incorrect info on old pages in 2 days, so I removed the alias
21:45:56<Figs>ACTION takes that as a 'not at the moment.'
21:46:02<SamB>Igloo: "alias"?
21:46:04<Figs>ok, bbl
21:46:14<Vulpyne>figs: I'd go ahead and ask the question if I were you.
21:46:19<Igloo>Alias /hawiki /mumble/moinmoin.cgi
21:46:21<Figs>it's kind of OT
21:46:22<_Nucleo>mm, sure hope it's coming back
21:46:33<Vulpyne>Ah.
21:46:33<Figs>or I should say "really" OT :)
21:47:04<monochrom>http://www.haskell.org/mumble/moinmoin.cgi still doesn't work
21:47:16<SamB>Igloo: so we can find it at www.haskell.org/mumble/moinmoin.cgi?TailRecursive ?
21:47:38<Figs>basically, I'm working on a C++ parser library, and when I came to get feedback from people here yesterday (since you guys usually have a different perspective on things) ddarius, I think it was, pointed out that since I'm using recursive descent, left-recursion will fail.
21:47:56<Igloo>No, "mumble" just means I can't remember what it was. But the old wiki was dead anyway. It was announced that it would be removed ages ago
21:47:57<SamB>Igloo: I think you should place a script there that will redirect people after subjecting them to a blinking disclaimer
21:48:18<SamB>Igloo: and we still haven't managed to copy much over...
21:48:32<SamB>largely because of license issues, afaik
21:48:37<Igloo>http://groups.google.com/group/fa.haskell/browse_thread/thread/94212312bd35555d
21:48:38<lambdabot>Title: HaWiki closing in one month; migrate content to HaskellWiki now! - fa.haskell | ..., http://tinyurl.com/2nx5sw
21:48:47<CosmicRay>gtk2hs is so awesome. this is the first time I've ever enjoyed gui programming.
21:48:50<Igloo>If you haven't managed by now, you probably never would have done
21:48:51<Vulpyne>Figs: I'm not smart enough to help you, unfortunately.
21:48:59<Figs>Ah :(
21:49:12<CosmicRay>http://hg.complete.org/gtkrsync/raw-file/44d245cdab4d/screenshot2.png
21:49:12<_Nucleo>So that content is gone, then.
21:49:14<lambdabot>http://tinyurl.com/35y6rg
21:49:18<Cale>http://en.wikipedia.org/wiki/Left_recursion
21:49:19<lambdabot>Title: Left recursion - Wikipedia, the free encyclopedia
21:49:25<Figs>I've read it cale :)
21:49:36<kolmodin>shapr: in the haskell group?
21:49:43<kolmodin>or what I said?
21:50:11<Figs>but it doesn't help me much thinking about Z = A >> ( opt(by_ref(Z)) >> B) >> C unfortunately
21:50:27<Figs>or I should say opt(by_ref(Z)) << B
21:50:41<shapr>kolmodin: Your response said "member of haskell community since 2005" and I can't tell whether that applies to me, you, or both.
21:51:01<Figs>Z = A >> (opt(by_ref(Z)) << B) >> C
21:51:03<Figs>that's what I meant
21:51:16<monochrom>Eh? What's wrong with Z = A >> ( opt(by_ref(Z)) >> B) >> C?
21:51:28<Figs>I'm talking about left recursion
21:51:32<SamB>I found some interesting informmation on the old wiki just the other day...
21:51:37<monochrom>That is not left recursion.
21:51:41<kolmodin>it's where we met. or at least that's how I interpret how it works
21:51:46<Figs>A (Z b) c
21:51:50<shapr>kolmodin: Ok, works for me.
21:51:53<Cale>Could be if A is nullable
21:51:54<_Nucleo>SamB: I'll mostly miss the quotes page ;)
21:51:57<Figs>a (a Z b c) b c
21:52:05<kolmodin>shapr: it was actually you who introduced me to this channel :D
21:52:13<Figs>aa(a Z bc)bc
21:52:22<kolmodin>shapr: a little more than two years ago...
21:52:37<Cale>Figs: that's okay, so long as A doesn't match the empty string
21:52:49<kolmodin>when waern and me and others where working on haste
21:52:56<kolmodin>hi waern :D
21:53:03<Figs>well, even supposing that A did match it,
21:53:12<Figs>the opt() would ensure it terminates
21:53:18<monochrom>The input string to parse cannot contain infinitely many 'a's
21:53:20<shapr>kolmodin: Wow, cool!
21:53:31<waern>kolmodin: hi there
21:53:34<Figs>exactly
21:53:42<Figs>so as long as it has
21:53:56<Figs>bcbcbcbcbc... for a finite number
21:53:57<monochrom>The recursion is no deeper than the number of 'a's present at the beginning of the input string.
21:54:08<Figs>it should still match regardless of whether A is "" or not
21:54:10<kolmodin>shapr: you asked what I was doing, more or less. I told you guys about haste and there was great excitement :D
21:54:42<Cale>Figs: I generally think it's okay to make people rewrite grammars so they're not left-recursive.
21:55:03<Cale>Though you can provide tools to help with that.
21:55:08<Figs>how to deal with the left-associativity issue?
21:55:45<waern>kolmodin: how's code?
21:56:11<SamB>Igloo: a lot of good it does to declare our posts to the old wiki SPL'd if you take it down days later :-(
21:56:32<kolmodin>waern: not much haskell the past months I'm afraid :(
21:57:06<kolmodin>waern: much more gentoo work. we have made yet a turn to get ghc 6.6 and 6.6.1 into the tree, yet a new master plan :D
21:57:23<Cale>For example, in parsec, there's a combinator called chainl such that (chainl p op x) parses zero or more occurrences of p, separated by op, returning a left associative application of all functions returned by op to the values returned by p (using x when there are zero occurrences of p)
21:57:52<Cale>(p and op are parsers)
21:58:36<Cale>So that helps eliminate left recursion whenever it would have come up.
21:58:38<kolmodin>shapr: hit the Friends link at the top. under details you will see: You have been members of Haskell Community since 2005.
21:59:01<Cale>http://legacy.cs.uu.nl/daan/download/parsec/parsec.html#chainl -- see the example here
21:59:31<kolmodin>waern: how about you?
21:59:42<kolmodin>code progressing? :)
21:59:42<waern>kolmodin: heh... will 6.8 take less time to package? :)
21:59:51<kolmodin>haha :D yes
22:00:00<waern>kolmodin: mostly exjobb
22:00:00<kolmodin>we will have fought the major fight by then :D
22:00:10<Figs>ok
22:00:32<Figs>it might just make more sense for me to write a special left parser
22:00:36<kolmodin>the "trouble" has been that ghc split out many libs into separate packages
22:00:49<kolmodin>and that we then decided to do a few more changes we have been thinking of
22:01:01<kolmodin>neither of us are working full time on this :)
22:01:50<Cale>Figs: Automatically rewriting parsers so that they avoid left-recursion takes quite a bit of introspection, and so it's only typically done by tools which generate parsers statically, if at all.
22:02:15<Figs>Cale, I can just do something like this:
22:02:16<waern>kolmodin: ok
22:02:26<Figs>foo >> left(A << B << C) >> X;
22:02:49<kolmodin>waern: so how is the exjobb progressing? haskell?
22:03:08<waern>kolmodin: ok I guess. haskell :)
22:03:22<kolmodin>aw maaaj gaaad! I wish I could have used haskell too :D
22:03:44<Cale>exjobb?
22:03:46<waern>well.. it's pretty boring anyway
22:03:51<kolmodin>exjobb = master thesis
22:04:04<Cale>ah
22:04:06<Figs>I think the left recursion object would be very slow though in my parser
22:04:20<kolmodin>waern: imagine boring master thesis + java. compare that to boring master thesis + haskell. make your choice!
22:04:32<waern>hehe
22:04:39<kolmodin>see? you have to put things in perspective :D
22:07:47<Figs>ok, well thanks
22:07:51<Figs>I'm going to go play with it for a while
22:07:53<Figs>bbl
22:09:45<ddarius>ACTION owns "Categories for the Working Mathematician" now.
22:16:08<astrolabe>I've got one too. I just need to read it.
22:20:21<ddarius>Oh, I'll read it.
22:23:36<Binkley>?quote
22:23:37<lambdabot>ihope says: Laziness is free, but it doesn't always pay off.
22:24:16<ihope>Whoa, it's my quote!
22:24:18<ihope>:-P
22:27:56<kjdf>how does "newtype" differ from "data" declaration?
22:31:12<EvilTerran>kjdf, given "newtype Foo a = Foo a; data Bar a = Bar a", Foo undefined is indistinguishable from undefined, but Bar undefined can still match a pattern of the form "Bar x"
22:31:32<EvilTerran>you can only have one constructor of one argument on a newtype
22:32:32<EvilTerran>(these are both caused by "Foo a" being effectively just "a" at runtime)
22:33:07<kjdf>and Bar is wrapped around?
22:33:16<Saizan>also case undefined of Foo _ -> 0 == 0, case undefined of Bar _ -> 0 == undefined
22:33:19<EvilTerran>and GHC can derive anything for a newtype that's instantiated by the argument
22:33:56<kjdf>hm
22:34:05<EvilTerran>kjdf, yes, at runtime, "Bar x" would be stored differently from just "x"
22:34:15<kjdf>and what do you mean by derive?
22:34:43<EvilTerran>newtype MyInt = MyInt Int deriving (Eq, Ord, Integral, Num, Ix...)
22:34:58<kjdf>and with data it is not possible?
22:35:24<EvilTerran>you can't normally say "deriving Num" (for example), but GHC lets you in the case of a newtype
22:35:35<EvilTerran>you may need -fglasgow-exts for this, i forget.
22:36:04<kjdf>ok
22:36:06<kjdf>thanks
22:36:14<EvilTerran>np =)
22:37:25<EvilTerran>BTW, another way of thinking about my first point (and Saizan's point) is that a newtype constructor is strict in its argument
22:37:30<EvilTerran>i think
22:42:22<sioraiocht>is parsec a recursive descent parser?
22:43:20<oerjan>it can be used that way.
22:44:06<oerjan>but it can also do arbitrary backtracking
22:45:47<SamB>ACTION wonders about the utility of this "Poke her" link on his sister's facebook page.
22:45:56<oerjan>er, i'm not sure whether recursive descent includes that. but parsec parsers are generally written recursively.
22:46:01<SamB>ACTION thinks if he wanted to poke her... he would just poke her...
22:47:18<oerjan>SamB: one day, you will be on a different continent than her, and then that link will be very useful.
22:47:22<monochrom>More generally, you should wonder the utility of facebook altogether. But I digress.
22:47:52<SamB>monochrom: well you can get away with writing on the walls without getting in any trouble or having to clean it up
22:47:55<Philippa>oerjan: "recursive descent with backtracking" is sometimes considered to come under the general heading of "recursive descent" anyway
22:48:17<oerjan>Philippa: that was what i was wondering, thanks
22:52:07<newsham>poke her? sister? ewww.
22:52:42<EvilTerran>what's the matter, newsham? it's not your business if he happens to like nuns...
22:53:01<newsham>blue nuns of the revolution?
22:54:39<EvilTerran>ACTION tries to envisage "nun of revolution" as in "surface of revolution"
23:02:47<SamB>so... it looks like JHC is adopting PNG format for it's object files ;-)
23:03:24<oerjan>creative.
23:03:46<SamB>well, actually, *adapting*
23:05:51<monochrom>@quote undefined
23:05:51<lambdabot>No quotes match. It can only be attributed to human error.
23:09:27<oerjan>@quote undefined
23:09:28<lambdabot>No quotes match. I've seen penguins that can type better than that.
23:10:14<oerjan>@quote quotes.match
23:10:14<lambdabot>No quotes match. My pet ferret can type better than you!
23:10:23<oerjan>@quote quotes.match
23:10:24<lambdabot>No quotes match. That's something I cannot allow to happen.
23:11:33<SamB>apparantly John believes that such a format will lazy reading?
23:11:36<SamB>er.
23:11:40<SamB>insert "enable"
23:14:27<oerjan>persistent laziness?
23:16:16<chessguy>@undo do { b <- o; if b then (e x) else (e y) }
23:16:16<lambdabot>o >>= \ b -> if b then (e x) else (e y)
23:16:44<chessguy>@pl e x y = o >>= \ b -> if b then (e x) else (e y)
23:16:44<lambdabot>e = fix ((((o >>=) .) .) . (flip =<< (((.) . flip . flip if') .)))
23:19:08<chessguy>@pl f x n xs = take (n-1) xs ++ x ++ drop n xs
23:19:09<lambdabot>f = ap (ap . ((++) .) . take . subtract 1) . (. drop) . (.) . (++)
23:29:27<msouth>read "5" gives me an error in ghci
23:29:38<msouth>but read "5" + 3 works
23:29:49<oerjan>> read "5"
23:29:51<lambdabot> 5
23:29:52<msouth>and lambdabot is happy with read "5"
23:30:05<newsham>> read "5" :: Int
23:30:06<lambdabot> 5
23:30:16<newsham>try giving it a hint about what you want
23:30:20<msouth>that works
23:30:20<Excedrin>msouth: what error? (it's obv because you need to add a type annotation)
23:30:22<oerjan>msouth: there was someone today complaining that 6.7 defaults to ()
23:30:41<newsham>?type read
23:30:43<lambdabot>forall a. (Read a) => String -> a
23:31:09<msouth>so the + 3 hints that I want some kind of number
23:31:12<newsham>?type read "5"
23:31:14<lambdabot>forall a. (Read a) => a
23:31:35<newsham>?type read "5" + 3
23:31:37<lambdabot>forall a. (Read a, Num a) => a
23:31:38<Excedrin>+ 3 causes type inference to constrain the result of read to (Num a)
23:32:08<oerjan>which removes the possible () default option
23:32:09<newsham>> read "5" :: Char
23:32:10<lambdabot> Exception: Prelude.read: no parse
23:32:55<oerjan>msouth: try let x = read "5" and then :t x
23:33:00<Excedrin>> read "'5'" :: Char
23:33:01<lambdabot> '5'
23:33:07<oerjan>then you can see what type it defaults to
23:33:31<msouth>ambiguous
23:33:35<msouth>type variable
23:33:37<msouth>it says
23:33:48<msouth>at least it's consistent
23:34:08<oerjan>oh, so you are not getting a "no parse" error?
23:34:44<msouth>@paste Prelude> let x=read "5"
23:34:44<msouth><interactive>:1:6:
23:34:44<msouth> Ambiguous type variable `a' in the constraint:
23:34:44<msouth> `Read a' arising from use of `read' at <interactive>:1:6-13
23:34:44<msouth> Probable fix: add a type signature that fixes these type variable(s)
23:34:45<lambdabot>Haskell pastebin: http://hpaste.org/new
23:34:47<msouth>sorry
23:35:33<hpaste> msouth pasted "read "5" question" at http://hpaste.org/1720
23:35:34<Excedrin>I'm not sure why you'd use let and then check the type..
23:35:38<oerjan>sounds like you have _no_ defaulting
23:35:44<Excedrin>you can definitely use :t read "5"
23:35:51<Excedrin>or just :t read
23:35:57<msouth>yes
23:36:15<oerjan>Excedrin: i thought that would not give the defaulting result
23:37:19<msouth>is it better for me to run with -fglasgow-exts
23:37:20<msouth>?
23:37:40<oerjan>msouth: what ghci version?
23:38:02<msouth>GHC Interactive, version 6.6, for Haskell 98.
23:38:13<msouth>I'm on os x if that matters
23:38:14<Excedrin>if you need exts :)
23:38:40<oerjan>i'm not knowledgable enough for that :|
23:38:49<msouth>well, I'm just wondering because the type stuff comes out differently
23:38:59<msouth>like is it better for me to be used to that forall a. stuff.
23:39:17<msouth>my understanding is still pretty limited as I just started this a couple of days ago.
23:39:18<oerjan>the type stuff might be without applying the monomorphism restriction and defaults
23:39:52<oerjan>however, it _should_ default to Integer, and work, as far as i know
23:40:37<Excedrin>hmm, in what context does read default to Integer?
23:41:18<Excedrin>(or is that not what you meant...)
23:41:24<oerjan>Excedrin: when bound by a simple pattern binding, you get the m.r. and (Integer,Double) is the default defaulting
23:42:26<shapr>SamB: I wonder if facebook needs a #haskell group
23:42:33<Binkley>good idea
23:44:01<Nafai>I joined a Haskell group earlier
23:44:11<Nafai>But I would join a #haskell group
23:44:28<Excedrin>oerjan: I see, but that's for the default type of numbers, not related to read's type
23:44:28<SamB>ditto
23:44:37<SamB>where by "earlier", I mean "earlier today"
23:44:37<oerjan>oh right.
23:44:53<oerjan>ah, i forgot that.
23:45:15<oerjan>msouth: what you got is actually the "correct" behavior!
23:45:20<SamB>oerjan: however lambdabot uses stronger defaulting, I think it's the same rules as GHCi
23:45:27<Nafai>SamB: yes :)
23:45:30<Binkley>I created a #haskell group
23:45:30<Excedrin>and yes, "let x = 4" followed by ":t x" results in x::Integer
23:45:33<Binkley>join away :-)
23:45:53<oerjan>you may want to start with an option -fextended-defaulting-rules or something like that
23:46:05<SamB>man that was easy
23:46:05<Excedrin>can you change the default types in ghci interactively?
23:46:10<SamB>I didn't even have to search for it
23:46:33<SamB>*Science*?
23:47:07<SamB>wait, shapr just made one...
23:47:10<oerjan>i think there is a command to set flags. :f maybe?
23:47:14<shapr>SamB: And you already joined!
23:47:56<SamB>yes. but where is binkley's?
23:48:01<shapr>I dunno
23:48:06<Excedrin>there's -<flags> but I'm not sure if there's a way to do: "default (Int,Float)" via a flag
23:48:17<shapr>Already joined
23:48:23<Binkley>I'll put a link to the other one in mine
23:48:26<Binkley>we don't need two :-)
23:48:47<oerjan>Excedrin: msouth's problem is not about that setting though
23:48:54<SamB>whoo
23:48:57<SamB>I'm an admin
23:48:59<Excedrin>I know, just curious about defaults in general
23:49:30<Nafai>Yay!
23:50:27<oerjan>i recall i saw just today something when browsing the manual about ghci not using the defaults from the module.
23:50:28<SamB>@tell sjanssen we just formed a #haskell group on facebook
23:50:28<lambdabot>Consider it noted.
23:51:03<Binkley>haha, I hadn't seen the photo of SPJ on a unicycle
23:51:30<shapr>ACTION grins
23:51:34<shapr>On *my* unicycle even!
23:52:08<SamB>who's that on the right?
23:52:24<shapr>dcoutts
23:52:34<shapr>The photo should have names.
23:52:44<SamB>yes! who will caption it?
23:53:13<shapr>Hm, I added names of the people, dunno why it doesn't show up.
23:53:57<msouth>so :t - read "5" has type (Num a, Read a) => a, that means....here's my guess--the thing in quotes must be something in the Num family of types and also in the Read family of types, and it's going to give me back one of those?
23:54:17<msouth>and it was because of the - that it added the Num on there?
23:54:34<msouth>you guys will kickban me if I ask too many annoying newbie questions, right?
23:55:03<SamB>oops.
23:55:11<SamB>now we have two sets of captions...
23:55:17<Binkley>silly facebook
23:55:18<SamB>but I put in the IRC nicks
23:55:27<shapr>msouth: Nah, we'll just promote you.
23:55:28<Botje>msouth: you are correct, and no, you won't get kicked. ask away :)
23:55:50<shapr>msouth: Once we've answered enough of your questions, you get promoted to "able to answer questions for others."
23:56:14<Binkley>is that John Hughes in the other photo?
23:56:21<monochrom>read "5" alone has type (Read a) => a. If you also have Num it is due to other context.
23:56:23<msouth>first I'll be promoted to "thinks he knows the answers and gets them almost right then has to be corrected"
23:56:29<shapr>Binkley: Yup
23:56:56<monochrom>@type read
23:56:59<lambdabot>forall a. (Read a) => String -> a
23:59:08<shapr>edwinb: Mind if I steal and republish some of your photos?
23:59:24<edwinb>ACTION spots photos of unicyclists
23:59:34<edwinb>shapr: no problem, I was just digging out some to uplaod ;)

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