Experimental IRC log haskell-2008-06-01

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:14:37<hpaste> SamB annotated "difficult Coq Lemma" with "Where I get stuck with the Set version..." at http://hpaste.org/8013#a4
00:14:40<travisbrady_>:t fromListWith
00:14:42<lambdabot>Not in scope: `fromListWith'
00:14:50<travisbrady_>:t Data.Map.fromListWith
00:14:52<lambdabot>forall a k. (Ord k) => (a -> a -> a) -> [(k, a)] -> M.Map k a
00:41:03<Peaker>raytrace: Error in array index -- any way to get a traceback/line num/etc?
00:41:36<dmwit>Use assert?
00:43:39<dbueno>Peaker: http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-debugger.html#ghci-debugger-exceptions
00:43:40<lambdabot>Title: 3.5. The GHCi Debugger, http://tinyurl.com/2orwlb
00:44:19<Eiler>dons: that dynamic loaded plugins at summer of code, is that something similiar to hs-plugins?
00:44:19<dbueno>Peaker: The section from the manual is entitled "Debugging exceptions" but really all the info about the GHCi debugger is useful.
00:44:31<NRee1>hey is there a way to limit the memory ghci can use?
00:44:39<Peaker>dbueno, thanks
00:44:41<NRee1>I find it painful for it to page out firefox etc
00:47:47<TomMD>Sure is - just use GHC in a Xen VM and limit that VM to X megs.
00:47:59<EvilTerran>ha
00:48:18<bd_>TomMD: or use +RTS heap size limits
00:48:25<TomMD>I like my way.
00:48:27<NRee1>hehe ya good way to keep memory usage down ^^
00:48:33<bd_>+RTS -Mmaxsize
00:49:55<NRee1>thanks bd_ thats what I was looking for
00:50:05<NRee1>but I think TomMD's was more clever ;)
00:50:26<TomMD>:)
01:13:38<hpaste> morrow pasted "sqlite3-amalgamation.sh" at http://hpaste.org/8015
01:16:45<hpaste> morrow annotated "sqlite3-amalgamation.sh" with "better" at http://hpaste.org/8015#a1
01:28:59<TomMD>Arrr, I miss my community.h.o account!
01:29:09<hpaste> (anonymous) pasted "(no title)" at http://hpaste.org/8016
01:29:18<NRee1>why does that stack overflow?
01:30:49<ddarius>:t Text.ParserCombinators.Parsec.chainl
01:30:52<lambdabot>forall tok st a. Text.ParserCombinators.Parsec.Prim.GenParser tok st a -> Text.ParserCombinators.Parsec.Prim.GenParser tok st (a -> a -> a) -> a -> Text.ParserCombinators.Parsec.Prim.GenParser tok
01:30:52<lambdabot>st a
01:30:53<ddarius>:t Text.ParserCombinators.Parsec.chainr
01:30:55<lambdabot>forall tok st a. Text.ParserCombinators.Parsec.Prim.GenParser tok st a -> Text.ParserCombinators.Parsec.Prim.GenParser tok st (a -> a -> a) -> a -> Text.ParserCombinators.Parsec.Prim.GenParser tok
01:30:55<lambdabot>st a
01:32:44<mar77a>is there anyway to pattern match an array
01:32:52<mar77a>like you do f (x:xs) for lists, but for an array?
01:33:17<mauke>no
01:33:41<ddarius>NRee1: Try compiling with -O2
01:33:53<ddarius>:t Text.ParserCombinators.Parsec.chainr1
01:33:55<lambdabot>forall tok st a. Text.ParserCombinators.Parsec.Prim.GenParser tok st a -> Text.ParserCombinators.Parsec.Prim.GenParser tok st (a -> a -> a) -> Text.ParserCombinators.Parsec.Prim.GenParser tok st
01:33:55<lambdabot>a
01:37:01<ddarius>:t \a b -> ord <$> a <*> b
01:37:03<lambdabot> Couldn't match expected type `a -> b' against inferred type `Int'
01:37:03<lambdabot> Probable cause: `ord' is applied to too many arguments
01:37:03<lambdabot> In the first argument of `(<$>)', namely `ord'
01:37:13<ddarius>:t \a b -> (+) <$> a <*> b
01:37:15<lambdabot>forall a (f :: * -> *). (Applicative f, Num a) => f a -> f a -> f a
01:48:12<NRee1>ddarius: compiling worked like a charm
01:48:23<NRee1>so does compiling increase the stack space?
01:48:46<EvilTerran>it means a lot of optimisations get done that wouldn't be otherwise
01:49:13<SamB>it makes better use of stack space
01:49:32<SamB>I'm not sure if it can make better asymptotic use of stack space or not...
01:50:17<ddarius>NRee1: I suspect the problem is that the definition of maximum in GHC relies on strictness analysis.
01:51:31<NRee1>ya from my little analysis, i noticed maximum was the "stack overflower" in the sense that if it was removed and I just straight printed the list, it wouldnt crash
01:55:52<scriptdevil>[Not homework but prereading for it] I am assigned a project to develop an almost Version 0 compiler from one language to another. As pre-reading, I have now come to understand the haskell syntax fluently. But is there any book specifically aimed at writing a parser so that I make efficient use of the libraries
01:55:57<scriptdevil>?
01:57:14<lament>there's... the parsec homepage :)
01:57:32<dolio>Parsec is probably the most used library for parsing.
01:58:00<jeffz>I also recommend the parsec homepage...
01:58:02<dolio>There are papers/manuals about it, although they're probably somewhat out of date (not fundamentally, but in the specifics of what the libraries contain).
01:58:35<scriptdevil>:) Thanks.
02:00:12<ddarius>There are also a variety of parser generators, most notably happy.
02:00:43<scriptdevil>Also, This is my first big sized project. How do I ensure that my code remains extensibe and well spread out into modules? Are there any guides on this? Or does it come down to experience?
02:01:53<bd_>scriptdevil: If you start getting lost in a file, it's time to split it up :)
02:02:59<scriptdevil>bd_: Can I actually check out a copy of some previous compiler and keep its structure as the skeleton?
02:03:20<shapr>@users
02:03:20<lambdabot>Plugin `seen' failed with: too few bytes. Failed reading at byte position 8
02:03:22<shapr>aww
02:03:51<bd_>scriptdevil: What language are you trying to compile? It's probably best not to, just so you can have freedom in designing it, imo
02:03:56<shapr>Aw, I forgot happy birthday #haskell
02:04:00<shapr>some 4 weeks ago.
02:04:11<scriptdevil>bd_: They are two HDLs
02:04:33<ddarius>(<$) makes sense to me now
02:04:54<vininim>"the next haskell will be strict, but still pure" <- wut
02:05:10<ddarius>scriptdevil: The rules are more or less the same as other languages and programming in general.
02:05:33<eu-prleu-peupeu1>can i alter the abstract syntax tree in run-time in haskell ?
02:05:38<eu-prleu-peupeu1>like ruby :P
02:05:57<bd_>eu-prleu-peupeu1: nope, sorry. You could use the GHC-API to compile stuff at runtime though
02:06:05<monochrom>run-time? please don't.
02:06:22<SamB>eu-prleu-peupeu1: what?
02:06:47<scriptdevil>Thanks all.. Gotta rush to college :D
02:06:49<SamB>AST's aren't supposed to exist at runtime except in exceedingly slow implementations of lisp, or implementations of lambda calculi...
02:07:23<vininim>http://portal.acm.org/supp_gateway.cfm?id=1238856&type=pdf&path=%2F1240000%2F1238856%2Fsupp%2FHaskell%2Epdf&coll=GUIDE&dl=GUIDE&CFID=30248690&CFTOKEN=97968208
02:07:33<vininim>what is this "next haskell" that simon talks about?
02:07:35<ddarius>SamB: Why should they exist in implementations of lambda calculi?
02:07:38<bd_>SamB: Well, you could JIT-compile the AST, and if something starts editing it, undo the compilation
02:08:05<SamB>ddarius: well, you know, the kind that you would use in a proof system
02:08:22<SamB>of course the lambda calculus isn't able to access ths
02:08:26<SamB>s/ths/this/.
02:11:22<monochrom>Self-modifying programs are a fun sports, but not a viable engineering technique.
02:13:19<SamB>monochrom: not at that scale, at any rate
02:41:54<NRee1>is there a design reason why log is base-e rather than ln?
02:43:20<SamB>NRee1: it's more natural
02:43:23<SamB>duh ;-)
02:43:57<NRee1>hehe
02:44:03<SamB>were you expecting log to be base-2?
02:44:10<hpaste> morrow annotated "sqlite3-amalgamation.sh" with "thanks for the advice!" at http://hpaste.org/8015#a3
02:44:10<NRee1>base-10
02:44:16<mauke>no, log should take two arguments
02:44:20<mauke>base 10 is lg
02:44:38<SamB>mauke: that would be REALLY confusing
02:44:49<SamB>lg is base-2 in Knuth's books
02:44:51<mauke>that's how preflex does it!
02:44:55<mauke>no, base 2 is ld
02:45:06<SamB>in knuth's books?
02:45:09<dolio>ACTION has never seen ld.
02:45:15<mauke>knuth obviously never went to my school
02:45:21<NRee1>ACTION has never seen lg or ld
02:45:30<mauke>preflex: calc ld 10
02:45:31<preflex> 3.321928094887363
02:45:34<mauke>now you have
02:45:48<dolio>I've seen lg for base 2, and log for base 10, and ln for base 3.
02:46:11<dolio>And, of course, log with subscript b for some other base.
02:46:20<NRee1>http://en.wikipedia.org/wiki/Logarithm#Bases
02:46:24<monochrom>base 3? :)
02:46:35<NRee1>so the common approach is to have log to default to base 10 ;)
02:46:45<monochrom>Who would use base 3, other than someone crazy like Cantor?
02:48:03<SamB>NRee1: only in decimal contexts
02:48:10<SamB>programming is not one of these
02:48:15<dolio>I've seen log as base 2 in stuff about algorithm analysis, too, but I suppose it usually doesn't matter there.
02:48:16<mauke>http://de.wikipedia.org/wiki/Logarithmus#Bezeichnungen <-
02:48:32<SamB>I'm fairly certain the top two contenders would be e and 2
02:49:50<dolio>Although I think the papers I've read where 'log' means base 2 usually explicitly say so.
02:50:07<NRee1>hm wow.. i never realized that.. but in C log is base-e too
02:50:23<monochrom>trig uses radians.
02:50:43<SamB>monochrom: well, it's the natural way
02:51:16<SamB>ACTION is reminded of the "natural selection" sort algorithm
02:52:01<[Justice]>if you're doing asymptotic analysis, it shouldn't matter what the base is
02:52:43<monochrom>until you happen to do n^(log_b m)
02:52:59<[Justice]>well, true
02:53:18<monochrom>trick question on exam: e^ln n polynomial time or not? :)
02:53:30<[Justice]>yes
02:55:19<[Justice]>(n) is a polynomial in n
02:55:57<ddarius>Writing naive code is relaxing.
02:56:32<[Justice]>eg, fib n = fib (n - 1) + fib (n - 2)
02:56:33<bd_>[Justice]: Isn't copying an integer O(lg n)?
02:57:04<monochrom>"integer"
02:57:23<monochrom>This hour has 24 minutes. This integer has 24 bits.
02:57:37<[Justice]>copying an Int is O(1), copying an Integer is (log_100000 n)
02:58:19<dolio>100000?
02:58:42<[Justice]>any base you like is fine, within big-O notation
02:59:00<dolio>Yeah.
03:02:52<bd_>I thought O(lg n) is sub-polynomial time?
03:03:58<[Justice]>it's sub-linear time
03:04:26<[Justice]>(k) is a polynomial in n, one of an infinite number of constant, degree-0 polynomials
03:05:25<bd_>It's not constant, though, since we need to copy (?) a value of unknown size
03:05:41<bd_>so does sub-linear (but above constant time) put it outside P?
03:05:57<[Justice]>Int is known size, Integer is unknown size
03:06:14<bd_>e^ln n <-- types were unspecified :)
03:06:23<bd_>also, Int is still O(lg n), with n being a constant ;)
03:07:50<[Justice]>class P includes all functions f such that there exists a polynomial function g such that f(j) < g(j) for all j larger than a sufficiently large k
03:08:26<[Justice]>if f in O(log n) then f in P
03:09:03<[Justice]>if f in O(1) then f in P
03:09:04<dolio>It doesn't depend on the value n, though. Copying 0 takes as much time as copying 2147483647.
03:09:32<[Justice]>n is the number of bits
03:09:41<[Justice]>or bytes, or words, or whatever
03:09:51<[Justice]>wait that's wrong
03:10:04<dolio>Well, that would make copying an integer O(n).
03:10:06<[Justice]>no, copying 0 takes less time then copying 10^100
03:10:10<dolio>Or, unbounded integer.
03:10:33<[Justice]>the size of 0 is perhaps 1 word, whereas the size of 10^100 is multiple words
03:11:08<dolio>Yeah, but he was talking about Int being O(lg n).
03:11:29<TomMD>I there a preferred structure for bindings to C libraries? I started with a two module approach: one CBindings.hs that didn't really introduce any types beyond Foreign.C, and a Haskellized API that introduced types and used all the foreign functions. I'm considering that splitting these up was a mistake and I should introduce the haskell types earlier (i.e. declare the types and make Storable instances for them that will marshall them
03:11:39<dolio>Int can't represent googol.
03:11:40<bd_>dolio: where n is constant :P
03:12:17<dolio>At least, not on my machine. :)
03:12:26<[Justice]>Integer can represent 10^100, Int cannot ... copying Integer is O(log n) and not O(1), while copying Int is O(log n) and also O(1)
03:12:37<TomMD>Need a PS3, that will work out for you.
03:19:19<Twey>ACTION wonders vaguely why there are no n - k patterns...
03:21:33<Chater4567>http://www.meine-wilde-ex.net/?uid=156037
03:21:34<lambdabot>Title: Meine wilde Ex!!!
03:21:53<lament>Chater4567: or else?
03:24:55<Mr_Awesome>is there perhaps a way to do this with a single list comprehension? map (\x -> [(x, y) | y <- [0..h-1]]) [0..w-1]
03:25:39<Mr_Awesome>> map (\x -> [(x, y) | y <- [0..2]]) [0..2]
03:25:41<lambdabot> [[(0,0),(0,1),(0,2)],[(1,0),(1,1),(1,2)],[(2,0),(2,1),(2,2)]]
03:26:07<ddarius>> range (0,2) (0,2)
03:26:08<lambdabot> Couldn't match expected type `(t1, t2) -> t'
03:26:19<ddarius>> range ((0,2), (0,2))
03:26:21<lambdabot> [(0,2)]
03:26:29<ddarius>> range ((0,0), (2,2))
03:26:30<lambdabot> [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]
03:27:09<ddarius>Mr_Awesome: A list comprehension always produces a list. You could nest list comprehensions but that wouldn't be doing anything different.
03:27:24<ddarius>map (\x -> ...) l = [... | x <- l]
03:28:05<ddarius>> map (\x -> map ((,) x) [0..2]) [0..2]
03:28:07<lambdabot> [[(0,0),(0,1),(0,2)],[(1,0),(1,1),(1,2)],[(2,0),(2,1),(2,2)]]
03:28:15<Mr_Awesome>ddarius: ah, i see what you mean
03:28:41<ddarius>> map (flip map [0..2] . (,)) [0..2]
03:28:42<lambdabot> [[(0,0),(0,1),(0,2)],[(1,0),(1,1),(1,2)],[(2,0),(2,1),(2,2)]]
03:29:09<dmwit>> [(x, y) | x <- [0..2], y <- [0..2]]
03:29:10<lambdabot> [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]
03:29:24<dmwit>> replicateM2 [0..2]
03:29:24<lambdabot> Not in scope: `replicateM2'
03:29:28<dmwit>> replicateM 2 [0..2]
03:29:30<lambdabot> [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]
03:29:40<ddarius>Now transpose.
03:29:54<dmwit>what?
03:30:12<ddarius>> transpose $ replicateM 2 [0..2]
03:30:13<lambdabot> [[0,0,0,1,1,1,2,2,2],[0,1,2,0,1,2,0,1,2]]
03:30:51<gwern>ACTION happily sends off some cabalization patches for pencilpond
03:30:56<Mr_Awesome>> [[(x, y) | y <- [0..2]] | x <- [0..2]]
03:30:58<lambdabot> [[(0,0),(0,1),(0,2)],[(1,0),(1,1),(1,2)],[(2,0),(2,1),(2,2)]]
03:31:23<gwern>it is a fun little GUI thing, for looking at a hyperbolic plane. imo, a lot of code for what it does (but whatever)
03:31:31<dmwit>> [(x,y) | [x,y] <- replicateM 2 [0..2]]
03:31:35<lambdabot> [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]
03:43:41<gubagem>why does my console app have line history
03:44:28<Lemmih>gubagem: Are you using readline?
03:44:51<Lemmih>gubagem: Or rlwrap?
03:45:10<gubagem>not to my knowledge
03:45:27<gubagem>and its in a windows xp command prompt
03:45:42<gubagem>im just using getLine with GHC
03:47:19<dmwit>I find "lying" or "confusion" the most likely explanation.
03:47:53<Lemmih>We shouldn't rule out divine intervention, either.
03:48:11<gubagem>im inside a batch file loop
03:48:44<gubagem>i mean its nice, but I dont know how it got there
03:52:38<dmwit>[r | x <- m, ...] --> m >>= \x -> [r | ...]; [r | p, ...] --> guard p >> [r | ...]; [r] --> return r
03:52:41<dmwit>Is this correct?
03:53:43<Zao>NRee1: I beat #14 now.
03:54:23<Zao>NRee1: I used a Map to memoize the subsequences, but ended up eating 600-some MiB memory :)
03:54:28<NRee1>hehe
03:54:30<dmwit>Zao: Project Euler?
03:54:36<NRee1>can you post your code?
03:54:39<Saizan>dmwit: yup, if x is irrefutable
03:54:42<NRee1>I would like to compare
03:54:55<dmwit>Saizan: thanks
03:54:58<NRee1>and hopefully learn something ^^
03:55:04<dmwit>Saizan: Or wait, what?
03:55:15<dmwit>Oh, if x is refutable, then, let's see...
03:55:45<dmwit>[r | pat <- m, ...] --> m >>= \x -> case x of pat -> [r | ...]; _ -> fail ""
03:55:47<dmwit>Like that?
03:55:52<Saizan>yeah
03:55:58<Zao>NRee1: http://www.acc.umu.se/~zao/014.hs.html
03:56:00<lambdabot>Title: ~/euler/014.hs.html
03:56:11<Zao>NRee1: Did you finish yet?
03:56:32<NRee1>ya i did
03:56:34<dmwit>Zao: Pretty colors!
03:56:40<dmwit>Looks like vim's coloring.
03:56:54<Zao>:TOhtml is a lovely command.
03:57:08<NRee1>dmwit: our definition of pretty is different, but i guess it is in the eye of the beholder ;)
03:57:16<dmwit>Zao: Beautiful.
03:57:21<dmwit>Zao++
03:57:41<mar77a>interesting
03:57:49<mar77a>i got my first karma points thanks to project euler too
03:58:15<mar77a>one liner is_prime function :p
03:58:20<Zao>Oops, forgot to use -O.
03:58:36<hpaste> NReed pasted "Project Euler" at http://hpaste.org/8017
03:59:19<dmwit>NRee1: looks slow ;-)
03:59:31<NRee1>hm
03:59:43<dons>ah, collatz.
04:00:00<NRee1>ya i cant actually run it under ghci
04:00:12<dons>for euler stuff, i think it makes sense to compile the code.
04:00:15<dons>but also think hard :)
04:00:16<NRee1>i have to compile it otherwise i get a stack overflow
04:00:28<dons>right, so it depends on the strictness analyser
04:00:38<dons>or possibly one of the fusion rules kicking in
04:00:58<NRee1>so how would you guys recommend speeding this thing up?
04:01:01<dons>ghc -O2 --make is a good option for quick code, btw.
04:01:19<mar77a>hm if i do a foldr with (/) is that like a continued fraction?
04:01:21<dmwit>NRee1: I think a stateful calculation that keeps track of pre-computed run lengths makes sense.
04:01:32<dmwit>> foldr (/) z [a,b,c]
04:01:37<lambdabot> a / (b / (c / z))
04:01:43<mar77a>mm
04:01:55<dmwit>So... not really.
04:01:57<mar77a>maybe a foldl
04:01:58<dons>yeah, glguy liked using a memo array for this
04:02:01<dmwit>But you can get it to be.
04:02:04<NRee1>dmwit ah I just remembered that I was going to do that, but I got lazy
04:02:06<mar77a>i wonder how
04:02:34<dmwit>> foldr (\a b -> 1 / (a + b)) z [a,b,c]
04:02:36<lambdabot> 1 / (a + 1 / (b + 1 / (c + z)))
04:03:06<dons>NRee1: what value of 'n' were you using, btw?
04:03:19<dons>ACTION notes hpaste is a good source of collatz implementations
04:03:25<dons>hey, speak of the devilish glguy
04:03:28<NReed>wow I cant believe I miss typed my name :S
04:03:36<NReed>and didnt notice till now
04:03:51<dmwit>'1' is a pretty bad typo for 'd'.
04:04:04<dmwit>I just figured it was the "away" variant of your name. =)
04:04:07<SamB_XP>what's your excuse?
04:04:16<NReed>i know :S i guess haskell for a whole day mashes your brain :)
04:04:18<glguy>dons, if that is your real nick
04:04:18<lambdabot>glguy: You have 1 new message. '/msg lambdabot @messages' to read it.
04:04:23<glguy>weird that you aren't identified...
04:05:01<glguy>I can't make changes to hpaste
04:05:09<glguy>so I'll just keep getting that same bug report
04:05:11<NReed>dons I dont get the question...
04:05:12<glguy>over and o ver and over ;)
04:05:29<SamB_XP>glguy: well, it's probably because your name is at the bottom of the page!
04:05:39<glguy>I can't change that either!
04:05:39<glguy>:)
04:05:52<SamB_XP>glguy: perhaps you should suggest it to whoever can
04:06:09<mar77a>:t foldr
04:06:10<dons>NReed: oh, i didn't see the [1..1000000] list, sok
04:06:11<glguy>its just a matter of finding a server to run the new hpaste on
04:06:13<lambdabot>forall a b. (a -> b -> b) -> b -> [a] -> b
04:06:25<dons>glguy: i think we have servers
04:06:33<mar77a>:t (+)
04:06:35<lambdabot>forall a. (Num a) => a -> a -> a
04:06:39<shapr>glguy: Why can't you make changes to hpaste?
04:06:53<SamB_XP>glguy: how much bandwidth does it use?
04:06:55<mar77a>:t (\a b -> 1 / (a+b))
04:06:56<lambdabot>forall a. (Fractional a) => a -> a -> a
04:07:06<mar77a>interesting
04:07:08<glguy>shapr: how much bandwidth does hpaste use?
04:07:11<shapr>um
04:07:13<shapr>I haven't checked.
04:07:18<glguy>shapr: I don't have the right version of happs anywhere
04:07:21<shapr>oh
04:07:36<glguy>and all my machines are 64bit
04:07:46<glguy>so its not just a matter of building on my machine but building on someone elses
04:07:50<shapr>hpaste doesn't work 64bit?
04:07:55<shapr>oh I see
04:08:00<glguy>kakapo is 64 bit?
04:08:03<shapr>Nah
04:08:09<shapr>I wonder if I could upgrade it...
04:08:38<shapr>I'm slowly moving all my scannedinavian stuff to my desktop, now that I have a static public ip.
04:08:41<shapr>And it's 64 bit.
04:15:13<dons>this looks interesting, http://haskell.org/haskellwiki/SceneGraph
04:15:14<lambdabot>Title: SceneGraph - HaskellWiki
04:15:30<dons>conal`: "he module Graphics.SceneGraph.Reactive uses Reactive to enliven a scene. ExampleReactive.hs provides an example of this.This uses a calculator defined independantly of the GUI and is made tangible by SceneGraph."
04:17:53<slava>hi dons
04:18:01<sjanssen>@keal
04:18:02<lambdabot>actually it bug in math
04:18:12<sjanssen>oh noes
04:19:18<dons>heya slava
04:22:58<thetallguy>ACTION wonders what language dons is speaking
04:28:06<dmwit>heh heh heh
04:28:41<Twey>thetallguy: Haskell 2.0 -- it was so useful they merged it with Lojban and made it a human language.
04:29:22<dmwit>Dang, I can't even compute all the primes up to 5e7 in under a minute. How am I supposed to do this problem?
04:30:03<bd_>which problem?
04:30:10<sjanssen>just do it in C
04:30:32<dmwit>http://projecteuler.net/index.php?section=problems&id=187
04:30:33<lambdabot>Title: Problem 187 - Project Euler
04:30:33<Twey>*chuckle*
04:31:48<dmwit>ACTION has trouble imagining a way to do this without computing a buttload of primes
04:31:53<dolio>How are you computing them?
04:32:12<dmwit>?wiki primes
04:32:12<lambdabot>http://www.haskell.org/haskellwiki/primes
04:32:32<dmwit>...not like that
04:33:05<dmwit>http://www.haskell.org/haskellwiki/Prime_numbers
04:33:06<lambdabot>Title: Prime numbers - HaskellWiki
04:33:14<dmwit>The one there that starts with "merge".
04:34:08<dolio>I used trial division and it worked for that problem.
04:34:16<bd_>ACTION tries implementing a sieve of eratosthenes up to 10^8
04:34:42<dmwit>> 2e8 / 1024 / 1024
04:34:43<lambdabot> 190.73486328125
04:35:01<dolio>(And then I wrote another solution with STUArrays, but whatever. :))
04:35:01<dmwit>190 megs might not be that bad, assuming Bool will fit in two bytes.
04:35:11<bd_>dmwit: STUarray puts Bool on one bit, I think?
04:35:14<bd_>in one bit*
04:35:17<sjanssen>bd_: yes, it does
04:35:22<dmwit>It wouldn't surprise me.
04:35:32<dmwit>So call it 15 megs, then.
04:36:01<dolio>I'm pretty sure the one with trial division worked in a reasonable amount of time, though.
04:36:14<dmwit>Okay, time to try using naiveIsPrime, then. =)
04:36:35<dons>bitwise bool sieve, http://shootout.alioth.debian.org/gp4/benchmark.php?test=nsievebits&lang=ghc&id=0
04:36:36<lambdabot>Title: nsieve-bits Haskell GHC program | Gentoo : Intel&#174; Pentium&#174;&nbsp;4 Comp ..., http://tinyurl.com/2xnch4
04:37:21<dolio>My solution using STUArrays apparently took some fact I learned in the comments on that problem, though.
04:37:57<dolio>Some way of computing the answer based on the number of primes below a given value, so it computed the answer during the prime sieve loop.
04:39:35<dmwit>Oh, yeah, it's (n `choose` 2) if n is the number of primes.
04:39:45<dmwit>But that doesn't help until you've counted the primes...
04:40:27<dolio>Yeah, well, my sieve had both an STUArray Int Bool for the primes and an STUArray Int Int for pi(n).
04:40:28<dmwit>(Well... n `choose` 2 + n, I guess.)
04:40:51<dolio>Or something like that.
04:41:37<dmwit>Oh, heh, that reduces to n(n+1)/2, which should have been the first thing I said anyway.
04:41:46<dmwit>It's the sum of the first 'n' naturals.
04:43:04<dolio>The STUArray version takes 9 - 10 seconds. I think the one with lists took a minute or two.
04:43:40<bd_>@hoogle STUArray
04:43:41<lambdabot>Data.Array.ST.STUArray :: data STUArray s i a
04:43:41<lambdabot>Data.Array.ST.runSTUArray :: Ix i => ST s (STUArray s i e) -> UArray i e
04:43:41<lambdabot>Data.Array.ST.castSTUArray :: STUArray s ix a -> ST s (STUArray s ix b)
04:46:20<dmwit>This naive version definitely isn't going to make it in under a minute.
04:46:45<dmwit>It barely got up to 15,000 in a minute.
04:51:47<bd_>woo, got the answer in 46.12 seconds :3
04:52:12<bd_>(runtime, not thinking time :)
04:52:20<ddarius>Hmm. Lollimon parses ! ! a, but the paper suggests that that isn't syntactically valid (in a sense ! : A -> S)
04:56:07<dmwit>bd_: ghci or ghc?
04:58:08<bd_>dmwit: ghc -O2, native code generator
04:58:19<dmwit>Oh, okay.
04:58:42<dmwit>I don't feel so bad, then, as the primes generator I already have can solve it in 145s under -O2.
04:59:09<dmwit>If you were getting 46s in ghci, I would have been way less happy. =P
04:59:19<ddarius>Wait. It seems to be in the wrong syntactic class altogether.
04:59:41<mbz>bd_, what kind of cpu do you have?
04:59:59<bd_>mbz: AMD Turion(tm) 64 X2 Mobile Technology TL-50
05:00:08<bd_>I did not attempt to paralleize it, and it's running in 32-bit mode
05:03:35<ddarius>well shit
05:06:34<nolrai_>:t (&&&)
05:06:36<lambdabot>forall (a :: * -> * -> *) b c c'. (Arrow a) => a b c -> a b c' -> a b (c, c')
05:07:53<nolrai_>> :t curry
05:07:54<lambdabot> parse error on input `:'
05:08:01<nolrai_>:t curry
05:08:03<lambdabot>forall a b c. ((a, b) -> c) -> a -> b -> c
05:08:52<nolrai_>:t \f g -> curry (uncurry f &&& uncurry g)
05:08:54<lambdabot>forall a b c c1. (a -> b -> c) -> (a -> b -> c1) -> a -> b -> (c, c1)
05:09:39<nolrai_>meh
05:09:54<cdsmithus>There seem to be several different ways to do exceptions in Haskell. Which one should I mention to new Haskell programmers?
05:10:20<ddarius>It depends on your goals.
05:10:34<cdsmithus>My goal is to stick a slide in this presentation about exceptions
05:11:25<ddarius>Then any exception mechanism can be described on a slide and put into your presentation.
05:11:58<cdsmithus>Yeah, I was just wondering is there's some conventional wisdom; like avoid ioError and use Control.Exception, or vice versa
05:12:33<ddarius>Again, it depends on your goals. What do you want the audience to get out of your slide?
05:13:02<SamB_XP>I would mention Exception
05:13:38<cdsmithus>ddarius, that's a good question. I honestly don't know at this point. It just seems like something I should mention, even though I've never had a reason to use it.
05:14:22<SamB_XP>why mention it if you don't use it?
05:14:22<dmwit>If you just want to cover error-handling, and have a Haskell-ish way of doing it, why not just show MonadError?
05:15:22<cdsmithus>Hmm. I already am talking about the Maybe monad. Maybe I'll just take exceptions out.
05:18:03<nolrai_>that might be best.
05:18:22<ddarius>ACTION needs to consider the laws of the monad.
05:18:54<SamB_XP>cdsmithus: or talk about Either instead ;-)
05:19:05<glguy>dons: github is pretty awesome
05:19:05<glguy>I'm going to have to give you a demo when I get back
05:20:33<ddarius>:t (. return)
05:20:35<lambdabot>forall b a (m :: * -> *). (Monad m) => (m a -> b) -> a -> b
05:20:59<ddarius>That's the secret.
05:21:59<ddarius>I think...
05:23:21<nolrai_>thats a weird type, what are you doing?
05:24:36<ddarius>Trying to understand why ! a -o b is legal in the CLF/Lollimon when S ::= A | ! A | ... and A ::= A -o A | { S } | ...
05:24:58<ddarius>Where { _ } represents a monad type constructor.
05:25:28<ddarius>Where (! a -o b) means ((! a) -o b)
05:38:24<nolrai_>:t guard
05:38:26<lambdabot>forall (m :: * -> *). (MonadPlus m) => Bool -> m ()
05:40:33<bd_>@hoogle compareBy
05:40:33<lambdabot>No matches found
05:40:40<bd_>:t soryBy
05:40:42<bd_>:t sortBy
05:40:42<lambdabot>Not in scope: `soryBy'
05:40:43<lambdabot>forall a. (a -> a -> Ordering) -> [a] -> [a]
05:41:00<nolrai_>> [guard (x > 3) >> return $ show x | x <- [0..7]]
05:41:01<lambdabot> add an instance declaration for (Show (m String))
05:41:14<nolrai_>> [guard (x > 3) >> return $ x | x <- [0..7]]
05:41:15<lambdabot> add an instance declaration for (MonadPlus ((->) a))
05:41:31<nolrai_>> [guard (x > 3) >> return x | x <- [0..7]]
05:41:32<lambdabot> add an instance declaration for (Show (m t))
05:42:26<nolrai_>> do {x <- [0..6]; guard (x > 3); return (x * 2)}
05:42:28<lambdabot> [8,10,12]
05:43:33<nolrai_>:t fail
05:43:35<lambdabot>forall (m :: * -> *) a. (Monad m) => String -> m a
05:44:15<nolrai_>@src State fail
05:44:15<lambdabot>Source not found. I've seen penguins that can type better than that.
05:44:23<nolrai_>@src fail
05:44:23<lambdabot>fail s = error s
05:46:14<ddarius>:t (=<<)
05:46:15<lambdabot>forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> m a -> m b
05:47:11<Twey>@pl \x y -> (y, x + y)
05:47:11<lambdabot>ap (,) . (+)
05:49:19<nolrai_>:t (>==)
05:49:20<lambdabot>Not in scope: `>=='
05:49:26<nolrai_>:t (<==)
05:49:27<lambdabot>Not in scope: `<=='
05:49:34<dmwit>:t ==>
05:49:36<lambdabot>parse error on input `==>'
05:49:38<dmwit>:t (==>)
05:49:40<lambdabot>forall a. (Testable a) => Bool -> a -> Property
05:50:02<nolrai_>?
05:50:13<nolrai_>@src ==>
05:50:13<lambdabot>Source not found. Just what do you think you're doing Dave?
05:50:28<dmwit>?check \n -> even n ==> 2 * (n `div` 2) == n
05:50:29<lambdabot> OK, passed 500 tests.
05:50:37<dmwit>?check \n -> 2 * (n `div` 2) == n
05:50:38<lambdabot> Falsifiable, after 1 tests: 1
05:50:53<nolrai_>impiles?
05:51:00<dmwit>yes
05:52:56<nolrai_>is there a standard symbol for cobind?
05:53:06<dmwit>=>>, I think
05:55:25<dmwit>Will it be faster to readArray multiple times, or (!) multiple times?
05:55:59<dmwit>i.e. if I'm going to be in the ST monad anyway, should I bother runSTUArray'ing the part of the computation that's done?
05:56:29<mbz>dmwit, why not to test it?
05:56:35<dmwit>right
05:58:26<dmwit>:t unfoldr
05:58:28<lambdabot>forall b a. (b -> Maybe (a, b)) -> b -> [a]
06:00:02<dmwit>:t accumArray
06:00:04<lambdabot>forall e a i. (Ix i) => (e -> a -> e) -> e -> (i, i) -> [(i, a)] -> Array i e
06:10:52<ddarius>:t (ap .) . join
06:10:53<lambdabot>forall (m :: * -> *) a b (m1 :: * -> *). (Monad m1, Functor m1, Monad m) => m1 (m1 (m (a -> b))) -> m1 (m a -> m b)
06:11:08<ddarius>:t (join .) . ap
06:11:10<lambdabot>forall a (m :: * -> *) a1. (Monad m) => m (a1 -> m a) -> m a1 -> m a
06:11:25<ddarius>:t (join .) . (=<<)
06:11:26<lambdabot>forall a a1 (m :: * -> *). (Monad m) => (a1 -> m (m a)) -> m a1 -> m a
06:11:34<ddarius>:t (join .) . (>>=)
06:11:36<lambdabot>forall a (m :: * -> *) a1. (Monad m) => m a1 -> (a1 -> m (m a)) -> m a
06:12:11<ddarius>\mf a -> mf >>= ($ a)
06:12:19<ddarius>:t \mf a -> mf >>= ($ a)
06:12:20<lambdabot>forall (m :: * -> *) a b. (Monad m) => m (a -> m b) -> a -> m b
06:20:19<nolrai_>@src join
06:20:20<lambdabot>join x = x >>= id
06:28:27<dons>there you go, http://reddit.com/r/programming/info/6ll73/comments/
06:28:34<dons>"hsXenCtrl: script Xen with Haskell"
06:28:43<dons>good to see new areas being pushed on.
06:28:51<dons>the scenegraph lib released today also looks interesting
06:31:30<gwern>ACTION reads about the [[American flag sort]]
06:32:11<dons>dcoutts: this one might be for you, "Subject: [Haskell-cafe] Images and GUIs in Haskell"
06:32:18<dons>ACTION does triage on the mailing list
06:32:43<dons>hmm. i wonder if triage for community help has been written down before.
06:33:06<dons>we could have little forms like this, http://upload.wikimedia.org/wikipedia/commons/9/97/Deconference-2002-triage-tag.jpg
06:33:07<lambdabot>http://tinyurl.com/5k5jro
06:33:09<dons>:)
06:33:23<dons>"Stack overflow: Yes/No"
06:33:30<dons>"Forgot --make"
06:33:39<dons>"Andrew Coppin"
06:33:58<dons>"Blunt object trauma inflicted by GHC"
06:35:52<dmwit>"Function is monomorphic, but should be polymorphic"
06:36:09<dmwit>"Don't understand $!@% about monads"
06:36:15<dons>heh
06:36:28<dons>a top 10 FAQs would be useful
06:36:36<dons>lots of projects have FAQs, why not haskell
06:36:51<dons>"How do I catch the exception that 'read' throws"
06:37:53<dmwit>"Disenchanted because I have to tell compiler how to parallelize my code"
06:38:27<dmwit>Actually, that's not such an FAQ.
06:40:46<dons>well, its that general theme of wtf, i thought haskell could do parallel for me!?
06:41:06<dons>"Is Haskell just for mathematicians?"
06:41:12<araujo>No!
06:42:14<proqesi>sure
06:42:15<dancor>my biggest problem is that i feel _slow_ in haskell
06:42:41<proqesi>and C is just for OS designers
06:43:04<ddarius>dons: There was a FAQ on the old wiki.
06:43:23<dancor>maybe because every time you do a hack to save time, haskell makes you feel really bad about it, like you killed a puppy
06:44:10<Twey>Hahahahaha
06:44:19<dmwit>Hum, how can a run to STUArrays at once?
06:44:29<dons>hmm, we need a "haskell really damn fast" do we?
06:44:33<dmwit>Do I have to have an STUArray of a pair?
06:44:36<dons>for just getting the job done.
06:44:46<dons>dmwit: hmm, you can allocate inside a runST
06:44:47<atp>you can most likely have two stuarrays
06:44:49<dons>as many as you need
06:44:59<dons>just ask for a newArray
06:45:05<dmwit>right...
06:45:25<atp>the ST monad is sort of a pain
06:45:26<dmwit>So I can get (ST s (STUArray a, STUArray b)).
06:45:31<dmwit>(schematically)
06:45:34<dmwit>Then what?
06:46:01<dmwit>runST gets me a pair of STUArrays, but I can't really see any operations that take straight STUArrays.
06:46:12<dolio>You'd want to freeze them.
06:46:31<dolio>And get 'ST s (UArray a, UArray b)'.
06:46:33<dmwit>Ah, freeze operates on all instances of MArray.
06:46:45<dmwit>Sweet, thanks.
06:53:20<dmwit>?index newSTRef
06:53:20<lambdabot>Data.STRef.Lazy, Data.STRef, Data.STRef.Strict
07:00:21<dmwit>?index UArray
07:00:21<lambdabot>Data.Array.Unboxed
07:13:39<dmwit>hum
07:13:51<dmwit>:t ST.runSTUArray $ createFactorCounts 10 -- gives an error
07:13:57<lambdabot>Couldn't find qualified module.
07:14:17<dmwit> :t ST.runSTUArray $ createFactorCounts 10 :: UA.UArray Int Int -- does not give an error
07:16:46<Lemmih>dmwit: createFactorCounts is too general?
07:17:42<dmwit>I guess so, but I don't understand how or why.
07:18:20<dmwit>I thought the big idea of HM type systems was that anything that has some valid type has an automatically-inferrable most general type.
07:27:14<nolrai_>what does "the eta-reduction property does not hold" mean in an erro about newtype deriving?
07:27:27<nolrai_>s/erro/error
07:28:16<nolrai_>never mind i think i got it.
07:31:00<Twey>nolrai_: That's one scary-lookin' error you got there, sonny-Jim... O.O
08:02:01<kaol>I'm trying to come up with a way to write code that can both generate XSLT and apply it to a haskell data structure and generate XML. Fun stuff.
08:03:58<kaol>trying to include some sort of caching logic with those document() XSL functions too
08:05:37<int-e>hGetContents--
08:44:57<quicksilver>int-e++
08:49:42<Saul_>I'm having some problems installing hsql 1.7
08:49:45<Saul_> Could not find module `System.Time':
08:49:45<Saul_> it is a member of package old-time-1.0.0.0, which is hidden
08:50:48<Saul_>Does anyone know how to fix this?
08:51:22<quicksilver>it means hsql hasn't been ported to 6.8.2 I think
08:51:33<quicksilver>you can try adding old-time to the depends in the cabal
08:51:40<quicksilver>and keep adding any more packages it complains about
08:53:26<Saul_>Ok I'll try it
08:56:28<Saul_>ok I think I got it
08:56:53<Saul_>I also got a compile error, but adding -fglasgow-exts solved it
08:59:18<Saul_>Hmmz now I get this error while configuring hsql-mysql
08:59:20<Saul_>Setup.lhs:8:33:
08:59:20<Saul_> Module
08:59:20<Saul_> `Distribution.Simple.Utils'
08:59:20<Saul_> does not export
08:59:21<Saul_> `rawSystemVerbose'
09:02:47<Saul_>Oh great it even says so on the hackage page
09:02:48<Saul_>http://hackage.haskell.org/cgi-bin/hackage-scripts/package/hsql-mysql
09:02:50<lambdabot>http://tinyurl.com/5khq9n
09:19:19<Saul_>Argh, I figured I would use HDBC sqlite instead, and I get different weird errors :(
09:20:32<Heffalump>I use hsql-mysql with ghc 6.8.2, but I can't remember if I had to make any local changes
09:21:14<Heffalump>hmm, none that I can find
09:26:22<Saul_>:(
09:30:28<Saul_>It seems like the Setup.lhs file itself is containing compile errors
09:31:09<Saul_>I took out the explicit import of rawSystemVerbose (it's not even used) but now I got other errors that are less easy to solve
09:35:20<Heffalump>which cabal are you using?
09:36:58<Heffalump>you might want to build from the darcs repo at http://code.haskell.org/HSQL/ instead
09:36:58<lambdabot>Title: Index of /HSQL
09:41:01<Saul_>I'm using Cabal-1.2.3.0
09:41:46<Saul_>which appears to be the newest version
09:41:55<Heffalump>for 6.8.2, yeah
09:42:08<Heffalump>try that darcs repo for HSQL, I'm fairly sure I've built it ok from that
09:43:08<Saul_>ok
09:44:50<Saul_>Setup.lhs:9:7:
09:44:50<Saul_> Could not find module `Distribution.PackageDescription.Parse':
09:44:50<Saul_> Use -v to see a list of the files searched for.
09:44:57<Saul_>different error :)
09:48:37<Heffalump>Wed Apr 16 06:56:15 BST 2008 marco-oweber@gmx.de
09:48:38<Heffalump> * fixed verbose flag FIXME in Setup.lhs of MySQL
09:48:40<Heffalump>unpull that patch
09:50:44<Saul_>Heffalump: How do I use unpull to unpull that patch?
09:50:58<Saul_>I'm not that savy with darcs yet
09:51:01<dmwit>darcs unpull -p "verbose flag FIXME"
09:55:50<Saul_>ok that seemed to work, thanks dmwit and Heffalump
10:12:26<mxc_>is anyone here familiar with Data.Binary and laziness?
10:12:47<mxc_>quesiton is, if i have a tuple (x,y) that I decode
10:13:05<mxc_>say data MyTup = MyTup (x,y)
10:13:26<mxc_>and in the get implementation, the data for x is read frist, if I never reference y, will it just lazily ignore it?
10:13:45<Twey>Yep
10:14:22<mxc_>cool, so in my situation, x is a single word8 which functions use to determine if they want to decode y (some big ugly record)
10:14:33<mxc_>speed is important so i only want to decode y when necessary
10:15:22<mxc_>thanks twey
10:16:09<Twey>Welcome
10:16:16<Heffalump>the downside of it being lazily ignored is that the source data will hang around as long as references to y do
10:18:34<MedeaMelana>morning
10:26:19<flippo>preflex, be poppavic
10:26:19<preflex> dude, you need to stop hollering and either spend more verbage explaining it to them or just DON'T.
10:26:32<flippo>(Sorry.)
10:34:51<vixey>Heffalump, why ban it?
10:35:29<Twey>Wasn't the real IRSeekBot
10:38:31<MedeaMelana>it's quiet today
10:40:17<vixey>> let f91 x | x > 100 = x - 10 | otherwise = f91 . f91 $ x + 11 in map f91 [1..]
10:40:19<lambdabot> [91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,...
10:41:28<MedeaMelana>does that work for other numbers than -10 too?
10:43:36<Heffalump>vixey: I assumed it was up to something nefarious, given the number of times it's flooded itself of
10:43:41<MedeaMelana>> let f91 x | x > 100 = x - 9 | otherwise = f91 . f91 $ x + 11 in map f91 [1..]
10:43:42<Heffalump>do you know something about it?
10:43:43<lambdabot> [92,93,92,93,92,93,92,93,92,93,92,93,92,93,92,93,92,93,92,93,92,93,92,93,92,...
10:44:09<mercury^>MedeaMelana: maybe you have to adjust teh +11 too
10:45:14<MedeaMelana>> let f91 x | x > 100 = x - 9 | otherwise = f91 . f91 $ x + 10 in map f91 [1..]
10:45:15<lambdabot> [92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,...
10:45:24<MedeaMelana>hmm
10:46:13<nornagon>> repeat 92
10:46:14<lambdabot> [92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,...
10:46:21<MedeaMelana>Something else I've been wondering about: why isn't ($) defined as id, with type a -> a ?
10:46:30<nornagon>@src ($)
10:46:30<lambdabot>f $ x = f x
10:46:35<vixey>MedeaMelana: that's a valid definition
10:46:46<MedeaMelana>:t ($)
10:46:48<lambdabot>forall a b. (a -> b) -> a -> b
10:46:52<MedeaMelana>:t id
10:46:54<lambdabot>forall a. a -> a
10:46:58<vixey>MedeaMelana: (a -> b) -> a -> b is more descriptive though
10:47:17<MedeaMelana>yes, more descriptive, more restrictive
10:47:26<nornagon>more restrictive?
10:47:27<nornagon>how?
10:47:32<vixey>it's not a restriction
10:47:35<vixey>id still exists
10:47:44<nornagon>a -> a is a subset of a -> b
10:48:05<MedeaMelana>> head `id` [1..]
10:48:06<lambdabot> 1
10:48:10<MedeaMelana>> head $ [1..]
10:48:12<lambdabot> 1
10:48:22<vixey>> id 3
10:48:23<lambdabot> 3
10:48:24<vixey>> ($) 3
10:48:24<lambdabot> add an instance declaration for (Num (a -> b))
10:48:42<MedeaMelana>yes, that makes it more restrictive, I think
10:48:47<MedeaMelana>id does everything $ does
10:48:48<nornagon>ah, right.
10:49:05<vixey>id has a more general type
10:49:16<nornagon>sry, not thinking :P
10:49:41<mercury^>MedeaMelana: you can force the type of something with $
10:49:56<MedeaMelana>Yes. Why is that useful here?
10:50:20<vixey>> map ($ 3) [(+3), (*2)]
10:50:21<lambdabot> [6,6]
10:50:41<mercury^>MedeaMelana: I had a good example where you needed $ and could not use id
10:50:46<mercury^>now I just need to remember it
10:50:48<mercury^>-.-
10:50:57<MedeaMelana>Maybe vixey's example works?
10:51:03<vixey>mercury^: I don't think that it exists
10:51:09<nornagon>> map (`id` 3) [(+3),(*2)]
10:51:10<MedeaMelana>> map (`id` 3) [(+3), (*2)]
10:51:10<lambdabot> [6,6]
10:51:11<lambdabot> [6,6]
10:51:14<vixey>:t id :: (a -> b) -> a -> b
10:51:16<lambdabot>forall a b. (a -> b) -> a -> b
10:51:16<nornagon>:D
10:52:11<MedeaMelana>I realized a while ago that $ is id for functions, but I never realized that it actually *is* id
10:52:21<vixey>currying
10:52:24<Heffalump>well, it's not because of the type
10:52:37<Heffalump>The only reason I can think of for restricting the type is to improve error messages
10:52:50<MedeaMelana>That's a good reason
10:52:50<vixey>I think the type is documentation
10:53:47<Heffalump>I can't think of a good example of it actually improving an error message in any sensible use, though.
10:54:13<vixey>and f $ x = f x describes its use much better than ($) = id
10:54:16<MedeaMelana>You have to misuse $ before you get any error messages
10:54:30<MedeaMelana>How could one misuse $
10:54:39<vixey>> 7 * ($)
10:54:39<lambdabot> add an instance declaration for (Num ((a -> b) -> a -> b))
10:54:48<MedeaMelana>I mean, what are understandable ways to misuse $
10:54:55<vixey>there aren't any
10:55:07<vixey>any badly typed expression is nonsens
10:55:39<MedeaMelana>What I mean is: some mistakes are easily made and very common.
10:55:47<MedeaMelana>At least for those who are new to Haskell.
10:56:16<Heffalump>I meant "any sensible misuse"
10:56:22<vixey>> let f91 x | x > 100 = x - 10 | otherwise = f91 . f91 $ x + 11 in drop 95 (map f91 [1..])
10:56:24<lambdabot> [91,91,91,91,91,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,1...
10:56:26<Heffalump>i.e. any code that someone might reasonably be trying to write, but got wrong
10:56:37<MedeaMelana>Exactly
10:57:01<MedeaMelana>Of course, there's normal misapplication of arguments to functions, and the programmer might have used $ there
10:57:41<Heffalump>the thing is, as soon as you use it as a fully-applied infix operator, its type is forced to the function type anyway
10:57:46<Heffalump>since that's the only way it can take two arguments
10:58:04<Heffalump>so a "sensible misuse" would have to use it as a sectioned operator somehow
10:58:25<vixey>any misuse of ($) will look like nonsense
10:58:33<MedeaMelana>> head True
10:58:34<lambdabot> Couldn't match expected type `[a]' against inferred type `Bool'
10:58:40<vixey>just like 7 * ($)
10:58:40<MedeaMelana>> head $ True
10:58:40<lambdabot> Couldn't match expected type `[a]' against inferred type `Bool'
10:58:46<MedeaMelana>> head `id` True
10:58:47<lambdabot> Couldn't match expected type `Bool' against inferred type `[a]'
10:58:53<MedeaMelana>hehe
10:59:07<Heffalump>vixey: I'm not completely convinced of that, but I certainly can't think of any good examples to contradict it.
10:59:25<Heffalump>MedeaMelana: ok, that's actually halfway decent
10:59:26<vixey>*any* badly typed expression is complete nonsense
10:59:33<Heffalump>vixey: oh, now that is rubbish
10:59:44<Heffalump>a simple error can move you from a well-typed expression to an ill-typed one
10:59:46<vixey>if it doesn't type the expression has no meanin
11:00:05<Heffalump>the question is how well the implementation does at explaining what is wrong to the user
11:00:12<vixey>:t 2 ^ 0.5
11:00:14<lambdabot> Ambiguous type variable `t' in the constraints:
11:00:14<lambdabot> `Integral t' arising from a use of `^' at <interactive>:1:0-6
11:00:14<lambdabot> `Fractional t'
11:00:23<vixey>this -doesn't- take the square root of two
11:00:25<Heffalump>MedeaMelana: because there's nothing in head $ True that has type [a], so it's a bit odd to see it being inferred for something.
11:02:21<MedeaMelana>vixey: the question is whether $'s current (restrictive) type could ever improve the quality of error messages
11:02:41<MedeaMelana>apart from the fact that it's current type describes its common use better
11:02:48<MedeaMelana>its*
11:02:51<vixey>> ($) 3
11:02:52<lambdabot> add an instance declaration for (Num (a -> b))
11:03:41<Heffalump>that's a nice example too
11:04:03<MedeaMelana>i'm not sure what that shows
11:04:20<Heffalump>> id 3
11:04:21<lambdabot> 3
11:04:21<vixey>it's at type error I got from misuse of ($)
11:04:29<Heffalump>it provides an error that you wouldn't have got from id
11:04:34<Heffalump>which is useful
11:04:45<Heffalump>> id 3 2
11:04:45<lambdabot> add an instance declaration for (Num (t -> a))
11:04:49<Heffalump>> ($) 3 2
11:04:50<lambdabot> add an instance declaration for (Num (a -> b))
11:04:57<vixey>anyway the real reason ($) :: (a -> b) -> a -> b is documentation as I said before
11:05:20<MedeaMelana>probably
11:05:20<Heffalump>do you actually know this from a historical perspective, or are you just guessing?
11:05:29<MedeaMelana>which i'm not sure is a good enough reason
11:05:33<vixey>it suggests: ((foo :: a -> b) $ (bar :: a)) :: b
11:11:23<kowey>?seen gour
11:11:23<lambdabot>Plugin `seen' failed with: too few bytes. Failed reading at byte position 8
11:11:43<Heffalump>I guess it's database is broken
11:11:49<Heffalump>s/it's/its/
11:12:09<kowey>hmm... yeah, just signaling the problem
11:22:43<MedeaMelana>I think it'd be pretty fun if everywhere I wrote id I could write ($) instead :-)
11:23:12<MedeaMelana>Though id is a better name for identity
11:23:47<Baughn>$ does have the distinct advantage of being slicable
11:24:05<Baughn>map (`id` 42) [(+1)] just doesn't have the same feel. ;)
11:24:16<Baughn>> map (`id` 42) [(+1)] -- does it even work?
11:24:17<lambdabot> [43]
11:24:23<MedeaMelana>What does slicable mean here?
11:24:53<Baughn>($ 42) <- There. A slice. Unless of course I completely forgot the right word to use.
11:25:07<Deewiant>a section, I believe, is the standard term.
11:25:20<MedeaMelana>Ah, right
11:25:21<Baughn>Right you are
11:25:40<MedeaMelana>Maybe $ is more easy to optimize if it is restricted to functions?
11:28:16<Baughn>@type id
11:28:18<lambdabot>forall a. a -> a
11:28:23<Baughn>@type `id` 42
11:28:25<lambdabot>parse error on input ``'
11:28:29<Baughn>@type (`id` 42)
11:28:30<MedeaMelana>you need ()
11:28:31<lambdabot>forall t t1. (Num t) => (t -> t1) -> t1
11:30:24<MedeaMelana>Because most (non-section) uses of $ can be trivially rewritten to an expression with $ but with more parentheses. Which might save a reduction?
11:30:52<MedeaMelana>I meant without $
11:31:27<Baughn>The optimizer does a fine job. Don't worry about it.
11:31:41<MedeaMelana>That doesn't help
11:34:56<Saul_>@seen shapr
11:34:56<lambdabot>Plugin `seen' failed with: too few bytes. Failed reading at byte position 8
11:35:08<Saul_>awesome
11:35:52<maltem___>Do I remember incorrectly, or wouldn't ($) having the general type of id :: a -> a be impossible in Haskell98?
11:36:22<mattam>@type flip id
11:36:24<lambdabot>forall b c. b -> (b -> c) -> c
11:36:35<Philippa_>MedeaMelana: if you're working with purely unoptimised implementations then yes, $ is slower. Any compiler that can do inlining will inline something as small as $ though
11:36:35<lambdabot>Philippa_: You have 1 new message. '/msg lambdabot @messages' to read it.
11:36:46<Baughn>@dict-all pulchritudinous
11:36:46<lambdabot>Unknown command, try @list
11:37:37<MedeaMelana>Yes, so what I was asking is: maybe inlining $ is easier if it has type (a -> b) -> a -> b instead of a -> a
11:38:01<MedeaMelana>But I guess that doesn't make much sense
11:39:08<Baughn>It gets inferred down to a concrete type either way
11:47:24<ziman>@pl \f -> f x1 x2
11:47:25<lambdabot>flip ($ x1) x2
11:47:49<Saul_>is there any decent documentation out there for either haskelldb or hsql (in a tutorial-like fashion)?
11:48:16<Saul_>and are they mature enough to use, or should I use something else?
11:49:05<Baughn>I've done fine with just hdbc
11:49:45<Baughn>(hsql lacks parametrized queries. Don't use it.)
11:53:12<MedeaMelana>ACTION waves
11:57:42<Heffalump>as long as you're careful about SQL injection, parameterized queries are just an efficiency concern
11:57:53<jeffz>http://reddit.com/r/prolog/info/6llqb/comments/ might be of general interest to people - "A Wake Up Call for the Logic Programming Community", Haskell is mentioned a few times
12:02:13<opqdonut>hmm
12:02:25<xci>mmh
12:04:59<augustss>mhm
12:06:45<mattam>hmm
12:06:54<ivanm>mmh?
12:07:04<ivanm>oh, what, xci already did that one
12:07:24<Heffalump>no, xci did the other one
12:07:39<Heffalump>mhm
12:07:44<Heffalump>now we're done
12:07:50<augustss>i did that one
12:07:52<ivanm>no, xci did mmh...
12:07:59<ivanm>and opqdonut beat mattam
12:08:05<Heffalump>no, you did the other one. Can't you tell the difference between your 'm's? :-)
12:08:24<ivanm>ACTION 's brain hurts
12:09:49<int-e>@type liftM2 const
12:09:51<lambdabot>forall a1 a2 (m :: * -> *). (Monad m) => m a1 -> m a2 -> m a1
12:10:28<PantheraPardus>err, what does mhm stand for?
12:10:42<ivanm>PantheraPardus: permutation of "hmm"
12:11:18<PantheraPardus>hmm
12:12:09<ivanm>ACTION resists the temptation to start that nonsense all over again
12:12:47<PantheraPardus>lol
12:13:00<Heffalump>llo
12:13:12<ivanm>*sigh*
12:13:17<PantheraPardus>ACTION waits for the last variant
12:13:55<PantheraPardus>let's do it ;)
12:15:35<DRMacIver>Hm. gtk2hs appears to have bytestring 0.9.0.5 as a dependency.This is somewhat perplexing as such a package does not exist.
12:16:17<ivanm>which version of gtk2hs?
12:16:25<ivanm>there's a bytestring-0.9.1.0 ...
12:16:34<DRMacIver>Yes, and I have that.
12:16:44<DRMacIver>gtk2hs 0.9.12.1
12:17:17<DRMacIver>But the build is failing with ghc-6.8.2: unknown package: bytestring-0.9.0.5 (dependency of cairo-0.9.12.1)
12:17:30<ivanm>hmmm, I don't have it requring bytestring at all...
12:17:50<ivanm>though that's because dcoutts didn't set it as a dependenciy in the ebuild ;-)
12:17:56<ivanm>@seen dcoutts
12:17:56<lambdabot>Plugin `seen' failed with: too few bytes. Failed reading at byte position 8
12:18:00<ivanm>preflex: seen dcoutts
12:18:01<preflex> dcoutts was last seen on #gentoo-haskell 1 day, 3 hours, 31 minutes and 38 seconds ago, saying: hia ivanm
12:19:19<DRMacIver>There's definitely a ByteString dependency in the makefile. Even more curiously, it's set to 0.9.1.0
12:24:24<DRMacIver>Hm. Couldn't be a ghc compatibility issue could it? gtk2hs only explictly mentions 6.8.1 and 6.6.1, but I'm running 6.8.2. (I can't really imagine that being the problem though)
12:24:44<ivanm>I doubt it
12:24:55<ivanm>how are you installing it? make?
12:25:00<DRMacIver>yeah
12:25:12<ivanm>... wierd
12:25:24<DRMacIver>I'm really good at generating that reaction. :)
12:25:56<ivanm>lol
12:26:37<DRMacIver>Anyway, I've tried ghc-pkg hiding the old version of bytestring I also had installed and am rebuilding. Will see if that helps.
12:34:14<DRMacIver>That seems to have done it
12:43:35<DRMacIver>Is it normal to find glade completely and utterly maddening?
12:43:48<TSC>Yes
12:43:56<DRMacIver>ok. Just wanted to make sure.
12:43:58<TSC>At least common (:
12:46:07<kpreid>Disagreement: http://blog.plover.com/prog/glade.html
12:46:08<lambdabot>Title: The Universe of Discourse : Glade
12:46:17<DRMacIver>Yes, I saw that.
12:46:31<DRMacIver>It's a large part of why I decided to give this stuff a try. :)
12:47:06<DRMacIver>But it's also an example that would be trivial in any GUI builder that even pretends to the name.
12:49:38<DRMacIver>You never know, I might get used to it and love it. But initial impressions of the w handles widget layout and similar are very far from positive.
12:51:35<kpreid>DRMacIver: Ah. Yeah, I recognize the difference and was being a bit silly
12:51:59<DRMacIver>Fair enough. :)
13:17:38<jaj>I think back then when glade was able to create C/python/whatever code it was quite interesting but now that you have to depend on libglade and you have to have an xml file lying around it's a bit annoying
13:18:25<DRMacIver>On the other hand makes it a bit easier to use with new languages (like Haskell) :)
13:18:44<jaj>of course it's quite difficult to support different languages and generate good code for them
13:20:15<jaj>I think it would be quite interesting to create a DSL which let's you describe a GUI. I never used gtk2hs, perhaps it can do that? :)
13:21:37<wjt>jaj: perhaps you could write a gladexml -> Hypothetical Gtk DSL converter? :)
13:22:04<DRMacIver>Hm. I love it when tutorials purport to be for the version of the software you're using and refer to features that flat out don't exist.
13:23:34<jaj>wjt: that would be interesting :) not sure I'm up to the task but I could try
13:25:37<DRMacIver>And the fact that the glade documentation is full of sections like "FIXME" and "Please Write Me" continues to make me less than happy with it. :)
13:53:47<Jaak>deamnit, is hoogle down?
13:56:05<ivanm>@hoogle map
13:56:06<lambdabot>Prelude.map :: (a -> b) -> [a] -> [b]
13:56:06<lambdabot>Data.List.map :: (a -> b) -> [a] -> [b]
13:56:06<lambdabot>Data.ByteString.map :: (Word8 -> Word8) -> ByteString -> ByteString
13:56:23<DRMacIver>Jaak: Looks it
13:56:58<jaj>seems like haskell.org is down
13:59:49<Jaak>@hoogle queue
13:59:49<lambdabot>No matches found
13:59:58<Jaak>@hoogle min
13:59:59<lambdabot>Prelude.min :: Ord a => a -> a -> a
13:59:59<lambdabot>Data.Ord.min :: Ord a => a -> a -> a
13:59:59<lambdabot>Prelude.minBound :: Bounded a => a
14:00:11<Jaak>@hoogle findMin
14:00:11<lambdabot>Data.Set.findMin :: Set a -> a
14:00:11<lambdabot>Data.Map.findMin :: Map k a -> (k, a)
14:00:11<lambdabot>Data.IntSet.findMin :: IntSet -> Int
14:04:21<Jaak>and back up
14:06:34<TomMD>@seen areYouWorking?
14:06:35<lambdabot>Plugin `seen' failed with: too few bytes. Failed reading at byte position 8
14:09:47<DRMacIver>lambdabot is such a great example of how Haskell's strong type system helps you prevent bugs.
14:09:51<Lycurgus>i'd call that a bug
14:10:02<jdh30>lol
14:10:05<DRMacIver>That might have been my point...
14:10:34<Lycurgus>without the error message it would have been regular in-principle perfect haskell
14:10:38<jdh30>what are you up to these days DRMacIver?
14:10:51<TomMD>If only you could force files never to be corrupt using the type system.
14:12:29<DRMacIver>At work, visualisation software in Scala (though soon to move to ruby due to politics). At home, the usual assortment of random hackery. How about you? Still telling the world why everything except F# and OCaml are awful?
14:12:52<jdh30>Actually I am currently telling the world why OCaml is awful. :-)
14:13:15<TomMD>So that only leaves F# as acceptable?
14:13:37<jdh30>For me, yes. :-(
14:14:01<TomMD>I take it you don't have *nix as a platform often.
14:14:16<TomMD>*target platform
14:14:32<jdh30>DRMacIver: is that JRuby now or Ruby Ruby?
14:15:10<jdh30>Actually I am still predominantly Linux and several of our products are still Linux/OSX. I'm getting pretty sick of Linux to be honest though.
14:15:38<Heffalump>ACTION is very sick of Windows
14:16:11<DRMacIver>jdh30: JRuby.
14:16:23<Heffalump>.NET is quite nice though
14:16:27<DRMacIver>Although we do use Ruby Ruby as well, and will probably try to make most of the code portable between the two.
14:16:45<DRMacIver>(except for the bits that are explicitly there to use Java libraries of course)
14:16:46<jdh30>What is JRuby like? I get the impression it is vastly more popular that IronRuby/Python on .NET?
14:17:03<jdh30>Heffalump: yeah, .NET rocks.
14:17:14<sclv>pl ftw: any (s ==) . map (second (drop 1) . span (/= '=') . takeWhile (/= ';') ) . map snd . filter ((HeaderName "set-cookie" ==) . fst) $ hs
14:17:35<jdh30>I actually came here because I saw some of what DonS had written about me here.
14:17:49<Heffalump>what did he say?
14:17:54<mrd>sclv: pl? plz... (s ==) ?
14:18:24<DRMacIver>JRuby seems to be among the most popular of the dynamic languages for the JVM crowd. It's moving along nicely as far as I can tell. But we're way off topic for #haskell
14:18:52<sclv>its just a function to test if any cookie is set to a particular value on an http response. i was just happy with how condensed it came out.
14:19:06<Heffalump>how do types work in dynamic languages on the JVM? Is everything an object?
14:19:41<jdh30>he didn't understand why I alienate portions of the functional programming community, why I don't go to ICFP and so on. Here's a link: http://tuukka.iki.fi/tmp/haskell-2007-12-01.html
14:19:41<lambdabot>Title: haskell-2007-12-01
14:20:28<DRMacIver>Heffalump: How do you mean? From a user visible point of view or from an implementation point of view?
14:20:42<Heffalump>DRMacIver: implementation
14:20:45<jdh30>DRMacIver: Yeah. I was amazed (and very happy ;-) to see this trend: http://www.google.com/trends?q=f%23%2Cironpython
14:20:46<lambdabot>Title: Google Trends: f#,ironpython
14:21:16<DRMacIver>Heffalump: I think JRuby objects implement some interface which has a method pointing to a ruby style class object.
14:21:23<DRMacIver>And are otherwise just objects.
14:21:25<Heffalump>jdh30: I vaguely remember that conversation. It seemed accurate at the time and looks that way too now from a quick skim.
14:21:27<jdh30>I can't explain it though.
14:21:44<Heffalump>jdh30: but primitive types have to be objects too?
14:21:47<DRMacIver>Heffalump: I'm not totally sure though. My Ruby foo is weak as hell. :)
14:21:48<Heffalump>sorry, not jdh30
14:21:56<DRMacIver>Heffalump: Yes, they typically don't get to use primitive types
14:22:09<Heffalump>how does performance work out?
14:22:24<sclv>bad.
14:22:30<jdh30>I'd have thought you could optimize that away easily enough but apparently many dynamic languages make no attempt to.
14:22:44<jdh30>But nothing like as bad as Groovy, apparently.
14:22:54<DRMacIver>Heffalump: As I understand it, they tend to suffer a fair bit on numerics as a result but it's not too awful.
14:23:11<DRMacIver>Heffalump: They can still take advantage of arrays of primitives as far as I know.
14:23:20<DRMacIver>which should offset the worst of it.
14:23:24<Heffalump>true
14:23:29<DRMacIver>And I suspect a lot of primitive heavy library code is written in Java.
14:24:02<Heffalump>heh, writing code in java for efficiency
14:24:03<sclv>I don't know if its true anymore, but a big issue used to be with the jvm that object creation is expensive, compared to what one would need for a simple tagged union type or etc.
14:24:21<jdh30>I have actually been quite impressed with Java's performance lately.
14:24:26<sclv>so dynamic languages that represent everything as an object get nailed by the java runtime.
14:24:29<Heffalump>the .NET type system has a built-in variant style type, I wonder what implementations use it.
14:24:32<DRMacIver>jdh30: It's harder to do on the JVM, alas. Ruby Ruby does do some optimisations I think.
14:24:44<jdh30>Right.
14:24:48<Heffalump>I originally thought it was for VB, but it turns out that VB.NET gets rid of having that kind of thing.
14:25:14<DRMacIver>sclv: Allocation is pretty fast these days. The problem is more that Java objects weigh a fair bit and there's not much you can do to offset that.
14:25:34<sclv>java for numerics with a good jit approaches C speeds though, no?
14:25:46<jdh30>ish, yes.
14:26:09<sclv>DRMacIver: Right, but then there's also lookup for creation methods etc, too, no?
14:26:24<Heffalump>sclv: that's statically resolvable, though
14:26:31<Heffalump>constructors are the one thing that never require virtual dispatch
14:26:32<jdh30>I ported SciMark2 from Java to OCaml and F# recently. Java on 64-bit Debian AMD64 beats everything else except C (and even beats C on the SOR subtask where aliasing is important).
14:26:38<sclv>but is it statically resolved in the jvm?
14:27:05<Heffalump>sclv: yes
14:27:05<DRMacIver>jdh30: By the way, I don't think the primitives thing is something where .NET wins.
14:27:25<sclv>ah, good to know.
14:27:41<DRMacIver>jdh30: As the issue isn't just "good support for primitives" it's "providing a uniform object model over primitives and objects", which needs more low level hackery than I think either provides
14:28:31<Heffalump>it's not the uniform object model I was thinking of, though that may be an issue too - it's just the lack of static type information
14:28:34<DRMacIver>(also I suspect the issue with using objects instead of primitives is more that there are a lot of optimisations performed for primitives that aren't for their corresponding objects)
14:28:41<jdh30>DRMacIver: I see. I've no idea about the performance of dynamic languages on .NET, BTW. AFAICT, nobody uses them.
14:28:47<Heffalump>you can't represent something as an int if you don't know for sure it'll be an int
14:29:10<jdh30>You can certainly unbox it locally, which should be all you need for the vast majority of performance-critical sections.
14:29:18<luite>DRMacIver: some of the optimizations (no need for garbage collection etc) can now be performed in specific cases for objects too, because jvm 1.6 has escape analysis
14:29:40<DRMacIver>luite: I was thinking more in terms of numerics, loop optimisations, etc.
14:30:24<Heffalump>luite: as in the JIT in Sun JVM 1.6 does the analysis? Or do you mean that there is something added to the JVM spec to make it easier?
14:31:01<DRMacIver>Heffalump: I think the sun 1.6 JVM has the capability to do escape analysis but it's switched off
14:32:21<luite>I read some articles about it, but I'm not sure whether it is actually already used. 1.6 does have some performance improvements, but that might be because of some other optimizations (register allocation)
14:34:28<DRMacIver>Heffalump: The uniform object model and lack of static type checking are both part of the same issue here though. If you can treat an Int as an object, you need to box it a lot of the time. If you *always* treat an int as an object (because of the dynamic typing) then you have to box it all the time.
14:34:50<DRMacIver>Scala suffers from the first problem and its a noticable performance hit far more often than I'd like
14:35:01<DRMacIver>(though not as bad as for the dynamic languages)
14:35:13<Heffalump>can't you just box it when it's used as an object?
14:35:33<Heffalump>or do the mutability semantics force that to happen when it's passed to things as well?
14:35:57<DRMacIver>Yes, and Scala does for the most part. But there are a lot of cases where it does have to be treated as an object.
14:36:20<DRMacIver>For example you have to box an int to pass it through the identity function.
14:36:38<DRMacIver>Parameterized things don't get templated for primitives, so basically every time you hit a type parameter you have to box
14:37:17<Heffalump>ah, yes
14:37:20<Baughn>That's scala. GHC does specialize them, right?
14:37:31<Heffalump>Baughn: typically only by inlining
14:37:47<Heffalump>I think it only specializes if you tell it to (with a pragma) though I could be wrong
14:38:45<Baughn>Heffalump: Mm. That's one optimization I could see helping - there usually aren't enough types passing through a polymorphic function that boxing is better than specializing, I don't think. There aren't too many that can be unboxed in the first place.
14:39:10<DRMacIver>Generally speaking comparing Scala optimisations with GHC ones makes the Scala compiler team sad. :)
14:39:21<Heffalump>Baughn: well, it's a code bloat issue
14:39:25<Baughn>But if it already has the machinery, and just doesn't do it by default, that suggests I'd be wrong
14:39:28<Heffalump>DRMacIver: is scala strict or lazy?
14:39:52<DRMacIver>Strict with optional laziness.
14:40:03<Baughn>Heffalump: I suppose. There /is/ something to be said for haskell programs fitting in L2 cache
14:40:07<DRMacIver>Although I have some Issues with the laziness implementation. I keep meaning to see if I can improve it.
14:40:12<Heffalump>Baughn: if you're talking about GHC, then you can't pass unboxed stuff to polymorphic things anyway
14:40:30<Heffalump>as an optimisation, you could specialise the thing and unbox the parameter together
14:40:34<DRMacIver>(It plays very badly with the garbage collector)
14:40:35<Baughn>Heffalump: Well, not /explicitly/ unboxed stuff
14:40:42<Heffalump>right
14:40:55<Heffalump>but since you have to do both together, it's probably rather harder to decide to do so
14:42:20<Baughn>DRMacIver: If you do look at that, I'd love to have time-driven weak references. That is to say, weak references that get collected in LRU order
14:42:42<DRMacIver>Sorry, I meant the Scala laziness implementation. :) I wouldn't know where to start with GHC's
14:43:10<EvilTerran>Baughn, ooh, that's terribly clever
14:43:20<DRMacIver>And Scala isn't pure, so that's not really appropriate for its laziness.
14:43:26<pejo>Isn't the implementation in GHC pretty good, considering how well it does in the shootout?
14:43:30<jdh30>Does Scala get JIT-time type specialized like F#?
14:43:37<Baughn>pejo: Sure, but it can always get better
14:43:46<DRMacIver>(But yes, I've often wondered about something like that as well)
14:43:55<EvilTerran>so, if some big expression gets CSEd and unexpectedly cached for a long time, and it's being held in a weak reference, it can be GCed and re-calculated if there's not enough memory to keep it around
14:44:00<DRMacIver>jdh30: No more so than anything on the JVM does.
14:44:16<Baughn>EvilTerran: Yep, that's the idea
14:44:31<Heffalump>but then the GC would need to roll the expression back to the uncomputed state, too
14:44:40<EvilTerran>i love it. seems like a great solution to the CSE-isn't-always-an-optimisation problem
14:44:55<Heffalump>and that might well take up more space anyway..
14:45:10<EvilTerran>altho Heffalump has a point - a weak reference would have to include a reference to the unevaluated thunk
14:45:10<Baughn>Heffalump: True. It wouldn't always be a win, so you'd want to do it explicitly
14:45:30<Heffalump>also, LRU doesn't make too much sense on its own, you need to trace the LRUness right through
14:45:33<Baughn>EvilTerran: We'd have to play tricks with the local page table, though. I'm not sure how it'd work on platforms that don't /have/ a user-level page table, ie. non-x86
14:46:04<Baughn>Hm
14:46:35<EvilTerran>aaaand suddenly the conversation's over my head. never mind, IANA compiler designer :P
14:46:37<Baughn>Keep a counter of weak-thunks-evaluated, increment and assign every time you dethunk one, store in sorted order?
14:47:00<Baughn>Or don't keep a counter, and just use the memory location for same
14:47:01<Heffalump>re the page table, you want to keep all the weak stuff in separate pages that you can just drop?
14:47:29<Baughn>Yes, and so you can track LRUness by reading the access bit on said table
14:47:46<Baughn>x86 tracks accesses to pages, both reads and writes. It's very handy
14:48:14<Baughn>The granularity could be an issue, though.. *ponder*
14:48:18<Heffalump>yeah
14:48:35<Heffalump>have you read the PLDI '05 paper on this subject (using page tables with GC)?
14:49:03<Baughn>No. I'm sure it'd be interesting, but I'm not normally on the internals side of things
14:49:21<Baughn>(And I have a few hundred papers scheduled to read already. :P)
14:49:47<EvilTerran>ACTION notes that it'd be occasionally handy to have (^-) x y = x ^^ (-y)
14:49:57<jdh30>Are there any industrial programmers here?
14:50:05<EvilTerran>so you could write stuff like (2^-10)
14:50:15<Heffalump>how do you define industrial?
14:50:52<jdh30>Make products and sell them to make money.
14:51:02<jdh30>So MSR doesn't count.
14:51:10<Heffalump>even F#?
14:51:32<jdh30>Not when it was in MSR, no.
14:51:42<Heffalump>ok, so Don Syme doesn't count?
14:51:50<jdh30>Don is productizing it.
14:52:01<Heffalump>he's still in MSR
14:52:21<jdh30>He's in Redmond.
14:52:47<Heffalump>that doesn't preclude him being in MSR..
14:52:58<Heffalump>but fair enough if he's temporarily moved to a product group again
14:53:13<jdh30>He is in Redmond working on F# with the product team. Yes.
14:53:22<DRMacIver>Do you consider services companies and/or people developing internal tools to be "industrial"?
14:53:29<Baughn>So.. weak reference = (reference/thunk, thunk copy, last access time). Keep a global counter for accesses; update the access time anytime you actually dereference it explicitly. In times of memory pressure (must be tunable) allow the GC to collect the /least recently/ accessed reference, copying back the thunk. Problem: If you hang on to references to inside whatever structure your weak ref is holding, you could conceivably get multiple
14:53:37<Heffalump>anyway, can you prove MS are going to make money from F#?
14:53:46<DRMacIver>(Neither of which apply to me. I fit into that category fairly unambiguously)
14:53:51<jdh30>Yes but they are uninteresting if their work is invisible from the outside.
14:53:52<Heffalump>given that they probably won't change the price of VS anyway
14:53:57<DRMacIver>(though not using Haskell, alas)
14:53:59<jdh30>MS already have made money from F#.
14:54:05<Heffalump>oh, how?
14:54:16<Heffalump>people write about internal work they do externally, sometimes
14:54:43<DRMacIver>Baughn: You cut off at "conceivably get multiple c"
14:55:50<Baughn>DRMacIver: The thunk can end up being evaluated multiple times, producing multiple, identical data structures that are all held in memory by non-weak references
14:55:57<Baughn>DRMacIver: The programmer would have to be careful
14:55:58<jdh30>Yes. The occasional writings can make these things visible from the outside but it is much less interesting that a real product. For example, it would be much more interesting to be able to quantify revenue objectively rather than have someone conjecture as to their work's internal worth.
14:56:27<Heffalump>jdh30: sure. But the same thing applies to a product that is bundled up with a much bigger thing, like F#.
14:56:37<Twinside>hello everyone
14:56:41<jdh30>Heffalump: MS are already making money from F# because people are migrating to .NET because of it and, inevitably, buying VS and other developer tools.
14:56:53<Heffalump>and you can quantify that?
14:57:01<jdh30>Quantify what?
14:57:08<Heffalump>what money they have made from F#
14:57:37<jdh30>You could make a pretty good estimate for now but they will start making serious money when 1.0 is out later this year.
14:57:46<pejo>jdh30, isn't VS a necessary evil that doesn't generate any direct revenue for MS?
14:58:04<Baughn>All things aren't quantifiable. How much money has Foo Company made because their programmers are better as a result of learning haskell, despite their not actually /using/ haskell?
14:58:07<jdh30>VS generates some revenue but nothing like as much as Office, of course.
14:58:27<jdh30>Some things are quantifiable, of course.
14:58:31<Heffalump>jdh30: go on then (make a "pretty good estimate")
14:58:38<[Justice]>it could be argued that Microsoft's core business is VS
14:58:49<jdh30>Justice: yes.
14:58:50<Heffalump>[Justice]: it could be argued, but it'd be wrong :-)
14:58:58<Twinside>I've got an error of "rigid type" with ghc, but I've got issues to really understand what the problem is, can someone help me?
14:58:59<sclv>F# is probably keeping some companies from jumping ship away from .NET, actually.
14:59:17<Baughn>Twinside: Sure, if you post the entire error message and preferably code
14:59:17<jdh30>Not really, Microsoft depend upon third party developers building the applications that their end users buy. That is the foundation of their entire platform.
14:59:23<Heffalump>you'd have to make a very indirect argument about VS helping to maintain the dominance of the Windows platform
14:59:28<Lycurgus>really (re F#)?
14:59:31<Twinside>Baughn > in channel or in private?
14:59:38<Baughn>Twinside: In pastebin
14:59:41<Heffalump>Twinside: http://hpaste.org
14:59:50<jdh30>Lycurgus: definitely.
15:00:07<Heffalump>jdh30: got examples?
15:00:10<[Justice]>not necessarily VS the product, VS the idea of developers writing programs for Windows
15:00:24<Lycurgus>my impression is that only a miniscule number of .net shops ever heard of F#
15:00:34<Lycurgus>or haskell for that matter
15:00:37<[Justice]>.net shops aren't going to write in F#
15:00:40<[Justice]>or haskell
15:00:49<jdh30>Lycurgus: that is precisely why it is good: F# will attract people from other platforms (like me) rather than simply stealing from C#.
15:00:53<sclv>Lycurgus: I know some banks that are moving to increasingly functional methods, and are using F# to work with extant systems.
15:00:55<[Justice]>.net shops are going to stick with VB7
15:01:02<EvilTerran>[Justice], ah, you mean "get everyone writing in .net so they'll get vendor lock-in and be stuck on windows"?
15:01:43<hpaste> Twinside pasted "Compilation problem" at http://hpaste.org/8018
15:01:46<pejo>I think we got slightly sidetracked from Haskell all the sudden. Perhaps this conversation should move to #haskell-blah?
15:01:52<[Justice]>exactly, banks & financial institutions, researchers, etc need F# or functional languages in general
15:02:01<Lycurgus>i was surprised to find out how mono works
15:02:02<Twinside>Baughn > done
15:02:06<jdh30>EvilTerran: Even if it is possible for people to migrate to Mono they won't because it will remain so much worse.
15:02:12<DRMacIver>The only .NET shop I've worked in (well, it was about half .NET shop half Java shop, but it startd as a .NET shop) used C#. I expect a couple people there had heard of F# but there wouldn't have been a snowball's chance in hell of using it.
15:02:14<EvilTerran>Lycurgus, in what way?
15:02:22<Heffalump>pejo: I would argue that language discussions belong here unless they are blatantly not at all to do with Haskell
15:02:28<Lycurgus>it uses the .net binaries
15:02:33<EvilTerran>oh, right
15:02:59<sclv>My understanding is that msoft is very friendly towards the Mono ppl actually.
15:03:06<[Justice]>MS building a superb platform for developing software is ... a problem?
15:03:08<EvilTerran>Lycurgus, ... as in the windows runtimes that MS wrote?
15:03:11<Lycurgus>so it doesn't hit that recreate the world situation
15:03:15<sclv>although it might go all evil-empire on them later, of course.
15:03:21<Lycurgus>ET: yes.
15:03:25<EvilTerran>cunning
15:03:26<EvilTerran>i like that
15:03:31<Heffalump>[Justice]: well, it could be, in the same way as them bundling IE with Windows was a problem
15:04:06<jdh30>DRMacIver: Yes, existing .NET shops are not likely to use F#. Other people will.
15:04:11<Heffalump>ACTION is still waiting for jdh30's F# revenue estimates and examples of it stopping people moving away from .NET :-)
15:04:35<jdh30>sclv: Consider what it would take to threaten Microsoft now and look at how fast Mono is progressing. I can't see the curves ever meeting.
15:04:38<[Justice]>F# is keeping me hoping for an H# ... there's one example
15:04:44<Heffalump>Baughn: are you looking at Twinside's error? Otherwise I will, I just don't want to duplicate work as those things usually take some work to understand.
15:05:07<DRMacIver>Heffalump: It's such an easy estimate to do that it's been left as an exercise for the reader? :)
15:05:14<Baughn>Heffalump: I'm looking, but I think you'd better do it. THis is into trial-error-and-read territory for me
15:05:17<jdh30>I would guess $1M just from people toying with F# for now. I'd expect that to rise to $100M over the next few years, as it sees more serious adoption.
15:05:36<DRMacIver>ACTION holds up his "citation needed" banner
15:05:39<Heffalump>jdh30: that sounds like a conjecture, not an objective quantification
15:05:50<EvilTerran>[Justice], isn't there a Haskell.net project hiding somewhere already?
15:06:02<[Justice]>*shrug*
15:06:05<jdh30>Just multiply the cost of VS by the number of relevant F# users.
15:06:10<Lycurgus>'conjecture' is kind
15:06:11<sjanssen>isn't F# free?
15:06:21<sclv>sjanssen: but VS is not.
15:06:22<[Justice]>there's an abandoned alpha VS plugin for Haskell
15:06:24<EvilTerran>if not, it'd be a good use of YHC's pluggable backends
15:06:28<jdh30>F# is free but you need commercial tools to make it useful.
15:06:33<Twinside>is my error resulting of a bad design?
15:06:36<jdh30>VS is also free (you can use F# with the free VS shell).
15:06:47<Heffalump>jdh30: (a) how do you know how many "relevant F# users" there are and (b) how do you know they wouldn't have bought VS anyway, or just use it from the shell?
15:06:52<Heffalump>and what commercial tools do you need?
15:06:59<jdh30>The money comes from things like VS team edition for its profiler. You can't write performant code without a profiler and most F# users will want to.
15:07:31<Heffalump>but those tools are free if you already have VS for other reasons
15:07:44<jdh30>The relevant F# users are among our customers, so that is easy. We also do market research among prospective customers and non-MS users account for almost half.
15:07:50<jdh30>Yes, they are the other half.
15:07:54<conal>what's the ghc flag for showing which rewrite rules fire
15:07:56<vixey>someone took the book out the library I wanted
15:08:00<vixey>I bet it was someone here!
15:08:15<Heffalump>vixey: what library? :-)
15:08:22<vixey>conal: -v I think .. notsure
15:08:37<EvilTerran>ACTION seems to be in the right country to have taken it, at least
15:08:44<jdh30>Has anyone tried H
15:08:51<jdh30>H#, the Haskell for .NET?
15:08:52<DRMacIver>When you say "our", I can't help but notice that the other members of your company are conspicuously silent...
15:08:55<conal>vixey: i'll try that. thx.
15:08:58<Heffalump>Twinside: ok, so the problem is that you haven't made your serialize polymorphic enough
15:09:12<jdh30>Yes. I am the vocal member. :-)
15:09:21<Twinside>Heffalump > how's that?
15:09:22<Heffalump>your type signature says that if you are implementing StrictPixel for a certain b, you have to make serialize work for *any* b
15:09:22<EvilTerran>vixey, what book, anyway?
15:09:43<Heffalump>sorry, "implementing it for a certain 'a'"
15:09:45<DRMacIver>It's not so much "vocal" as "not completely mute and invisible" in this case.
15:09:48<Heffalump>but you have made b = a
15:10:00<jdh30>Yes.
15:10:08<sjanssen>conal: -ddump-simpl-stats
15:10:11<conal>ah, found it: -ddump-rules
15:10:14<conal>sjanssen: thx!
15:10:16<vixey>EvilTerran; did you get any books out by Luo Zhaohui? :p
15:10:24<EvilTerran>er... no.
15:10:25<vixey>(like yesterday)
15:10:26<Twinside>Heffalump > the compiler can't unify this? because a = b is a possible case for me
15:10:48<Heffalump>Twinside: it's a possible case, but your signature says it must work for *all* cases
15:10:52<jdh30>She is actually quite visible though, albeit only IRL.
15:10:57<sclv>you need mptcs and fundeps, maybe?
15:11:09<EvilTerran>vixey, not out of any oxford library, and definitely not out of a library anywhere else
15:11:09<Heffalump>either make 'b' be another parameter to the class, or fix the class so that b is always a
15:11:41<vixey>ACTION has to wait ages until to get it :/
15:11:59<Twinside>Heffalump > ok I'm going to try adding another parameter to the class, thanks
15:12:26<Heffalump>jdh30: H# doesn't really seem to have much sign of life
15:12:51<jdh30>That is the impression I got. OCamlJava is showing signs of life but it has lots of problems, unfortunately.
15:12:58<[Justice]>H# isn't a real thing, so far as i know ... i meant, a Haskell on the CLR
15:13:04<jdh30>I'm surprised they didn't target Mono instead...
15:13:05<Heffalump>re "relevant F# users", who are they?
15:13:12<jdh30>Oh.
15:13:24<jdh30>Relevant F# users are the ones who did not already own .NET dev tools.
15:13:28<DRMacIver>Haskell seems really unsuited for running on existing virtual machines.
15:13:39<Heffalump>no, I mean give names. Otherwise we just have your unverified assertions.
15:13:45<[Justice]>so did ruby and python
15:13:47<DRMacIver>Is that just a misunderstanding on my part?
15:13:48<Twinside>Heffalump > thanks it work very well :)
15:13:54<jdh30>Depending what Haskell users require, that might not be a practically-important concern
15:14:31<DRMacIver>[Justice]: Not really.
15:14:32<Heffalump>.NET would be nice to have, cos of all the infrastructure that already exists
15:14:32<jdh30>I cannot name my customers, of course.
15:14:35<DRMacIver>[Justice]: Ruby and python execution both fall into the same class of problems as smalltalk, and the JVM at least owes a lot to smalltalk VMs.
15:14:45<Heffalump>and because it's stupid for to be implementing libraries once per platform
15:15:07<DRMacIver>And the bits where it doesn't match up terribly well with the smalltalk VMs are exactly where the implementations on the JVM have all the predicted problems. :)
15:15:37<Heffalump>jdh30: so your claims about revenue to Microsoft are completely unverifiable. It's not even as if you *are* Microsoft, you're just some random consultant who likes evangelizing F#.
15:15:48<jdh30>Heffalump: absolutely. You don't need .NET though: the creators of Linux-based FPLs could just collaborate on a suitable VM design. Well, that is the theory. In practice, they have never managed to collaborate on anything for long enough to see it through to completion and none of them have ever managed to write a working concurrent GC.
15:16:02<DRMacIver>Good compilation of Haskell on the other hand seems to rely on a lot of control over the stack (which I think is why ghc doesn't even use the x86 stack?) and heap (e.g. doing a lot of on heap replacement)
15:16:18<Heffalump>DRMacIver: GHC does a lot of on heap replacement?
15:16:22<DRMacIver>I thought it did
15:16:26<DRMacIver>I may be completely wrong!
15:16:32<Heffalump>I didn't, but I could be wrong too :-)
15:17:04<jdh30>Heffalump: You can easily verify it by counting them yourself. Just post on a relevant forum and I am sure you will get a lot of responses.
15:17:11<DRMacIver>I may also be using the wrong terms. Brief possibilities at ARM aside I'm very much not a compiler engineer. :)
15:17:29<jdh30>I met someone from ARM in my antenatal classes.
15:17:32<Heffalump>"in-place update" is the term I'd use, but it's clear what you meant
15:17:43<Heffalump>they're everywhere..
15:17:45<DRMacIver>but e.g. I was under the impression that when you evaluated a thunk it replaced the original with the result
15:17:58<jdh30>I suppose if I said "our antenatal classes" someone would accuse me of cloning because my wife is "invisible". ;-)
15:18:02<Heffalump>DRMacIver: well, it'll overwrite the pointer with the value, yes. But that's not really a big deal.
15:18:16<Heffalump>jdh30: does your wife actually write F#?
15:18:22<jdh30>No.
15:18:23<[Justice]>*shrug* i dunno what ghc does ... but i guess you could check out the C source it emits
15:18:34<Heffalump>what does she do, then?
15:18:38<DRMacIver>Heffalump: It is if you have multiple copies of it floating around isn't it?
15:18:42<jdh30>Publishing and marketing.
15:18:45<Baughn>[Justice]: I would not recommend that. Read the documentation instead.. really
15:18:49<jdh30>Graphic design.
15:18:52<jdh30>etc.
15:19:09<Heffalump>so you're the only engineer?
15:19:10<[Justice]>> man ghc
15:19:11<lambdabot> Not in scope: `ghc'
15:19:14<jdh30>Oh, and she is a veterinary surgeon. :-)
15:19:17<jdh30>Yes.
15:19:28<[Justice]>lambdabot says the docs are missing
15:19:36<Heffalump>this is why you saying "our" when talking about technical things tends to sound ridiculous
15:19:52<vixey>[Justice]: get them from HTTP
15:20:12<Baughn>[Justice]: http://hackage.haskell.org/trac/ghc/wiki/Commentary
15:20:13<lambdabot>Title: Commentary - GHC - Trac
15:20:35<jdh30>Using the plural is perfectly normal in both academia and industry.
15:20:41<DRMacIver>Heffalump: e.g. if you alias a thunk a lot of times and then evaluate it you need to either update all those aliases, update the current heap location in place, or add an additional level of indirection to make it work.
15:20:59<Heffalump>DRMacIver: yeah, ok
15:21:03<DRMacIver>Heffalump: And the third is really the only one you can do on the JVM or .NET because there's no way to replace the object on the heap.
15:21:16<Heffalump>oh, right. Good point.
15:21:36<Heffalump>I was thinking of "proper" in-place update where you actually skip the GC step when an object becomes dead and can be reused.
15:21:37<jdh30>Incidentally, that was a large part of what I was saying before: my perspective is one of an industrial user and not one of a functional programming evangelist.
15:21:43<DRMacIver>I'm not saying this is a big deal if you control the low level implementation.
15:21:54<DRMacIver>I'm saying that things like this are why it's not easy if you *don't* have that control.
15:22:07<Heffalump>jdh30: an industrial user as in you sell products for money (your own definition from above)?
15:22:18<jdh30>Exactly, yes.
15:22:18<Heffalump>DRMacIver: yeah, fair enough
15:22:30<DRMacIver>phew. Glad I'm not totally on the wrong track. :)
15:23:06<Heffalump>I think the weird control-flow that GHC compiles to is the biggest obstacle, though
15:23:35<DRMacIver>in what sense?
15:24:05<Heffalump>it makes verification hard
15:24:12<DRMacIver>Ah
15:24:25<Heffalump>current verification is very much based on traditional stack-based structured code
15:24:26<[Justice]>sure
15:24:46<[Justice]>and at some point, MS will give us support for lazy evaluations
15:24:46<Heffalump>(even though bytecode isn't actually structured, functions are well-defined etc)
15:24:58<Heffalump>[Justice]: on .NET? I find that very unlikely.
15:25:10<DRMacIver>Why unlikely?
15:25:12<Heffalump>They won't even add higher-kinded type variables to .NET to make F#'s monads properly abstractable.
15:25:24<DRMacIver>Politically or technically?
15:25:27<DRMacIver>Ah
15:25:50<Heffalump>I dunno which you'd describe it as, but essentially the core design of .NET is "done", AIUI.
15:25:57<jdh30>AFAIK they have completely stopped developing .NET now.
15:26:13<vixey>why people are concerned with .net I will never know..
15:26:28<DRMacIver>That's encouraging. Maybe the JVM will have time to catch up. :)
15:26:33<jdh30>.NET accounts for most of our revenue. That's why we care about it.
15:26:35<Heffalump>vixey: because it's very convenient, particularly if you care about binary distribution
15:26:53<Heffalump>which is why it has so much more traction in the commercial world than in the open-source world
15:28:00<jdh30>DRMacIver: apparently Sun are still working on tail calls. <yawn>
15:28:05<[Justice]>it's so easy to write in .net
15:28:19<jdh30>and its so easy to sell with .NET.
15:28:21<vixey>jdh30: why "<yawn>"?
15:28:33<[Justice]>because .net has had tail calls since 1.0
15:28:55<[Justice]>not C# or VB, but it's in the CLR
15:28:57<jdh30>They've been talking about tail calls for several years now but have yet to actually implement anything at all.
15:29:21<sclv>preflex: seen ndm
15:29:21<preflex> ndm was last seen on #haskell 2 days, 4 hours, 4 minutes and 33 seconds ago, saying: mm_freak_work: its a lot of work to learn! just trying to help before people search the Prelude, which gets very confusing
15:29:24<DRMacIver>With the da vinci VM they're starting to do a lot more experimentation with adding new features.
15:29:54<jdh30>As soon as Sun add tail calls to the JVM there will be a huge flurry of ported and new FPLs built upon the JVM and we shall certainly diversify to them. In the mean time, we're F# only for software products.
15:30:03<Heffalump>jdh30: so how much money do you make selling F# products?
15:30:24<jdh30>~$100k p.a.
15:30:41<jdh30>Sorry, halve that (the other half is services).
15:31:20<DRMacIver>There seems to be some work on first class continuations (I suspect that won't ever make it into the real thing, but who knows), Java 1.7 is purported to have tail calls planned although I've not seen an official comment to that effect and a bunch of other interesting features.
15:31:21<Heffalump>ah, I was about to say that's quite impressive
15:31:24<vixey>jdh30: why do you think that? If someone wanted to target the jvm it shouldn't think it makes much difference (implementing TCO in the compiler itsself is relatively simple)
15:31:35<DRMacIver>vixey: No, it's really not. :(
15:31:40<DRMacIver>Not on the JVM anyway
15:31:41<Heffalump>I'll be more impressed once you can make more from writing F# than I do from writing Haskell :-)
15:31:45<clkao>hi! are there cli tools that i can read installed module docs withoug going to hoogle ?
15:31:54<jdh30>OCaml for Scientists was making a similar amount but it has since all but died. Fortunately the F#.NET Journal rose at exactly the same time.
15:32:03<Baughn>DRMacIver: Call me when it gets first-class functions
15:32:16<opqdonut>clkao: haddock
15:32:28<jdh30>vixey: Like David said, it really isn't easy at all. Even if you manage to implement the workaround the results are awful (obfuscated call stacks and terrible performance).
15:32:54<jdh30>TCO is absolutely critical for a wide variety of idiomatic code. So the lack of proper tail calls on the JVM is really holding it back as far as FPL implementations are concerned.
15:32:56<DRMacIver>Baughn: First class functions aren't really a VM detail. The object support works quite happily for them for the most part. But it's getting method handles and lightweight classloading of anonymous classes.
15:32:58<mtag55>hi
15:33:03<DRMacIver>Or at least they're planned. Whether it gets them is unknown.
15:33:18<mtag55>i have a function with a parameter a
15:33:20<Baughn>DRMacIver: Oh, I meant java 1.7, not the jvm
15:33:31<DRMacIver>Oh, I don't give a shit about Java 1.7 :)
15:33:38<vixey>jdh: shouldn't cause performance problems, but yeah you wouldn't get nice backtraces
15:33:41<mtag55>when i run the program it say type error in application
15:33:46<mtag55>term a
15:33:51<DRMacIver>ACTION hasn't written more than a few hundred lines of Java in the last few months.
15:33:52<mtag55>type : integer
15:33:57<Heffalump>vixey: don't you have to make huge methods to work around lack of tailcalls?
15:33:58<mtag55>does not match : int
15:33:59<jdh30>vixey: the workaround relies upon exception handling which is really slow on the JVM.
15:34:04<mtag55>what can i do?
15:34:05<Heffalump>and how do you tailcall to something that isn't statically known?
15:34:06<DRMacIver>I'm purely interested in the VM and libraries at this point.
15:34:11<DRMacIver>jdh30: No, it's not.
15:34:19<DRMacIver>jdh30: It's consistently better than exception handling on .NET
15:34:26<DRMacIver>What's slow is stack trace generation.
15:34:29<DRMacIver>Which is easy to turn off
15:34:32<jdh30>But 10-30x slower than OCaml.
15:34:41<vixey>Heffalump: no, you can pass continuations around (a continuation could be as simple as a single integer)
15:35:03<Heffalump>vixey: oh, I see. Fair enough.
15:35:11<mtag55>a actually use term "a" also like list !! a and like (a + 1)
15:35:14<DRMacIver>jdh30: I really doubt it. You're almost certainly comparing with stack trace exceptions to ocaml exceptions.
15:35:19<mtag55>how must i declare the type of a?
15:35:27<DRMacIver>Without the stack introspection most of the time hotspot turns exception throwing into gotos.
15:35:45<mtag55>can anybody help?
15:36:04<jdh30>Only local exceptions and stack unwinding exceptions from trampolining are anything but local.
15:36:06<vixey>mtag55: I don't understand what you're asking
15:36:10<Heffalump>mtag55: hpaste your code
15:36:14<Heffalump>or at least the error
15:36:22<mtag55>- Type error in application
15:36:22<mtag55>*** Expression : costuri !! a
15:36:22<mtag55>*** Term : a
15:36:22<mtag55>*** Type : Integer
15:36:22<mtag55>*** Does not match : Int
15:36:33<vixey>ohh
15:36:42<Heffalump>for next time, hpaste = http://hpaste.org, not do it on channel
15:36:50<mtag55>ok
15:36:51<vixey>:t fromIntegral :: Integer -> Int
15:36:52<lambdabot>Integer -> Int
15:36:57<vixey>so one thing you could do is write
15:37:04<Heffalump>mtag55: where did a come from?
15:37:04<vixey>costuri !! (fromIntegral a)
15:37:12<vixey>but I think it might be better to redefine !!
15:37:22<mtag55>how?
15:37:26<Heffalump>I think it would be better to figure out why a needs to be an Integer and stop it being one, if possible!
15:37:40<Heffalump>if it really needs to be one, then using it for !! would have some issues...
15:37:46<vixey>(x:_)!!0=x;(_:xs)!!(n+1)=xs!!n
15:38:00<EvilTerran>?hoogle [a] -> Integer -> a
15:38:01<lambdabot>No matches, try a more general search
15:38:15<vixey>:t let (x:_)!!0=x;(_:xs)!!(n+1)=xs!!n in (!!)
15:38:15<Heffalump>@type Data.List.genericIndex
15:38:17<Deewiant>vixey: how about (!!) = genericIndex
15:38:17<lambdabot>forall t t1. (Integral t1) => [t] -> t1 -> t
15:38:18<lambdabot>forall b a. (Integral a) => [b] -> a -> b
15:38:18<EvilTerran>Data.List.genericIndex :: Integral a => [b] -> a -> b
15:38:30<EvilTerran>that's the one i was thinking of
15:40:03<DRMacIver>jdh30: As far as I know, it's pretty good about non local exceptions too
15:40:24<jdh30>DRMacIver: this is the kind of source I got this from: http://debasishg.blogspot.com/2006/03/non-java-languages-on-jvm.html
15:40:26<lambdabot>Title: Ruminations of a Programmer: Non Java Languages on the JVM, http://tinyurl.com/65am4l
15:40:49<vixey>yeah maybe #haskell-blah
15:40:53<jdh30>they list three ways to implement tail calls. "Use of trampolines limit indefinite stack growth, but at the expense of performance, since all calls made by the trampoline are statically unknown method dispatches."
15:40:55<DRMacIver>Also, hotspot is basically a great big inlining machine, so nonlocal exceptions will often become local.
15:41:11<[Justice]>is the speed of throwing exceptions important? would fast exceptions mean that it's acceptable to use them to control program flow?
15:41:34<Heffalump>[Justice]: yes. See O'Caml for an example
15:41:43<sclv>@tell ndm If you're interested in the cgi testsuite I've been working on, here's its repo: http://code.haskell.org/~sclv/cgicheck/
15:41:43<lambdabot>Consider it noted.
15:41:44<DRMacIver>[Justice]: In this case this is an implementation detail. It's often nice to be able to use them for compiler generated control flow.
15:42:03<jdh30>If you're throwing and catching an exception every time you make a tail call then you're looking at up to 30x performance degradation on current JVMs. So it is serious, yes.
15:42:07<Heffalump>and of course all the various kinds of Haskell exceptions, at least some of them are definitely fast, and they may well all be.
15:43:01<jdh30>Justice: Yes. OCaml uses exceptions extensively for ordinary control flow. Incidentally, this is probably the single biggest problem when porting OCaml code to F# where exceptions are 600x slower. You have to convert all of that exception-based control flow into explicit constructs.
15:43:19<jdh30>How are exceptions handled by GHC?
15:43:21<[Justice]>hmm
15:43:33<vixey>jdh30: "30x"?
15:43:45<vixey>jdh30: what are you measuring against are you just making up numbers
15:44:18<Heffalump>jdh30: depends on the kind of exception. I was thinking of explicit ones like Either.
15:44:34<jdh30>Exceptions can be that much slower on the JVM compared to OCaml. I'm assuming function calls are the same.
15:44:38<[Justice]>Either is an exception?
15:44:54<Heffalump>[Justice]: yes, Left for the exceptional values and Right for real values.
15:44:56<jdh30>Isn't either equivalent to returning a variant?
15:45:08<jdh30>So the performance is different between left and right?
15:45:15<Heffalump>variants have more options than either
15:45:19<[Justice]>that's not language/platform exceptions
15:45:22<DRMacIver>I don't have absolute numbers compared to normal returns, but if you take a look at Odersky's paper comparing two approaches to tail call optimisations, the one using exceptions isn't actually that much slower and is occasionally faster.
15:45:41<Heffalump>[Justice]: sure, but monads make them look quite like it
15:45:54<Heffalump>a lot of stuff in Haskell is in the libraries when it would be in the language in other languages
15:46:02<[Justice]>seems like everything's a monad in H
15:46:17<DRMacIver>Everything is a monad in most languages. Haskell just makes it explicit. :)
15:46:25<DRMacIver>(And lets you benefit from it)
15:46:41<jdh30>Odersky says 20x slower in sec 3.1 http://citeseer.ist.psu.edu/cache/papers/cs/22759/http:zSzzSzlampwww.epfl.chzSzpaperszSzbabel01.pdf/schinz01tail.pdf
15:46:42<lambdabot>http://tinyurl.com/5eqnze
15:47:56<DRMacIver>Specifically Odersky says "Here's this technique which we didn't use because it was 25 times slower than the standard version"
15:48:17<jdh30>Yes.
15:48:43<DRMacIver>In particular that version doesn't use exceptions at all...
15:49:14<vixey>I am not sure if this is a #java invasion :p
15:49:29<jdh30>Would you be interested in a Haskell for the JVM. :-)
15:49:35<Heffalump>it's a language implementation discussion
15:49:39<mrd>java is just trying to cash in on haskell popularity
15:49:43<DRMacIver>Well, it's a #language-implementations invasion which happens to be targeted at the JVM.
15:49:45<jdh30>lol
15:49:50<vixey>jdh30: that's why I read through lambdavm
15:49:51<DRMacIver>jdh30: lambdavm has been around for a while.
15:49:55<vixey>jdh30: didn't learn much
15:49:57<Heffalump>mrd: hmm. I think java is still a few orders of magnitude more popular than haskell :-)
15:49:59<DRMacIver>I don't think anyone uses it. :)
15:50:04<mrd>pfft
15:50:09<DRMacIver>Heffalump: Or at least a few orders of magnitude more *used* than Haskell. :)
15:50:16<DRMacIver>Not neccessarily the same thing.
15:50:19<jdh30>:-)
15:50:42<Heffalump>yes, Haskell is very popular with most people who use it.
15:50:44<[Justice]>someday soon, java will get rid of inner classes and support closures and tail calls
15:50:45<DRMacIver>jdh30: The relevant point here is that they compare two versions. One uses ordinary returns and one uses exceptions. The two are not noticably different in performance.
15:50:47<Heffalump>I guess that could make up for it :-)
15:50:57<DRMacIver>[Justice]: I *like* inner classes.
15:51:05<vixey>or you could just program in Scheme
15:51:11<Heffalump>inner classes give you closures, right?
15:51:14<DRMacIver>The fact that they're a shitty substitute for first class functions doesn't mean they're a bad feature.
15:51:22<vixey>it's a lot easier to write Scheme in Scheme than Scheme in Java
15:51:25<jdh30>No. He failed to observe a difference but measuring the wrong thing. Look at his benchmarks: tail calls weren't even relevant for the first three!
15:51:29<geezusfreeek>java? dangit i want some coffee
15:51:56<jdh30>Do inner classes automate closing of the environment?
15:52:06<[Justice]>sort of, yes
15:52:20<vixey>jdh30: yes that's why they are innerclasses
15:52:27<vixey>(rather than just normal classes)
15:52:40<vixey>(but this is kind of offtopic)
15:52:55<[Justice]>bringing it back on topic, i hear H is getting inner classes
15:52:59<jdh30>If you want to stress test Odersky's implementation you need to run a program that performs alternative tail and non-tail calls. He didn't do that so his results don't show the worse-case behaviour.
15:53:10<vixey>[Justice]: "H" is what?
15:53:16<[Justice]>Haskell
15:53:42<DRMacIver>jdh30: It's not really relevant. The approach shrinks the stack at a fixed depth regardless of how you reach that depth.
15:53:43<geezusfreeek>...
15:53:51<Heffalump>[Justice]: if you mean associated types, then sort of.
15:54:11<jdh30>But he optimized repeated tail-only calls and then benchmarked only that, AFAICT.
15:54:15<geezusfreeek>i don't think that's the same at all
15:54:31<DRMacIver>It's basically the usual continuation based approach of "make everything a tail call then shrink the stack at a fixed depth"
15:54:51<DRMacIver>I think. It's been a while since I've actually read this paper.
15:55:07<augustss_>DRMacIver: is this for Scala?
15:55:21<DRMacIver>augustss_: No, Scala's tail call optimisation is kinda feeble. This is for his previous work.
15:55:32<augustss_>oh, ok
15:55:37<Heffalump>geezusfreeek: it gives you the possibility to make "inner type classes" via a bit of a hack (with wrapping up contexts)
15:55:50<jdh30>That also begs the question: why did he give up on tail calls if they worked so well?
15:56:00<jdh30>hi lennart
15:56:04<augustss_>hi
15:56:14<DRMacIver>jdh30: They didn't work so well. I'm just using this to demonstrate the reletive performance of exceptions and returns.
15:56:16<geezusfreeek>Heffalump: hmm. i didn't realize that.
15:56:47<jdh30>But you can measure the relative performance really easily?
15:56:58<sclv>whoa (vis a vis inner type classes)
15:57:20<DRMacIver>Measuring performance on the JVM is never easy. :)
15:57:23<augustss_>hmmm, what does inner type classes even mean?
15:57:27<[Justice]>finally, scared someone! no inner classes in haskell, sorry
15:57:32<sclv>I feel like when ATs start to get real use I'll have to learn haskell all over again.
15:57:54<geezusfreeek>[Justice]: if you mean me then you are mistaken :P i didn't believe you for a second
15:58:01<jdh30>There is another problem. The exception optimizations you referred to only work well when the exception does not carry any associated data.
15:58:02<Heffalump>augustss_: well, I was arbitrarily taking it to mean the same thing as what "associated type classes" would mean if they existed.
15:58:21<jdh30>Maybe you can work around that by using a global mutable though...
15:58:28<DRMacIver>jdh30: No, it works pretty well even with the associated data.
15:58:42<jdh30>Only if the data is static.
15:58:45<DRMacIver>No
15:58:49<jdh30>Which it isn't here.
15:58:55<Heffalump>push the data and jump to the handler, surely?
15:58:58<DRMacIver>It's perfectly legit to allocate a new exception with the data each time.
15:59:03<jdh30>It certainly didn't work when I tested it.
15:59:13<Heffalump>or rather, put the data on the stack after unwinding the stack back to the handler
15:59:29<DRMacIver>You almost certainly weren't suppressing stack trace generation then.
15:59:33<Heffalump>(where unwind = modify the stack pointer by the relevant number)
16:00:05<DRMacIver>http://blogs.sun.com/jrose/entry/longjumps_considered_inexpensive
16:00:12<jdh30>Conflicts with verification and the concurrent GC make the implementation complicated IIRC. I'm sure I can dig out the code.
16:00:19<jdh30>Yes, that was the exact article I was working from.
16:00:39<Heffalump>why would an implementation trick conflict with verification? You verify first, then run.
16:00:47<jdh30>There is a workaround where you statically allocate an exception with dummy data and use cloning instead...
16:02:02<Heffalump>I thought DRMacIver was saying that there is a way to turn off stack trace generation, which would negate the whole thing about it being expensive?
16:02:11<DRMacIver>There is. It's mentioned in the comments there.
16:02:21<DRMacIver>Here's a larger article about it: http://www.javaspecialists.co.za/archive/Issue129.html
16:02:23<lambdabot>Title: [JavaSpecialists 129] - Fast Exceptions in RIFE
16:02:51<Heffalump>is fillInStackTrace part of the standard? That's quite nice, if so.
16:02:56<DRMacIver>In particular note the comparison between throwing a new exception and throwing a preallocated one.
16:02:59<DRMacIver>Heffalump: Yes
16:03:04<DRMacIver>It's just a native method on Throwable
16:03:32<Heffalump>does the JIT actually notice that you overrode it and do any extra clever stuff? (beyond the gain of not having to actually run it)
16:03:34<DRMacIver>And thus is specified along with the rest of the standard library
16:03:40<DRMacIver>Not that I know of
16:03:50<DRMacIver>But the gain of not having to actually run it is kinda huge
16:03:51<Heffalump>I guess there could always be an unchecked exception.
16:04:17<jdh30>Why? I never understood that. Why are exceptions so much slower on the JVM and .NET?
16:04:21<DRMacIver>Because it basically has to perform some really nastily slow stack inspection in the standard implementation.
16:04:34<sclv>that trick is quite nice.
16:05:01<jdh30>Why do other language implementations like OCaml not have to do that?
16:05:12<Heffalump>they don't offer stack introspection
16:05:19<DRMacIver>Well, OCaml doesn't do stack traces in the same way.
16:05:28<Heffalump>the JVM and .NET offer it both for stack traces and for security policies (I think)
16:05:57<DRMacIver>On top of that, I think a large part of it is because the JVM and .NET use a very C-like stack and lose some optimisation potential as a result
16:06:10<jdh30>OCaml has stack traces but no security.
16:06:11<jdh30>interesting
16:06:19<sclv>@go stackless python
16:06:20<[Justice]>stack introspection is very nice when your code is wrong ... so you get slower exceptions in development and test, but then you don't throw any exceptions in the first place (hopefully) when your code is out in the wild
16:06:21<lambdabot>http://www.stackless.com/
16:06:21<lambdabot>Title: Stackless.com - About Stackless
16:06:22<vixey>"no security"?
16:06:28<vixey>I guess type safety doesn't mean anything?
16:06:53<Heffalump>jdh30: under what circumstances does it provide stack traces?
16:06:54<jdh30>Not in this context, no.
16:06:58<sclv>vixey: the JVM has a very fancy security policy for running untrusted code with various levels of sandboxing.
16:07:05<DRMacIver>In particular if you have a continuations based implementation (I don't know if either Haskell or OCaml do) then you can treat exception throwing as basically just another type of return.
16:07:15<Heffalump>in principle that kind of thing can be expressed in types, but in practice it isn't
16:07:41<mar77a>> 7 * 5
16:07:43<lambdabot> 35
16:08:32<DRMacIver>(I seem to recall that stack frames are heap allocated in OCaml, which probably helps in a similar way)
16:08:54<nolrai_>>zipWith take [1..] [x..] :: http://en.wikipedia.org/wiki/Special:Search?go=Go&search=Expr
16:09:08<vixey>nolrai_: lol
16:09:30<nolrai_>bwuag!?
16:09:47<nolrai_>> zipWith take [1..] [x..] :: [ [Expr] ]
16:09:47<lambdabot> Couldn't match expected type `[Expr]' against inferred type `Expr'
16:10:02<[Justice]>> take 5 $ zipWith take [1..] [1..]
16:10:03<lambdabot> add an instance declaration for (Enum [a], Num [a])
16:10:04<vixey>> [x..] :: [Expr]
16:10:05<lambdabot> [Exception: not a number
16:10:16<jdh30>Incidentally, I'd like to make some parallel benchmarks for OCaml, Haskell and F#. Anyone interested in helping?
16:10:30<jdh30>Does Haskell have a parallel tree-based set implementation?
16:10:42<nolrai_>> zipWith take [1..] ['a' ..]
16:10:43<lambdabot> Couldn't match expected type `[a]' against inferred type `Char'
16:11:00<Heffalump>jdh30: what do you mean by parallel in that context?
16:11:08<vixey>> iterate (drop 1) ['a'..]
16:11:09<lambdabot> ["abcdefghijklmnopqrstuvwxyz{|}~\DEL\128\129\130\131\132\133\134\135\136\137...
16:11:12<BONUS>> zipWith take [1..] [['a'..]]
16:11:13<lambdabot> ["a"]
16:11:21<jdh30>As in benefitting from multicore (but not embarassingly parallel).
16:11:34<Heffalump>wouldn't a tree-based implementation be parallel by default, in the sense of supporting access from multiple threads at once?
16:11:35<nolrai_>vixey: thats it.
16:11:38<vixey>> map (take 3) . iterate (drop 1) $ ['a'..]
16:11:39<lambdabot> ["abc","bcd","cde","def","efg","fgh","ghi","hij","ijk","jkl","klm","lmn","mn...
16:12:06<jdh30>I'm looking for a set union implementation that automatically distributes itself over multiple cores.
16:12:17<Heffalump>oh, right
16:12:21<Twinside>jdh30 > I remember some benchmark done to compare OCaml and F# in a french developer's forum, they got many issue because OCaml's Garbage COllector is not thread safe
16:12:22<Heffalump>no, then
16:12:33<[Justice]>> do { x <- Left 10 ; return "ABC" }
16:12:34<lambdabot> Add a type signature
16:12:44<jdh30>Yes. OCaml will definitely lose until it gets its parallel GC this summer...
16:12:49<jdh30>really?
16:13:05<[Justice]>> do { x <- Nothing ; return "ABC" }
16:13:06<lambdabot> Nothing
16:13:10<Twinside>i'm searching the link
16:13:16<jdh30>i thought the Haskell stdlib would be automagically parallelized...
16:13:16<BONUS>> map (take 3) . tails $ ['a'..]
16:13:18<lambdabot> ["abc","bcd","cde","def","efg","fgh","ghi","hij","ijk","jkl","klm","lmn","mn...
16:13:26<Heffalump>jdh30: why did you think that?
16:13:50<malebria>Good afternoon.
16:13:51<Heffalump>> do { x <- Left "boo!" ; return "ABC" }
16:13:53<lambdabot> Left "boo!"
16:13:56<vixey>hi
16:13:58<jdh30>I assumed Haskellers would be very keen to leverage their shiny new multicores.
16:14:04<DRMacIver>Because the web is full of lies and deceit about "Purely functional means you can automagically parallelise!!"
16:14:06<sclv>jdh: nothing in the haskell stdlibs is auto-parallelized.
16:14:13<Heffalump>yes, but automagic paralellization is hard..
16:14:17<DRMacIver>Usually from people who don't know what they're talking about.
16:14:21<malebria>> (\x -> y where y = x * 2) 2
16:14:21<lambdabot> Parse error at "where" (column 10)
16:14:24<jdh30>Really? Oh bloody hell that sucks.
16:14:32<malebria>Is it not possible to use where inside of lambda notation?
16:14:36<malebria>Or am I missing something?
16:14:38<Heffalump>jdh30: you didn't know that automagic parallelization is hard???
16:14:40<BONUS>use let
16:14:47<vixey>malebria: You can't use where at all with lambdabot
16:14:51<Heffalump>malebria: where applies to declarations, not expressions
16:14:55<[Justice]>> (\ x -> y where { y = x * 2 }) 2
16:14:55<lambdabot> Parse error at "where" (column 11)
16:14:56<jdh30>I know automagic parallelization is easy in F#. :-)
16:15:00<Heffalump>the thing immediately inside a lambda is an expression
16:15:02<sclv>writing a set union in parallel that is across-the-board more performance seems tricky.
16:15:06<DRMacIver>As I recall there's been research that basically shows that there's very little room for automatic parallelisation even in purely functional code.
16:15:12<Heffalump>jdh30: it is? how?
16:15:14<BONUS>> (\x -> let y = x * 2 in y) 2
16:15:15<lambdabot> 4
16:15:17<sclv>s/performance/performant/
16:15:24<jdh30>The next versions of both of our F# libraries are parallel and it was quite easy (with MS's TPL CTP) and I'd assumed the same would be true of Haskell.
16:15:32<malebria>Heffalump: hum, I think I got the point.
16:15:35<sclv>writing a unions function across n sets that parallelizes is easy, though...
16:15:40<Heffalump>jdh30: in what way is that automagic?
16:16:06<Heffalump>is the code online somewhere? I'd like to understand what precise kind of parallelization you mean.
16:16:08<sclv>(we could, e.g., turn our mergesort parallel too, but the question is how often it would actually be a win)
16:16:12<jdh30>sclv: that is actually what I want: map reduce over sets where the reduce operation is set union.
16:16:34<jdh30>you mean the source code to our products? No, that isn't on-line. :-)
16:16:39<sclv>oh -- not over just two sets, but over a whole bunch. yeah. that's a one liner.
16:16:42<pejo>DRMacIver, Satnam Singh and some other people had a paper at ICFP (2007?) that showed very little gain in practice, but in theory a bunch of sequential stuff from nofib could be quite parallel.
16:16:50<sclv>its just not the default.
16:16:53<jdh30>Not quite a one-liner, but it is easy enough.
16:17:03<sclv>jdh30: in haskell it is a one liner.
16:17:09<jdh30>:-)
16:17:12<sclv>?hoogle parMap
16:17:12<lambdabot>Control.Parallel.Strategies.parMap :: Strategy b -> (a -> b) -> [a] -> [b]
16:17:44<DRMacIver>pejo: Ah. That's probably what I'm thinking of.
16:17:50<Heffalump>none of this is automagic, that's the key point. Automagic parallelization doesn't work because compilers don't know what's expensive.
16:17:56<jdh30>The basic idea is to convey a cost function that gives the approximate number of operations (or time) required for a sub computation. Then you use that to control whether or not divide and conquor algorithms spawn subtasks in parallel or resort to single threaded code.
16:17:59<Heffalump>And F# doesn't have it any more than Haskell does.
16:18:26<jdh30>Sure. You have to write it yourself but that covers a lot of practically-important applications.
16:18:29<Heffalump>jdh30: right, that's the kind of thing data parallel Haskell does (or will do when it works properly)
16:18:32<Codex_>can we just make compilers know what's expensive? :)
16:18:46<Baughn>Codex_: Not if we don't know it ourselves
16:18:53<jdh30>Codex_: Intel's Fortran compiler is actually already quite clever in that respect.
16:18:55<Heffalump>putting cost into the type system might be neat
16:18:57<Baughn>Though some runtime optimization would be nice
16:19:06<pejo>Codex, that's very hard, as Heffalump just said.
16:19:13<Baughn>Heffalump: How? The cost usually depends on the /size/ of the input data
16:19:15<EvilTerran>Baughn, :O that's crazy talk!
16:19:20<Heffalump>Baughn: polymorphism
16:19:37<Heffalump>if the input data is size x, the output is size 2x and takes 3x time to produce.
16:19:40<Heffalump>That kind of thing.
16:19:49<jdh30>Yes. The compiler injects run-time dispatches (when it knows they are cheap) that dispatch to parallel code for large input (= long arrays in Fortran).
16:19:56<sclv>haha and track the input size with type-level nats!
16:19:59<Heffalump>I'm just speculating wildly, I'm sure it's really hard in practice too.
16:20:30<jdh30>It detects O(x^n) complexity for simple nested functions (e.g. rectangular or triangular) and acts accordingly.
16:20:34<Heffalump>jdh30: for user-written functions, or just specific library functions?
16:20:45<jdh30>Library specific functions only.
16:20:57<jdh30>assuming you're talking about what we were talking about. :-)
16:21:00<Heffalump>ah, that's not very interesting (although still quite useful in practice, no doubt)
16:21:05<mtag55>i have a list defined like list = [1,2,3,etc] and i want to change an element like list !! 2 = 124
16:21:06<jdh30>Absolutely.
16:21:10<mtag55>how can i do that?
16:21:14<mar77a>:t elems
16:21:16<lambdabot>forall i e. (Ix i) => Array i e -> [e]
16:21:37<jdh30>So what 3rd party Haskell libraries have been parallelized?
16:21:43<Heffalump>it's kind of the moral equivalent of having the compiler implement strcpy/memcpy.
16:21:46<EvilTerran>mtag55, there isn't a builtin for it
16:22:25<jdh30>If the compiler does it, yes. I was originally talking about the moral equivalent of calling memcpy yourself. ;-)
16:22:25<EvilTerran>mtag55, however, i think you should be able to implement it without resorting to explicit recursion
16:22:26<Baughn>mtag55: You'll need to copy the list up to the element you want to change, and then you can share the rest
16:22:57<Heffalump>compilers often recognise memory copy loops and change it to the library call.
16:22:58<Baughn>mtag55: If that's a common operation, may I suggest you use IntMap instead? Or maybe starray, or map, or... yeah, lots of options.
16:23:02<jdh30>DRMacIver: what gave you the impression that ocaml heap allocated stack frames?
16:23:15<jdh30>Yes.
16:23:17<mtag55>ok
16:23:18<mtag55>tnx
16:23:38<EvilTerran>mtag55, Baughn has a good point. O(ix) to change the ix'th element of a list
16:23:40<jdh30>A lot of compilers claim to do such things but suck at them. SGI's Fortran compiler for one...
16:24:12<DRMacIver>jdh30: Good question. I believe it's a commonly used approach in SML compilers and assumed OCaml did similarly. I vaguely recall I might have had some more specific reason but could be totally wrong.
16:24:23<Heffalump>ARM's C++ compiler does automatic vectorization
16:24:44<Botje>@src maybeToList
16:24:45<lambdabot>maybeToList Nothing = []
16:24:45<lambdabot>maybeToList (Just x) = [x]
16:24:50<jdh30>Heffalump: is that just what the salesman said or do you know that it works?
16:24:51<Botje>@src listToMaybe
16:24:51<lambdabot>listToMaybe [] = Nothing
16:24:52<lambdabot>listToMaybe (a:_) = Just a
16:24:55<Botje>okay :)
16:25:03<Baughn>mtag55: If you change elements of a list often, you're doing something wrong.
16:25:08<Heffalump>jdh30: I know that it works.
16:25:15<jdh30>Ah, very interesting.
16:25:22<Heffalump>I think you still have to pay extra for it, though.
16:25:24<EvilTerran>mtag55, another possibility would be to replace your [a] with a [STRef a], thus rendering the cells mutable
16:25:29<Baughn>mtag55: (Unless they're always close to the head, in which case the cost is O(1)
16:25:41<jdh30>Yes. ARM are very good at business as well as technology. :-)
16:25:53<EvilTerran>mtag55, but that'd only be the best option very occasionally
16:26:01<jdh30>Ok. Here is another crazy idea.
16:26:02<Baughn>mtag55: Evilterran has a point, too, though STArray would have less overhead - but we really don't know enough about your program to say
16:26:09<Heffalump>actually I think they're very good at milking an early success for all its worth
16:26:20<jdh30>That's the same thing. ;-)
16:26:29<mtag55>i don't know what STArray is
16:26:30<EvilTerran>indeed. i was just about to mention Data.Array.ST.STArray
16:26:52<Heffalump>it doesn't imply that they continue to build good technology consistently (though they do in some cases, certainly)
16:26:54<mtag55>i want to find the minimum within a matrix and change it
16:27:04<DRMacIver>The talk about fortran reminds me of something I've been wondering: How much fun you could have with compiler optimisations using some combination of fortran and Haskell feature sets. e.g. if you had a language with a very restricted set of datatypes (say: numerics, records, arrays) + more semantic restrictions (maybe only allowing tail recursion + some fixed combinators), but it was purely functional, had higher order functions, etc.
16:27:06<jdh30>If GHC had a commerce-friendly intermediate representation like DLLs, could it be used to create a commercial platform where people buy and sell Haskell libraries?
16:27:15<EvilTerran>mtag55, the ST monad is like the IO monad, except with only mutable values (called STRefs) and no other side-effects
16:27:17<Baughn>mtag55: STArray is, basically, a mutable array type. A type trick allows you to embed imperative array-mutating code deep inside functional code
16:27:25<DRMacIver>The GHC array fusion stuff seems to suggest you can do an awful lot for optimising purely functional array code.
16:27:30<Heffalump>jdh30: "like DLLs"? as in DLLs, or something different?
16:27:41<Heffalump>it'll get proper DLL support in 6.10, AIUI.
16:27:42<DRMacIver>And something like clean's uniqueness typing might be a win here too.
16:27:44<EvilTerran>mtag55, which means that it's impossible for side-effects to escape the monadic action where the mutability is contained
16:27:46<jdh30>Managed code DLLs, like our F# products.
16:28:12<Baughn>mtag55: And then there are zippers. Using one of those (google it) allows you to change any data structure repeatedly in the same spot for O(1) cost, but means /moving/ through the structure gets more expensive
16:28:26<Heffalump>http://www.arm.com/products/DevTools/RVCT.html has an example of the kind of vectorization it does, btw
16:28:27<lambdabot>Title: RealView Compilation Tools
16:28:36<jdh30>That's really my single biggest gripe with OCaml: that it is not viable as a commercial platform. I don't believe that will ever be addressed but I spoke to SPJ about this in the context of Haskell and he was interested in the idea.
16:28:48<Heffalump>jdh30: that requires inventing a whole concept of managed code (and therefore a VM), right?
16:29:04<gubagem>why isnt ocaml viable as a commerical product/platform?
16:29:12<vixey>"not viable as a commercial platform" -- not true
16:29:14<jdh30>Heffalump: I have no idea.
16:29:19<Heffalump>some people care about binary libraries.
16:29:21<vixey>gubagem: it is
16:29:26<vixey>gubagem: that's a blatant lie
16:29:31<Heffalump>More so in the commercial world than in the OS world. But not universally.
16:29:41<jdh30>gubagem: you cannot create a market where people can buy and sell OCaml libraries because of the limitations of the language implementation.
16:29:47<gubagem>oh, is haskell viable as a 'commerical platform'
16:29:47<Heffalump>jdh30: I'm just trying to understand what you mean.
16:29:48<EvilTerran>mtag55, hmm?
16:29:56<Baughn>mtag55: For your particular case of a list, a zipper means just keeping /two/ lists - "ahead" and "behind" - and moving elements from one to the other when you move through the list. Obviously you can then alter the element at the "cursor" easily
16:30:00<Heffalump>If you just mean DLLs, then what does the "Managed code" bit mean?
16:30:08<jdh30>gubagem: Haskell is not yet AFAIK.
16:30:19<obk>ACTION has a program that goes into an endless loop, *unless* it is run in the debugger - in which case it works fine. ?????
16:30:28<Heffalump>jdh30: only by your rather restricted definition of "commercial"
16:30:28<jdh30>gubagem: for exactly the same reasons. However, Haskell is not dead from an evolutionary perspective...
16:30:33<DRMacIver>Binary libraries aren't the only way to go. Source licenses are totally acceptable.
16:30:42<Baughn>obk: Fun. Define "endless loop"; also, does it use any concurrency?
16:30:45<Heffalump>DRMacIver: not everyone thinks that.
16:30:56<Heffalump>also, binary distribution is important in some environments
16:31:01<Baughn>obk: (Eg. 100% cpu use loop, 0% use hang, or <<LOOOP>> exception)
16:31:02<gubagem>i am just learning haskell and i havent seen the line savings yet, then again im passing around lists as state
16:31:03<obk>Baughn: Nope. Normal "sequential" code. It just hangs in the middle
16:31:04<Heffalump>even internally to a cmopany
16:31:07<DRMacIver>Indeed. But "not everyone likes that" is not the same as "not commercially viable"
16:31:19<cjb>Heffalump: a company that doesn't trust its employees, I guess?
16:31:19<Heffalump>DRMacIver: yes, indeed.
16:31:20<Baughn>obk: Try compiling it with -threaded and see what happens
16:31:23<mtag55>you gave me headacke :P
16:31:32<obk>100% CPU, yes
16:31:32<mtag55>many new information for a newbie
16:31:33<Baughn>obk: (That turns on extra deadlock detection code, among other things)
16:31:36<Heffalump>cjb: not exactly. A company that can't afford to be compiling on every employee's desktop.
16:31:40<DRMacIver>I'm not saying that having libraries distributable as binaries isn't a good thing. It obviously is. I'm just saying it isn't essential.
16:31:45<obk>ACTION will try
16:31:50<Baughn>obk: Oh. Then it's not a hang, and -threaded won't help. Can try, but..
16:31:56<DRMacIver>And being able to distribute application binaries is distinct from being able to distribute library binaries
16:32:08<cjb>Heffalump: Oh, I see.
16:32:13<Heffalump>yep (but every language supports that, so it doesn't really matter)
16:32:17<Baughn>obk: I think, at this point, you need to paste the code. And preferably point out which line causes the loop. ;)
16:32:26<pejo>cjb, having an *identical* binary saves a great deal of pain when trying to reproduce errors.
16:32:29<DRMacIver>Well, every language other than all the ones which are source interpreted only. :)
16:32:38<Heffalump>cjb: COM was very successful in certain areas precisely because of this.
16:32:54<obk>Baughn: ha ha. If I knew that...
16:32:55<Heffalump>and in some senses .NET is the natural follow-on to COM.
16:32:56<DRMacIver>But my point was that it's not a case of compiling on *everyone's* desktop, just the developers. :)
16:33:11<obk>The program isn't excatly small :-(
16:33:30<jdh30>Heffalump: managed code DLLs have a safe high-level interface.
16:33:33<Heffalump>DRMacIver: if everyone's desktop can in principle have different combinations of versions, then they all need to compile, or you need binary libraries.
16:34:01<obk>-threaded didn't help, as expected
16:34:07<Heffalump>jdh30: safe against what? Malicious code, or just broken code? (In what way is the C calling convention not safe, for the purposes of this discussion?)
16:34:41<gubagem>obk: do you know which part has the infinite loop? if so through in some I/O and see if its still infinite outside of the debugger
16:35:07<Heffalump>for safety against broken code, you just need some metadata + the C calling convention. GHC is getting pretty close to having that AIUI.
16:35:09<jdh30>DRMacIver: we also sell source licences.
16:35:14<DRMacIver>Heffalump: Hm. I don't follow.
16:35:14<Baughn>obk: If it's at 100% cpu you could throw the profiler at it
16:35:21<Heffalump>For safety against malicious code, you need a verification step. Which implies a VM, or PCC.
16:35:26<obk>gubagem: I guess I can do binary search for the offending loop (in fact have started doing so before hittong on the bright idea of using the debugger)
16:35:39<jdh30>Heffalump: I meant safe against broken code (i.e. no segfaults) but the JVM and .NET also try to provide security against malicious code.
16:35:51<obk>The profiler will work even if I kill the program with ^C right? That sounds like a plan...
16:35:53<Heffalump>DRMacIver: if your environment is built up from a big set of libraries, which each have multiple versions
16:35:57<jdh30>Heffalump: I'd be happy with safe against broken code.
16:36:09<jdh30>Heffalump: type safe DLLs.
16:36:10<Heffalump>then either you need binary libraries and binary compatibility, or you need to recompile for each combination of versions
16:36:17<gubagem>obk: isolate , tinker, get it to where it doesnt have the bug, then maybe reimplement the buggy part
16:36:37<Heffalump>jdh30: ok, so that's DLLs + a bit of metadata. As I say I don't think GHC is far off supporting that.
16:36:37<obk>Sure. I'm just stuck at "isolate" at the moment :-)
16:36:49<vixey>you don't need any types to be type safe
16:36:59<vixey>think about a haskell -> scheme translator
16:37:10<Heffalump>However you'll probably also want binary compatibility between code compiled with different GHC versions, and that's probably further off.
16:37:24<gubagem>obk: if you code allows it sprinkle with putStrLn's with little messages, and check and see what your variables really are doing
16:37:27<jdh30>Heffalump: Yes, I think it would be feasible to implement but is it possible to build a commercial market for Haskell libraries?
16:37:30<malebria>When I call forkProcess $ executeFile .... I get a defunct proccess left.
16:37:38<malebria>malebria 8129 0.0 0.0 0 0 pts/2 Z+ 13:27 0:00 \_ [aplay] <defunct>
16:37:43<malebria>I used it with aplay.
16:37:44<Heffalump>jdh30: No idea. You're the expert on selling libraries commercially.
16:38:03<malebria>Is something being made wrong?
16:38:07<Heffalump>I've never either wanted to do that or to buy them (either professionally or personally).
16:38:09<geezusfreeek>i would *guess* that such a market would be very small
16:38:14<obk>gubagem: Code is 99.99% pure, so it is more 'trace' than putStrLn, but yes that's what I've been doing. However, like I said, it isn't exactly small, so... :-(
16:38:18<jdh30>Heffalump: Well, I can tell you that we made £25 in three years of selling OCaml code and a hell of a lot more from F#. :-)
16:38:20<geezusfreeek>unfortunately :(
16:38:38<Heffalump>who do you sell to (in general terms)?
16:38:38<Baughn>obk: As I said, you should be able to get some use from the profiler
16:38:41<jdh30>vixey: yes about type safe.
16:38:49<Baughn>obk: Any infinite loop is going to show up on that. ;)
16:38:58<jdh30>Heffalump: I am happy to sell to anyone with money. :-)
16:39:16<Heffalump>jdh30: no doubt, but where did you get the £25 and the "hell of a lot more" from? :-)
16:39:26<obk>Baughn: Installing the prof libraries as we speak. This will take a few minutes...
16:39:29<jdh30>Heffalump: technical computing is our traditional market because I can do that with my eyes closed and we have a name in it but all ideas are welcome. :-)
16:39:41<gubagem>how do i turn a String into an Integer
16:39:46<obk>Interesting that it avoids the loop in the debugger though. When I figure it out I'll let you know.
16:39:48<[Justice]>:t read
16:39:49<Heffalump>jdh30: right, but what kind of person/institution buys your code?
16:39:49<opqdonut>gubagem: read
16:39:50<lambdabot>forall a. (Read a) => String -> a
16:39:53<vixey>:t read :: String -> Integer
16:39:55<lambdabot>String -> Integer
16:39:55<gubagem>oh yea
16:39:57<Baughn>obk: You don't actually need profiling libraries to profile your own code, although it's mre important in haskell than some other languages
16:39:57<DRMacIver>I've only come across one library I'd be willing to pay for, though I think there are a few more if my needs were specialised. The problem with libraries is that in order to be commercially viable they have to be kinda niche
16:39:57<gubagem>thx
16:40:06<DRMacIver>Niche or really hard to do right
16:40:16<jdh30>Heffalump: Ah, we sold one copy of Presenta (our technical presentation software written entirely in OCaml) but shelved it because it was so unreliable. We've sold lots of copies of F# for Numerics and F# for Visualization already.
16:40:18<Heffalump>nag is a good example of a library with fairly broad appeal
16:40:20<obk>I mean the base profiling libraries - won't link without them
16:40:21<Baughn>obk: And yes, please do. It's undoubtedly some sort of bug; they're supposed to act identically
16:40:30<jdh30>DRMacIver: Yes.
16:40:41<DRMacIver>(the one library is QT incidentally)
16:40:51<DRMacIver>(QT Jambi specifically)
16:40:53<jdh30>Heffalump: Yes. F# for Numerics is the new NAG. ;-)
16:41:08<Heffalump>jdh30: my question is who you sell to (in general terms describing the kind of institution or person, not specific names)
16:41:15<jdh30>DRMacIver: I also considered buying Qt but their demos segfaulted on my machine so I kept my money.
16:41:29<Heffalump>jdh30: is the low-level implementation in native code then?
16:41:42<jdh30>Heffalump: No, the low-level code is currently entirely F#.
16:41:45<SamB>Baughn: what have you been saying?
16:41:51<Heffalump>it'll be a while before it's the new NAG then :-)
16:42:23<DRMacIver>jdh30: One of the demos seg faults on my machine, but most of it works fine and the results are a lot better than any of the other GUI libraries I've looked at.
16:42:31<DRMacIver>(And the Jambi API is surprisingly pleasant)
16:42:32<jdh30>Heffalump: Performance-wise, yes. But it is vastly easier to use thanks to an elegant functional interface.
16:42:33<SamB>Baughn: the profiling RTS is not compatible with the non-profiling RTSs
16:42:54<jdh30>Heffalump: I'm not actually sure how to pigeon hole our software customers.
16:43:02<Heffalump>jdh30: no doubt. But NAG can just steal your market by making a similar interface, surely?
16:43:12<jdh30>Heffalump: I dissected the OCaml for Scientists customers accurately but I think that is quite difficult.
16:43:15<SamB>(in terms of compiled code, I mean)
16:43:43<Heffalump>jdh30: well, understanding the market is probably quite important when trying to work out if you might be able to sell something
16:43:52<jdh30>Heffalump: NAG could steal our interface but they would need to learn how to first and that would basically require them to give us a consultancy contract. :-)
16:43:54<gubagem>what does prelude.read : no parse mean?
16:44:13<gubagem>i believe im feeding read correct input...but it is just barfing out on me :(
16:44:23<jdh30>Heffalump: I believe our F# market is basically completely random. Composed almost entirely of tinkerers who just want something to play with.
16:44:36<Heffalump>jdh30: I didn't actually mean steal your specific interface, I just meant write a functional interface of their own. And they could do either by just hiring a functional programmer, surely?
16:44:40<EvilTerran>gubagem, maybe the return value of read's ending up the wrong type?
16:44:46<[Justice]>> read "10" :: Integer
16:44:47<lambdabot> 10
16:45:00<[Justice]>> read "10"
16:45:01<lambdabot> Exception: Prelude.read: no parse
16:45:02<malebria>Shouldn't forkProcess be used then?
16:45:03<jdh30>Heffalump: If they could find a functional programmer versed in numerical methods, yes. But they don't exactly grow on trees.
16:45:09<Heffalump>jdh30: interesting. In my experience tinkerers don't spend money.
16:45:21<SamB>jdh30: what do they grow on?
16:45:28<Heffalump>quant groups :-)
16:45:32<[Justice]>make sure you specify what the resulting type should be
16:45:33<cjb>Heffalump: the .NET world is likely to be more amenable
16:45:34<jdh30>Heffalump: Right. I think that is really particular to Windows, where users expect to throw money at fun things.
16:45:40<jdh30>ROTFL
16:45:57<cjb>just as in the OS X world, people pay $30 for random pieces of shareware.
16:46:12<jdh30>Yes. We never managed to make any money out of OSX either...
16:46:22<Heffalump>jdh30: do you really think you need a deep understanding of numerical methods to write a good interface?
16:46:23<SamB>it's really unbelievable the stuff you have to pay for (or almost do) in Windows
16:46:44<cjb>SamB: e.g. WinZip
16:46:53<jdh30>Heffalump: Absolutely, yes. Not just a deep understanding of numerical methods (i.e. the functions themselves) but also how they are used.
16:47:31<jdh30>Mathematica is an excellent example of what good functional design can bring to technical computing but, of course, it is based around a grindingly-slow general term rewriter.
16:47:31<Heffalump>Fair enough. Though that requirement wouldn't stop a functional programmer stealing your interface :-)
16:47:35<hpaste> gubagem pasted "my offensive newbie code parse no read :-(" at http://hpaste.org/8019
16:48:21<jdh30>Heffalump: Yes. Conversely, we can steal NAG's performance by licensing the Intel MKL and bundling it into F# for Numerics, just as the Extreme Optimization library for C# does.
16:48:32<Heffalump>and anyway I reckon that a functional programmer and a numerical methods expert working together would be able to do a good job, the knowledge doesn't need to be in one head
16:48:41<jdh30>Do many Haskellers use OSX?
16:48:46<Heffalump>yes, quite a few
16:49:10<Baughn>Enough that it works well on OS X (except opengl in ghci.. ;(
16:49:13<Saizan>gubagem: read for string expexcts it in quotes.
16:49:22<Heffalump>jdh30: matlab has a compiler, I wonder how well that works
16:49:30<Saizan>> read "\"foo\"" :: String
16:49:32<lambdabot> "foo"
16:49:36<cjb>Heffalump: goes to C, I think?
16:49:43<Saizan>> read "foo" :: String
16:49:45<gubagem>Saizan: uhhh how do i pass read just a String value then?
16:49:45<lambdabot> "Exception: Prelude.read: no parse
16:49:54<Heffalump>cjb: no doubt, but that's doesn't tell us much :-)
16:49:57<jdh30>Mathematica also has a compiler but it only compiles to an interpreted bytecode. I believe MATLAB's is much better. They gave me free copies so I should try them... :-)
16:50:07<gubagem>> read "1322"::Integer
16:50:09<lambdabot> 1322
16:50:22<Saizan>gubagem: why use read at all for myName ?
16:50:27<Baughn>> read "42" -- It says "no parse". Curious; I wonder what it's defaulting to
16:50:28<lambdabot> Exception: Prelude.read: no parse
16:50:40<gubagem>cause im lazy and it looks nice :(
16:50:50<cjb>http://hogbaysoftware.com/products/writeroom is my favorite example of how OS X software works :)
16:50:51<lambdabot>Title: Writeroom
16:51:08<cjb>("you want a text editor that can GO FULLSCREEN? that'll be $24.95, please.")
16:51:13<Heffalump>:-)
16:51:33<Saizan>gubagem: (head args) is sufficient, and you don't need a let for each variable
16:51:42<Saizan>Baughn: ()
16:51:48<gubagem>> let myVar="happy happy joy joy" in read myVar::String
16:51:50<Baughn>> read "()"
16:51:50<lambdabot> "Exception: Prelude.read: no parse
16:51:51<lambdabot> ()
16:51:53<jdh30>Wow. That application rocks.
16:52:23<Baughn>> let myVar = show "happy happy zombies" in read myVar :: String
16:52:24<lambdabot> "happy happy zombies"
16:52:44<cjb>hm, maybe I should make a writeroom.el
16:52:45<jdh30>Incidentally, few of our customers ever actually use what they buy. Some of them even buy multiple copies by accident...
16:53:02<SamB>jdh30: huh?
16:53:16<cjb>I don't think "go fullscreen and make the background black and the text green and a blinky block cursor" would be more than five lines of elisp :)
16:53:22<Heffalump>jdh30: that's an interesting business model you have
16:53:26<SamB>how do you know they don't use them?
16:53:36<jdh30>It wasn't deliberate. :-)
16:53:45<Heffalump>no, I didn't imagine it was :-)
16:53:56<SamB>that would be a silly business model
16:53:57<Heffalump>I think I'd be quite worried by it if it was me, though.
16:53:59<jdh30>They have individual logins and our web server says several have never been used.
16:54:04<cjb>jdh30: have you considered the options that bartending has to offer?
16:54:26<DRMacIver>cjb: It certainly guarantees that customers would use his products.
16:54:34<cjb>:)
16:54:37<jdh30>I found it quite worrying too so I tracked down some of the people and they explained that they had paid for something like a journal subscription and forgotten about it.
16:54:48<jdh30>When they were notified it had expired they just bought a new subscription.
16:55:06<Heffalump>so that's not quite buying the same product multiple times, is it?
16:55:23<jdh30>other people have bought multiple copies of one library for themselves as well.
16:55:24<cjb>It's leasing the same product multiple times.
16:55:42<Heffalump>jdh30: perhaps they think they need it to use them in parallel ;-)
16:55:53<jdh30>For the journals, yes. They've also done that for single user binary libraries.
16:56:04<jdh30>ROTFL. Yes, they must have had a dual core... :-)
16:56:15<Heffalump>isn't that the way M$ works these days?
16:56:22<Heffalump>get to enough cores and you have to spend more
16:56:51<Baughn>Heffalump: For values of "enough" that equal variously eight, four and /two/, yes
16:56:59<jdh30>It is really wierd though, and completely different from the OCaml world where people demand huge amounts of work for pennies.
16:57:07<cjb>Heffalump: Oracle, especially.
16:57:09<DRMacIver>Heffalump: It's the way Oracle works. :(
16:57:17<pejo>Heffalump, it's very much the way Oracle works
16:57:22<cjb>heh
16:57:28<pejo>Heh, stereo-quote seems apropriate.
16:57:29<Heffalump>I see this is a widely-felt sore point :-)
16:57:32<DRMacIver>Oracle's pricing model was written up by satan.
16:57:42<jdh30>Yes. I bought Windows XP Pro for £250 for my dual core. I am upgrading to eight cores and realised that I would need a new copy of Windows because my licence only covers 2 cores.
16:57:42<DRMacIver>There's no other explanation for it.
16:57:50<Heffalump>it seems mostly reasonable to me to make the charges proportional to the use
16:58:01<DRMacIver>Heffalump: The story with clustering multiple machines is particularly special
16:58:09<Heffalump>oh?
16:58:11<Baughn>Heffalump: I seem to recall some company once wanted to price proportional to the number of /execution units/ in the CPU
16:58:23<jdh30>I've heard that story before...
16:58:27<DRMacIver>There are two types of license. The standard and the enterprise license.
16:58:31<Heffalump>Baughn: why not just do it in proportion to the number of transistors x the clock rate?
16:58:37<DRMacIver>With the standard license you may cluster up to 4 machines for free.
16:58:41<pejo>Heffalump, they have some fishy stuff like charging for the amount of physical CPUs in the machine, instead of how many you actually use for example.
16:58:42<DRMacIver>You may not cluster more than 4 machines.
16:58:48<jdh30>Or the power dissipation?>
16:58:49<Baughn>Heffalump: Presumably because that's more or less a secret
16:59:04<Heffalump>don't CPU manufacturers generally advertise the number of transistors?
16:59:12<Baughn>Sure. To two significant digits.
16:59:14<DRMacIver>If you want to cluster more than 4 machines you need to buy the enterprise license for them, which costs > twice the prices of the standard license.
16:59:14<Heffalump>anyway, jdh30's idea is probably a good proxy (and easier to find out)
16:59:17<jdh30>It is a bit odd. I hadn't actually thought how we should start to impose such constraints on our own software.
16:59:19<Heffalump>Baughn: that would be enough.
16:59:31<Baughn>Heffalump: Well, probably
16:59:39<Heffalump>jdh30: you're not big enough to make it wortwhile, I suspect. There's a lot of overhead in doing it.
16:59:41<Baughn>Heffalump: Just don't ask me to run oracle on the gpu
16:59:42<DRMacIver>But you no longer get those four machines clustered for free. And you have to pay an additional outrageous amount for every machine you want to cluster.
17:00:06<DRMacIver></outrage>
17:00:08<jdh30>Well, we already have customers beating down our door to release new versions of our libraries as soon as a new F# compiler is out.
17:00:20<Heffalump>well, licence an ARM core and you have to pay an additional amount for every single one you fab :-)
17:00:26<jdh30>Sooner or later, we shall no doubt start charging money for the priviledge (when everything is out of beta release).
17:00:44<jdh30>Is that proportional to the floor space of the fab?
17:00:58<Heffalump>jdh30: I think I'd be pretty annoyed (as a customer) if you charged me to give me a recompiled version of the same source.
17:01:22<Heffalump>but once F# is out of beta that won't really be necessary anyway
17:01:28<jdh30>The journals are quite bad in this context, actually. We have two customers who regularly consume more bandwidth than everyone else combined.
17:01:39<Botje>dammit
17:01:55<jdh30>There will be several incompatible releases over the next 2-3 years.
17:02:00<jdh30>We could charge for each.
17:02:03<Heffalump>jdh30: no, it's per core (with different rates for different cores)
17:02:17<Baughn>Heffalump: I just had a thought. There are people who charge per cpu core, regardless of whether or not they're actually being /used/?
17:02:30<Heffalump>Baughn: apparently Oracle do, from the conversation above
17:02:38<Baughn>Heffalump: I wonder how that's going to work with nanocomputers, where you might conceivably stick a couple million cores in a laptop just in case they come in handy someday
17:02:51<Heffalump>I think the business models might perhaps change by that time :-)
17:02:51<DRMacIver>I suspect they'll change the model by then. :)
17:03:13<jdh30>I wonder what the next model will be...
17:03:14<Baughn>Hey, could be just a decade. ^^;
17:03:26<Baughn>jdh30: Heavily DRM'd, I get the impression
17:04:20<cjb>all this talk of charging people for access to math is making me nauseous :)
17:04:37<cjb>ACTION == Linux-using hippy, or something.
17:04:59<DRMacIver>Charging people for access to maths seems fairly reasonable to me.
17:05:04<Baughn>ACTION == Hardware hippy working on self-plugging extension cords
17:05:11<DRMacIver>Good numerical routines are really hard to do well and efficiently.
17:05:18<jdh30>True.
17:05:40<jdh30>However, most of the numerical libraries on .NET are of extremely low quality. That was one of the reasons we went into that market.
17:05:43<DRMacIver>Although I certainly wouldn't say no to good free numerical libraries.
17:05:58<cjb>DRMacIver: It's just so far away from any reasonable utopia. You want to build something, so you go to the math store and buy some math, but only rich people can afford the best math, and blargh.
17:06:04<u_quark>hello, where can i find some help/documentation on happs ?
17:06:15<jdh30>Linux has better free numerical libraries than .NET has commercial numerical libraries but there is still huge demand for any numerical libraries on .NET.
17:06:26<cjb>u_quark: #happs, usually
17:06:39<jdh30>cjb: what is the alternative?
17:06:44<u_quark>cjb: no luck :P
17:06:45<DRMacIver>Ideally the way this would work would be some open standard for the interface and then you could choose between free or commercial implementations.
17:07:02<DRMacIver>But for most of such the "open standard" is the de facto fortran ones. :)
17:07:10<Heffalump>cjb: someone has to pay to create the math, though, otherwise it won't be created at all.
17:07:11<cjb>jdh30: well, having software that no-one owns, of course. I guess you want to turn my moral nausea into an economic one.
17:07:14<jdh30>Yes.
17:07:39<jdh30>cjb: how do the creators of the software feed their kids?
17:07:46<Heffalump>I think the present world, where open-source and proprietary code compete, works quite well.
17:07:47<obk>It seems profiling only creates an empty .prof file if the process is interrupted. Back to binary search of the code :-(
17:07:53<jdh30>cjb: or are you assuming that programmers do not breed?
17:07:57<Heffalump>obk: do a heap profile, those write out partial results.
17:08:01<cjb>jdh30: by being bartenders? :) I'm regularly unpaid for the software I write.
17:08:08<obk>Thanks
17:08:17<DRMacIver>Heffalump: I agree, but I'd like to see more standardisation across the two so it was more easy to get started and transition later.
17:08:36<Heffalump>DRMacIver: the question is where you draw the balance on allowing lock-in.
17:08:38<cjb>anyway, I think I'd favor a software tax in this case. We don't need 30 competing numerical algorithms libraries, we just need a handful of good ones.
17:08:46<jdh30>cjb: Sure but free software usually really sucks. You get what you pay for. That is even true of FPLs now, IMHO...
17:08:50<Heffalump>lock-in creates more value for commercial vendors at the expense of everyone else
17:08:58<DRMacIver>Indeed. It's hard to get right.
17:09:03<Heffalump>which is good in terms of having them produce stuff, but bad in terms of having that stuff be used efficiently
17:09:43<jdh30>Heffalump: That is not true. We are benefitting enormously from Microsoft's locked-in customers.
17:09:51<Heffalump>I think patent and copyright terms for computing stuff should be reduced massively.
17:09:56<DRMacIver>Heffalump: I don't think lock in is a massive problem in that regards, in that I'm talking about the case of doing well enough on the open source case and then making it easier to migrate to a closed one.
17:10:08<Heffalump>jdh30: in that context, you are the same commercial vendor as Microsoft.
17:10:50<DRMacIver>I agree that reduction of patent and copyright issues for software would be a big win.
17:10:54<jdh30>Heffalump: Then you are talking about lock in to an entire industry, which is silly. Nobody is any more locked in to our libraries than they are to KMail.
17:10:57<Heffalump>DRMacIver: oh, right. I assumed you meant the other way.
17:11:22<Heffalump>jdh30: no, I'm talking about lock-in to an entire subset of the industry, where industry = software development and sub-set = the M$ ecosystem
17:11:31<DRMacIver>Heffalump: No. I'm in favour of commercial software and libraries. What I'm not in favour of is *requiring* their use.
17:11:55<Heffalump>DRMacIver: right, but I thought you wanted to make it easier to migrate from commerical libraries to open-source ones, but it turned out you meant the other way round.
17:12:00<DRMacIver>Which is why an open standard that can be shared between commercial and open source implementations are a good thing.
17:12:01<Heffalump>lock-in is rather more relevant in the former case.
17:12:06<DRMacIver>Absolutely.
17:12:15<Heffalump>in any case, I entirely agree about open standards
17:12:26<jdh30>DRMacIver: That's fair enough but there is an enormous gap between free and commercial software. Look for free alternatives to Mathematica, for example.
17:12:35<DRMacIver>I know that.
17:12:45<DRMacIver>I'm talking about a hypothetical "How I'd like things to be" :)
17:12:52<DRMacIver>Particularly in the case of things like numerical libraries
17:13:57<obk>heffalump: You sure about the partial results? I'm getting an empty .hp file
17:14:28<Heffalump>obk: well, I do it all the time, so I'm pretty sure, yes :-)
17:14:40<obk>+RTS -h<what> ?
17:14:42<Heffalump>-hc
17:14:51<Heffalump>what GHC version are you using?
17:15:04<obk>6.8.2
17:15:10<Heffalump>well, -hc is what I usually use, but I've tried all the options. Not sure if I've interrupted them all, though.
17:15:14<jdh30>DRMacIver: How could commercial software survive without copyright?
17:15:26<Heffalump>I'm mostly using an early 6.9 snapshot. But I could test with 6.8.2 quickly too, one sec.
17:15:29<obk>You kill the program before it exits and you get a non-empty .hp file?
17:15:38<Heffalump>obk: I ^C it
17:15:38<obk>Thanks
17:15:40<Heffalump>not kill -9 it
17:15:44<obk>Me too
17:15:45<Heffalump>or even kill -TERM
17:15:51<Heffalump>obk: what platform are you on?
17:15:58<obk>Ubuntu hardy
17:16:09<Heffalump>jdh30: I don't think DRMacIver is suggesting abolishing copyright for code, just for standards (if anything)
17:16:24<DRMacIver>I'm definitely not in favour of abolishing copyright for code.
17:16:32<DRMacIver>I'm much more so about patents.
17:16:35<Heffalump>actually, I take that back, I can't test easily with 6.8.2. But I'll test with 6.9 on linux.
17:16:51<obk>Heffalump: What platform are you using?
17:17:02<Heffalump>the one I do it on most is Windows
17:17:11<DRMacIver>It's more that I'd like more openness within the commercial implementations and collaboration with open source versions.
17:17:16<Heffalump>but I have some profiling-compiled code lying around I'm about to try on Linux
17:17:40<DRMacIver>An ideal situation would be that companies contributed to open source software and sold their own value added version. (Not quite like what QT do, though that works too)
17:17:55<Igloo>obk: -h doesn't make a .prof file, you need -p for that
17:18:11<jdh30>DRMacIver: Consider our closed-source F# for Numerics product and the open source Math.NET, for example. How would you have us collaborate?
17:18:12<Heffalump>Igloo: obk is talking about the .hp file
17:18:17<obk>Igloo: I'm doing -hc and looking at the .hp file
17:18:34<Heffalump>obk: I just did that with 6.9.20080316 and I have a non-empty .hp file.
17:18:43<Heffalump>./foo_p +RTS -hc -RTS ; wait a bit ; ^C
17:18:45<obk>Maybe it is a new 6.9 feature then
17:18:51<Heffalump>I didn't think it was.
17:18:53<Igloo>Fair enough, I was going by "[18:07] < obk> It seems profiling only creates an empty .prof file if the process is interrupted. Back to binary search of the code :-(" :-)
17:18:56<Heffalump>but Igloo can confirm.
17:18:59<jdh30>DRMacIver: Do you think it is possible to earn money that way?
17:19:05<Heffalump>Igloo: we moved on frmo that, I suggested a heap profile
17:19:09<Heffalump>see [18:13]
17:19:15<Igloo>Ah, OK. It should work in 6.8, anyway
17:19:25<obk>Igloo: yes, that's true, when I was using -p :-)
17:19:43<jdh30>DRMacIver: What happens when another open source developer improves the open source version? You can't copy it into your product so they diverge?
17:20:09<Deewiant>Igloo: this sounds highly platform-dependent unless there are explicit flushes in the code
17:20:09<DRMacIver>jdh30: Ideally the two would be interface compatible, or have a large subset that was (presumably Math.NET is C# oriented, so this isn't practical here). Sharing some subset of the implementation may be good.
17:20:39<obk>ACTION let it run for over a minute, buffered output should have produced _something_ I think...
17:20:41<DRMacIver>jdh30: And if another open source developer improves the open source version, you'd hopefully be able to integrate those improvements.
17:21:13<Heffalump>obk: yes, it should have
17:21:21<DRMacIver>But you would add value in a) Performance (you might even be able to do so more than you would if you developed it on its own) and b) Additional features (this is where the "large subset" becomes an option).
17:21:28<DRMacIver>As to whether it's possible to make money this way, I don't know.
17:21:40<DRMacIver>It might be that it's not. Or at least that it's prohibitively difficult.
17:21:46<DRMacIver>It would be interesting to find out.
17:21:52<obk>Heffalump: Did you say you have a _p at the end of the executable? I don't!
17:21:59<jdh30>Interesting idea.
17:22:16<Heffalump>obk: that's just because I name my profiling executables separately to my non-profiling ones
17:22:17<obk>I have Gch-Options set to -prof -auto-all and the exe does respond well to +RTS -hc, so ...
17:22:20<obk>Ah
17:22:21<obk>Ok
17:22:25<Heffalump>I used -o foo_p when I compiled
17:22:28<obk>ACTION was worried he's running the wrong exe
17:22:40<Heffalump>the exe wouldn't run with the RTS option if it wasn't compiled for it
17:22:46<Heffalump>is your code (or binary) available?
17:23:20<obk>Is ~1600 lines in 7 files
17:23:21<Igloo>obk: Definitely works here with 6.8.2 on amd64/Linux
17:23:26<obk>I can zip it to you if you want
17:23:26<Heffalump>ACTION is sleepy, and hasn't accomplished any of the stuff he meant to today. Grmph.
17:23:34<Heffalump>sure.
17:23:39<obk>Sec
17:23:48<DRMacIver>jdh30: Even if you offered a very large supset of the open source version in the commercial version, it would be good if one could easily migrate from the open source to the commercial one.
17:23:50<Heffalump>preferably mail it to ganesh@earth.li
17:24:08<DRMacIver>jdh30: It may even be that this is *more* profitable, because you can get people hooked on an open source library and then offer them shiny incentives to pay you. :)
17:24:33<jdh30>Yes. That is much closer to the shareware approach to business. I've never tried it.
17:24:51<jdh30>Our next major venture may well be a game...
17:25:06<Heffalump>I'm sure some people would be able to make money this way, and I think it's very likely that it would be fewer people than can make money now.
17:25:07<DRMacIver>It's different from shareware because it creates an open standard which other people are free to improve upon.
17:25:55<DRMacIver>Heffalump: Yes. I suspect that's true.
17:26:18<DRMacIver>Heffalump: But not very many people are making money on libraries anyway are they? At least compared to the application and services markets
17:26:20<gubagem>is there any physical example for a monad? or is it sooo abstract none exists
17:26:31<vixey>@instances Monad
17:26:33<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, []
17:26:38<Heffalump>DRMacIver: I wouldn't have thought so, no. But jdh30 is :-)
17:26:38<vixey>gubagem: there are lots of examples
17:26:49<DRMacIver>Heffalump: And this might well benefit the latter markets more than it does the former.
17:26:49<opqdonut>gubagem: all the physical metaphors (containers etc) tend to be pretty poor
17:26:59<DRMacIver>err
17:27:02<DRMacIver>more than it hurts the former
17:27:03<cjb>gubagem: Schroedinger's Box? :)
17:27:08<Heffalump>DRMacIver: well, only if a decent set of libraries still got produced.
17:27:32<DRMacIver>Indeed.
17:27:34<jdh30>Heffalump: are you Ganesh?
17:27:46<obk>Heffalump: ben-kiki.org/Obk.tgz
17:27:48<DRMacIver>I'd rather have a good set of libraries in the current system than a bad in the one I'm suggesting
17:27:49<Heffalump>well, that's my name, yes.
17:27:55<jdh30>Oh, hi.
17:27:58<Heffalump>as /whois should tell you :-)
17:27:59<jdh30>Hello again. :-)
17:27:59<DRMacIver>Like I say, I don't really know if this would work. But it's a nice theory. :)
17:28:18<Heffalump>hi :-) I assumed you would have already worked out who I am :-)
17:28:22<jdh30>So it does. Wonders never cease...
17:28:34<jdh30>No, I had no idea. I had some strange images from the name though...
17:29:22<jdh30>DRMacIver: the sticking point of your idea is giving away half of my work (that already earns me money) for free.
17:29:49<Lycurgus>sticky sticky
17:29:54<Heffalump>jdh30: well, it's a sticking point for you, but DRMacIver's thesis is that it would make the world a better place overall.
17:29:57<jdh30>Also, you cannot grow such a thing because a commercial product must reach a certain size before anyone will buy it.
17:30:38<jdh30>Heffalump: Sure, but impractical routes to utopia aren't very useful.
17:30:40<DRMacIver>jdh30: It doesn't actually need that though. For example, my idea is compatible with you not publishing a single line of code but instead providing a publicly specified API and selling an implementation of that.
17:30:52<Lycurgus>ACTION sees a future for jdh30 in ...
17:30:55<Heffalump>jdh30: we don't know if it's impractical or not, though
17:30:58<jdh30>Ah, ok. That is what we already do though.
17:31:12<Heffalump>obk: your program terminates quite fast when I run it
17:31:17<jdh30>Well, if it is what we already do then it is clearly practicable. :-)
17:31:19<obk>Sigh
17:31:22<obk>As it should
17:31:26<Heffalump>ghc -prof -auto-all --make -o obk Main.hs
17:31:28<Lycurgus>management (if you're not there already).
17:31:28<Heffalump>is how I compiled it
17:31:41<obk>Maybe I should upgrade to 6.9
17:31:43<Heffalump>jdh30: that doesn't prove that the alternative is impractical.
17:31:49<Heffalump>obk: no, this is with 6.8.2
17:31:56<jdh30>I'd like to try Frag again but I get "Could not find module `Graphics.UI.GLUT'". Can I install it with apt?
17:32:02<obk><grrr> Must be some strange environment issue
17:32:07<jdh30>Heffalump: yes.
17:32:10<DRMacIver>jdh30: Well, sortof. I suspect it's more of a "here's our API, feel free to have a browse". I'm suggesting it should be unencumbered and vaguely standardised.
17:32:19<Baughn>jdh30: Yes. Something like libghc6-foo-bar-glut-dev
17:32:34<Heffalump>DRMacIver: but the conversation above implied that his API in F# for numerics is valuable in itself.
17:33:02<DRMacIver>Indeed. And I'll grant that that's a potential problem. :)
17:33:20<jdh30>I already have libghc6-glut-dev
17:33:20<Heffalump>obk: also, by interrupting it quickly with +RTS -hc -RTS, I still managed to get a partial .hp file.
17:33:24<obk>Hey!
17:33:31<obk>If I compile it like you do it works!
17:33:41<Heffalump>how were you compiling it?
17:33:42<Igloo>How were you compiling it?
17:33:47<obk>But if I compile it as part of a package (see the README for the flags) it does not!
17:33:50<obk>Aha!
17:33:56<obk>Must be some combination of the extensions
17:34:02<obk>I'll do a quick binary search on them
17:34:09<Igloo>Are you compiling the package with -prof?
17:34:22<Igloo>And -auto-all?
17:34:25<obk>Just that program but it does not link with the rest of the package
17:34:37<jdh30>So how do I compile frag?
17:34:45<Igloo>I didn't follow that
17:35:51<jdh30>Oh no, wait. I have to use "ghc-6.8.2" instead of just "ghc". Hmm, lots of warnings...
17:36:17<Baughn>jdh30: Hm, how many ghcs do you have installed?
17:36:28<Baughn>jdh30: It might be more convenient to use cabal (the binary) to install it
17:37:11<jdh30>5 different names for 3 versions. I don't need any though, so I can just remove them.
17:37:33<obk>Ok, now *this* is strange. If I compile it through runhaskell Setup.hs, it goes into the loop; if I compile it with --make, it works fine.
17:37:47<obk>How to I see _exactly_ how the cabal is compiling it?
17:37:50<Heffalump>-v
17:38:03<obk>ACTION always felt Cabal not using make is a mistake :-)
17:38:21<mauke>I have make use cabal
17:38:23<Heffalump>I tend to agree
17:38:27<Baughn>obk: make isn't flexible enough. Now, not building them into each other mmight be a mistake
17:38:30<mauke>EGRAMMAR
17:38:34<Heffalump>though it's tricky because make isn't cross-platform
17:38:52<Baughn>Hang on. make, or --make?
17:39:02<Deewiant>--make.
17:39:03<Heffalump>make.
17:39:19<Deewiant>it started with --make. :-)
17:39:26<Heffalump>it seems there are cross-purposes going on here :-)
17:39:28<dmwit>runhaskell doesn't compile it.
17:39:28<obk>Baughn: there's gnu make, and jam, cake, bake, rake, cook, to name a few off the top of my head. We could easily write hake if we wanted to (like rake).
17:39:29<Baughn>Ow my head -_-
17:39:40<Heffalump>dmwit: runhaskell Setup.lhs build does
17:39:48<dmwit>Okay, yes.
17:39:52<Baughn>obk: The cake is a lie. Might as well use fake
17:39:57<Heffalump>I want cake now.
17:40:02<obk>Anyway. I got the list of commands cabal is using. I'll do a binary search to find out what is the offending flag(s)
17:40:20<alexander>insane how this nick wasn't taken :)
17:40:32<obk>alexander: They die young :-)
17:41:13<HairyDude>@hoogle Monoid a => Bool -> a -> a
17:41:14<lambdabot>GHC.Exts.breakpointCond :: Bool -> a -> a
17:41:14<lambdabot>Control.Exception.assert :: Bool -> a -> a
17:41:52<dmwit>:t let ensure p x = guard p >> return (p x) in ensure
17:42:04<Deewiant>@bot
17:42:05<lambdabot>:)
17:42:06<dmwit>*poke*
17:42:07<lambdabot>thread killed
17:42:11<dmwit>:t let ensure p x = guard p >> return (p x) in ensure
17:42:12<Deewiant>@ty let ensure p x = guard p >> return (p x) in ensure
17:42:16<mauke>dmwit: looks like a type error
17:42:19<HairyDude>:t ensure b x = if b then x else mempty
17:42:27<lambdabot>thread killed
17:42:27<lambdabot>thread killed
17:42:31<Deewiant>> 1+1
17:42:31<HairyDude>dmwit: that unnecessarily depends on Monad
17:42:34<pastorn>@type guard
17:42:34<lambdabot>thread killed
17:42:38<pastorn>@type guard
17:42:40<HairyDude>oh dear, lambda bot is feeling ill again :(
17:42:43<dmwit>mauke: YOu're right.
17:42:46<lambdabot> thread killed
17:42:49<lambdabot>forall (m :: * -> *). (MonadPlus m) => Bool -> m ()
17:42:51<lambdabot>forall (m :: * -> *). (MonadPlus m) => Bool -> m ()
17:42:55<Deewiant>> 2+2
17:42:56<lambdabot> 4
17:42:58<dmwit>:t let ensure p x = guard (p x) >> return x in ensure
17:43:00<lambdabot>forall b (m :: * -> *). (MonadPlus m) => (b -> Bool) -> b -> m b
17:43:03<HairyDude>:t ensure b x = if b then x else mempty
17:43:04<pastorn>@type guard
17:43:04<lambdabot>parse error on input `='
17:43:06<lambdabot>forall (m :: * -> *). (MonadPlus m) => Bool -> m ()
17:43:14<HairyDude>:t let ensure b x = if b then x else mempty in ensure
17:43:16<lambdabot>forall a. (Monoid a) => Bool -> a -> a
17:43:33<HairyDude>funny that that isn't in Data.Monoid already, it seems useful
17:43:49<dmwit>HairyDude: I know it depends on MonadPlus, I just want that ensure more often than I want your one. =)
17:44:45<Heffalump>I don't really understand why that should be called 'ensure'
17:44:46<HairyDude>dmwit: {-# LANGUAGE FlexibleContexts, OverlappingInstances #-} instance MonadPlus m => Monoid (m a) where { mempty = mzero; mappend = mplus }
17:45:06<dmwit>sure
17:45:17<dmwit>Heffalump: Something like this:
17:45:34<dmwit>Heffalump: [1..10] >>= ensure even
17:45:51<dmwit>> let ensure p x = guard (p x) >> return x in [1..10] >>= ensure even
17:45:52<lambdabot> [2,4,6,8,10]
17:46:20<mar77a>:t ensure
17:46:21<lambdabot>Not in scope: `ensure'
17:46:25<mar77a>doh
17:46:31<jdh30>bfn
17:46:35<Heffalump>I understand the MonadPlus one, but not the Monoid one.
17:46:37<dmwit>(b -> Bool) -> b -> monadPlus b
17:46:59<HairyDude>Heffalump: the function, or just its name? I'm not attached to that name, in fact I called it something else
17:47:04<Heffalump>it's name
17:47:10<Heffalump>s/it's/its/ # gah
17:53:34<HairyDude>ACTION wonders why guard has to use m () instead of m a
17:53:59<vixey>@src guard
17:53:59<lambdabot>guard True = return ()
17:53:59<lambdabot>guard False = mzero
17:54:02<vixey>that's why
17:54:25<HairyDude>oh wait, that's not the function I was thinking of
17:54:26<obk>Obvious in retrospect
17:54:32<HairyDude>I mean when
17:54:34<obk>Bug was introduced by the -O compile flag
17:54:36<HairyDude>@src when
17:54:37<lambdabot>when p s = if p then s else return ()
17:54:43<obk>Haffelump: Can you verify?
17:54:44<HairyDude>:t when
17:54:45<lambdabot>forall (m :: * -> *). (Monad m) => Bool -> m () -> m ()
17:55:43<dmwit>when doesn't require MonadPlus
17:56:34<obk>Heffalump: Can you test whether -O also breaks this program on 6.9 ?
17:57:05<Vq^>i can't grok this memoization with recursion from the haskell wiki
17:57:20<vixey>Vq^: we could look at fibs if you like?
17:57:25<HairyDude>ah, so it doesn't
17:57:44<Heffalump>obk: confirmed that it hangs on 6.8.2
17:57:58<Vq^>whats so different between "fib n = map fib' [0..] !! n" and "fib = (map fib' [0..] !!)"
17:58:09<obk>relief! my machine is not haunted by gremlins! :-)
17:58:21<obk>Heffalump: In 6.9 as well?
17:58:24<Heffalump>it also doesn't interrupt properly, which probably explains the empty .hp
17:58:38<Heffalump>oh, though I have a non-empty .hp, actually
17:58:53<obk>Well, either way, this seems worthy of a bug report.
17:59:03<obk>Though less so if it was fixed on 6.9
17:59:10<Heffalump>yeah, just about to try that
17:59:19<Vq^>vixey: fibs?
18:00:08<Heffalump>it segfaults!
18:00:21<vixey>Vq^: it's a good example because the recursion blows up really fast
18:00:27<obk>Ha!
18:00:30<obk>Even better
18:00:37<obk>Ok, I'm entering a bug report on this
18:00:47<vixey>> let fib 0 = 0 ; fib 1 = 1 ; fib n = fib (n-2) + fib (n-1) in fib 3
18:00:48<obk>Heffalump: many thanks for the help!
18:00:48<lambdabot> 2
18:00:50<ttt-->@src when
18:00:51<lambdabot>when p s = if p then s else return ()
18:00:52<vixey>> let fib 0 = 0 ; fib 1 = 1 ; fib n = fib (n-2) + fib (n-1) in fib 300
18:00:55<Vq^>vixey: well, i understand memoization and every fibonacci example i have seen so far
18:01:02<lambdabot> Exception: Time limit exceeded
18:01:08<obk>Now how do I tell cabal not to use -O ... hmmm... looking up
18:01:34<vixey>> let fib 0 = 0 ; fib 1 = 1 ; fib n = fib' (n-2) + fib' (n-1) ; fib' n = fibs!!n ; fibs = map fib [0..] in fib 300
18:01:35<lambdabot> 222232244629420445529739893461909967206666939096499764990979600
18:02:05<vixey>Vq^: so is it clear why this version memoized?
18:02:14<Vq^>vixey: yes, very clear
18:02:23<Heffalump>obk: -O0 as an explicit option
18:02:29<Vq^>vixey: thought i like the zipWith trick better ;)
18:02:31<obk>Thanks!
18:02:37<Heffalump>at a guess, anyway
18:02:45<Heffalump>it would be silly if that didn't work
18:02:53<vixey>Vq^: what's that?
18:03:04<Saizan>obk: configure with --disable-optimization
18:03:12<vixey>Vq^: changing the entire algorithm just to memo?
18:03:13<Vq^>> let fibs = 0 : 1 : zipWith (+) fibs (tail fibs) in fibs !! 300
18:03:15<lambdabot> 222232244629420445529739893461909967206666939096499764990979600
18:03:18<obk>Saizan: But then my users will suffer
18:03:21<vixey>yeah not so keen on that
18:03:26<Deewiant>> let fibs = fix ((0:).scanl (+) 1) in fibs !! 300
18:03:27<lambdabot> 222232244629420445529739893461909967206666939096499764990979600
18:03:40<Baughn>obk: You've tracked the loop to the /optimizer/?
18:04:02<obk>Baughn: Yes!!!
18:04:02<Heffalump>Baughn: seems so.
18:04:17<obk>Should have been the 1st thing I tried <sheepish>
18:04:34<mauke>:t ((. flip (:)) . (flip ($!)))
18:04:35<lambdabot>forall a. a -> [a] -> [a]
18:04:38<Baughn>obk: Then. It might be a bit hard, but it would be a very good thing to figure out exactly what causes it - the optimizer should never, ever do that.
18:04:48<Vq^>my problem is when there is no clear list of memoized values
18:04:49<Deewiant>@unpl ((. flip (:)) . (flip ($!)))
18:04:50<lambdabot>(\ j m -> (\ c -> (:) c m) $! j)
18:04:54<Heffalump>we really could do with a proper reducer for Haskell code
18:05:05<vixey>Heffalump: what would it do?
18:05:14<vixey>like an evaluator but step by step?
18:05:15<Heffalump>cut down test cases like this
18:05:22<vixey>huh
18:05:25<Vq^>http://haskell.org/haskellwiki/Memoization#Memoization_with_recursion
18:05:29<lambdabot>Title: Memoization - HaskellWiki, http://tinyurl.com/65yh9u
18:05:32<Heffalump>hangon, I'm trying to find the C utility I'm thinking of
18:05:38<obk>Baughn: I am submitting a bug report with the program
18:05:54<DRMacIver>Heffalump: You mean delta?
18:05:59<Heffalump>DRMacIver: yes, I do. Thanks!
18:06:04<Vq^>im trying to understand how memoized_fib evaluates
18:06:04<DRMacIver>No problem
18:06:08<mauke>> let fs = 0 : 1 : zipWith (+) fs (tail fs) in fs !! 10000
18:06:10<lambdabot> 3364476487643178326662161200510754331030214846068006390656476997468008144216...
18:06:14<mauke>> let fs = 0 : 1 : zipWith (+) fs (tail fs) in fs !! 100000
18:06:14<vixey>Vq^: That's exactly the same as my example which you said you understood ...
18:06:16<lambdabot> out of memory (requested 1048576 bytes)
18:06:22<Heffalump>if we had an unlayout utility, we could probably just use delta.
18:06:56<Vq^>vixey: except you defined fibs
18:07:01<DRMacIver>unlayout doesn't seem like it should be hard to write if you have a parser and pretty printer for Haskell already
18:07:03<vixey>Vq^: syntax
18:07:05<gubagem>@hoogle !!
18:07:09<Heffalump>agreed.
18:07:12<lambdabot>Prelude.(!!) :: [a] -> Int -> a
18:07:12<lambdabot>Data.List.(!!) :: [a] -> Int -> a
18:07:17<Heffalump>We also need a hsallinone for GHC Haskell.
18:07:23<DRMacIver>A what?
18:07:32<Heffalump>merges multiple modules into one
18:07:33<Vq^>vixey: i guess i don't see that jump :/
18:07:35<DRMacIver>Oh, right.
18:07:43<Deewiant>vixey: why doesn't memoized_fib there evaluate the map fib [0..] on each call?
18:07:44<vixey>Vq^: there is no jump
18:07:49<DRMacIver>Does delta really need them all in one file?
18:07:56<vixey>> let fib 0 = 0 ; fib 1 = 1 ; fib n = fib' (n-2) + fib' (n-1) ; fib' n = fibs!!n ; fibs = map fib [0..] in fib 300
18:07:57<lambdabot> 222232244629420445529739893461909967206666939096499764990979600
18:08:00<Vq^>vixey: then i guess im just plain confused...
18:08:03<Heffalump>no, there's multidelta (IIRC) which doesn't. But I think it's much harder to operate.
18:08:08<DRMacIver>Ah
18:08:14<Heffalump>and it's nice to have your test case all in one file if at all possible
18:08:43<obk>Ticket #2327 if anyone is interested - the -O flag producing faulty code
18:09:21<Vq^>hmm, i guess it's the body of the function/value that is memoized_fib that gets memoized
18:09:24<Deewiant>> let fib 0 = 0 ; fib 1 = 1 ; fib n = fib' (n-2) + fib' (n-1) ; fib' n = map fib [0..] !!n in fib 300
18:09:25<lambdabot> 222232244629420445529739893461909967206666939096499764990979600
18:09:26<DRMacIver>Heffalump: True
18:09:36<Deewiant>vixey: that one runs much slower for me in GHCi
18:09:51<DRMacIver>Something like this? http://www.cs.utah.edu/~hal/HAllInOne/index.html
18:09:52<lambdabot>Title: Haskell All-In-One
18:10:08<DRMacIver>Oh, it only handles H98
18:10:09<Heffalump>DRMacIver: yes, precisely that.
18:10:28<DRMacIver>Oh, sorry
18:10:33<DRMacIver>I totally misread your comment
18:10:44<Heffalump>I got the name slightly wrong (HSAllInOne verses HAllInOne)
18:11:33<DRMacIver>I parsed what you said as "We need this tool" rather than "We need this tool to support GHC's dialect of Haskell"
18:11:41<DRMacIver>ACTION fails. :)
18:11:51<Heffalump>we need such a tool that supports GHC Haskell
18:12:01<Heffalump>whether it's that tool update or a new one, I don't care
18:13:10<Vq^>vixey: i guess you are completely right, my problem is only about syntax
18:14:20<Vq^>it's the big difference between "f = (fs !!)" and "f x = fs !! x" that i seem to be somewhat confused by
18:15:33<hpaste> Orchid pasted "Achievement cat... is pround of self" at http://hpaste.org/8022
18:16:53<ziman>what is the best way to parse two kinds of blocks, one beginning with "Frame ", the other with "FrameMatrix", using Parsec? do i have to factor the grammar or is there a friendlier way? :)
18:17:03<chessguy>@pl \s -> u s >>= u
18:17:03<lambdabot>(u =<<) . u
18:17:22<mauke>@pl \u -> u s >>= u
18:17:22<lambdabot>(>>=) =<< ($ s)
18:17:27<mauke>haha
18:18:17<chessguy>@pl \u s -> u s >.>= u
18:18:17<lambdabot>flip =<< ((>.>=) .)
18:18:25<DRMacIver>Hm. Is there any way to tell ghc to recompile all its libraries from source?
18:18:33<chessguy>@pl \s u -> u s >>= u
18:18:33<lambdabot>join . ((>>=) .) . flip id
18:18:40<Heffalump>I don't think it even knows where the source is
18:18:53<DRMacIver>Ah well
18:19:03<DRMacIver>I suspect it's time to reinstall ghc. Again.
18:19:07<Heffalump>why?
18:19:16<Deewiant>@src (>=>)
18:19:17<lambdabot>Source not found. You speak an infinite deal of nothing
18:19:18<Dzlk>ziman: for what value of "best"?
18:19:21<Deewiant>chessguy: (>=>)
18:19:29<Deewiant>@ty (>=>)
18:19:30<DRMacIver>Because I didn't reinstall after I last broke it with that pretty printers bug.
18:19:31<lambdabot>forall a (m :: * -> *) b c. (Monad m) => (a -> m b) -> (b -> m c) -> a -> m c
18:19:48<DRMacIver>I just rebuilt some of the modules that depended on it
18:20:08<DRMacIver>And now I'm finding I can't use the Language.Haskell stuff which dependended on that and can't figure out where to recompile them from.
18:20:32<Toxaris_>ziman: something like (keyword s = try $ string s >> whitespace), and then (keyword "FrameMatrix" >> ...) <|> (keyword "Frame" >> ...) should work
18:20:37<Heffalump>ah
18:22:14<Toxaris_>ziman: if you make sure that (keyword "Frame") does not accept "FrameMatrix", you're on the safe side. The try in keyword enables local backtracking, to allow different keywords to begin with the same prefix
18:22:51<gpds>how is an int different from an integer?
18:23:03<Heffalump>smaller range
18:23:05<Heffalump>integer is unbounded
18:23:16<gpds>whats the range?
18:23:22<ziman>Toxaris_, i see, thanks. I thought of `try'ing whole blocks but `try'ing the keyword is clearly better :)
18:23:28<mauke>> [minBound, maxBound] :: [Int]
18:23:29<lambdabot> [-2147483648,2147483647]
18:23:40<gpds>thanks!
18:23:48<DRMacIver>Technically the range is unspecified...
18:23:50<Heffalump>standard says 29 bits minimum, GHC uses machine words
18:24:02<Toxaris_>ziman: yeah, that's a general design pattern with Parsec: use try on the lexer level, but try :) to avoid it on the parser level
18:24:03<DRMacIver>At least specified to be within a certain bound
18:24:15<Toxaris_>ziman: with lexer and parser levels not exactly seperate :)
18:25:26<ziman>hm, good point
18:25:41<chessguy>Deewiant: is that in the libraries somewhere?
18:25:47<chessguy>@hoogle (>=>)
18:25:47<lambdabot>Control.Monad.(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c
18:26:53<hpaste> vicky pasted "fib memo" at http://hpaste.org/8023
18:27:03<chessguy>guess that answers that question :)
18:27:06<vixey>Vq^ & Deewiant
18:27:59<DRMacIver>Heffalump: Well, I was right about it being ridiculously easy to implement NoLayout. Took all of four lines to throw together with Language.Haskell. :)
18:28:07<DRMacIver>(Well, four lines plus imports)
18:28:24<mauke>.oO( import XMonad.Layout.NoLayout )
18:28:43<DRMacIver>Sorry, unlayout
18:28:49<hpaste> DRMacIver pasted "unlayout" at http://hpaste.org/8024
18:29:42<Deewiant>vixey: how about fib2 such that fibs is written inline, i.e. fib3' n = map fib3 [0..] !! n
18:29:44<Heffalump>DRMacIver: does it work on GHC Haskell? I thought Language.Haskell was H98
18:29:53<Heffalump>not that it's not a good thing.
18:29:57<vixey>Deewiant: please paste it with times
18:31:36<DRMacIver>Heffalump: I was under the impression that the Language.Haskell module provided with ghc used ghc's parser
18:31:38<chessguy>@seen conal
18:31:39<lambdabot>Plugin `seen' failed with: too few bytes. Failed reading at byte position 8
18:31:52<DRMacIver>Heffalump: Again, I could be totally wrong
18:31:59<Heffalump>I didn't think it had syntactic elements for non-H98. I also could be wrong.
18:32:01<mauke>preflex: seen conal
18:32:01<preflex> conal was last seen on #haskell 3 hours, 21 minutes and 47 seconds ago, saying: sjanssen: thx!
18:32:12<ziman>@pl \x -> whitespace >> return x
18:32:13<lambdabot>(whitespace >>) . return
18:32:33<gpds>preflex: seen jdh30
18:32:33<preflex> jdh30 was last seen on #haskell 46 minutes and 1 second ago, saying: bfn
18:32:38<Heffalump>http://www.cs.chalmers.se/~d00nibro/haskell-src-exts/
18:32:39<lambdabot>Title: haskell-src-exts: Haskell-Source with Extensions
18:32:40<dmwit>:t \x -> liftM (const x) whitespace
18:32:42<lambdabot>Not in scope: `whitespace'
18:32:58<dmwit>ziman: flip liftM whitespace . const
18:33:07<gubagem>thats fib memo code looks wicked simple
18:33:07<dmwit>Is even less readable. ;-)
18:33:18<ziman>dmwit, :D
18:33:38<DRMacIver>Heffalump: Hm. Just tried it, you're right
18:33:50<hpaste> Deewiant annotated "fib memo" with "inlining fibs" at http://hpaste.org/8023#a1
18:34:05<Deewiant>vixey: as I thought, it's the slowest of all four
18:34:09<Heffalump>haskell-src-exts is the way to go, I suspect
18:34:25<vixey>Deewiant: I couldn't have predicted that
18:34:36<BONUS>@src ap
18:34:37<lambdabot>ap = liftM2 id
18:34:37<Heffalump>either that or ghc-api
18:34:58<Deewiant>vixey: it's doing the map fib3 [0..] for each call to fib3', nothing is memoized
18:35:03<DRMacIver>ACTION is slightly perplexed that GHC bundles a parser that doesn't handle GHC extensions.
18:35:04<vixey>Deewiant: I thought it would be equivalent to fib2 actually
18:35:07<DRMacIver>Oh welll
18:35:09<vixey>Deewiant: but it makes sense
18:35:15<vixey>in retrospect
18:35:36<Vq^>> let fib = (map fib' [0..] !!); fib' 0 = 0; fib' 1 = 1; fib' n = fib (n-2) + fib (n-1) in fib 300
18:35:38<lambdabot> 222232244629420445529739893461909967206666939096499764990979600
18:35:51<Deewiant>vixey: what I don't get is why the same doesn't happen with memoized_fib
18:36:05<Vq^>> let fib n = map fib' [0..] !! n; fib' 0 = 0; fib' 1 = 1; fib' n = fib (n-2) + fib (n-1) in fib 300
18:36:07<lambdabot> 222232244629420445529739893461909967206666939096499764990979600
18:36:11<vixey>have you timed memoized_fibs?
18:36:17<vixey>(which of my examples is it equivalent to?)
18:36:23<Deewiant>has the speed of fib2
18:36:29<vixey>right
18:36:35<vixey>so it's the same code
18:36:43<vixey>just written in a silly way
18:36:52<vixey>(I think we could impove the wiki article)
18:36:55<chessguy>@type iterateM
18:36:57<lambdabot>Not in scope: `iterateM'
18:37:02<jleedev>> let fibs = 1 : scanl (+) 1 fibs in fibs !! 300
18:37:03<lambdabot> 359579325206583560961765665172189099052367214309267232255589801
18:37:06<chessguy>@hoogle iterateM
18:37:06<lambdabot>No matches found
18:37:17<Vq^>that last example i pasted doesn't terminate within a minute
18:37:19<chessguy>@type iterate
18:37:20<lambdabot>forall a. (a -> a) -> a -> [a]
18:37:42<Vq^>lambdabot seems to solve it thought :/
18:37:49<Deewiant>vixey: but it looks like it should have the speed of fib3 :-/
18:37:58<DRMacIver>Hm. Where can I find the ghc api?
18:38:21<DRMacIver>Ah, never mind
18:39:02<Deewiant>vixey: :-OOOO
18:39:07<chessguy>@hoogle (a -> m a) -> a -> [a]
18:39:07<Deewiant>vixey: making it pointy slows it down to fib3 speed
18:39:07<lambdabot>Prelude.iterate :: (a -> a) -> a -> [a]
18:39:07<lambdabot>Data.List.iterate :: (a -> a) -> a -> [a]
18:39:07<lambdabot>Prelude.scanl :: (a -> b -> a) -> a -> [b] -> [a]
18:39:17<chessguy>:hoogle+
18:39:22<Heffalump>DRMacIver: it bundles a standard library
18:39:27<chessguy>@hoogle+
18:39:27<lambdabot>Data.List.scanl :: (a -> b -> a) -> a -> [b] -> [a]
18:39:27<lambdabot>Prelude.scanr :: (a -> b -> b) -> b -> [a] -> [b]
18:39:27<lambdabot>Data.List.scanr :: (a -> b -> b) -> b -> [a] -> [b]
18:39:51<Heffalump>if it produced a datatype that included constructors for non-H98 stuff, that standard library wouldn't be compatible across implementations
18:39:51<vixey>Deewiant: at least I don't think that these 3 typed of memoization (none, one time, every time) can be written simpler
18:40:26<chessguy>@hoogle (a -> Maybe a) -> a -> [a]
18:40:27<lambdabot>No matches, try a more general search
18:40:50<Vq^>vixey: did you see my last fib?
18:41:23<adekoba>is there a variable in ghci that stores the last answer?
18:41:35<mauke>it
18:41:44<adekoba><3
18:41:45<adekoba>thanks
18:42:00<tusho>what are the monad laws again?
18:42:04<hpaste> Deewiant annotated "fib memo" with "pointless vs. pointy" at http://hpaste.org/8023#a2
18:42:07<tusho>a >>= return === a
18:42:10<tusho>what else?
18:42:11<Vq^>vixey: and if you did do you know why lambdabot seems to optimize it to "do memoization"?
18:42:12<DRMacIver>Heffalump: I'd sortof expect that to be moved out to hackage with the library reorg if it wasn't actually part of ghc.
18:42:16<DRMacIver>But I guess not.
18:42:25<chessguy>@type \f x -> takeWhile isJust $ iterate (\x -> x >>= f) x
18:42:25<lambdabot>forall a. (a -> Maybe a) -> Maybe a -> [Maybe a]
18:42:30<Deewiant>vixey: see paste, that is weird IMO O_o
18:42:36<mauke>@wiki Monad_laws
18:42:36<lambdabot>http://www.haskell.org/haskellwiki/Monad_laws
18:42:49<chessguy>@pl \x -> x >>= f
18:42:50<lambdabot>(f =<<)
18:43:00<Deewiant>or (>>= f) :-P
18:43:20<chessguy>@pl \f x -> takeWhile isJust $ iterate (>>= f) x
18:43:21<lambdabot>(takeWhile isJust .) . iterate . (=<<)
18:43:46<chessguy>@type \f x -> takeWhile isJust $ iterate (>>= f) x
18:43:47<lambdabot>forall a. (a -> Maybe a) -> Maybe a -> [Maybe a]
18:43:57<Vq^>Deewiant: did you see lambdabots result from your fib5_ ?
18:44:08<chessguy>@hoogle [Maybe a] -> a
18:44:09<lambdabot>No matches, try a more general search
18:44:18<chessguy>@hoogle [Maybe a] -> [a]
18:44:18<lambdabot>Data.Maybe.catMaybes :: [Maybe a] -> [a]
18:45:28<Deewiant>Vq^: yes, can't explain it
18:45:38<bd_>@src catMaybes
18:45:38<lambdabot>catMaybes ls = [x | Just x <- ls]
18:45:39<Deewiant>Vq^: I'm not sure, perhaps lambdabot compiles the code?
18:45:52<bd_>there needs to be a maybeToMonadPlus :|
18:46:06<Vq^>it seems that lambdabots compiler sees that the right hand side of !! isn't affected by it's arguments
18:46:19<Vq^>er, left hand side
18:46:51<hpaste> vicky annotated "fib memo" with "clue" at http://hpaste.org/8023#a3
18:47:32<vixey>Vq^: no I didn't se it
18:47:35<Deewiant>O_o, why does that happen
18:47:44<vixey>monomorphism
18:47:57<gpds>@type zipWith
18:47:59<lambdabot>forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
18:48:01<Deewiant>monomorphism restriction speeds up programs, right
18:48:11<vixey>well it's about types
18:48:21<bd_>Deewiant: depends
18:48:23<vixey>speed up is a possible consequence
18:48:39<bd_>Deewiant: the goal is to avoid situations where an expression is unexpectedly evaluated twice, with two different types
18:48:40<Deewiant>sure
18:48:43<sclv_>any folks familiar with DPH around?
18:48:54<bd_>by forcing you to explicitly annotate when you want that to happen
18:48:58<sclv_>The parallels with *lisp are sort of striking me lately.
18:49:05<Deewiant>bd_: it's just that in this case it unexpectedly causes something to be evaluated only once instead of N times :-)
18:49:17<sclv_>Was wondering how much influence there was (haven't trawled through all the papers yet)
18:49:32<dons>sclv_: very little, afaik
18:49:42<dons>it came out of work on nested data paralellism in the early 90s
18:49:43<bd_>Deewiant: oO
18:50:11<dons>sclv_: based on Nesl
18:50:19<sclv_>the distribution law of the alpha operator in *lisp is pretty cool
18:50:22<Vq^>the types may not be the cause thought
18:50:40<dons>http://citeseer.ist.psu.edu/blelloch90nesl.html
18:50:42<lambdabot>Title: Nesl: A Nested Data-Parallel Language - Blelloch (ResearchIndex)
18:50:52<dons>"Nesl, a strongly-typed, applicative, data-parallel language."
18:50:57<bd_>Deewiant: when you bind fibs at the toplevel (in fib2 example), GHC keeps it around until the program terminates
18:50:58<vixey>hi dons!
18:51:17<Deewiant>bd_: yep, but I'm looking only at fib5 and fib5_
18:51:38<vixey>I tried to show that with fib2 vs fib3
18:51:49<vixey>(specifically timing them twice)
18:52:05<dons>and the ubiquitous reddit link http://reddit.com/info/6lmsz/comments/
18:52:25<vixey>I guess not :/
18:52:42<halberd>where can I find an algorithm or heuristic for representing a graph that is not planar, but that would be planar if a few edges were removed?
18:52:50<Vq^>you can force the type of fib5 to Num a => Int -> a without any large difference in performance
18:52:52<bd_>Deewiant: hmm... I guess GHC bound (map fib5' [0..] !!) at the toplevel, thus keeping the (map fib5' [0..]) around too?
18:53:10<halberd>that is I want an algorithm that will take a non-planar graph and return a small set of edges that can be removed from the graph to make it planar
18:53:28<Deewiant>bd_: this is GHCi, I wouldn't expect it do that kind of a transformation
18:53:50<bd_>Deewiant: it might.
18:53:55<bd_>It's not actually a transformation
18:53:57<vixey>isn't ghci the same as ghc?
18:54:10<Deewiant>I don't know, is it?
18:54:15<bd_>vixey: It optimizes less, and uses a bytecode VM rather than a native code generator
18:54:27<bd_>the libraries are the same though
18:54:35<bd_>and the RTS
18:54:36<Vq^>well, lambdabot transforms f n = fs !! n to f = (fs !!) causing it to do memoization
18:54:39<Deewiant>bd_: and sure it is, in this case it changes a temporary to a global o_O
18:54:55<Deewiant>Vq^: that shouldn't make a difference in terms of memoization, that's just syntax
18:54:55<Vq^>thats somewhat niftier
18:55:02<Deewiant>and that's what I'm confused about
18:55:08<Deewiant>because it is causing memoization
18:55:20<bd_>Deewiant: Consider that you have (!!) (map fib5' [0..]) - a naive implementation would be to put a partial application of (!!) (with the map term bound into a closure) as a global
18:55:20<Vq^>Deewiant: it's like bd_ is saying
18:55:33<bd_>Deewiant: Thus, it's memoized if you don't optimize it much :)
18:55:36<Vq^>Deewiant: the left hand of !! gets stored between the calls
18:55:48<Vq^>Deewiant: because it's not dependent on the argument
18:55:55<Deewiant>bd_: ah, good point, it becomes a closure
18:56:01<vixey>how can you memo typeclasses
18:56:19<Deewiant>I wonder if -O2 slows that down :-D
18:56:37<Vq^>it's a bit tricky to spot which caused my initial confusion
18:56:46<Deewiant>I still wouldn't expect it to happen
18:56:53<Deewiant>now I just understand why it does
18:57:01<Vq^>especially since different implementation handles it differently
18:57:13<Deewiant>but I definitely wouldn't call the "memoized_fib" on that wiki page a memoized version of fib
18:57:25<Deewiant>just one that happens to get memoized depending on how the compiler chooses to generate the code for it
18:57:31<Vq^>Deewiant: not really
18:57:36<bd_>with fib5_, since n is in scope, and since you're light on the optimizations, fib5_' ends up depending on the outer n
18:58:18<Vq^>Deewiant: the function is a value, and all dependencies of that value should really just be computed once
18:58:21<Deewiant>a where- or let- or global binding of fibs = map fib [0..] is what I'd call a memoized one
18:58:45<ddarius>vixey: The intent that is trying to be communicated is the difference between fib n = let memotable = ... in memotable !! n and fib = let memotable = ... in \n -> memotable !! n
18:58:47<vixey>A global definition is equivalent to a let isn't it?
18:58:48<Deewiant>Vq^: should, but nobody's saying you have to
18:59:05<Deewiant>Vq^: there's a bug that GHC doesn't calculate "1 + 2" at compile-time if they're of type Integer
18:59:09<bd_>Deewiant: fib5 is isomorphic to such a binding :)
18:59:18<vixey>ddarius: oh ok
18:59:23<vixey>that makes sense
18:59:39<Deewiant>bd_: sure, but it still depends on the compiler running it through the isomorphism :-P
18:59:54<bd_>Deewiant: not really, the naive implementation of either works similarly :)
19:00:05<mauke>optimisomorphism
19:00:09<bd_>How is 'map fib' any different from '(!!) . map fib' ?
19:00:20<Vq^>Deewiant: you could say that, i would think that it's only a bug if they get recalculated if they isn't part of a function scope
19:00:41<Deewiant>Vq^: it's a global of the form x = 1 + 2
19:00:51<Vq^>Deewiant: and with optimizations like the one which speeds up fib5_ it should never be recalculated
19:01:36<Vq^>Deewiant: then i would expect it to get recalculated unless the compiler optimizes that by seeing which scopes doesn't depend on the function argument
19:02:41<Deewiant>with ghc -O2 they both appear to run at about the same speed
19:03:20<Deewiant>but I still think it's dependent on a compiler optimization and not memoized in itself
19:03:34<Vq^>only fib5_
19:03:47<Vq^>fib5 doesn't make that assumption
19:03:48<bd_>Deewiant: check how they're transformed in the core, if you're really curious
19:03:55<bd_>-ddump-stg
19:04:04<vixey>ddarius, how is your linear logic stuff going ?
19:04:10<Vq^>and fib5 is equivalent to memoized_fib in the wiki
19:04:26<ddarius>vixey: I have a parser. I'm not sure what all rules LolliMon uses to loosen up the grammar.
19:04:39<vixey>oh cool
19:05:11<vixey>do you have any repo online ?
19:05:19<vixey>like a darcs thing..
19:05:51<Deewiant>bd_: I can't read core well enough to see the difference :-)
19:05:55<ddarius>LolliMon accepts a,b -o {c} as being equivalent to a -o b -o {c} which makes sense, but apparently it also accepts a o- sigma U \ f U, top which doesn't make sense syntactically.
19:06:02<ddarius>vixey: No repo, not even locally yet.
19:06:34<ddarius>The next step is either kind/type checking or figuring out how the heck I'm going to evaluate this stuff.
19:06:43<vixey>:D
19:06:54<vixey>I think pfenning has some text on evalution
19:07:22<vixey>some of lolli is described heer http://www.cs.cmu.edu/~fp/courses/linear/handouts.html
19:07:23<lambdabot>Title: 15-816 Linear Logic / Handouts
19:07:36<vixey>iirc...
19:08:55<ddarius>The backward chaining part is easy. The forward chaining probably isn't too hard, but I haven't really thought that hard about it.
19:09:06<vixey>oh I have no idea about forward chaining
19:09:18<vixey>is that how things like: a, b -o c. are evaluated?
19:10:53<ddarius>The monad {_} starts forward chaining.
19:11:11<vixey>oh I see
19:11:25<conal>chessguy: hi
19:11:36<chessguy>howdy
19:11:42<sclv_>I actually don't think that *lisp gave anything especially "nested" at all -- the alpha operator's rules are semantically good to think with though.
19:11:42<conal>chessguy: how's it going?
19:11:47<chessguy>meh, it's going
19:11:57<chessguy>life has been crazy
19:12:47<chessguy>conal: had any chance to look at my code lately? we had talked about trying to figure out why the test harness sucked
19:13:10<DRMacIver>The fact that there are no less than three tools for converting from darcs to git is vaguely unsettling
19:13:29<conal>chessguy: i did look at it some, though i didn't delve deeply enough to find a more elegant angle
19:13:51<bd_>DRMacIver: I tried running one of those on the GHC repo once - darcs proceeded to OOM my machine >_>
19:14:03<DRMacIver>Ha
19:14:09<DRMacIver>I wish I could be surprised by that. :)
19:17:16<ddarius>vixey: If you had a linear context with facts like item(1) and you had the rule item(X), list(XS) -o {list(X:XS)} then if you had the linear fact list([]) then the query {list(XS)} would bind XS to a list of numbers is some non-deterministically chosen order.
19:22:37<u_quark>hello, where can i find some help/documentation on happs ?
19:22:52<mauke>u_quark: the internet
19:23:17<chessguy>conal: the issue seems to be needing a value instead of a type in some places
19:23:39<sclv_>oh hey, it turns out that CM Lisp did provide Nested operations -- it just only parallelized the bottom layer
19:23:39<u_quark>mauke: I need something more specific than that ...
19:24:07<mauke>u_quark: ask a more specific question :-)
19:24:13<conal>chessguy: interesting. do you have an example?
19:24:17<mauke>u_quark: oops, sorry
19:24:31<mauke>u_quark: I actually got confused by a display error in my client. my fault :(
19:24:43<u_quark>lol it's ok
19:26:07<chessguy>conal: ok, so there's this 'perft' function in TestHarness.hs
19:26:32<chessguy>it takes a value of type (Chessboard c) => c, when really all it 'needs' is the type
19:27:28<Heffalump>it doesn't actually have 'c' anywhere else in the type?
19:27:30<chessguy>conal: because any type in Chessboard is going to have a value named 'emptyBoard'
19:28:27<conal>chessguy: i see. sounds like a consequence of having Chessboard be a class rather than a type.
19:28:37<chessguy>conal: indeed
19:29:09<chessguy>because the definition has class Chessboard c where ... emptyBoard :: c
19:29:10<Heffalump>you could wrap it up with an existential
19:29:15<Heffalump>or turn it into a record
19:29:20<Heffalump>(instead of a class)
19:29:51<chessguy>Heffalump: well, the purpose of the class is to define default behavior, but allow it to be overridden
19:30:02<Heffalump>you can do that with a record too
19:30:11<hpaste> koast pasted "(no title)" at http://hpaste.org/8025
19:30:11<Heffalump>given record update syntax
19:30:45<conal>Heffalump: i wonder if your suggestion would amount to making chessguy's dictionaries explicit.
19:30:52<Heffalump>yes, of course
19:31:00<quicksilver>explicit dictionaries are much better than classes
19:31:05<quicksilver>classes are vastly overused :)
19:31:08<Heffalump>either using existentials or a record type is equivalent to that
19:31:16<chessguy>quicksilver: 'better' in what way?
19:31:26<quicksilver>classes have one specific use case : where you want the type-inference enginge in the compiler to pick the dictionary automatically
19:31:33<Heffalump>indeed, passing an unused value of type 'c' is also equivalent to that, really
19:31:58<quicksilver>chessguy: 'better' in the sense of more general, more flexible, more expressive
19:32:08<Heffalump>quicksilver: agreed, but this might be useful in other cases with this same thing.
19:32:15<quicksilver>of course.
19:32:20<quicksilver>I haven't studied chessguy 's code
19:32:24<quicksilver>just making a general observation
19:32:32<Heffalump>me neither, but it's not stopping me from speculating wildly
19:32:33<quicksilver>classes are overused and dictionaries are more flexible :)
19:33:43<chessguy>yeah, but haskell records suck
19:33:52<Heffalump>not that badly, and not for this purpose
19:33:53<quicksilver>no more than classes
19:33:59<lament>yeah, javascript is much better in that sense ;0
19:34:02<quicksilver>the syntax is beguilingly similar
19:34:19<Heffalump>also you can't make anonymous type class instances, and you can make anonymous record values
19:34:28<quicksilver>being able to override one member (method) at a time is very handy.
19:34:44<quicksilver>so you can specify behaviour (methods) of one value (object) in terms of another
19:34:52<quicksilver>a bit like what you can do in prototype object systems
19:35:02<lament>yeah, it's very much like javascript
19:48:07<wieczyk>Hi, could someone explain me what is a 'type order' in lambda calculus ?
19:48:52<dmwit>> let fib 0 = 0; fib 1 = 1; fib n | even n = c^2 - a^2 | otherwise = c^2 + b^2 where { n' = div n 2; [a, b, c] = map fib [n'-1..n'+1] } in fib 300
19:48:54<lambdabot> Exception: stack overflow
19:49:45<Philippa_>wieczyk: doesn't mean anything to me. Is this in the same sense as 'higher-order function'?
19:50:02<dmwit>> let fib 0 = 0; fib 1 = 1; fib 2 = 1; fib n | even n = c^2 - a^2 | otherwise = c^2 + b^2 where { n' = div n 2; [a, b, c] = map fib [n'-1..n'+1] } in fib 300
19:50:03<lambdabot> 222232244629420445529739893461909967206666939096499764990979600
19:50:49<dmwit>vixey, Heffalump: Still interested in fib? That one doesn't even use memoization...
19:51:16<Heffalump>interested in what sense?
19:51:26<vixey>that's quite neat :)
19:51:38<vixey>there are lots of ways to do it
19:51:45<dmwit>Dunno, you were talking about it a lot, earlier, but I had to go to lunch with my girlfriend.
19:51:52<wieczyk>Philippa_: well, types with order > 1 are higher-order types.
19:51:56<dmwit>So it took me 'til now to do what I was thinking of. =)
19:52:07<Heffalump>ACTION doesn't even remember that
19:52:09<vixey>well I was just using it to show some details of memoization
19:52:14<dmwit>oh
19:52:17<dmwit>Well, never mind then.
19:52:18<wieczyk>Philippa_: I am studying lambda on my univ now, and i have exercised. But in my point of view i have a mistake in definition of type order
19:52:19<dmwit>=P
19:52:29<wieczyk>Philippa_: but i cannot find any definition on internet.
19:52:46<dcoutts>obk, Heffalump: if you're using the latest Cabal then you can: cabal configure -O0
19:52:50<vixey>wieczyk: Why would you want a definition of this word? Where does it come from?
19:53:06<wieczyk>Philippa_: I have defintion order(t0 -> t1 -> ... -> tn -> a) = 1 + max(1, t0, ..., tn)
19:53:06<vixey>s/word/phrase/
19:53:11<obk>dcoutts: Sure, but anyone downloading the package wouldn't know to do so
19:53:20<wieczyk>vixey: on my home-work list :)
19:53:32<vixey>what exactly is on your list?
19:53:38<wieczyk>and in my opinion it should be 1 + max (_0_,...)
19:53:46<wieczyk>not 1 + max (1,...)
19:54:00<Socrates`>Is it possible to do type class constraints in a data definition?
19:54:05<dcoutts>obk: oh you mean it fails with -O1 ? yeah, that'd be bad :-)
19:54:23<ddarius>Well max(0, ...) is the same as max(...) in this case.
19:54:27<obk>dcoutts: Just '-O' which AFAIR is the same as '-O1'
19:54:35<obk>yes, it is bad :-)
19:54:40<wieczyk>vixey: hm
19:54:42<vixey>shouldn't it be
19:54:44<dcoutts>obk: yes, I was just making it explicit
19:54:54<dcoutts>obk: btw, we are going to use something like make, there's a GSoC project to do a implementation of a make-style framework in Haskell
19:54:55<Socrates`>So, say rather than Maybe a, you could constrain a to say (Monad m) => m a?
19:54:56<vixey>1 + max(1, order(t0), ..., order(tn))
19:55:10<ddarius>Also, presumably that should be max(order(t0), order(t1), ... )
19:55:16<obk>dcoutts: Nice! Do you have a URL for it?
19:55:25<wieczyk>dcoutts: i need to proof some easy think at start, that order(t) = 1 => t = a
19:55:27<vixey>it's probably not worth defining this yourself
19:55:40<vixey>if it's used in any proofs you can just figure out what the definition should be
19:55:47<wieczyk>and type syntax, t = a | t -> t
19:56:17<wieczyk>it means that a is a type variable, and also some function type is a type.
19:56:18<wieczyk>and
19:56:19<dcoutts>obk: http://code.google.com/soc/2008/haskell/appinfo.html?csaid=56D60241D77CA94C
19:56:20<lambdabot>Title: Google Code - Summer of Code - Application Information, http://tinyurl.com/62c6aw
19:56:21<vixey>wieczyk: Do you have some test cases?
19:56:37<vixey>wieczyk: like order(x) = 1, order((a -> b) -> a -> b) = 2 ?
19:56:40<obk>dcoutts: Thanks! I'll give it a look
19:57:00<wieczyk>and, if i need to proof order(t) = 1 => t = a, it means that first-order are type-variables, not type of functions. But,
19:57:09<wieczyk>order(a) = 1 + max(1) = 1 + 1 = 2
19:57:23<wieczyk>that i have mistake in defintion of order(t) ?
19:57:59<wieczyk>becuase, if order(a) = 2 by using this defintion, that i cannot proof "order(t) = 1 => t = a"
19:59:16<wieczyk>Ah.
19:59:27<wieczyk>a lecturer send a info that it should be 0 in max()
19:59:29<wieczyk>sorry for problem.
19:59:40<wieczyk>btw: do yo know some good papers for lambda ?
19:59:47<nottha_k>what does it mean when a package is hidden? http://hpaste.org/8026
20:00:11<ddarius>wieczyk: There is tons of good information on the lambda calculus. Just put it into google or google scholar.
20:00:39<dmwit>nottha_k: It means you need more packages in the build-depends: line in the .cabal file.
20:01:09<dmwit>(...I think.)
20:02:13<nottha_k>dmwit: sounds right. I added "time" to the list of dependencies and got a little farther
20:02:16<nottha_k>thanks
20:03:08<oldsalt>@seen shag
20:03:08<lambdabot>Plugin `seen' failed with: too few bytes. Failed reading at byte position 8
20:03:31<mauke>preflex: seen shag
20:03:31<preflex> Sorry, I haven't seen shag
20:04:21<oldsalt>mauke: thx ;)
20:05:15<dmwit>So, \bot mostly replies to commands that start with ? or @.
20:05:32<dmwit>But she also has a tinyURL plugin and a title-grabbing plugin.
20:05:35<dmwit>Are there any others?
20:05:45<dmwit>(:t, :k, > don't count.)
20:05:47<mauke>karma, presumably
20:05:52<dmwit>Ah, karma.
20:07:09<dons>Igloo: the "GHC 6.8.2 and large source files" mail looks like a good test case generator
20:07:16<Corun>Ok, ok, it's not haskell.. But isn't this seriously awesome: http://www.youtube.com/watch?v=NHC_Qyov2Xc
20:07:16<lambdabot>Corun: You have 1 new message. '/msg lambdabot @messages' to read it.
20:08:01<Frederick>folks does soneone here had a good course in semantics on the university and can point me out the website for it so I can get exercises and solutions?
20:09:03<Baughn>Frederick: Semantics of what?
20:10:44<Igloo>dons: *nod*, and we have some other test cases to look at along similar lines, too
20:13:08<Frederick>Baughn: imperative languages
20:13:17<Frederick>Denotational Semantics
20:15:38<int-e>dcoutts: you have a typo in the gtk2hs motd - it's haskell.org, not hsakell.org
20:15:49<dcoutts>doh
20:16:07<dcoutts>int-e: fixed thanks
20:17:30<dmwit>Good thing we have wetware spelling correctors.
20:21:01<Frederick>Baughn: suggestions?
20:21:18<Baughn>Frederick: Apparently not. I haven't seen it, and google is helpless.
20:21:43<hpaste> (anonymous) pasted "(no title)" at http://hpaste.org/8027
20:22:03<Frederick>Baughn: not sure if google is helpless but I could not find the right terms
20:22:06<int-e>dmwit: actually I pasted the command (it's a darcs pull <url>) and only spotted the mistake after that failed. so it was computer aided spell checking.
20:23:09<dmwit>oh, heh
20:24:25<dons>int-e: good work on the git/darcs tool
20:24:35<dons>you should probably cc. the darcs list too
20:25:08<dons>Igloo++ Serge sez: "But I think that you have found a bug in the DoCon test program.
20:25:12<dons>Thank you"
20:25:28<dons>i wonder when we'll see docon on hackage.
20:27:00<dons>ah, it is even cabalised.
20:27:25<int-e>dons: maybe I'll do that for 0.2. right now it's a bit painful to build - it's really of little interest to people who don't know haskell.
20:28:19<dons>ACTION tries: cabal install docon
20:28:37<dcoutts>ACTION crosses his fingers on dons behalf
20:28:42<dons>20k lines of code.
20:29:13<dons>dcoutts: its all nicely cabalised, http://haskell.org/docon/distrib/2.11/
20:29:22<dons>we just need to convince serge to upload the source/ bundle
20:29:49<dcoutts>oh right
20:30:17<int-e>Oh and I've learned that the darcs repository at darcs.net is slightly inconsistent - at one point there's a patch that renames a Autoconf.lhs file that was never created.
20:31:18<dons>wow, this really does take a while to compile
20:31:25<dons>[22 of 83] Compiling VecMatr
20:31:30<dons>3 minutes in.
20:31:50<dons>ghc's doing ok though. 133M heap
20:33:09<dons>docon needs a better website, and haddocks
20:38:39<dons>half way..
20:38:55<ddarius>Conal Elliott and Frank Pfenning. A family of program derivations for higher order unification.
20:39:49<dons>that must have been a while ago, ddarius
20:39:53<Peaker>I converted my ray tracer from using a 2d Array of (Word8, Word8, Word8) to represent the pixels, to a 2d Array of Vector (where: data Vector = Vector (Double, Double, Double)) - this made it a _lot_ slower. Also, just converting from that format back to the array of (Word8,Word8,Word8) takes a looong time. Why is that?
20:40:02<dcoutts>ACTION piles in on the QC library testing debate
20:40:07<ddarius>dons: 1987
20:40:07<dons>oh horrible, you use triples, Peaker?
20:40:25<Peaker>dons, yeah, a Vector is a triplet/tuple yeah
20:40:35<ddarius>Vector3 !Double !Double !Double
20:40:36<Peaker>dons, mainly for 3d coordinates but now I am using it for r,g,b colorspace, heh
20:40:41<dcoutts>Peaker: if you're worrying about performance there are much better representations
20:40:51<Peaker>dcoutts, I'm pretty new at this :)
20:40:57<Peaker>ddarius, thanks I'll try that
20:41:04<dcoutts>you can do better still
20:41:14<hpaste> dons pasted "standard vector type for Double" at http://hpaste.org/8029
20:41:16<dcoutts>eg use a UArray Int Word32
20:41:28<ndm>dons, dcoutts: not tempted to start using Lazy SmallCheck rather than QuickCheck
20:41:41<dcoutts>ndm: what makes it Lazy?
20:41:46<ndm>its become to tool of choice for testing - the tests mean something, you can keep them going to get more results etc.
20:41:52<dons>ndm, we already use smallcheck + quickcheck + chasing bottoms
20:41:55<dcoutts>ndm: I have indeed used SmallCheck and it's great for some situations
20:42:06<ndm>dcoutts, think of it as smallcheck but more efficient - lazy is just an implementation detail
20:42:15<dons>do smallcheck for the 'inductive' cases, quickcheck for random extra wandering, and bottom testing for other things.
20:42:24<Peaker>dcoutts, I want a 2d array (UArray (Int,Int) ..)?
20:42:27<ndm>lazysmallcheck is loads faster, especially if you do validitycondition => test
20:42:28<conal>i'd like some help with ghc inlining & rules. i have a rule that would fire if 'id' is inlined and simplified. it won't fire unless i add a simplification rule saying "id = \ x -> x".
20:42:29<Peaker>dcoutts, why Word32 and not Vector?
20:42:32<dcoutts>dons, ndm: I should tidy up my SmallCheck strictness checking variation and release it as StrictCheck
20:42:50<dcoutts>ndm: ah I see
20:42:59<Peaker>dons, why the pragma there?
20:43:09<dons>Peaker: so it doesn't use slow Double math ops
20:43:15<dons>Peaker: also -fvia-C -optc-O2
20:43:22<Peaker>dons, will -O3 do?
20:43:26<dons>nothing
20:43:30<dcoutts>Peaker: an Array of a structure type has to use pointer indirections to other heap allocated objects
20:43:45<Peaker>dons, what does the unpack do to avoid double math ops?
20:43:53<dons>conal: have you checked out the rewrite rules wiki page?
20:43:55<dcoutts>Peaker: so for maximum performance we do not want to do that, we want to store the colour components directly in the array
20:44:07<conal>dons: no, i haven't. looking ...
20:44:07<Peaker>dcoutts, but I want a 2d array of vectors, how do I store a vector in a Word32?
20:44:16<dcoutts>Peaker: and 3 Word8's fit comfortably into a Word32
20:44:33<ndm>ACTION has just finished 0.5 billion lazy small check tests
20:44:33<Peaker>dcoutts, ah, but I want to be able to do interesting things to colors.. like averaging them - which is difficult when they wraparound as you add them
20:44:34<dons>conal: http://haskell.org/haskellwiki/GHC/Using_rules
20:44:42<dons>ndm, don't tell ian.
20:44:52<dcoutts>Peaker: it'd require store/fetch functions that pack/unpack
20:44:55<ndm>dons: only took 2 days :)
20:45:07<ndm>would hardly make a dent on the buildbots...
20:45:12<dons>docon now up to 50/80 modules
20:45:19<conal>dons: thanks much!
20:45:28<dcoutts>ndm: actually they're pretty sensitive to build times for validation
20:45:40<dcoutts>ndm: since that's part of their development cycle
20:45:44<ndm>dcoutts, i know - was joking :)
20:45:54<Peaker>dons, thanks for the tips
20:46:29<ndm>dcoutts, for filepath i use the policy of having quickcheck tests and unit tests, and if a quickcheck one ever fails i make that particular case (or a minimal variant) a unit test
20:46:41<dcoutts>ndm: pretty sensible
20:46:48<DRMacIver>Idle thought based on current libraries mailing list discussion. How hard would it be to create a setup where a set of quickcheck tests generated a file which creates test cases for the failures
20:47:14<sclv_>ndm: not to bug you, but did you get my lamdbabot msg?
20:47:24<DRMacIver>so you had developers running fullblown QC tests and the failures generated tests that could be added to the nightlies
20:47:24<ndm>DRMacIver: ever tried to do a test setup using cabal? now that's painful! - we need that infrastructure to work basicially before you do anything more
20:47:37<DRMacIver>Heh. No, I admit I haven't.
20:47:41<ndm>sclv_: nope, lambdabot often looses messages, or repeats them
20:48:00<dcoutts>ndm: I consider it non-existent :-)
20:48:02<DRMacIver>The number of serious Haskell projects I've written is sadly rather minimal
20:48:19<dcoutts>ndm: the support for tests/testing in Cabal
20:48:42<ndm>dcoutts, there is a badly designed hook with a constantly changing interface - what more would i want ;)
20:48:47<sclv_>ndm: if you're not already all set with a testing harness for hoogle4, I have my quickcheck based cgiCheck in a repo now.
20:48:56<sclv_>http://code.haskell.org/~sclv/cgicheck/
20:49:09<dcoutts>ndm: oh it's only badly designed, it's not constantly changing
20:49:37<ndm>dcoutts, it changed at least once, going from returning an ExitCode to () - or vice versa
20:49:37<sclv_>its usable, but not fully tested and sorta rough in terms of some api refinements -- I want to be able to insert random delays, for example, to force more concurrency issues.
20:49:51<dcoutts>ndm: oh, right, yeah ok :-)
20:50:25<dcoutts>ndm: I was going to say we've gone so far to maintain stability that we have an extra parmater to test that does nothing and we can't even figure out what it was ever for :-)
20:50:33<ndm>sclv_: Hoogle is entirely stateless, and i've been working on the pure test framework, using the console version - but i'll put this in the pile to check out when the CGI is ready for testing
20:51:07<dons>i'd be interested in seeing short runs each night, but seeded with new seeds
20:51:22<ndm>dcoutts, cabal-install makes me sufficiently happy that, provided it is bundled with the next full GHC release, i can forgive cabal a lot for the meantime
20:51:26<dons>over time you'd get rather good exploration of the value space. this is what john hughes set up for the ericcson guys
20:51:53<dcoutts>dons: right
20:52:10<dcoutts>dons: with a high 'size' on the Arbitrary instance
20:52:41<ndm>what you really want is one property language and instance declration structure that can do smallcheck, lazysmallcheck and quickcheck with a simple change of driver call
20:53:01<ndm>i bring this up with colin once a month, just to keep the idea floating around
20:53:02<dcoutts>ndm: but you'd write your properties differently I think
20:53:10<sclv_>ndm: it works pretty well for stateless stuff already actually -- just an easy way to generate and run requests with conditions on the responses. I might have just reinvented a subset of quickCheckM, I guess, but it seems pleasant enough to use for me.
20:53:11<ndm>dcoutts: how?
20:53:15<monochrom>ACTION has successfully built the ghc 6.8.3 release candidate (6.8.2. may 31)
20:53:24<dcoutts>ndm: especially between sc and qc
20:53:31<ndm>sclv_: i will check it out once i get there
20:53:44<dcoutts>ndm: because you have to worry about the size of the state space with SC
20:53:47<ndm>dcoutts, sc has existentials and uniques - but is a superset of qc
20:54:04<ndm>i've never had to worry with sc
20:54:15<ndm>but lazy small check is a lot better for that, which is what i always jump for
20:54:35<dcoutts>ndm: if your branching factor is too high then you cannot test to depth N where N = ??
20:55:28<ndm>dcoutts, lazy small check :) - it matters less about the branching factor of the data type, and more about the branching factor of your test
20:55:29<dcoutts>ndm: if there is a way to limit the total number of tests with SC then that point is moot
20:55:42<sclv_>yeah, don't mean to be pushy, just looking for use-cases/feedback.
20:55:46<ndm>and if your test has a high branching factor, more tests is probably a good idea
20:56:00<dcoutts>ndm: sure but time is a limitation
20:56:04<ndm>sclv, no worries - will probably be a few weeks but do want to give it a whirl
20:56:33<ndm>dcoutts, i've been using it to "prove" parts of my phd - small phd (relatively), and large computers for a weekend :)
20:56:51<dcoutts>ndm: one thing I worry about for SC/QC is that different tests actually need different test generators for the same types in different tests
20:57:01<monochrom>wow, ghc src + extralib build tree (source + binary) is approaching 1GB. :)
20:57:57<dcoutts>ndm: especially in SC actually, eg Char, in testing bytestring. What chars values do you allow?
20:58:05<ndm>dcoutts, you are like a sales pitch for lazy small check - you just generate everything
20:58:09<dcoutts>ndm: not too many or the branching factor is insane
20:58:30<ndm>dcoutts, lazysmallcheck reigns in the branching with some very clever tricks :)
20:58:41<dcoutts>ndm: it's not about the number that get eliminated, it's the number you actually test with
20:58:52<ndm>dcoutts, it eliminates them before generating them
20:59:07<ndm>i.e. if you test all (== 'a') xs
20:59:09<dcoutts>ndm: so you just add lots of ==> filters and it's all ok
20:59:21<ndm>it will generate x:xs, for all x in Char
20:59:34<ndm>but will only generate 'a':x:xs
20:59:54<ndm>dcoutts, you do nothing, it understands your code, and doesn't even generate "dull" cases
21:00:16<ndm>==> filters do the trick, but so does anything, the property itself, whatever
21:00:29<dcoutts>ndm: how does it know from looking at all (== 'a') xs that we only want 'a' values in some cases?
21:00:54<dcoutts>isn't the (a -> Bool) part of the property a black box?
21:01:01<ndm>dcoutts, laziness - it tries with 'b':_|_, sees you never evaluated _|_, and figures that all other tests are irrelevant
21:01:11<dcoutts>ohhh, sneaky
21:01:17<dcoutts>using _|_'s
21:01:17<ndm>its a black box unless you have impure exceptions, or IORefs
21:01:23<ndm>yeah, its very neat
21:01:44<ndm>means you don't need to trick out your generators, and it exploits laziness in properties automatically
21:02:01<dcoutts>ndm: sounds very much like the strictness adaptations I made to SC but with a different purpose
21:02:29<dcoutts>ndm: LSC uses it to see what was evaluated and guide further tests, I was using it to actually test properties at all partial values
21:02:57<ndm>yes, does sound similar
21:03:05<dcoutts>ndm: and there's an example where you do need different properties again, eg with partial values you don't need any pre-conditions :-)
21:03:50<dcoutts>mind you strictness properties are always going to be different
21:04:15<ndm>yeah
21:04:22<dcoutts>it might be useful to test ordinary properties with partial values too though
21:04:25<ndm>although a sufficiently generic generator could get them all
21:04:39<ndm>hmm, not sure - you are likely to get partial values back
21:04:41<dcoutts>eg to distinguish reverse . reverse /= foldr (:) []
21:05:01<ndm>ok, partial as in infinite, rather than _|_
21:05:05<dcoutts>both
21:05:08<dcoutts>all partial values
21:05:25<dcoutts>eg _|_, _|_ : _|_, 0 : _|_, etc etc
21:05:54<dcoutts>the ordinary SC generators but extended to generate _|_ as the initial value for every type
21:06:10<dcoutts>so you generate all partial and total values in domain order
21:06:11<ndm>yeah
21:06:46<dcoutts>and you can borrow the === and <== domain equality and refinement operators from the ChasingBottoms lib
21:06:57<dcoutts>that's basically what I did
21:07:35<dcoutts>perhaps I should talk to Colin about doing and releasing a variation like that
21:08:34<ndm>yep, you should!
21:09:21<monochrom>chasing bottoms sounds fun
21:09:52<dcoutts>@slap monochrom
21:10:08<dcoutts>@botsnack?
21:10:38<dcoutts>monochrom: ah well, no wet fish for you
21:10:44<monochrom>haha
21:11:41<jaj>@b52s
21:12:03<jaj>lazy evaluation...
21:14:58<dcoutts>@seen dbueno
21:15:33<dcoutts>doh! lambdabot must be asleep
21:15:47<EvilTerran>doh
21:16:12<jaj>@slap lambdabot
21:17:55<hpaste> petekaz pasted "Strictness question" at http://hpaste.org/8032
21:18:11<hpaste> conal pasted "rewrite example -- why doesn't id inline?" at http://hpaste.org/8033
21:19:22<conal>i'd appreciate tips on my paste. i'm trying to figure out when i can count on inlining to help with rule applicability.
21:19:52<dons>conal: ah, maybe both id and reverse inline at the same time
21:20:03<dons>you'd have to delay inlining on 'reverse' I think
21:20:05<petekaz>I'm reading dons on exploiting strictness, laziness, and recursion. In his definition of length', I asked at one point why 'go' doesn't accumalate thunks due to the (n+1). Someone told me ghc figures it out all by itself. So why then do I need to be explicit in my definition of 'mean'?
21:20:06<SamB>hmm.
21:20:17<conal>dons: oh
21:20:25<conal>dons: oh! that makes sense.
21:20:39<conal>dons: and my rule pseudo-inlined id early
21:20:43<SamB>dons: did you know that unstream doesn't seem to have any progress guarentees?
21:20:50<dons>conal, yeah, that's it.
21:20:54<dons>i just got it to work.
21:21:10<conal>dons: thanks. okay, now i'll see what i can make of my *real* example.
21:21:16<dons>SamB: sure. you can Skip forever. its not "progress" though, talk to dcoutts.
21:21:22<monochrom>Perhaps using a tuple blinds the strictness analyzer.
21:21:35<SamB>dons: why do you say it's not progress?
21:21:43<hpaste> dons pasted "control inlining of what you wish to match" at http://hpaste.org/8034
21:21:47<SamB>coq won't let me write it, that's all I'm sayin' ;-)
21:21:49<dons>conal: ^
21:22:30<ddarius>petekaz: go is strict in n, that foldl' is not strict in the components of the tuple (without the !s) although the overall function is strict.
21:22:45<ddarius>petekaz: Personally, I dislike relying on anything but very basic strictness analysis.
21:24:13<conal>dons: :). simple enough. does all inlining happen after all rewriting?
21:25:11<petekaz>ddarius: ok, thanks.
21:25:51<petekaz>ddarius: I guess when I read his post, I would have preferred to see 'go' written wia bang pattern just to be explicit.
21:26:08<petekaz>I'm a newbie so what do I know anyways.
21:26:10<dons>conal: its interleaved. see -ddump-simpl-iterations
21:26:22<dons>you get a phase of different inlinings, then rules, then repeat 3 or 4 times
21:26:24<dons>or more..
21:26:30<ddarius>petekaz: Extraneous strictness annotations can decrease performance and that go in length is strict.
21:26:49<ddarius>(in this case, I doubt it would hurt)
21:26:53<dons>i think if you've determined the precise strictness you want, making it explicit is a good idea though
21:27:03<dons>as for type annotations
21:28:49<petekaz>ddarius: why is the go in length strict? is it only because of the strictness analysis? or are you saying it is strict regardless?
21:29:20<petekaz>wouldn't the (n+1) just start accumulating thunks?
21:29:37<dons>since it is an Int, ghc can see through to the strictness of +#
21:29:48<monochrom>ghc -O0 will thunk it.
21:29:52<dons>which works for nice atomic types like Word, Int, etc.
21:29:58<dons>but relies on -fstrictness
21:29:58<monochrom>@quote thunk
21:30:00<ddarius>I'm saying semantically go is strict whereas that foldl' is not strict in the components of the pair without those bangs.
21:30:28<dons>right. foldl' is kinda broken :)
21:30:37<ddarius>dons: How so?
21:30:37<dons>we need foldl_rnf
21:30:56<dons>its only whnf strict in the accumulator, partially, which confuses people
21:31:00<ddarius>Blech, we need a library of strict types (which we have now, no?)
21:31:04<dons>right.
21:31:11<dons>cabal install strict , peoples!
21:31:20<dons>probably should be in base though, with more access to the NF class
21:31:34<ddarius>It should only reduce to whnf. rnf is almost certainly way too much.
21:31:58<dons>yeah, it'd be interesting to think about what it would take to get (Int,Int) into (# Int#, Int# ) in an accumulator
21:32:14<monochrom>superfoldl' :: NFData b => (b -> a -> b) -> b -> [a] -> b :)
21:32:15<dons>rnf would work, but could whnf + a bit of the nested CPR analysis (or something like it)
21:32:35<dons>really, folds are great if you can use tuples to describe register variable layout
21:33:01<dons>ACTION thinks we understand what ghc does a lot more than 5 years ago
21:33:14<ddarius>rnf would turn foldl' (flip (:)) [] from O(n) into O(n^2)
21:33:33<SamB>ACTION defines instead a function streamSteps which returns the coq equivalent of [Maybe a] (with a co-inductive list type)
21:33:55<dons>SamB: oh, you should check Jeremy gibbons paper with the correctness proof for streams
21:34:00<dons>formalising that would be an awesome HW paper...
21:34:08<dons>or mechanising metatheorey
21:34:26<dons>you could write it with swiert
21:34:32<dons>he's done a few coq papers, iirc
21:35:35<dons>SamB: http://www.comlab.ox.ac.uk/jeremy.gibbons/publications/adt.pdf
21:35:35<SamB>heh
21:36:02<dons>seriously, proving some nice thinks about the stream-fusion combinators would be an ICFP worthy paper
21:36:44<SamB>I mean ... like I have time to actually write a paper!
21:36:47<SamB>I've got classes
21:37:03<dons>well, do the proofs, i'll help you write the paper :)
21:37:13<dons>ACTION loves how academia works
21:38:04<SamB>hmm, nice hint here...
21:38:22<SamB>two types are different if there is an experiment that shows this, and not different otherwise
21:38:25<SamB>er.
21:38:27<SamB>values.
21:39:19<dcoutts>observational equality
21:39:53<SamB>yes, but the key there is that I should define inequality inductively, and simply define equality as the negation
21:40:25<dons>jeremy's paper is quite nice. i should reread it every 6 months till i remember the approach
21:41:15<dons>dcoutts: was jeremy's paper published in the end?
21:41:33<dcoutts>dons: not at ICFP last summer, perhaps elsewhere
21:41:46<dons>its the kind of thing we want to integrate into the jfp stuff
21:41:52<monochrom>Nice, it begins with "Dijkstra". :)
21:42:01<dons>that, and janis' two papers that cover streams
21:42:39<dons>and the constructor specialisation paper. and now also the story for SAT in ghc, and nested CPR
21:42:47<dons>fills out the performance story, and the correctness story
21:43:10<dons>we can end the paper with one of those little QED boxes. []
21:43:14<dcoutts>dons: yes I need to re-read it for one of my thesis chapters
21:43:57<dons>dcoutts: http://scholar.google.com/scholar?hl=en&lr=&safe=off&cites=8061486271207904370
21:44:22<dons>crikey, we got cited in a javascript paper..
21:44:45<dcoutts>heh heh
21:44:51<SamB>isn't that good?
21:44:53<dons>dcoutts, "Putting declarative programming into the web: translating curry to javascript"
21:44:58<dons>well, so it is a haskell guy.
21:45:30<monochrom>http://www.comlab.ox.ac.uk/jeremy.gibbons/publications/#adt says "submitted for publication, January 2008" but it doesn't say where and what is happening.
21:46:06<monochrom>ACTION personally prefers links like that to going straight to the pdf.
21:46:20<dons>jan 08, ok. so that's something new.
21:46:29<SamB>monochrom: me too
21:47:14<dcoutts>dons: I'll have to find out since I'll be citing it
21:47:18<monochrom>My heuristic guesses that it is submitted to something like Formal Aspects of Computing due to the long time between submission and hearing back. :)
21:47:39<BONUS>ugh i still can't decide whether to buy Programming in Haskell or not :[
21:48:30<dcoutts>BONUS: let me help you: yes. :-)
21:48:45<dcoutts>BONUS: did you read my review?
21:50:04<ddarius>ACTION has inadvertently stumbled over an answer to his lollimon syntax question.
21:50:07<BONUS>no i didnt
21:50:32<BONUS>i kind of heard that it's good but very, er, beginner-ish
21:50:48<BONUS>and i already know all the beginner stuff and some intermediate stuff
21:51:20<ddarius>Get Algebra of Programming
21:51:24<dcoutts>BONUS: http://www.cs.nott.ac.uk/~gmh/coutts.pdf
21:51:26<monochrom>Haha
21:51:47<BONUS>thanks i'll read that
21:51:48<BONUS>hmm
21:52:20<BONUS>dcoutts what did you use to typeset this?
21:52:45<dcoutts>BONUS: latex with The Monad.Reader style sheet
21:53:14<BONUS>yeah i thought it was latex but it looks more awesome hehe
21:53:17<dons>docon is still compiling..
21:53:24<BONUS>what's the documentclass used
21:53:47<dcoutts>BONUS: yeah it's nice, check The Monad.Reader advise for authors, it's got all the stuff
21:53:53<dons>this thing is amazing, Igloo , [67 of 83] after an hour.
21:53:53<dcoutts>advise/advice
21:54:13<BONUS>kewl
21:54:13<dcoutts>dons: heh heh
21:54:21<dcoutts>dons: at -O2 right?
21:54:41<dcoutts>dons: clearly we need parallel build in Cabal
21:54:47<dons>dcoutts: yeah. -O2
21:55:10<dons>serge's done an awful lot of work here. docon is one of the most underappreciated large haskell systems
21:55:22<dcoutts>ACTION wastes 3/4 cores, 3/4 of the time
21:55:30<dcoutts>dons: yes, he's terrible at publicity :-)
21:55:34<Lycurgus>on what kind of CPU?
21:55:35<dons>hey, reminds me, i wonder if my fibonacci primes is still running
21:56:02<dons>aweseoe, 275432.58835s 34 prime=104911
21:56:17<Lycurgus>(i.e the docon compile)
21:56:29<dons>i've been borrowing 3 cores on a server for a week now.
21:56:42<dcoutts>I bet it's warm
21:57:03<dons>well, we just have to get to prime 40 for new results.
21:58:16<dcoutts>dons: is that CPU seconds or real seconds?
21:58:24<dcoutts>dons: ie 3 CPU days or 1 real day?
21:59:03<dcoutts>dons: and the time doubles for each one right?
21:59:09<dons>roughly doubles, yep.
21:59:39<dons>its this program , with a few custom dons(TM) tweaks,
21:59:40<dons>http://haskell.org/haskellwiki/Fibonacci_primes_in_parallel
21:59:44<dcoutts>dons: so you're looking at ~64 days for 40
21:59:48<dons>the most useful program with `par` in it i've seen so far.
22:00:03<dons>hey, that's not too bad. the guy i'm competing against had 3.5 years to get to 37
22:00:11<dcoutts>ooh
22:01:15<dons>http://www.gristle.to/markup/primes/ppfibs.html
22:01:33<dons>actually, he says, "34. fibonacci (104911) is probably prime "
22:01:44<dons>so i think that means he found a bug in his program, and had to start over.
22:02:26<shepheb>if I want to fiddle with 6.9 on x86 Linux 32bit, should I grab the HEAD? Is there a way to check if there are any recent nightly builds that worked on my platform?
22:03:25<hpaste> Twinside pasted "(no title)" at http://hpaste.org/8036
22:03:38<Twinside>why ghc give me an error when i put a type signature which is the same that the inferred one?
22:08:15<MyCatVerbs>Twinside: that sounds strange. hpaste the code and the error, please?
22:08:38<Twinside> http://hpaste.org/8036 :)
22:09:28<BONUS>what does fix do
22:10:16<dons>recursion
22:10:18<dons>?src fix
22:10:35<dons>lambdabot's not a happy person of late
22:10:40<BONUS>haha
22:10:50<MyCatVerbs>BONUS: fix f = f (fix f)
22:10:52<BONUS>i was looking for it in the 98 report but its not in there
22:10:57<BONUS>ah
22:11:06<MyCatVerbs>BONUS: builds an infinite chain of f (f (f (f (f (f...
22:11:10<BONUS>whats the practical use
22:11:19<MyCatVerbs>BONUS: none whatsoever.
22:11:25<MedeaMelana>That's not true
22:11:29<MyCatVerbs>BONUS: just another way of writing recursions.
22:11:40<MedeaMelana>Though don't ask me for a good example
22:11:43<BONUS>ah
22:11:44<BONUS>haha
22:12:01<MyCatVerbs>For example, repeat a = fix (a:), equivalent to repeat a = a : repeat a.
22:12:16<MyCatVerbs>Which expands to a:(a:(a:(a:(... etc.
22:12:33<MyCatVerbs>Twinside: I have noooo idea. That is making me scratch my head.
22:12:40<Twinside>yeah me too
22:12:49<Twinside>if I remove the type signature, it compile just fine
22:13:24<dons>does it assume -fglasgow-exts perhaps?
22:13:36<Twinside>yep
22:13:45<Twinside>i've got the extensions enabled
22:13:58<BONUS>@src filterM
22:14:02<monochrom>BONUS: http://www.vex.net/~trebla/haskell/fix.xhtml "you could have invented fix too"
22:14:10<BONUS>haha
22:14:11<BONUS>cool
22:14:56<monochrom>When you're tired of "let" and "where", and you still need recursion, consider "fix".
22:16:27<MyCatVerbs>:t let hork f g = f (hork g f) in hork -- I think I actually used this once, but then later came to my senses.
22:16:37<MyCatVerbs>Oh blast, damnation and \bot.
22:16:41<BONUS>lol
22:17:10<BONUS>haha i read the you could have invented monads too article
22:17:13<BONUS>and i was thinking to myself
22:17:21<BONUS>no way, i probably wasn't even born when they were invented wtf
22:22:10<gwern>BONUS: in a counterfactual universe you could have!
22:22:36<ddarius>BONUS: Well I believe they were first invented/discovered in the 1960s
22:23:07<BONUS>hm wow
22:23:15<BONUS>how old is haskell again?
22:23:33<gwern>15 years or so
22:23:59<BONUS>ah well at least i'm older than haskell then
22:25:24<BONUS>hehe http://en.wikipedia.org/wiki/Timeline_of_programming_languages
22:25:34<BONUS>it looks like i'm as old as perl (1987)
22:27:03<dons>ACTION is going to wikify answers to any questions on the mailing list now.
22:27:07<ddarius>BONUS: 1987 was when Haskell first started being formulated. 1989 is when the Haskell 1.0 Report was made.
22:27:46<BONUS>ah
22:27:47<BONUS>awesome :D
22:28:03<ddarius>So Haskell is going on 20.
22:28:04<gwern>dons: a valiant goal, but google taught us that having answers is not the problem, but finding them
22:28:24<dons>gwern: right. refactoring will help here
22:28:31<dons>i think this approach has worked well for xmonad
22:28:43<dons>its just time and tenacity
22:29:03<andyjgill>Should all new packages use the Cabal 1.2 syntax for the .cabal file?
22:29:16<andyjgill>What is recommended?
22:29:18<dcoutts>andyjgill: if you want the new features, yes.
22:29:38<andyjgill>What are the requirements? 6.8.2+?
22:29:40<dcoutts>andyjgill: if your package is trivial it doesn't really matter, we're not going to kill off the old syntax any time soon
22:30:16<dcoutts>andyjgill: Cabal-1.2 was bundled with ghc-6.8.x if that's what you mean, one can of course install it for any version of ghc since 6.2
22:30:17<dons>we've a wiki page with the old and new library deps
22:30:38<dons>andyjgill: http://www.haskell.org/haskellwiki/Upgrading_packages
22:30:52<andyjgill>great.
22:31:58<andyjgill>I think we'll just use cabal-1.2 syntax. It seems cleaner. Any issues to want for?
22:32:50<andyjgill>want=>watch
22:32:57<dcoutts>andyjgill: ahh :-) no, not really
22:33:12<dons>just checking that you get any lib dependencies correct
22:33:18<dcoutts>andyjgill: except that older cabal will not understand it at all (no helpful error message)
22:33:29<andyjgill>Thanks!
22:33:50<dcoutts>dons: that's upgrading ghc-6.8, not cabal
22:34:00<andyjgill>What is *build-type*?
22:34:07<dcoutts>andyjgill: usually Simple
22:34:20<dons>or Configure if you run a configure script
22:34:27<dcoutts>andyjgill: unless you need a custom Setup.hs or ./configure script
22:34:42<andyjgill>Ahh. okay.
22:35:04<dcoutts>or *shudder* make
22:35:39<dons>but no one is that crazy, dcoutts
22:35:42<dcoutts>ACTION notes that out of the 1 cabal packages on hackage that use the Make build-type, 0 get it correct
22:36:04<dons>heh. that's a pretty poor percent
22:36:14<dons>just remove the Make option?
22:36:45<dcoutts>it's because if you use Make you essentially have to implement your own Haskell build system from scratch
22:37:07<dcoutts>so you end up ignoring many of the build flags/options that users expect
22:37:11<dons>wow, docon is really really stressing ghc. its not allocating a lot of memory, but it is now taking 10-20 minutes per module
22:37:42<dons>ACTION takes this as a sign that serge has done something interesting
22:37:51<dcoutts>dons: wx uses it and it needs some fairly complex build stuff
22:38:10<mm_freak>i'd like to write an MPD frontend using Gtk2hs and Network.MPD, but i can't figure out, how to keep the connection open for the program's lifetime, while allowing it to change… should i use concurrency?
22:38:33<dons>mm_freak: a process handle and a reader forkIO thread would work.
22:38:51<dons>mm_freak: see hmp3, perhaps, which talks to mpg321 over a channel, via a concurrent thread
22:39:05<mm_freak>dons: i used to use Chan for such things
22:39:26<dons>yeah, that's a good way. you just have a reader or writer thread communicating with the main program over a lazy chan
22:39:39<mm_freak>ok, thanks
22:39:56<dcoutts>mm_freak: that's a reasonable idea, use a Chan and that way you can switch network connection without the reader end of the Chan noticing
22:40:32<dcoutts>mm_freak: you can just kill off the old writer that was connected to the old network channel and fire up a new one to read from the new connection and keep writing into the Chan
22:41:02<dcoutts>or did I misunderstand the problem?
22:41:20<mm_freak>yes, that was my initial idea… it's just the monadic interface to MPD, which confused me
22:41:31<mm_freak>i'm used to handles and functions on them
22:46:10<mm_freak>seeing that MPD is a MonadIO, is there a better way to do it? or is that only useful, when the main part of the program consists of MPD actions and IO is only used for some output messages?
22:47:01<dcoutts>mm_freak: so does MPD only handle output or also input from the network?
22:47:43<mm_freak>dcoutts: everything
22:47:59<mm_freak>inside the MPD monad, you can get song info and stuff, add songs, etc.
22:48:24<dcoutts>mm_freak: hmm, so how do you tell it what channel to use?
22:48:38<dcoutts>channel/connection whatever
22:49:18<mm_freak>dcoutts: using withMPDEx, which you give connection informations and an action to run on that connection
22:49:31<mm_freak>or using withMPD, which is a simple interface to withMPDEx
22:49:45<dcoutts>mm_freak: so it doesn't let you change connection later
22:49:50<mm_freak>yes
22:50:37<mm_freak>there is a 'reconnect' function, but it doesn't allow altering connection info
22:50:47<dcoutts>ahh
22:51:03<dcoutts>mm_freak: and that's exactly what you want to do?
22:52:57<dcoutts>mm_freak: if so, I don't see any obvious workaround, you may just have to change the MPD stuff to be more flexible with the connection handling (either just to allow better reconnects or perhaps letting you manage the input and output separately)
22:53:01<mm_freak>my question is whether the liftIO is useful at all
22:53:32<mm_freak>other than for outputting simple status messages
22:54:25<Saizan>mm_freak: it's useful as much as the IO monad, no?
22:54:40<SamB>ACTION wonders why gibbons claims that ordinary ADTs are data, not codata
22:55:15<mm_freak>Saizan: in the MPD monad, specifically, but i think i see that i actually need it, at least to read from the channel
22:55:33<mm_freak>otherwise i'd need to close the connection to do it
22:56:44<Saizan>yeah, that was what i meant
22:57:11<dcoutts>SamB: hmm? I thought he does say ADTs are codata. In the abstract and intro.
22:57:36<SamB>dcoutts: section 3
22:57:36<dcoutts>SamB: which page are you looking at?
22:58:32<SamB>"as opposed to the ordinary data inhabiting the more familiar algebraic datatypes introduced by constructions such as Haskell's data declaration
23:00:07<Philippa_>dcoutts: algebraic datatypes are both in Haskell, but not in strict languages
23:00:27<Philippa_>SamB: the distinction is essentially that codata is coalgebraic
23:01:07<dcoutts>Philippa_: yes, and he does mention that on the following page
23:01:26<SamB>he "as opposed to" implies the negation of "haskell data declarations declare codata"
23:01:28<Philippa_>SamB: there's this "coincidence" whereby in CPO, initial algebras and final coalgebras are isomorphic
23:02:26<Philippa_>really it's that haskell's not an ideal choice of example language, that's all
23:03:20<dcoutts>SamB: he makes that point in the following paragraph
23:03:51<SamB>he could never get away with this in a formal proof
23:04:14<Philippa_>he's not presenting something formal
23:04:26<SamB>yes, it's easy to tell because he wrote it in english ;-)
23:04:48<Philippa_>no. The thing being presented with english around it /itself/ is not formal
23:05:12<SamB>what "thing" is that?
23:05:48<Philippa_>a slightly handwavy notion of 'codata', in the same sense that many people in here have a slightly handwavy notion of 'data' that makes no reference to initial algebras
23:06:14<Philippa_>and a similarly handwavy encoding into haskell
23:06:16<dcoutts>SamB: it's an illustration, haskell data is normally intended as data, not co-data
23:06:42<Philippa_>right. Half the point is "here is an idea, anyone else fancy playing with it?"
23:06:49<SamB>> cycle "orly"
23:07:04<SamB>where did lambdabot go???
23:07:28<jleedev>@seen lambdabot
23:07:32<SamB>hahaha
23:13:20<SamB>hmm, very frustrating not being able to convert the streams back to lists :-(...
23:15:54<dcoutts>SamB: ?
23:16:06<SamB>I'm not allowed to do that
23:16:13<ddarius>SamB: data isn't codata, that's the nature of the beast.
23:16:23<SamB>since it would not have productivity guarentees
23:16:34<SamB>even with lists as codata
23:16:48<dcoutts>oh it's just because one is a bigger type than the other
23:17:09<dcoutts>you have to restrict yourself to the list subset of Stream
23:17:31<dcoutts>or at least to respecting the equivalences classes in Stream that we map to list
23:18:01<SamB>I don't have a clue how to convince Coq that I'm doing that ;-)
23:18:20<dcoutts>hmm, can you define the equivalence classes precisely?
23:18:43<dcoutts>so there are two problems, co-data to data
23:18:50<SamB>that isn't it
23:18:55<dcoutts>and mapping back into a type without Skip
23:19:02<SamB>that IS it
23:19:17<dcoutts>and you're working in a system without _|_ too right?
23:19:25<SamB>indeed
23:19:27<ddarius>ACTION should be able to parse anything LolliMon parses now...
23:19:31<dcoutts>since of course lack of progress is just _|_
23:19:54<dcoutts>SamB: so you need to guarantee you're not in the pre-image of _|_ in List
23:20:09<SamB>I don't know how to do that either ;-)
23:20:12<dcoutts>there's the equivalence class in Stream that is mapped to _|_
23:20:17<dcoutts>define it, prove you're not in it
23:20:32<dcoutts>basically no infinite sequences of Skip
23:20:55<SamB>yeah
23:20:59<SamB>hmm.
23:21:15<SamB>I guess that could actually help me get where I want to go.
23:21:49<dcoutts>so whenever you make one you have to prove that if you're using Skip that you don't keep making more
23:22:13<SamB>but right now I'd like to define an equality relation that I can prove all three properties for ;-)
23:22:36<mm_freak>@src undefined
23:22:46<mm_freak>@src error
23:22:54<dolio>undefined = error "Prelude.undefined" or something like that.
23:23:02<mm_freak>> "I am here" :: String
23:23:07<dcoutts>na, undefined = undefined :-)
23:23:07<mm_freak>hmm
23:23:15<dolio>> undefined
23:23:37<SamB>dolio: it looks like lambdabot decided to just not terminate this time around?
23:23:40<SamB>ACTION teases dolio
23:23:42<dolio>The error message disagrees with you, I think. :)
23:23:42<mm_freak>how does 'error' work?
23:24:05<dolio>Magic.
23:24:18<SamB>mm_freak: it depends on whether or not you import Control.Exception
23:24:19<mm_freak>certainly, but what kind of magic? unsafe magic?
23:24:35<kadir>hello
23:24:39<kadir>getSelection :: MonadIO m => m String
23:24:44<SamB>if you don't, it doesn't really matter...
23:24:48<kadir>how to get String here
23:24:53<monochrom>mm_freak: I think you could elaborate your question.
23:24:57<dolio>It's probably hard wired to the runtime system or something. Although semantically you could write it as 'error s = error s' or any number of other things.
23:24:59<SamB>if you do, it raises an exception ;-)
23:25:20<mm_freak>yes, it drops me back to the IO monad, even from pure functions
23:25:25<mm_freak>that's what confuses me
23:25:37<SamB>mm_freak: because catching it is not pure
23:25:45<dcoutts>mm_freak: it's wired in to the rts, in yhc it terminates the prog, in ghc it raises an exception
23:26:08<mm_freak>ok
23:26:14<dcoutts>or maybe yhc uses exceptions now, in nhc98 it terminates the prog
23:26:37<mm_freak>so i shouldn't assume any particular implementation in "error"
23:27:13<dcoutts>mm_freak: not if you can help it
23:27:19<mm_freak>like a bottom value for errors
23:27:32<dcoutts>semantically it is bottom
23:27:38<mm_freak>ok, thanks
23:29:02<conal>mm_freak: the reason error handling is handled in IO, is that the semantics of pure values (including functions) is too simple to capture exceptions. IO has intractable semantics anyway, so exceptions etc are dumped there (the "sin bin").
23:29:59<mm_freak>conal, SamB: thank you, but that wasn't the source of my confusion… it's just that my understanding is that you can't throw exceptions in pure functions
23:30:12<SamB>mm_freak: but you can
23:30:15<augur>tuples are like lists right?
23:30:23<mm_freak>augur: no
23:30:23<SamB>there's nothing impure about that
23:30:25<augur>no?
23:30:29<conal>augur: yes & no
23:30:32<SamB>augur: only in Python
23:30:34<augur>well
23:30:39<augur>well what i mean is
23:30:42<augur>they can take any value
23:30:45<newsham>mmm python
23:30:48<augur>but only if they're all the same type right?
23:30:52<mm_freak>augur: they can be heterogenous and have a fixed length
23:30:55<newsham>> ("test", 23)
23:30:59<augur>oh i see.
23:31:07<newsham>?bot
23:31:09<lament>augur: they're the same as tuples in math.
23:31:23<ddarius>Curses!
23:32:31<kadir>i couldn't find any way to grab String from a monadic one
23:32:33<mm_freak>@src throw
23:32:35<mm_freak>oh
23:32:43<mm_freak>what's wrong with lambdabot ?
23:32:52<newsham>?bot temporary
23:32:52<noBotE>:)
23:32:54<kadir>could i ask for help?
23:33:15<newsham>kadir: you could
23:33:48<mm_freak>SamB: true, then it drops me back to IO, but how is 'throw' implemented?
23:33:57<kadir> getSelection :: MonadIO m => m String
23:34:01<mm_freak>does it need to use a special language feature?
23:34:04<SamB>mm_freak: magic!
23:34:09<mm_freak>ok
23:34:11<kadir>i want String here :)
23:34:20<kadir>but can't do
23:34:36<mm_freak>kadir: (>>=) or some monad-specific function
23:34:44<SamB>as in "rts functions"
23:35:10<mm_freak>SamB: i understand… i just thought that there is no such magic in haskell =)
23:35:48<mm_freak>if i wanted to write 'myThrow', would there be any way without resorting to 'throw'?
23:35:57<SamB>not really
23:35:59<kadir>i want somehow to concat another string to this string if i extract string from the function
23:36:09<mm_freak>ok
23:36:21<mm_freak>kadir: what is 'm'?
23:36:29<kadir>(foo $ getSelection) ++ "bar"
23:36:37<kadir>couldn't i do this?
23:36:41<mm_freak>no
23:37:06<mm_freak>unless foo is a function specific to a particular 'm', which removes the monad
23:37:40<kadir>of course i trying to write a function exactly you mention to do
23:37:45<kadir>but i couldn't
23:38:03<SamB>dcoutts: well I've found a definition which I can prove reflexivity for...
23:38:16<kadir>Control.Monad.Trans.MonadIO
23:38:23<kadir>what the 'm' is
23:38:36<dcoutts>SamB: sounds good
23:38:53<mm_freak>kadir: you can't, at that general level
23:39:23<mm_freak>value extraction is an optional feature for some monads… usually by some 'run' or 'eval' function
23:40:25<SamB>I'm defining the primitive equality in terms of a Coq equivalent of [Maybe a], since I *can* convert streams to those...
23:41:08<kadir>ohh :( is haskell structred on the big branch: Monad - non-Monad ?
23:41:51<kadir>i could'nt obtain simply a String created from a monadic function
23:41:57<mm_freak>kadir: no, but monads are an integral thing to haskell
23:42:37<mm_freak>you could, either inside of the monad, or with a special function to 'unwrap' the value
23:42:54<mm_freak>for example, you do it all the time inside the IO monad
23:43:07<mm_freak>do { args <- getArgs; print args }
23:43:16<mm_freak>getArgs :: IO [String]
23:44:00<malebria>YAHT is for people with some experience in programming, right? What would you recommend for complete begginers in programming?
23:44:01<kadir>but i want that args to concat with another string outside there
23:44:11<kadir>isn't that possbile
23:45:10<mm_freak>kadir: it is… inside IO =)
23:45:14<Torment>kadir: do { [string] <- getArgs; print (pureString ++ string) }
23:45:48<mm_freak>do { args <- getArgs; print (map (++ "blah") args) }
23:46:21<kadir>could i tell what i want to do?
23:46:50<mm_freak>sure, maybe that helps
23:46:59<kadir>i only wanted to add one usefull keybinding in xmonad
23:47:11<kadir>but couldn't succeed :(
23:47:19<malebria>Is there a page comparing GHC with other haskell interpreters/compilers?
23:47:23<kadir>here is keybinding
23:47:31<kadir> ((modMask .|. controlMask, xK_b), runInTerm "echo \"" ++ getSelection ++ "\" | vim -")
23:47:38<ivanm>kadir: you need to use something like M.union
23:48:02<mm_freak>kadir: maybe you just need to add parentheses
23:48:10<malebria>As I see everybody using GHC most of the time, I ask myself what are the reasons to use the others.
23:48:18<mm_freak>runInTerm ("echo" ++ … )
23:48:29<ivanm>kadir: see how they do it here: http://code.haskell.org/XMonadContrib/XMonad/Config/Xfce.hs
23:48:39<Jedai>kadir: ((modMask .|. controlMask, xK_b), do { sel <- getSelection; runInTerm "echo \"" ++ sel ++ "\" | vim -")
23:48:41<dons>they have mainly only niche uses now, malebria
23:48:51<Jedai>kadir: ((modMask .|. controlMask, xK_b), do { sel <- getSelection; runInTerm "echo \"" ++ sel ++ "\" | vim -" } )
23:48:53<mm_freak>malebria: you should read the homepages for the other compilers/interpreters… they usually compare themselves to GHC
23:49:39<Jedai>Or something like that, I'm pretty sure there's a simple way to do it anyway
23:49:47<malebria>I'll take a look..
23:51:55<kadir>yep, it compiled :) but didn't work :(
23:57:55<malebria>mm_freak: this is true for nhc98, but I hugs page, I couldn't find such comparision.
23:58:41<mm_freak>malebria: because Hugs is one of the more frequently used interpreters… people 'just know' the differences, but maybe the FAQ tells you
23:59:13<ddarius>Parsing D ::= G -o D | D o- G | ... and G ::= D -o G | G o- D | ... where D \subset G is tricky.
23:59:49<ddarius>ACTION should probably just postprocess it.

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