Available formats: content-negotiated html turtle (see SIOC for the vocabulary)
Back to channel and daily index: content-negotiated html turtle
These logs are provided as an experiment in indexing discussions using IRCHub.py, Irc2RDF.hs, and SIOC.
| 00:02:26 | <int-e> | shachaf: Hmm. You'd still have to lift IO actions into your monad to use them wouldn't you? So I expect the difference in amount of code between a monad transformer (used on a user provided monad) and a monad transfromer transformer (used with a user provided transformer which is applied to the IO monad) to be small. |
| 00:03:51 | <shachaf> | int-e: But a function that doesn't use any part of the transformer (say, refresh :: IO ()) wouldn't need any extra, would it? |
| 00:05:15 | <shachaf> | int-e: That is, functions that use a part of UserT would have to, say, add (MonadIO m) =>, but functions that don't (part of the regular code, that assumes IdentityT) wouldn't. |
| 00:05:21 | <shachaf> | int-e: Or would they? |
| 00:08:58 | <int-e> | shachaf: hmm. this is all too vague. I'd like to stop here unless there's a concrete code example to discuss. |
| 00:12:49 | <shachaf> | int-e: Probably, yes. :-) |
| 00:12:53 | <shachaf> | int-e: I was just wondering. |
| 00:13:23 | <shachaf> | ACTION probably has no idea what he's talk about. :-) |
| 00:13:27 | <shachaf> | s/k/king/ |
| 00:45:29 | <ddarius> | There you go Philippa |
| 00:45:52 | <Philippa_> | ? |
| 00:45:56 | <Philippa_> | ah |
| 00:46:03 | <PeterMc> | Hi there, Philippa. |
| 00:46:11 | <Philippa_> | hi |
| 00:47:02 | <PeterMc> | Had much response to the lambda-the-ultimate announcement? (Apart from me wondering about Haskell vs. Asperger's Syndrome, that is.) |
| 00:47:19 | <dolio> | This Hugh Perkins fellow is quite something. |
| 00:47:40 | <Philippa_> | it's tricky to know what's specifically in response to the LtU announcement rather than other ones - nothing else on the site itself |
| 00:47:51 | <dons> | dolio: :/ |
| 00:48:21 | <PeterMc> | Scary, innit! |
| 00:48:35 | <PeterMc> | Trying to organise something, I mean. |
| 00:49:28 | <dolio> | I wonder what SuperO does for a high level prime sieve. |
| 00:49:39 | <Philippa_> | heh, yeah. ndm's been a big help though, and thankfully the 'established' tradition is such that doing everything ad-hoc and at the last minute^W^W^W^Won demand is what's expected |
| 00:53:34 | <dolio> | If 'print . length . words =<< getContents' can beat C, maybe a lazy list prime sieve can beat a C# loop. :) |
| 00:57:22 | <EvilTerran> | probably not a list as such. the O(n) lookup complexity would sting. |
| 00:59:12 | <dolio> | Well, I haven't looked at what they're doing with it closely, but I think they're traversing it once to see how many primes are below a certain value... |
| 00:59:13 | <EvilTerran> | ACTION was thinking about a lazy data structure of the form 'array (0,1) ... : [array (2^i,2^(i+1)) ... | i <- [0..]]' a while ago. that might suit itself to that sort of thing. |
| 00:59:21 | <ddarius> | EvilTerran: But you don't "lookup" stuff in that case. |
| 00:59:25 | <dolio> | So the O(n) may be moot. |
| 00:59:42 | <EvilTerran> | hm. i don't know what algorithm you're thinking of exactly, so i can't say. |
| 01:00:19 | <EvilTerran> | (that thing i just mentioned needs a '-1' inserted somewhere, and probably arranged a bit differently at the start, but you get the idea) |
| 01:02:17 | <hpaste> | int-e pasted "something like this? (for EvilTerran)" at http://hpaste.org/1701 |
| 01:02:56 | <int-e> | (this uses exactly such a data structure to memoize a recursive function on natural numbers) |
| 01:03:53 | <EvilTerran> | looks about right. am i right in thinking that yields O(log n) lookup time? |
| 01:04:01 | <int-e> | yep |
| 01:04:12 | <EvilTerran> | spiffing |
| 01:04:25 | <|Steve|> | There was an efnet math problem posed a while back about finding a function f such that for all natural number f(f(n)) = h(n) where h(n) was something like n^2 - 19n + 99. Is there anyway to speed this up, it gets extremely slow: http://pahtak.org/~steve/f.hs |
| 01:05:15 | <|Steve|> | Oh, g is the function, not h. and I got it right. |
| 01:07:42 | <dolio> | I can't seem to connect... |
| 01:07:56 | <|Steve|> | Oh, yeah, bit torrent is killing my connection. |
| 01:08:00 | <|Steve|> | I'll paste on hpaste. |
| 01:08:04 | <dolio> | :) |
| 01:08:58 | <PeterMc> | I can't get through to pahtak.org either. |
| 01:09:11 | <int-e> | I could but it took ages :) |
| 01:09:27 | <|Steve|> | _Something_ just really hates bit torrent. It's either my router or my ISP. |
| 01:09:40 | <|Steve|> | I pasted on hpaste, we'll see if it times out or not. |
| 01:10:15 | <shachaf> | |Steve|: (By the way, you can use "case comparse x y of LT -> ...; EQ -> ...; GT -> ..." instead of comparing up to three times.) |
| 01:10:56 | <ddarius> | where comparse = compare |
| 01:10:59 | <|Steve|> | Good point. I wrote this some time ago. I only learned about case recently. |
| 01:11:10 | <shachaf> | ddarius: Uh, yes. :-) |
| 01:11:31 | <shachaf> | |Steve|: The important thing is compare, not case. |
| 01:11:49 | <campusblo> | hi is there a function that will tell you the position of an element in a list ? |
| 01:12:01 | <shachaf> | |Steve|: You can always say "f (compare x y) where f EQ = ...;..." |
| 01:12:03 | <|Steve|> | I don't think the numbers are getting large enough that doing the comparison is actually a bottleneck. |
| 01:12:15 | <campusblo> | eg positionNum 6 [1,2,3,6,7] = 4 |
| 01:12:19 | <ddarius> | Bah, where is ordering :: Ord a => a -> a -> b -> b -> b |
| 01:12:29 | <TSC> | campusblo: elemIndex |
| 01:12:49 | <TSC> | > elemIndex 'e' "hello" |
| 01:12:50 | <shachaf> | |Steve|: (Which is why I only said this incidentally, in parentheses.) |
| 01:12:50 | <lambdabot> | Just 1 |
| 01:12:50 | <|Steve|> | Heh, timed out. |
| 01:12:51 | <hpaste> | Steve pasted "f.f = g" at http://hpaste.org/1702 |
| 01:12:54 | <campusblo> | in the prelude? |
| 01:12:57 | <|Steve|> | There we go. |
| 01:12:58 | <PeterMc> | The download from pahtak.org worked this time. |
| 01:13:02 | <PeterMc> | Now what? |
| 01:13:04 | <shachaf> | campusblo: In Data.List. |
| 01:13:19 | <campusblo> | ok thanks |
| 01:13:20 | <shachaf> | campusblo: Why would you need it to be in the Prelude? |
| 01:13:26 | <|Steve|> | Meh, it might get pasted twice. |
| 01:13:39 | <campusblo> | i just wanted to know where it was. |
| 01:13:51 | <ddarius> | @index elemIndex |
| 01:13:52 | <lambdabot> | Data.List |
| 01:14:15 | <shachaf> | @hoogle a -> [a] -> Int |
| 01:14:15 | <lambdabot> | No matches, try a more general search |
| 01:14:18 | <shachaf> | @hoogle a -> [a] -> b |
| 01:14:19 | <lambdabot> | Prelude.foldl :: (a -> b -> a) -> a -> [b] -> a |
| 01:14:19 | <lambdabot> | Prelude.foldr :: (a -> b -> b) -> b -> [a] -> b |
| 01:14:19 | <lambdabot> | Data.List.foldl' :: (a -> b -> a) -> a -> [b] -> a |
| 01:14:25 | <ddarius> | @hoogle elemIndex |
| 01:14:25 | <lambdabot> | List.elemIndex :: Eq => a -> [a] -> Maybe Int |
| 01:14:25 | <lambdabot> | Data.List.elemIndex :: Eq a => a -> [a] -> Maybe Int |
| 01:14:37 | <campusblo> | how would i import that into a file im working on? |
| 01:14:45 | <ddarius> | import Data.List |
| 01:14:48 | <shachaf> | campusblo: "import Data.List". |
| 01:15:14 | <ddarius> | Haskell and it's cryptic naming... </prick> |
| 01:15:25 | <campusblo> | so ill just copy that and put it at the top of the file |
| 01:17:25 | <campusblo> | ddarius why do i get the word "just" when i use that elemIndex function? |
| 01:17:36 | <campusblo> | i can't use that |
| 01:17:42 | <campusblo> | the just i mean |
| 01:17:45 | <shachaf> | campusblo: What if the element isn't in the list? |
| 01:17:47 | <ddarius> | > elemIndex 3 [1,2] |
| 01:17:48 | <|Steve|> | > elemIndex 5 [1,2,7,9] |
| 01:17:49 | <lambdabot> | Nothing |
| 01:17:50 | <lambdabot> | Nothing |
| 01:17:52 | <shachaf> | > elemIndex [5] [1,2,3,4] |
| 01:17:53 | <lambdabot> | add an instance declaration for (Num [t]) |
| 01:17:53 | <lambdabot> | In the expression: 4 |
| 01:17:56 | <shachaf> | > elemIndex 5 [1,2,3,4] |
| 01:17:57 | <lambdabot> | Nothing |
| 01:18:00 | <|Steve|> | > elemIndex 7 [1,2,7,9] |
| 01:18:01 | <lambdabot> | Just 2 |
| 01:18:15 | <|Steve|> | It's the Maybe datatype. |
| 01:18:29 | <|Steve|> | data Maybe a = Nothing | Just a -- Something like that. |
| 01:18:47 | <campusblo> | ok |
| 01:18:51 | <shachaf> | |Steve|: Just like that. :-) |
| 01:18:57 | <campusblo> | @paste |
| 01:18:57 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 01:19:18 | <|Steve|> | Whee. |
| 01:19:35 | <shachaf> | @instances Ord |
| 01:19:37 | <lambdabot> | (), All, Any, Bool, Char, Double, Either a b, Float, Int, Integer, Maybe a, Ordering, Product a, Sum a, [a] |
| 01:19:51 | <EvilTerran> | > () >= () |
| 01:19:52 | <lambdabot> | True |
| 01:19:53 | <EvilTerran> | heh |
| 01:20:00 | <|Steve|> | @instances Monad |
| 01:20:01 | <lambdabot> | ((->) r), ArrowMonad a, Cont r, ContT r m, Either e, ErrorT e m, IO, Maybe, RWS r w s, RWST r w s m, Reader r, ReaderT r m, ST s, State s, StateT s m, Writer w, WriterT w m, [] |
| 01:20:08 | <ddarius> | @src () compare |
| 01:20:08 | <lambdabot> | compare () () = EQ |
| 01:20:33 | <shachaf> | > Nothing `compare` Just 5 |
| 01:20:33 | <lambdabot> | LT |
| 01:20:38 | <shachaf> | > Just 3 `compare` Just 5 |
| 01:20:40 | <lambdabot> | LT |
| 01:20:59 | <|Steve|> | Nothing is less than Just 5? |
| 01:21:10 | <shachaf> | @src Maybe compare |
| 01:21:10 | <lambdabot> | Source not found. Have you considered trying to match wits with a rutabaga? |
| 01:21:20 | <ddarius> | It's derived. |
| 01:21:26 | <TSC> | Nothing is probably the minimum for all Maybe types |
| 01:21:35 | <|Steve|> | Odd. |
| 01:21:37 | <dolio> | > Nothing < Just undefined |
| 01:21:38 | <lambdabot> | True |
| 01:21:43 | <hpaste> | campusblo pasted "aaaarrgggggh" at http://hpaste.org/1703 |
| 01:21:53 | <campusblo> | so what's wrong with that? |
| 01:21:57 | <campusblo> | why do i get that error? |
| 01:22:08 | <ddarius> | > [Nothing..] :: Maybe Int |
| 01:22:08 | <lambdabot> | Parse error |
| 01:22:09 | <ihope_> | > Just undefined < Just undefined |
| 01:22:10 | <lambdabot> | Undefined |
| 01:22:12 | <ddarius> | > [Nothing ..] :: Maybe Int |
| 01:22:12 | <lambdabot> | Couldn't match expected type `Maybe Int' |
| 01:22:21 | <ddarius> | > [Nothing ..] :: [Maybe Int] |
| 01:22:22 | <lambdabot> | add an instance declaration for (Enum (Maybe Int)) |
| 01:22:22 | <lambdabot> | In the expression: [... |
| 01:22:25 | <ddarius> | Darn |
| 01:22:40 | <ihope_> | > [minBound..] :: [Int] |
| 01:22:42 | <lambdabot> | [-2147483648,-2147483647,-2147483646,-2147483645,-2147483644,-2147483643,-21... |
| 01:22:45 | <dolio> | > minBound :: Maybe Int |
| 01:22:46 | <lambdabot> | add an instance declaration for (Bounded (Maybe Int)) |
| 01:22:46 | <lambdabot> | In the expression... |
| 01:23:10 | <ihope_> | When can you derive Enum? |
| 01:23:17 | <Cale> | campusblo: postitonNum |
| 01:23:29 | <campusblo> | oh |
| 01:23:32 | <campusblo> | lol |
| 01:23:33 | <campusblo> | ok |
| 01:23:41 | <campusblo> | im tired |
| 01:24:37 | <campusblo> | i thought i was going crazy. nevermind me |
| 01:25:18 | <Cale> | positionNum x = maybe 0 (+1) . elemIndex x |
| 01:25:28 | <|Steve|> | Does haskell guarantee tail recursion like scheme does? |
| 01:25:38 | <TSC> | campusblo: Compiling with warnings on would help to find errors like that |
| 01:26:04 | <SamB> | |Steve|: not that I know of |
| 01:26:07 | <Cale> | |Steve|: I don't think the Haskell standard says anything at all about evaluation. |
| 01:26:10 | <SamB> | but it would be stupid not to implement it |
| 01:26:39 | <|Steve|> | So an conforming implementation could stack overflow on a simple read-eval-print loop? |
| 01:26:50 | <campusblo> | TSC im in hugs |
| 01:26:58 | <geezusfreeek> | |Steve|: i'm pretty sure that writing a tail recursive function can still help you to avoid a space leak in most cases |
| 01:27:01 | <TSC> | Hugs doesn't have warnings? |
| 01:27:14 | <campusblo> | and the good news is im done a project im working on |
| 01:27:16 | <campusblo> | yay! |
| 01:27:19 | <SamB> | TSC: hugs doesn't compile ;-) |
| 01:27:42 | <campusblo> | well more or less done |
| 01:28:12 | <SamB> | |Steve|: it would be shunned |
| 01:28:58 | <SamB> | they don't write "don't be stupid" anywhere in the report either, you know ;-) |
| 01:29:29 | <|Steve|> | geezusfreeek: Well, what if you did something like: main = do { line <- getLine; if line == "" then return () else do {putStrLn line; main } } |
| 01:29:55 | <|Steve|> | And it did that as function calls? |
| 01:30:10 | <SamB_XP> | |Steve|: no big deal |
| 01:30:21 | <Cale> | |Steve|: Well, strictly speaking, I think all stack overflows sort of violate the semantics of the language already. |
| 01:30:53 | <geezusfreeek> | i'm pretty sure most implementations would garbage collect most of the old trash there |
| 01:30:56 | <Cale> | After all, they sort of make values into _|_ which shouldn't be _|_. |
| 01:30:57 | <ddarius> | As does running out of memory... |
| 01:31:02 | <Cale> | right |
| 01:31:15 | <|Steve|> | geezusfreeek: There is no garbage, it's all on the stack if it's doing function calls. |
| 01:31:36 | <ddarius> | |Steve|: Not true at all. |
| 01:31:43 | <ddarius> | Necessarily. |
| 01:31:47 | <geezusfreeek> | are thunks done on the stack? (i don't know much about haskell implementations) |
| 01:31:48 | <SamB_XP> | |Steve|: the Haskell standard, like the C standard, does not say anything about this matter |
| 01:32:02 | <SamB_XP> | ... that doesn't stop a good C compiler either... |
| 01:32:03 | <|Steve|> | The scheme standard does. |
| 01:32:17 | <|Steve|> | But in C, I can write a loop. I can't in haskell. |
| 01:32:20 | <Cale> | |Steve|: The Haskell standard doesn't say anything about the order of evaluation, or how an evaluator might even work. It just says what programs mean. |
| 01:32:30 | <|Steve|> | I _have_ to use recursion. |
| 01:32:36 | <SamB_XP> | C doesn't have a stack any more than Haskell has |
| 01:32:46 | <ddarius> | |Steve|: You can safely assume that all implementations do tail call optimization. |
| 01:32:49 | <SamB_XP> | anyway, as I said, we would *shun* any implementation that got it wrong |
| 01:32:51 | <Cale> | |Steve|: It's safe to use recursion, because any *sane* implementation will do tail recursion optimisation. |
| 01:33:01 | <|Steve|> | Okay. |
| 01:33:14 | <SamB_XP> | after all, the report doesn't say "don't be stupid" either ;-) |
| 01:33:18 | <|Steve|> | Fair enough. It just seems like it's something that should be in the language given that there are no looping constructs. |
| 01:33:26 | <ddarius> | You'd think. |
| 01:33:40 | <SamB_XP> | ddarius: it would be too hard to say |
| 01:33:52 | <Cale> | Given that the language spec doesn't specify what order expressions are reduced in, it's sort of meaningless to even talk about the stack. |
| 01:33:53 | <geezusfreeek> | i don't know, i always thought it was kind of pointless to put implementation details into a language spec |
| 01:33:55 | <Cale> | What stack? |
| 01:34:06 | <SamB_XP> | C doesn't have a stack, why should we? |
| 01:34:24 | <ddarius> | SamB_XP: You'd more talk about space rather than stack. |
| 01:34:43 | <Cale> | You might just have an implementation which works by treating the program as a big graph and doing matching and reduction on that in a semi-random order. |
| 01:34:56 | <SamB_XP> | I don't believe that the report *ever* mentions space |
| 01:35:01 | <|Steve|> | You're right, the c99 standard doesn't use the word stack once. |
| 01:36:11 | <SamB_XP> | now, of course, it's less stupid to leave out tail-call optimization in a C compiler since, as you say, you can loop in C |
| 01:36:32 | <|Steve|> | The c++98 standard does mention stack unwinding. |
| 01:37:09 | <SamB_XP> | C++ is a bit of a different beast |
| 01:37:38 | <|Steve|> | It never refers to a call stack though. |
| 01:37:57 | <SamB_XP> | it might have been a slip-up ;-) |
| 01:38:11 | <|Steve|> | What might have been a slip up? |
| 01:38:23 | <SamB_XP> | using the word stack in "stack unwinding" |
| 01:38:41 | <|Steve|> | They use it 7 times. |
| 01:39:01 | <SamB_XP> | or maybe they couldn't come up with a better term... |
| 01:39:07 | <|Steve|> | And say stack is unwound twice more and stack shall not be unwound once. |
| 01:39:23 | <|Steve|> | But they're talking about object destruction. |
| 01:39:36 | <SamB_XP> | anyway, the stack doesn't actually need to be a conventional stack |
| 01:39:45 | <|Steve|> | "The process of calling destructors for automatic objects constructed on the path from a try block to a throw-expression is called "stack unwinding." |
| 01:41:26 | <SamB_XP> | anyway, C++ is a bit different I think |
| 01:41:33 | <SamB_XP> | since it has those pesky destructors |
| 01:41:35 | <|Steve|> | The c++ standard is way to long. 776 pages. |
| 01:41:45 | <|Steve|> | too* |
| 01:41:54 | <|Steve|> | I no speak the English. |
| 01:42:18 | <SamB_XP> | um, that's no excuse! I speak english and I still make mistakes like that ;-P |
| 01:42:58 | <|Steve|> | It was a joke since apparently I failed in that sentence. |
| 01:43:18 | <SamB_XP> | ACTION was somewhat kidding too |
| 01:47:12 | <Baughn> | This is why IRC should have humor tags |
| 01:47:59 | <SamB_XP> | </joke> |
| 01:49:15 | <msouth> | so I could tell if "stack is unwound twice more and stack shall not be unwound once." was a reference to the Holy Hand Grenade? |
| 01:50:33 | <|Steve|> | It wasn't. |
| 01:50:47 | <|Steve|> | I was reading off stats about the standard. |
| 01:50:49 | <Baughn> | "Once shalt thou free objects. Objects shall be freed once, and one shall be the number of the freeing." |
| 01:51:08 | <Baughn> | I'm going to have to remember that one, for a channel where it actually fits |
| 01:51:22 | <|Steve|> | Heh. |
| 01:51:36 | <SamB_XP> | why doesn't it fit here? |
| 01:51:49 | <SamB_XP> | we can even free *functions* here |
| 01:52:23 | <dons> | have people see http://leiffrenzel.de/eclipse/cohatoe/ ? |
| 01:52:24 | <lambdabot> | Title: Cohatoe - Contributing Haskell to Eclipse |
| 01:52:47 | <Baughn> | SamB_XP: I'm thinking up a.. poem?.. that explains malloc/free in a rememberable way |
| 01:52:58 | <Baughn> | Remembrable? |
| 01:53:12 | <SamB_XP> | memorable |
| 01:53:32 | <Baughn> | I prefer remembrable. |
| 01:53:32 | <msouth> | "mnemonish" |
| 01:53:58 | <dons> | http://programming.reddit.com/info/26nde/comments |
| 01:53:59 | <lambdabot> | Title: Cohatoe: Extending Eclipse in Haskell (reddit.com) |
| 01:54:40 | <cytzol> | :r |
| 01:54:42 | <cytzol> | whoops |
| 01:54:49 | <geezusfreeek> | :) |
| 02:02:33 | <hpaste> | int-e annotated "f.f = g" with "using Data.Set as a priority queue" at http://hpaste.org/1702#a1 |
| 02:02:53 | <EvilTerran> | hm. GHC's postfix operator support doesn't seem to extend to type constructors. |
| 02:03:31 | <dons> | http://programming.reddit.com/info/26nfh/comments |
| 02:03:32 | <lambdabot> | Title: An introduction to unit testing in Haskell with HUnit (reddit.com) |
| 02:03:50 | <int-e> | |Steve|: see annotation. it's quite a bit faster |
| 02:04:37 | <sjanssen> | dons: psssh, unit tests are just zero arity quickchecks :) |
| 02:04:54 | <|Steve|> | int-e: Looking. |
| 02:05:02 | <geezusfreeek> | sjanssen: what about for effectful code? |
| 02:05:15 | <dons> | sjanssen: I agree :) |
| 02:05:23 | <sjanssen> | geezusfreeek: that might be another story. I'm partly joking |
| 02:05:25 | <dons> | geezusfreeek: we can do that in QC these days too |
| 02:05:27 | <|Steve|> | Well, once the stupid page loads anyway. |
| 02:05:31 | <geezusfreeek> | dons: orly? |
| 02:05:34 | <dons> | see swiert's HW paper |
| 02:05:42 | <geezusfreeek> | ACTION peeks |
| 02:06:29 | <geezusfreeek> | ACTION is searching and not finding |
| 02:06:47 | <dons> | let's see.. |
| 02:07:26 | <dons> | http://programming.reddit.com/info/26nge/comments |
| 02:07:27 | <lambdabot> | Title: Beauty in the Beast: testing impure code with QuickCheck (reddit.com) |
| 02:07:37 | <dons> | hang on, got to fix that |
| 02:07:38 | <dons> | its a pdf |
| 02:08:28 | <int-e> | |Steve|: the Queue type implements a queue made up off finitely many, sorted, infinite lists. the nextQ function is badly named - what it does is pick the next number (starting from m) that is *not* in the queue. |
| 02:08:40 | <dons> | http://programming.reddit.com/info/26ngk/comments |
| 02:08:41 | <lambdabot> | Title: Beauty in the Beast: checking IO, state and concurrent code with QuickCheck (pdf ... |
| 02:08:56 | <geezusfreeek> | dons: thanks |
| 02:09:04 | <|Steve|> | Okay. |
| 02:09:54 | <dons> | sjanssen: we could take a similar approach to QC X11 |
| 02:10:10 | <sjanssen> | dons: that would require a purely functional spec of an X server |
| 02:10:12 | <dons> | (a data type for X11 operations, form a monad, test that purely, evaluate it it to actually execute the actions) |
| 02:10:16 | <sjanssen> | I imagine |
| 02:10:16 | <dons> | yes :) |
| 02:10:22 | <|Steve|> | Ugh, the page hasn't loaded yet. I'm going to put some laundry in and then look. |
| 02:11:05 | <dons> | yes, just have to write down the dX server semantics |
| 02:11:06 | <dons> | then its easy |
| 02:12:38 | <|Steve|> | You have an embedded delete character in there. |
| 02:13:43 | <|Steve|> | (Between the d and the X.) |
| 02:19:21 | <SamB_XP> | |Steve|: perhaps he thought he'd deleted the d? |
| 02:21:59 | <dons> | bad wifi, control chars not getting escaped by a bit too much latency |
| 02:25:47 | <|Steve|> | 0x7f is typically a forward delete though. |
| 02:26:19 | <|Steve|> | 0x08 is backspace. |
| 02:26:52 | <glguy> | > "\x7f" |
| 02:26:59 | <glguy> | ?bot |
| 02:26:59 | <lambdabot> | :) |
| 02:27:00 | <lambdabot> | "\DEL" |
| 02:27:19 | <glguy> | > "\8" |
| 02:27:20 | <lambdabot> | "\b" |
| 02:27:26 | <glguy> | > "\x08" |
| 02:27:28 | <lambdabot> | "\b" |
| 02:27:40 | <|Steve|> | int-e: I have to admit, I don't quite know what this is doing. |
| 02:30:55 | <int-e> | |Steve|: it's the same algorithm as yours really, except for two major differences: a) instead of removing entries from a list of candidates ([12..]) it keeps a list of forbidden candidates; secondly these lists are stored in a Queue (basically getting O(log m) instead of O(m) processing time per element for merging m infinite lists) |
| 02:31:32 | <glguy> | what algorithm is this? |
| 02:31:36 | <glguy> | ACTION came in a bit late |
| 02:31:43 | <|Steve|> | Ah. I'm amazed you could even follow the algorithm. |
| 02:32:02 | <|Steve|> | glguy: It's a construction for a function f such that f . f = n^2 -19n + 99 for all natural numbers n. |
| 02:32:04 | <int-e> | |Steve|: well I did that problem of the day, too. my haskell version was worse than yours actually ;) |
| 02:32:11 | <|Steve|> | Heh, okay. |
| 02:32:29 | <|Steve|> | I didn't actually solve the problem. TRWBW did. I just implemented it. |
| 02:32:43 | <int-e> | well I did it the same way :) |
| 02:32:56 | <|Steve|> | It took him about half an hour to explain it to me. Then he solved it some other way that I didn't follow. |
| 02:33:20 | <necroforest> | Is there anything like arrays in haskell? Or do you have to access things sequentially in lists? |
| 02:33:26 | <bos> | ACTION loves conor mcbride's Punter -> (String -> Punter) |
| 02:34:04 | <|Steve|> | necroforest: There are arrays. |
| 02:34:54 | <int-e> | |Steve|: anyway it eats a crazy amount of memory now but is fast enough to verify that f . f = g for 1..500 in 12 seconds here |
| 02:35:38 | <|Steve|> | More memory than mine? |
| 02:36:29 | <int-e> | |Steve|: I'm not patient enough to test that :) |
| 02:36:56 | <|Steve|> | heh |
| 02:37:48 | <hpaste> | int-e annotated "f.f = g" with "a strategical `seq` cuts memory usage by a factor of 4" at http://hpaste.org/1702#a2 |
| 02:38:30 | <campusblo> | hi folks. I wrote a program to crack code which takes strings as input |
| 02:38:36 | <int-e> | (if you're building a huge list, make sure that all list elements are fully evaluated) |
| 02:38:45 | <campusblo> | only problem is that its cant get around a " in the string |
| 02:38:53 | <campusblo> | anybody have any suggestions for that? |
| 02:39:06 | <campusblo> | i can get around everything else |
| 02:39:16 | <oklopol> | get around it? |
| 02:39:23 | <dons> | `to crack code' ? |
| 02:39:27 | <campusblo> | oh |
| 02:39:28 | <glguy> | > " a b \" c d " -- is this related? |
| 02:39:30 | <lambdabot> | " a b \" c d " |
| 02:39:36 | <campusblo> | its a ceaser cipher |
| 02:39:46 | <glguy> | the " stays a " |
| 02:40:02 | <bos> | i think a ceaser cipher would be defined as \_ -> [] |
| 02:40:16 | <oklopol> | campusblo: what do you mean you can't around a " in a string? |
| 02:40:26 | <dons> | do you mean you can't pattern match on " ? |
| 02:40:33 | <campusblo> | it creates an encrypted or decrypts messages by shifting all letters a certain number of letters down the alphabet |
| 02:40:35 | <dons> | > '"' == 'x' |
| 02:40:37 | <lambdabot> | False |
| 02:40:40 | <campusblo> | yes okpool |
| 02:40:53 | <campusblo> | if i put a " the string terminates |
| 02:40:58 | <oklopol> | ah |
| 02:40:59 | <oklopol> | \" |
| 02:40:59 | <campusblo> | and i get an error |
| 02:41:01 | <oklopol> | escape it |
| 02:41:10 | <oklopol> | \" where you want the " |
| 02:41:36 | <campusblo> | but thats still 2 characters |
| 02:41:41 | <oklopol> | unless i'm confusing languages here, i shouldn't be teaching on this channel, but the other way around :) |
| 02:41:46 | <campusblo> | i think it would still terminate |
| 02:41:50 | <campusblo> | lol |
| 02:41:52 | <oklopol> | campusblo: that will mean " |
| 02:41:58 | <oklopol> | it's a way to get a " in a string |
| 02:42:04 | <campusblo> | oh ok |
| 02:42:12 | <oklopol> | read up onescape sequences |
| 02:42:17 | <oklopol> | *on escape |
| 02:42:17 | <campusblo> | ill try it |
| 02:42:22 | <campusblo> | will do |
| 02:43:40 | <dolio> | campusblo: Is Haskell your first language? |
| 02:43:51 | <campusblo> | yes |
| 02:44:00 | <dolio> | Nice. |
| 02:44:04 | <glguy> | ACTION points out that he solved campusblo's problem before he knew what the problem was :) |
| 02:44:19 | <ddarius> | Lucky you. |
| 02:44:53 | <campusblo> | i guess. but why do you say that ddarius? |
| 02:44:57 | <glguy> | Haskell it is terrible first language, you won't bother to learn any others ;) |
| 02:45:12 | <jfredett> | tru that. |
| 02:45:15 | <SamB_XP> | glguy: but then what will you write in it? |
| 02:45:16 | <glguy> | Most people start on an imperative language, and get all sorts of bad habits |
| 02:45:20 | <dolio> | Heh. He can always go on to Coq/Epigram. |
| 02:45:24 | <SamB_XP> | anyway, you'll then want to learn C |
| 02:45:25 | <ddarius> | There are many worse languages to start learning programming on (though in my opinion there are better ones too) |
| 02:45:28 | <chrisamaphone> | sml, twelf :) |
| 02:45:34 | <oklopol> | glguy: i did too, i just don't like giving advise until i'm sure :) |
| 02:45:40 | <ddarius> | Yarrow or Agda. |
| 02:46:12 | <campusblo> | well cool. i like haskell. |
| 02:46:20 | <glguy> | oklopol: You should try to give advice early and often |
| 02:46:23 | <SamB_XP> | I didn't make it to the end of the agda tutorial |
| 02:46:27 | <campusblo> | and i hear functional programmers make the big bucks |
| 02:46:34 | <dons> | yeah, twelf or epigram would make strange first languages |
| 02:46:34 | <jfredett> | ddarius: I like Scheme for a first language, Haskell for the real work |
| 02:46:36 | <SamB_XP> | oh no! |
| 02:46:42 | <glguy> | oklopol: there was a thread on the mailing list about how we need to transition people into "answering questions" sooner to keep the community going |
| 02:46:44 | <SamB_XP> | he's in it for the money! |
| 02:46:47 | <campusblo> | scheme is the next languae i do |
| 02:46:49 | <SamB_XP> | kick him quick |
| 02:46:58 | <|Steve|> | campusblo: Heh. Big bucks. =) |
| 02:47:01 | <jfredett> | Scheme < Haskell, in terms of power and hardness to learn. |
| 02:47:18 | <jfredett> | i guess difficulty is what i meant. |
| 02:47:20 | <ddarius> | jfredett: Scheme is one of the languages I would recommend as better, though it could still be a better starting language that it is. |
| 02:47:23 | <|Steve|> | Scheme is easier to learn. Side effects, consistent syntax. |
| 02:47:25 | <glguy> | You can express more programs in Scheme than Haskell though |
| 02:47:46 | <campusblo> | i see. i guess ill see next semester |
| 02:47:47 | <chrisamaphone> | uh, they're both turing complete. |
| 02:47:49 | <|Steve|> | I wouldn't expect to make money writing scheme though... |
| 02:48:02 | <glguy> | Haskell's type system eliminates programs that are otherwise valid in some cases |
| 02:48:04 | <int-e> | glguy: how many countable infinities are there? |
| 02:48:14 | <glguy> | int-e: relatively more :) |
| 02:48:26 | <jfredett> | glguy: yes, but those programs are most often not needed. |
| 02:48:29 | <glguy> | chrisamaphone: we tend to leave the turing complete argument at the door |
| 02:48:41 | <campusblo> | i hear you. i think we learn on these then we have to choose a language. right now im thinking C# and Java |
| 02:48:46 | <oklopol> | glguy: you are saying there are problems haskell can't solve and lisp can? :) |
| 02:48:49 | <dons> | given unsafeCoerce#, they accept the same set of programs |
| 02:48:49 | <ddarius> | Actually, Scheme is ridiculously powerful. |
| 02:49:02 | <chrisamaphone> | glguy: fine, you can argue in terms of more expressive power, but saying one can write "more programs" than the other is false. |
| 02:49:06 | <campusblo> | so scheme is lisp? |
| 02:49:09 | <jfredett> | I agree its quite powerful, but that power is often less accessible |
| 02:49:12 | <jfredett> | campusblo: yes and no |
| 02:49:12 | <ddarius> | Last I checked Scheme code didn't parse as Haskell or vice versa. |
| 02:49:15 | <chrisamaphone> | dymanic languages are embeddable in static type systems. |
| 02:49:34 | <glguy> | to set some sort of starting point, I love Haskell and use it as my primary language at work :) |
| 02:49:35 | <chrisamaphone> | *dynamic |
| 02:49:40 | <campusblo> | I see ppl reccomending lisp all the time |
| 02:49:44 | <glguy> | I'm just defending the other languages since no one else was :) |
| 02:49:45 | <|Steve|> | Scheme is a lisp. |
| 02:49:49 | <geezusfreeek> | glguy: where do you work that you get to use haskell? |
| 02:49:53 | <glguy> | Galois |
| 02:50:25 | <ddarius> | Scheme has a lot of good introductory resources and is a rather nice language. |
| 02:50:28 | <jfredett> | IMO, Scheme and Haskell are useful in different situations |
| 02:50:45 | <|Steve|> | ACTION is teaching Scheme. It's a bit of a joke. |
| 02:50:47 | <jfredett> | and that set is mostly disjoint |
| 02:50:55 | <int-e> | > (map ((+) 2) ([1,2,3])) |
| 02:50:56 | <|Steve|> | I don't really know that much scheme. If my students know n, I try to know n+1. |
| 02:50:57 | <lambdabot> | [3,4,5] |
| 02:51:02 | <ddarius> | jfredett: Not my experience at all. |
| 02:51:29 | <|Steve|> | (map (lambda (n) (+ n 2)) '(1,2,3)) |
| 02:51:57 | <oklopol> | lose the , |
| 02:52:15 | <glguy> | isn't 1,2,3 a symbol? |
| 02:52:28 | <jfredett> | its a symbol for a list |
| 02:52:33 | <oklopol> | i don't think a number can start a symbol |
| 02:52:38 | <ddarius> | '(1 2 3) |
| 02:52:43 | <|Steve|> | oops, yeah. |
| 02:52:45 | <glguy> | ACTION fires up DrScheme to find out |
| 02:52:47 | <jfredett> | '(1 2 3) is the list (1 2 3) |
| 02:53:00 | <|Steve|> | guile> (map (lambda (n) (+ n 2)) '(1 2 3)) |
| 02:53:00 | <|Steve|> | (3 4 5) |
| 02:53:05 | <glguy> | > '(1,2,3) |
| 02:53:05 | <lambdabot> | Improperly terminated character constant |
| 02:53:06 | <glguy> | (1 ,2 ,3) |
| 02:53:14 | <glguy> | is what DrScheme returned |
| 02:53:23 | <|Steve|> | As was pointed out, lose the commas. |
| 02:53:29 | <jfredett> | bah, we need mzbot in here too. |
| 02:53:32 | <int-e> | uh does scheme have the , unquote character? |
| 02:53:34 | <oklopol> | does lambdabot do lisp? |
| 02:53:39 | <glguy> | |Steve|: I'm not concerned with correcting your example :) |
| 02:53:45 | <glguy> | |Steve|: I was wondering how that actually parsed |
| 02:53:45 | <ddarius> | jfredett: You'd think, but it actually doesn't come up that often. |
| 02:53:46 | <jfredett> | or at least a Lisp> for Lambdabot |
| 02:53:53 | <dons> | oklopol: no, because we can't analyse it for safety |
| 02:53:56 | <|Steve|> | Ah. |
| 02:54:00 | <dons> | which we can do with haskell |
| 02:54:05 | <dons> | > readFile "/etc/passwd" |
| 02:54:07 | <lambdabot> | <IO [Char]> |
| 02:54:08 | <glguy> | ACTION high fives haskell |
| 02:54:10 | <ddarius> | jfredett: You can write one with @let |
| 02:54:29 | <glguy> | dons: the safety check is just a more complicated version of: |
| 02:54:39 | <glguy> | > unsafePerformIO (putStrLn "this") |
| 02:54:40 | <lambdabot> | Not in scope: `unsafePerformIO' |
| 02:54:50 | <jfredett> | ddarius: hmm. I'll have to do that sometime. |
| 02:54:52 | <glguy> | You'd just have to take stuff out of scope, and kill off intern or something |
| 02:54:59 | <glguy> | and eval |
| 02:55:12 | <dons> | more than that, we only show types from a given class |
| 02:55:29 | <dons> | so the type checker rules out side effects. that's the strong weapon we use |
| 02:55:37 | <ddarius> | jfredett: I wrote a Joy interpreter in a mostly pure untyped lambda calculus interpreter that I had written as a plugin for lambdabot. |
| 02:55:41 | <dons> | the other stuff, a trusted base, timeouts and other things , are sugar after that |
| 02:55:53 | <campusblo> | can i do this | x == '\"' = '\"' |
| 02:55:54 | <glguy> | dons: I understand that aspect of it, but you fill the holes by not importing certain functions |
| 02:56:03 | <ddarius> | campusblo: Yes. |
| 02:56:08 | <dons> | right. nothing that hides an effect inside a pure value |
| 02:56:22 | <campusblo> | to keep the quote in the string |
| 02:56:29 | <campusblo> | ok cool ill test it now |
| 02:56:33 | <glguy> | campusblo: '\"' and ' |
| 02:56:37 | <glguy> | '"' are the same |
| 02:56:43 | <glguy> | (saves you a character ;) ) |
| 02:57:21 | <oklopol> | because " inside a '' doesn't end the string and thus needs no escaping from |
| 02:57:28 | <ddarius> | "not importing <things>" is the key to security anyways. |
| 02:57:50 | <int-e> | > ['\34', '\x22', '\"', '"'] |
| 02:57:51 | <lambdabot> | "\"\"\"\"" |
| 02:58:00 | <campusblo> | ERROR - Syntax error in input (unexpected `;', possibly due to bad layout) |
| 02:58:04 | <glguy> | > fix show |
| 02:58:06 | <lambdabot> | "\"\\\"\\\\\\\"\\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"\\\\\\\\\\\\\... |
| 02:58:13 | <oklopol> | > 1 |
| 02:58:15 | <lambdabot> | 1 |
| 02:58:18 | <oklopol> | hihi |
| 02:58:35 | <glguy> | ?vixen Have you met oklopol? |
| 02:58:36 | <lambdabot> | yeah, i'm ok |
| 02:58:49 | <oklopol> | ? :I |
| 03:03:54 | <glguy> | ACTION wonders if Haskell's type system could be implemented in Lisp using macros... |
| 03:04:16 | <ddarius> | glguy: Of course it can. |
| 03:04:34 | <glguy> | without having to change too much of the lisp code at least |
| 03:04:46 | <SamB_XP> | oh, probably not ;-) |
| 03:05:12 | <ddarius> | So your question is is typical Lisp code reasonably typeable in a H-M style type system? |
| 03:05:37 | <glguy> | I suppose it is |
| 03:06:08 | <thorat> | it's going to take a few milliOleg's of macro hackery |
| 03:06:36 | <ddarius> | thorat: No, you just implement the type checker exactly as you would normally. |
| 03:07:05 | <dons> | `Personally, I don't really classify CL as an FP language' -- i've been saying that for years :) |
| 03:07:20 | <ddarius> | dons: What about Scheme? |
| 03:07:21 | <glguy> | ACTION saw that on reddit |
| 03:07:40 | <dons> | I'd say if its not pure by default, its not functional. but that might be a little controversial |
| 03:07:51 | <Cale> | It seems that preventing I/O from occurring in pure code in CL would be tricky to accomplish with just macros. |
| 03:07:52 | <dons> | you have to have (.) anyway |
| 03:08:11 | <Cale> | CL makes it too much of a pain to write higher order functions |
| 03:08:12 | <thorat> | ddarius: ok, I thought glguy meant a similar approach to Kanren |
| 03:08:50 | <ddarius> | dons: ? |
| 03:09:02 | <Cale> | You have to quote things in funny ways, and use funcall/apply to call functions passed as parameters. That tends to make uses of functional programming less casual. |
| 03:09:25 | <ddarius> | The lack of TCO is one of the bigger issues for me. |
| 03:09:31 | <Cale> | Oh, that too. |
| 03:09:34 | <ddarius> | But I don't consider TCO an FP thing. |
| 03:09:35 | <glguy> | CL doesn't require tail recursion optimization either, right? |
| 03:09:59 | <Cale> | glguy: Many implementations don't support it. |
| 03:10:08 | <glguy> | ACTION wasn't paying attention when he typed that |
| 03:10:12 | <dons> | ddarius: did you see this thread, http://groups.google.com/group/comp.lang.lisp/msg/43090ddeeb50051c?dmode=source |
| 03:10:14 | <lambdabot> | Title: New Computer Language Shootout? - comp.lang.lisp | Google Groups, http://tinyurl.com/2uhxva |
| 03:10:20 | <dons> | (besides being started by Jon Harrop... :/ ) |
| 03:10:35 | <dons> | it makes a good case for why you never see lisp papers at ICFP :) |
| 03:10:39 | <ddarius> | dons: Unless it happened several years ago, I haven't been following c.l.l (or any newsgroups now) |
| 03:10:49 | <Cale> | The fact that Haskell isn't required to have TCO doesn't bother me, since it's defined at a completely different level of abstraction from that. |
| 03:11:05 | <ddarius> | Cale: And the fact that it is effectively required anyways. |
| 03:11:12 | <Cale> | yeah |
| 03:11:32 | <Cale> | at least, if you're doing anything like an ordinary implementation of it |
| 03:14:47 | <dancor> | can i somehow get Just 1 + Just 2 = Just 3 and Nothing + Just 4 = Nothing to work |
| 03:15:18 | <shachaf> | dancor: Use fmap (<$>). |
| 03:15:26 | <ddarius> | dancor: Make Maybe an instance of Num. |
| 03:15:34 | <int-e> | > liftM2 (+) (Just 1) (Just 2) -- hmm |
| 03:15:35 | <shachaf> | dancor: Or liftM2, I guess. |
| 03:15:42 | <lambdabot> | Just 3 |
| 03:15:50 | <dancor> | cool |
| 03:15:58 | <shachaf> | int-e: Yes, liftM2 is probably better in this case. |
| 03:16:17 | <dons> | > liftM2 div (Just 1) (Just 0) |
| 03:16:18 | <lambdabot> | Exception: divide by zero |
| 03:16:31 | <dons> | div should be in Maybe :) |
| 03:16:38 | <ddarius> | I'd rather it not. |
| 03:16:44 | <int-e> | > (+) <$> Just 2 <*> Just 3 -- or Applicative (as shachaf also suggested) |
| 03:16:46 | <lambdabot> | Just 5 |
| 03:16:50 | <ddarius> | Though I guess I could just throw a fromJust on it. |
| 03:17:06 | <dons> | unsafeDiv for things other than Rational |
| 03:20:04 | <glguy> | dons: Haskell is the most referenced nick? |
| 03:20:08 | <glguy> | I suppose that is my fault? |
| 03:20:39 | <shachaf> | glguy: Were you Haskell at one point? |
| 03:20:40 | <dons> | yeah :) told you so. |
| 03:20:40 | <dons> | |
| 03:21:00 | <glguy> | shachaf: yeah , I registered that at one point for fun |
| 03:22:27 | <glguy> | shachaf: according to the whowas, so were you :) |
| 03:22:43 | <shachaf> | glguy: Just for a moment. :-) |
| 03:23:28 | <glguy> | that way I could nickserv ghost someone that used the nick to do stuff like |
| 03:23:45 | <Haskell> | ACTION is strongly typed for weak minds |
| 03:24:12 | <shachaf> | What does "strongly typed" mean, anyway? |
| 03:24:39 | <glguy> | doesn't automatically coerce types, generally |
| 03:25:41 | <glguy> | I believe that "weak typing" is used to describe things like: "2" + True = 3 |
| 03:27:30 | <ddarius> | Usually it's a bit stronger than that, that you can't apply a function to a type that does not support it, i.e. unsafeCoerce 3 5 |
| 03:27:55 | <ddarius> | I.e. that the type system is sound |
| 03:28:06 | <ddarius> | For statically typed languages. |
| 03:28:56 | <oklopol> | > "2" + True |
| 03:28:57 | <lambdabot> | Couldn't match expected type `[Char]' against inferred type `Bool' |
| 03:29:17 | <oklopol> | > "2" + True /= 3 |
| 03:29:19 | <lambdabot> | Couldn't match expected type `[Char]' against inferred type `Bool' |
| 03:29:29 | <glguy> | (+) :: Num n => n -> n -> n |
| 03:29:45 | <glguy> | the two addends need to have the same type |
| 03:29:50 | <oklopol> | yeah, i'm just playing around :) |
| 03:29:58 | <oklopol> | > "23"+"44" |
| 03:29:59 | <lambdabot> | add an instance declaration for (Num [Char]) |
| 03:29:59 | <lambdabot> | In the expression: "23" + ... |
| 03:30:04 | <oklopol> | > "23"++"44" |
| 03:30:05 | <lambdabot> | "2344" |
| 03:30:11 | <siti> | > 1/2.0 ;) |
| 03:30:12 | <lambdabot> | Parse error |
| 03:30:16 | <siti> | > 1/2.0 |
| 03:30:17 | <lambdabot> | 0.5 |
| 03:30:22 | <glguy> | oklopol: through a gross instance definition "1" + "2" could work |
| 03:30:34 | <dolio> | > let a + b = read a Prelude.+ fromEnum b in "2" + True |
| 03:30:35 | <oklopol> | can you show me? :) |
| 03:30:36 | <lambdabot> | 3 |
| 03:30:43 | <shachaf> | oklopol: Not in lambdabot. |
| 03:30:55 | <oklopol> | i c |
| 03:30:57 | <shachaf> | oklopol: But "instance Num String where (+) = (++)" should work. |
| 03:31:44 | <Figs> | hi |
| 03:31:46 | <glguy> | a + b = show $ readInt a + readInt b |
| 03:31:57 | <shachaf> | Figs: Hello. |
| 03:31:59 | <Figs> | hi |
| 03:32:29 | <Figs> | http://rafb.net/p/krffm450.html <-- some real evil :) |
| 03:32:30 | <lambdabot> | Title: Nopaste - No description |
| 03:33:01 | <Figs> | a math expression parser that I *think* does order of ops correctly as it builds the tree |
| 03:33:08 | <shachaf> | Figs: Wasn't that your C++ thing? |
| 03:33:13 | <Figs> | it's build on it |
| 03:33:25 | <Figs> | this is what I'll test my rewrite with |
| 03:33:33 | <Figs> | it's not done yet |
| 03:33:38 | <Figs> | so this won't work in all cases |
| 03:33:51 | <shachaf> | Figs: Now try it in Haskell and see how much better it is. :-) |
| 03:33:55 | <Figs> | hehe :P |
| 03:33:58 | <ddarius> | I wonder how close to Tcl we can get if we just start making String an instance of everything. |
| 03:34:06 | <Figs> | I figured out something interesting |
| 03:34:17 | <Figs> | that you guys can probably give me some perspective on |
| 03:34:28 | <Figs> | My parser is very easily extensible, so |
| 03:34:32 | <Figs> | I can write things like |
| 03:34:47 | <Figs> | (or will be able to) |
| 03:35:19 | <ddarius> | What algorithm does it use to parse? |
| 03:35:37 | <Figs> | regex equalnumb = (S[0] << *A) >> repeat(B,count(S[0],A)) >> repeat(C,count(S[0],A)); //etc |
| 03:35:59 | <Figs> | which would match something like AAABBBCCC |
| 03:36:04 | <Figs> | AAAABBBBCCCC |
| 03:36:05 | <Figs> | etc |
| 03:36:15 | <dancor> | > printf "hi" |
| 03:36:16 | <lambdabot> | Add a type signature |
| 03:36:25 | <shachaf> | > printf "hi" :: String |
| 03:36:26 | <lambdabot> | "hi" |
| 03:36:32 | <dancor> | > printf "%.2f" pi |
| 03:36:33 | <lambdabot> | Add a type signature |
| 03:36:37 | <shachaf> | dancor: Lambdabot can't print to stdout. |
| 03:36:38 | <dancor> | man |
| 03:36:44 | <shachaf> | > printf "%.2f" pi :: String |
| 03:36:46 | <lambdabot> | "3.14" |
| 03:36:54 | <glguy> | printf could return a function, an IO action, or a String |
| 03:36:58 | <glguy> | you always have to specify |
| 03:37:03 | <dancor> | shachaf: then why did yours work |
| 03:37:10 | <ddarius> | Figs: The order of operations is right, but you can't write 3+4+5 without parentheses. |
| 03:37:15 | <shachaf> | dancor: I told it that it was a String. |
| 03:37:18 | <ddarius> | :t printf |
| 03:37:20 | <lambdabot> | forall r. (PrintfType r) => String -> r |
| 03:37:25 | <shachaf> | dancor: Keep in mind that printf is a bit magical. |
| 03:37:32 | <Figs> | ahh, I did miss something then |
| 03:37:42 | <glguy> | @instances PrintfType |
| 03:37:44 | <lambdabot> | Couldn't find class `PrintfType'. Try @instances-importing |
| 03:37:57 | <dancor> | is there a less magical way to get printf "%.2f" x :: String |
| 03:38:00 | <ddarius> | Similarly for * |
| 03:38:11 | <dancor> | ACTION isn't really into magic |
| 03:38:23 | <shachaf> | dancor: Not THAT magical. |
| 03:38:28 | <ddarius> | dancor: It's just normal type class resolution |
| 03:38:33 | <Figs> | http://rafb.net/p/NGVY1D91.html |
| 03:38:35 | <Figs> | is that better? |
| 03:38:36 | <lambdabot> | Title: Nopaste - No description |
| 03:38:43 | <ddarius> | But check out the stuff in Numeric perhaps? |
| 03:38:47 | <glguy> | (PrintfArg a, PrintfType r) => PrintfType (a -> r) |
| 03:38:47 | <glguy> | PrintfType (IO a) |
| 03:38:47 | <glguy> | IsChar c => PrintfType [c] |
| 03:39:00 | <shachaf> | dancor: It's just that a normal function in Haskell has a fixed number of arguments. |
| 03:39:27 | <shachaf> | dancor: Using type-classes, printf can work around it, because it knows how many arguments to expect (from the format string). |
| 03:39:29 | <dolio> | > showFFloat (Just 2) pi "" |
| 03:39:29 | <dancor> | shachaf: so why doesn't printf take [Dynamic] |
| 03:39:30 | <lambdabot> | "3.14" |
| 03:39:36 | <glguy> | :t printf "" :: Int -> String |
| 03:39:38 | <lambdabot> | Int -> String :: Int -> String |
| 03:39:39 | <dancor> | oh |
| 03:39:41 | <ddarius> | Figs: Can your parser handle that? And I believe 2+3+4*1 won't parse. |
| 03:39:54 | <ddarius> | dancor: Because this is Haskell. |
| 03:40:18 | <dancor> | do you mean Haskell :: ProgrammingLanguage |
| 03:40:30 | <dancor> | bc otherwise i will give you a meaningless error message |
| 03:40:43 | <shachaf> | dancor: No, printf is a special case. |
| 03:40:54 | <shachaf> | dancor: Normally the types can be inferred. |
| 03:41:04 | <Figs> | 2+3+4*1 should parse fine |
| 03:41:07 | <glguy> | printf just doesn't have defaulting |
| 03:41:13 | <dolio> | > let c = 299790000 in showEFloat (Just 4) c "" |
| 03:41:14 | <lambdabot> | "2.9979e8" |
| 03:41:18 | <glguy> | while Num and Floating do |
| 03:41:24 | <Figs> | oh |
| 03:41:26 | <Figs> | hmm |
| 03:41:29 | <Figs> | no |
| 03:41:44 | <ddarius> | Figs: It will be addterm(2+3)+error(4*1 doesn't parse as number) |
| 03:41:53 | <glguy> | printf is the standard case, Num and Floating are special cases |
| 03:42:13 | <Figs> | ok, that's resolveable though by adding one more case |
| 03:42:22 | <shachaf> | glguy: I didn't mean defaulting, I meant "your types not being inferred easily". :-) |
| 03:42:37 | <ddarius> | Figs: You don't need this many cases, further will your parser handle left recursion? |
| 03:42:49 | <ddarius> | shachaf: No worse than Read. |
| 03:43:07 | <glguy> | shachaf: I was saying that the type of 7 can not be inferred easily, that the reason you don't have to specify is defaulting |
| 03:43:29 | <glguy> | and that since PrintfType isn't special cased, you ave to specify |
| 03:43:35 | <Figs> | http://rafb.net/p/J8YNus24.html |
| 03:43:36 | <lambdabot> | Title: Nopaste - No description |
| 03:43:42 | <shachaf> | ddarius, glguy: You're right, I guess lambdabot specificaly is a bad place to test this. |
| 03:43:58 | <Figs> | ddarius, give me an example, and I'll think about it |
| 03:44:09 | <shachaf> | dancor: Normally, from the context (e.g., a do block), the type of printf can be inferred. |
| 03:44:18 | <Figs> | I'm not sure exactly what you mean. |
| 03:44:33 | <oklopol> | A = A | B; is left recursion |
| 03:44:34 | <oklopol> | err |
| 03:44:40 | <oklopol> | A = A >> B; |
| 03:44:46 | <Figs> | hi oklopol :) |
| 03:44:47 | <oklopol> | and hi Figs |
| 03:44:48 | <oklopol> | :) |
| 03:44:52 | <dancor> | > printf "%.2f" ((fromIntegral 4) / (fromIntegral 6) :: Float) :: String |
| 03:44:54 | <lambdabot> | "0.67" |
| 03:45:02 | <dancor> | that's what i had to do in my context |
| 03:45:09 | <ddarius> | If you use recursive descent, you have a problem. |
| 03:45:24 | <shachaf> | dancor: What was your context? |
| 03:45:30 | <Figs> | It's doing recursive descent right now, I think. |
| 03:45:35 | <Figs> | so probably not. |
| 03:45:36 | <dolio> | The fromIntegrals there should be redundant. |
| 03:45:38 | <shachaf> | dancor: You don't need those fromIntegrals. |
| 03:45:53 | <ddarius> | Then things like multerm and addterm won't terminate. |
| 03:46:00 | <dancor> | CM.liftM2 (divF) justMyIntA justMyIntB |
| 03:46:12 | <dancor> | which is later Show-n |
| 03:46:31 | <shachaf> | dancor: (You generally don't need to qualify Control.Monad, by the way.) |
| 03:46:42 | <dancor> | shachaf: i like to qualify everything |
| 03:46:45 | <ddarius> | shachaf: s/generally/usually |
| 03:47:07 | <shachaf> | ddarius: Yes, sorry. :-) |
| 03:47:18 | <Figs> | hmm, I don't know how hard it would be to fix that |
| 03:47:21 | <Figs> | :P |
| 03:47:34 | <Figs> | it could be simple, or it could be very difficult |
| 03:47:37 | <dancor> | and without the fromIntegral's i gett a "Couldn't match Float" blahblah |
| 03:47:52 | <shachaf> | dancor: That shouldn't happen. |
| 03:47:58 | <Figs> | the simple case would involve rewriting by_ref and operator >> |
| 03:48:00 | <shachaf> | dancor: Are the 4 and 6 hard-wired like in your example? |
| 03:48:02 | <glguy> | dancor: you don't need fromIntegral for literals |
| 03:48:09 | <Figs> | well, a seq object |
| 03:48:11 | <dancor> | they aren't literals |
| 03:48:13 | <glguy> | dancor: but you do for values in your code |
| 03:48:17 | <dancor> | 20:46 < dancor> CM.liftM2 (divF) justMyIntA justMyIntB |
| 03:48:42 | <glguy> | shachaf: that's why :) |
| 03:49:06 | <shachaf> | glguy: Yes, I guessed that myself. :-) |
| 03:49:11 | <ddarius> | Figs: You can use a different algorithm in which left-recursion is not a problem, require that left-recursion not be there, or "preprocess" the grammar to detect it and rewrite it. |
| 03:49:39 | <Figs> | the easiest solution would be to change the behavior of the search, I think |
| 03:49:51 | <shachaf> | dancor: Can you @paste with some more context? |
| 03:50:10 | <ddarius> | Just name the printf expression and give it a type. |
| 03:50:43 | <Figs> | actually |
| 03:50:49 | <Figs> | hmm |
| 03:50:53 | <dancor> | i think i see now that i will always need the :: Float and the :: String for my context |
| 03:51:06 | <dancor> | and i'm going to start the lengthy process of getting-over it now |
| 03:51:15 | <shachaf> | dancor: How are you using the printf? |
| 03:51:20 | <Figs> | do you have the name of another algorithm I can use? |
| 03:51:20 | <hpaste> | aeyakovenko pasted "fast sha1" at http://hpaste.org/1704 |
| 03:51:55 | <ddarius> | Look up LR parsing or if you want to be very friendly GLR parsing. |
| 03:52:53 | <Figs> | well the thing I need to be careful of is to keep it extensible |
| 03:53:20 | <Figs> | since that's the real power: it's easy to write a new parser type |
| 03:53:20 | <ddarius> | > let printFloat :: Float -> String; printFloat = printf ".2f" in printFloat 3 |
| 03:53:22 | <lambdabot> | Exception: Printf.printf: formatting string ended prematurely |
| 03:53:35 | <ddarius> | > let printFloat :: Float -> String; printFloat = printf "%.2f" in printFloat 3 |
| 03:53:36 | <lambdabot> | "3.00" |
| 03:54:07 | <Figs> | I could number the rules and keep track of the parents and detect infinite loops, couldn't I? |
| 03:54:41 | <ddarius> | Figs: Completely new? Wouldn't most be compositions of primitive parsers? |
| 03:54:52 | <hpaste> | dancar pasted "shachaf: printf needs lots of :: Love" at http://hpaste.org/1705 |
| 03:54:56 | <Figs> | most probably, but like my repeat example |
| 03:55:09 | <Figs> | I could just easily do something like |
| 03:55:26 | <mm_freak> | > div 15 (fromIntegral (3::Int)) |
| 03:55:28 | <lambdabot> | 5 |
| 03:55:35 | <Figs> | regex bothways = (S[0] << pattern ) >> '|' >> reverse(S[0]); |
| 03:55:39 | <mm_freak> | will this be translated into a long-short-division? |
| 03:55:57 | <mm_freak> | i.e. mpz_tdiv_q_ui instead of mpz_tdiv_q |
| 03:56:13 | <dancor> | oh interesting, hpaste truncates without telling where it will |
| 03:56:37 | <dancor> | i should have been counting |
| 03:56:53 | <dolio> | Actually, on the 'new' page it says it 'truncates after 5k'. |
| 03:57:04 | <dancor> | hence should have been counting |
| 03:57:07 | <shachaf> | dancor: You can simplify toDay to use pattern matching (unrelated). |
| 03:57:08 | <ddarius> | Is that characters or bytes? |
| 03:57:10 | <dolio> | Although, I suppose it could warn you if you try to post something big. |
| 03:57:36 | <SamB_XP> | I think it should truncate on 1kloc or something |
| 03:59:16 | <Figs> | you heard about the 500 mile email problem before? |
| 03:59:42 | <hpaste> | dancor pasted "shachaf: the end of my printf example" at http://hpaste.org/1706 |
| 03:59:50 | <Figs> | http://www.ibiblio.org/harris/500milemail.html :) |
| 03:59:51 | <lambdabot> | Title: The case of the 500-mile email |
| 04:00:03 | <dancor> | shachaf: ok i'll do that |
| 04:00:43 | <Figs> | ddarius, do you have any idea how I can check for infinite cycles? |
| 04:00:56 | <shachaf> | dancor: You're not using divF at all. |
| 04:01:01 | <Figs> | (when it is not so obvious as A = A|B? |
| 04:01:09 | <Figs> | like for example... |
| 04:01:10 | <shachaf> | dancor: Where are you planning to use it? |
| 04:01:17 | <Figs> | A = B|C |
| 04:01:19 | <dancor> | shachaf: http://hpaste.org/1706 |
| 04:01:24 | <Figs> | B = C|D |
| 04:01:33 | <Figs> | C= A |
| 04:01:43 | <shachaf> | dancor: Yes, I see that. |
| 04:01:51 | <oklopol> | Figs: if the string isn't consumed at all during a loop |
| 04:01:52 | <shachaf> | dancor: You're defnining it but never using it. |
| 04:01:59 | <oklopol> | then you have an infinite loop |
| 04:02:32 | <dancor> | shachaf: second post (1706 not 1705) 4th line from the bottom is: (i, CM.liftM2 (divF) (CM.liftM2 (-) (Just nowTime) t) |
| 04:02:34 | <oklopol> | in case your system is as flexible as i think it is, you'll get to undecidability and have to have a timeout. |
| 04:02:43 | <Figs> | I could just allow a "time out" of 10 hits to the same pattern with the same string length input |
| 04:02:48 | <hpaste> | aeyakovenko annotated "fast sha1" with "(no title)" at http://hpaste.org/1704#a1 |
| 04:03:02 | <shachaf> | dancor: Oh, sorry, I thought I was looking at 1706. |
| 04:03:16 | <shachaf> | dancor: Generally, you can annotate a post. |
| 04:03:28 | <Figs> | or check against the string passed :) |
| 04:03:49 | <hpaste> | aeyakovenko annotated "fast sha1" with "5k limit on hpaste sucks" at http://hpaste.org/1704#a2 |
| 04:03:51 | <shachaf> | dancor: putStrLn . show is called print (unrelated). |
| 04:04:12 | <Figs> | hmm, actually |
| 04:04:16 | <Figs> | if it hits the same one |
| 04:04:20 | <Figs> | without changing the length |
| 04:04:24 | <Figs> | then it's failed right? |
| 04:04:31 | <Figs> | because it will NEVER change the length? |
| 04:04:49 | <oklopol> | Figs: yes |
| 04:04:51 | <Figs> | of course, this means that I need to give each regex an ID |
| 04:04:59 | <Figs> | but that's not too hard really |
| 04:05:44 | <oklopol> | yes, but the problem is even if it's not tc and it's always decidable, it still might take weeks to match something if set up correct |
| 04:05:54 | <oklopol> | so the id wont save you all the time |
| 04:05:57 | <oklopol> | so make a timeout |
| 04:06:04 | <Figs> | and to make sure I haven't gone in a loop, I just need to have a simple test on each forwarding to make sure that the id of the instance isn't already in a list of ids |
| 04:06:04 | <oklopol> | as well i mean |
| 04:06:39 | <Figs> | no one would wait weeks anyway ;) |
| 04:06:48 | <Figs> | and it would be very hard I think |
| 04:06:52 | <hpaste> | glguy annotated "fast sha1" with "5k limit because hpaste is for snippets" at http://hpaste.org/1704#a3 |
| 04:06:56 | <Figs> | to set it up to take weeks |
| 04:07:01 | <Figs> | unless you can think of an example |
| 04:07:17 | <Figs> | I mean, there are plenty of stupid things you can do |
| 04:07:19 | <oklopol> | Figs: yes, but my point is it's better if it's automatically terminated than that the user will have to terminate it |
| 04:07:25 | <Figs> | but you'll run out of stack first |
| 04:07:28 | <oklopol> | by force |
| 04:07:31 | <oklopol> | yeah |
| 04:08:03 | <Figs> | my regex parser shouldn't have to deal with time |
| 04:08:07 | <Figs> | that is illogical |
| 04:08:11 | <ddarius> | @google detecting left recursion |
| 04:08:13 | <lambdabot> | Plugin `search' failed with: IRCRaised Lib.URL.isTextHTML: getHeader failed |
| 04:08:14 | <Figs> | what if it's running in another thread |
| 04:08:23 | <ddarius> | wtf? |
| 04:08:24 | <Figs> | and someone pauses the thread while waiting for the user to input something? |
| 04:08:36 | <oklopol> | Figs: indeed, i meant the kinda thing you said yourself, a match limit |
| 04:08:39 | <chessguy> | @go 3 parsecs in miles |
| 04:08:39 | <lambdabot> | 3 Parsecs = 5.75205844 x 10^13 miles |
| 04:08:40 | <Figs> | yeah |
| 04:08:45 | <Figs> | as soon as you hit one recursion |
| 04:08:47 | <ddarius> | wtf? |
| 04:08:49 | <chessguy> | @go recursion |
| 04:08:49 | <ddarius> | @google detecting left recursion |
| 04:08:49 | <Figs> | it will recurse again |
| 04:08:51 | <lambdabot> | http://en.wikipedia.org/wiki/Recursion |
| 04:08:51 | <lambdabot> | Title: Recursion - Wikipedia, the free encyclopedia |
| 04:08:52 | <lambdabot> | http://home.earthlink.net/~ltrammell/tech/recurs1.htm |
| 04:08:52 | <lambdabot> | Title: Detecting left recursion |
| 04:08:56 | <chessguy> | heh |
| 04:09:05 | <ddarius> | Whatever. |
| 04:09:23 | <chessguy> | ddarius, you must have caught google napping :) |
| 04:09:26 | <shachaf> | @ty (/) |
| 04:09:42 | <ddarius> | chessguy: Again! |
| 04:09:56 | <chessguy> | shameful |
| 04:10:07 | <shachaf> | @botsnack |
| 04:10:07 | <lambdabot> | :) |
| 04:10:20 | <shachaf> | @ty (/) -- Oh, extra space |
| 04:10:22 | <lambdabot> | forall a. (Fractional a) => a -> a -> a |
| 04:10:29 | <chessguy> | @quote extra.space |
| 04:10:29 | <lambdabot> | souwh says: <shapr> hm, I have extra spaces there. \n <souwh> oooh, those can be saved and reused later! |
| 04:11:12 | <shachaf> | ACTION stashes space in the Haskell code corner. |
| 04:11:35 | <chessguy> | and on that note... |
| 04:12:23 | <ddarius> | Indeed. |
| 04:16:26 | <Figs> | wow long load times |
| 04:16:59 | <shachaf> | Figs: For what? |
| 04:18:10 | <Figs> | home.earthlink.net .../ example from ddarius's search |
| 04:18:22 | <shachaf> | Oh. |
| 04:18:34 | <Figs> | see? forgotten about it already :D that long ago. |
| 04:18:59 | <shachaf> | Figs: First I thought you meant hpaste, then I thought you meant GHC or some other Haskell program. |
| 04:19:34 | <shachaf> | Figs: It loads instantly for me, though. |
| 04:20:11 | <Figs> | :S |
| 04:20:14 | <shachaf> | Figs: Have you done anything with Parsec yet, or is this only about your C++ parser? |
| 04:20:24 | <Figs> | only about C++ right now |
| 04:20:48 | <Figs> | so far this channel has been the most helpful :) |
| 04:21:25 | <Figs> | ergh |
| 04:21:31 | <Figs> | this hurts my head :P |
| 04:22:39 | <shachaf> | Of course #haskell is more helpful than ##c++ about C++... :-) |
| 04:23:07 | <Figs> | well, I was talking about #linguistics |
| 04:23:44 | <Figs> | they helped me a bit earlier, but they were offtopic for the last while |
| 04:23:57 | <Figs> | and have been fairly quiet |
| 04:24:04 | <Figs> | (I probably just picked a bad time :P) |
| 04:24:58 | <shachaf> | Figs: How can you be off-topic in #linguistics? They were probably just showing you some examples of colloquial English. :-) |
| 04:25:24 | <Figs> | you can be. :) |
| 04:25:55 | <Figs> | but it's ok |
| 04:27:36 | <Figs> | hmm, I guess I should make left-recursion a silent problem |
| 04:28:00 | <Figs> | since obviously if you have left-recursion, it's a dead end.... that goes on forever |
| 04:28:14 | <Figs> | and you can just go up and try the next branch |
| 04:28:42 | <brad_> | can someone provide a short, direct answer for what monad transformers (MaybeT) are, and where i would want to use them? i'm reading http://en.wikibooks.org/wiki/Haskell/Monad_transformers but it seems to not explane the motivation too well |
| 04:28:44 | <lambdabot> | Title: Haskell/Monad transformers - Wikibooks, collection of open-content textbooks |
| 04:29:13 | <brad_> | whoops, explane/explain...me kan spell! |
| 04:29:25 | <shachaf> | brad_: Have you used State yet? |
| 04:29:42 | <dolio> | Monad transformers let you augment one monad with the capabilities of another. |
| 04:29:48 | <brad_> | shachaf: not explicity, i have read about them a bit |
| 04:29:58 | <dolio> | Without having to rewrite them from scratch. |
| 04:30:00 | <oklopol> | Figs: left recursion isn't a "bug" in a regex, it's just hard to parse |
| 04:30:16 | <dolio> | So, state is 's -> (a, s)' |
| 04:30:18 | <Figs> | oklopol, if it goes on forever, it would count as a bug in my book. |
| 04:30:18 | <oklopol> | i mean, hard to match |
| 04:30:26 | <dolio> | And environment is 'r -> a' |
| 04:30:30 | <oklopol> | Figs: it doesn't necessarily go on forever |
| 04:30:41 | <Figs> | in the cases I'm talking about as bugs, it could |
| 04:30:52 | <Figs> | A = A|T |
| 04:30:57 | <dolio> | So, if you want state and environment, you could write a type 'newtype StateEnvironment r s a = SE (r -> s -> (a, s))' |
| 04:30:59 | <Figs> | would go on forever in my parser |
| 04:31:03 | <oklopol> | well, that's obviously a bug, yeah |
| 04:31:15 | <Figs> | actually, it's A = by_ref(A)|T |
| 04:31:16 | <oklopol> | but the state system would handle that easily |
| 04:31:16 | <Figs> | but meh |
| 04:31:16 | <bos> | is there a way to recover a real url from the clickthrough that reddit obfuscates with? |
| 04:31:19 | <dolio> | Or you could use 'ReaderT r (State s) a' |
| 04:31:31 | <Cale> | brad_: My take on it is that monads are, at least as far as programming is concerned, sort of like special-purpose programming languages. Monad transformers are things which construct new such programming languages from existing ones by adding features. |
| 04:31:32 | <dolio> | Which stacks environment on top of state. |
| 04:31:34 | <bos> | i find myself stymied every time i want to bookmark a pdf from reddit. |
| 04:31:43 | <Figs> | oklopol: what state system? |
| 04:31:45 | <brad_> | ah, thanks guys! |
| 04:32:01 | <oklopol> | Figs: the one for noticing infinite loops |
| 04:32:07 | <brad_> | it almost seems like monad transformers are a mechanism to do monad composition? or should i not abuse the term composition? |
| 04:32:12 | <Figs> | the one I'm trying to figure out how to write :) |
| 04:32:14 | <shachaf> | bos: Go to reddit.com/info/<id>/comments |
| 04:32:22 | <oklopol> | heh |
| 04:32:26 | <brad_> | thanks cale, that is a good explanation |
| 04:32:28 | <oklopol> | it shouldn't be that hard |
| 04:32:35 | <bos> | shachaf: exactly what i wanted, thanks! |
| 04:32:35 | <dolio> | brad_: Yeah. It's like composition. |
| 04:32:40 | <Figs> | it is |
| 04:32:50 | <Figs> | the problem is a bit hard to explain |
| 04:32:59 | <Figs> | you see, I expect this parser to be expanded on endlessly |
| 04:33:04 | <Cale> | The word "composition" gets my hopes up in ways that makes me not want to use it here, but yes. |
| 04:33:15 | <Figs> | composition? |
| 04:33:17 | <Figs> | :P |
| 04:33:25 | <shachaf> | bos: (Why do you want this, by the way?) |
| 04:33:28 | <Figs> | oh |
| 04:33:30 | <Figs> | never mind |
| 04:33:48 | <brad_> | thanks for the info guys! you are helpful as always. take care! |
| 04:34:02 | <Figs> | oklopol: I can extend my parser to do things most normal parsers don't really allow |
| 04:34:12 | <Figs> | like reversing strings |
| 04:34:20 | <bos> | shachaf: i bookmark the occasional reddit article in delicious |
| 04:34:30 | <oklopol> | Figs: can you parse code with it? :) |
| 04:34:33 | <bos> | ACTION has a few hundred haskell links in his delicious stream |
| 04:34:43 | <Figs> | if I can solve this problem, you can do a lot with it |
| 04:34:50 | <dancor> | is there a not for Ordering |
| 04:34:51 | <shachaf> | bos: Why not just go the reddit URL? It redirects anyway. |
| 04:35:08 | <Figs> | I'm trying to impliment exhaustive backtracking which is why this is just now becoming a problem |
| 04:35:13 | <dancor> | and why does @hoogle Ordering -> Ordering show me things for a -> a |
| 04:35:28 | <shachaf> | @hoogle Ordering -> Ordering |
| 04:35:28 | <lambdabot> | No matches, try a more general search |
| 04:35:37 | <Figs> | oh, crap :S |
| 04:35:41 | <dancor> | http://haskell.org/hoogle/?q=Ordering%20-%3E%20Ordering |
| 04:35:43 | <lambdabot> | Title: Ordering -> Ordering - Hoogle |
| 04:35:48 | <bos> | shachaf: i don't like the obfuscation and indirection |
| 04:35:51 | <dancor> | i didn't realzie that was diff from @hoogle |
| 04:35:55 | <dons> | after that silly thread last night about bit sieves, i updated the shootout entry, runs rather well! http://shootout.alioth.debian.org/gp4/benchmark.php?test=nsievebits&lang=all |
| 04:35:57 | <lambdabot> | Title: nsieve-bits benchmark | Gentoo : Intel® Pentium® 4 Computer Langu ..., http://tinyurl.com/sxpth |
| 04:36:30 | <Figs> | M = (T >> M) is ok, for example, since it will always pull of a T |
| 04:36:33 | <Figs> | or fail |
| 04:36:45 | <Figs> | *off |
| 04:37:03 | <shachaf> | bos: How is it more obfuscated to go through the reddit link? |
| 04:37:12 | <Figs> | but, M = M|T is bad |
| 04:37:17 | <bos> | because i can't see what it's pointing at? |
| 04:37:25 | <Figs> | M = T|M is bad too |
| 04:37:25 | <shachaf> | bos: Why not? |
| 04:37:31 | <dons> | reddit hides links |
| 04:37:46 | <bos> | for example, if i'm bookmarking a paper on wouter swierstra's home page, i can't see that in the url on delicious. |
| 04:37:53 | <bos> | all i see is a reddit link. |
| 04:38:17 | <shachaf> | bos: If I go to http://programming.reddit.com/goto?id=26nfh , it redirects me to the real URL. |
| 04:38:18 | <lambdabot> | Title: Getting started with HUnit |
| 04:38:23 | <dons> | authors should be encouraged to create .html pages for their papers |
| 04:38:27 | <bos> | shachaf: yes, but it's a redirect! |
| 04:38:29 | <dons> | ?go Stream Fusion |
| 04:38:30 | <lambdabot> | http://www.cse.unsw.edu.au/~dons/papers/CLS07.html |
| 04:38:30 | <lambdabot> | Title: Stream Fusion: From Lists to Streams to Nothing at All |
| 04:38:32 | <shachaf> | bos: And then I can just copy that one. |
| 04:38:34 | <dons> | like that, imo. |
| 04:38:44 | <bos> | shachaf: doesn't work if it's a PDF |
| 04:39:00 | <bos> | dons++ |
| 04:39:07 | <Figs> | hmm |
| 04:39:13 | <shachaf> | bos: Oh. |
| 04:39:20 | <Figs> | what about M = M>>T |
| 04:40:13 | <Figs> | it would be a bug eh |
| 04:40:14 | <dolio> | Figs: Isn't M = M>>T an infinite string of Ts? |
| 04:40:30 | <Figs> | basically, it'd turn into that, I think |
| 04:40:43 | <Figs> | not really what I meant though |
| 04:41:03 | <dolio> | If it were M = M>>T | e then it'd be T*. |
| 04:41:26 | <Figs> | yeah |
| 04:41:43 | <shachaf> | bos: I guess that might be the easiest way, then. |
| 04:41:50 | <Figs> | basically that'd be M = opt(by_ref(M) >> T); |
| 04:42:23 | <Figs> | which could be legal |
| 04:42:32 | <Figs> | ie, TTT |
| 04:43:11 | <Figs> | let's see... what'd happen though? |
| 04:43:24 | <Figs> | it tries to grab a by_ref(M) >> T... |
| 04:43:34 | <Figs> | the M will recurse and no change to input |
| 04:43:38 | <Figs> | at that point it should fail |
| 04:43:42 | <Figs> | go back up |
| 04:43:48 | <Figs> | then see a T |
| 04:43:51 | <Figs> | grab the T |
| 04:43:55 | <Figs> | and head out |
| 04:44:00 | <Figs> | but |
| 04:44:07 | <Figs> | that's not what it really means, is it? |
| 04:48:02 | <dancor> | > let notComp x = case x of EQ -> EQ; LT -> GT; GT -> LT in (notComp . compare) 4 5 |
| 04:48:03 | <lambdabot> | Couldn't match expected type `Ordering' |
| 04:48:21 | <dancor> | > (id . compare) 4 5 |
| 04:48:23 | <lambdabot> | LT |
| 04:48:40 | <dolio> | ((notComp .) . compare) |
| 04:48:58 | <dolio> | Of course, flip compare gets the same effect, I think. |
| 04:49:59 | <Jicksta> | hey guys |
| 04:50:10 | <dancor> | oh flip compare, brilliant |
| 04:50:18 | <shachaf> | Jicksta: Hello. |
| 04:50:24 | <Jicksta> | has anyone seen a comparison of the concurrency features in Haskell versus Erlang? |
| 04:52:18 | <dons> | Jicksta: good question |
| 04:52:23 | <Cale> | Jicksta: That would be useful, actually. |
| 04:52:38 | <Jicksta> | yeah. I'm very, very curious myself |
| 04:52:58 | <dons> | speedwise, compiled haskell concurrency seems to be a bit faster, but erlang supports distributoin better. erlang uses message passing a lot, haskell has Chans, Parallel hints, parallel arrays, STM and other things. |
| 04:53:30 | <dons> | the only speed benchmarks we know of are the two shootout benchmarks on concurrency |
| 04:53:41 | <siti> | I think ghc needs a parallel GC |
| 04:53:48 | <Jicksta> | does Haskell have an analog to Erlang's reloadable code? |
| 04:53:55 | <siti> | and haskell needs more standard libraries for concurrency, some things are missing |
| 04:54:02 | <dons> | Jicksta: yeah, but its more experimental, and not as pervasive as erlangs |
| 04:54:07 | <dancor> | dolio: i thought (f . g) x was the same as f (g x), e.g. http://www.cs.arizona.edu/~collberg/Teaching/372/2005/Html/Html-12/index.html |
| 04:54:10 | <lambdabot> | Title: CSc 372 - Comparative Programming Languages 12 : Haskell -- Composing Functions, http://tinyurl.com/36kn42 |
| 04:54:12 | <dons> | siti, oh, what kinds of things? |
| 04:54:15 | <shachaf> | dancor: It is. |
| 04:54:28 | <shachaf> | dancor: But (f . g) x y isn't the same as f (g x y) |
| 04:54:32 | <dolio> | dancor: Yes, but (f . g) x y /= f (g x y) |
| 04:54:42 | <dons> | erlang doesn't support large strings and binary files very well, we found out last week |
| 04:54:50 | <dons> | while ghc haskell can process terabytes happily. |
| 04:55:04 | <Jicksta> | hehe. I saw that on Dzone too |
| 04:55:05 | <siti> | dons: e.g. splitting a job in to many threads with load balancing etc. |
| 04:55:10 | <shachaf> | ACTION was under the impression Erlang had good support for binary files. |
| 04:55:14 | <siti> | I will try and get some code to show you an example |
| 04:55:15 | <dolio> | Essentially, you need a (.) for each argument of g, I think. |
| 04:55:16 | <shachaf> | I thought I'd heard that somewhere. |
| 04:55:21 | <dons> | shachaf: it has good support for pattern matching on binary |
| 04:55:23 | <Jicksta> | and someone actually retorted, claiming Erlang actually did handle those well |
| 04:55:30 | <Jicksta> | not one to call the shot -- it's not an issue I'd deal with often |
| 04:55:32 | <dons> | but loading large binary files into memory seemed to bang out at 300M on a recent thread |
| 04:55:51 | <dons> | its certainly has bit patterns, which are more flexible that pattern guards and Data.Binary |
| 04:56:11 | <dons> | I suspect Data.Binary is faster than erlang though, for streaming binary data |
| 04:56:25 | <dolio> | dancor: I've seen something that will let you do (f `comp` g) for g of more than one argument, but it involves some serious type hackery. |
| 04:56:50 | <Jicksta> | it seems to also depend on the algorithm (and knowledge of Erlang under the covers) |
| 04:56:56 | <dons> | definitely |
| 04:57:19 | <dons> | here's a generic speed benchmark, http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=ghc&lang2=hipe |
| 04:57:21 | <hpaste> | siti pasted "nice thread function" at http://hpaste.org/1707 |
| 04:57:21 | <lambdabot> | Title: Haskell GHC benchmarks | Gentoo : Intel® Pentium® 4 Computer Lang ..., http://tinyurl.com/28d6h2 |
| 04:57:27 | <dons> | so you can pretty much expect ghc to always be faster. |
| 04:57:29 | <Jicksta> | for example, it's more efficient to store bytes into an array, and then reverse and convert it to binary at the very end... |
| 04:57:36 | <dolio> | dancor: That is, the same 'comp' works for gs of various number of arguments. You can, of course, make comp1 comp2 ... without type hackery. |
| 04:57:38 | <dons> | but whether its as easy to reload code, distribute across many cluster nodes and so on |
| 04:57:57 | <Jicksta> | instead of composing binary objects together... |
| 04:58:07 | <Cale> | For shared-memory concurrency, GHC is getting quite good. |
| 04:58:42 | <dons> | so HIPE erlang is around the speed of GHC on concurrent stuff , for sequential stuff its far behind, is probably what we could conclude from the shootout |
| 04:58:47 | <Cale> | It'll be interesting to see how the data parallelism stuff goes if/when they end up adding support for distributed computation. |
| 04:58:49 | <dons> | i think that would be fairly uncontroversial |
| 04:59:05 | <dons> | Cale, yeah, there's other distributoin stuff already (e.g. the `ports' library) |
| 04:59:30 | <dons> | we've written a few things to run on the linux cluster here, a parallel monte carlo simulator, made up of tiny haskell nodes, for example |
| 04:59:46 | <dons> | Jicksta: so what particular things were you looking at? |
| 04:59:54 | <Cale> | dons: heh, I see you updated it just today? |
| 05:00:00 | <dons> | yesterday, yep |
| 05:00:31 | <Jicksta> | well, I have a hackery project coming up that requires dumbfounding speed... |
| 05:00:43 | <dons> | do you have a lot of cores to play with? |
| 05:00:47 | <Jicksta> | basically serving as a TCP proxy for a certain VoIP-related protocol |
| 05:01:04 | <dons> | doesn't erlang only run in SMP on x86 too? |
| 05:01:06 | <Jicksta> | not immediately... |
| 05:01:32 | <Jicksta> | Erlang doesn't require SMP to my knowledge |
| 05:01:36 | <dons> | so you need low level protocol parsing, binary data streaming |
| 05:01:41 | <Jicksta> | nope |
| 05:01:44 | <Jicksta> | plain text protocol |
| 05:01:52 | <dons> | yeah, they tend to distribute separate erlang nodes |
| 05:01:53 | <Jicksta> | proxying lines of text, actually |
| 05:02:04 | <Jicksta> | the command delimiter is \n |
| 05:02:09 | <dons> | so just fast strings? with the optoin to do things concurrently in the future? |
| 05:02:32 | <dons> | Haskell bytestrings are much much faster than strings in erlang, if that's relevant. |
| 05:02:35 | <Jicksta> | right... the idea is the switch/PBX connects to the proxy at localhost... |
| 05:02:51 | <Jicksta> | the proxy then tries to find the best candidate to proxy the call handling to... |
| 05:03:03 | <dons> | you might have libraries for some of the telecoms stuff already in erlang though, not sure. |
| 05:03:06 | <Jicksta> | if the thing to which it's proxying goes down, it recovers cleanly and connects elsewhere |
| 05:03:31 | <Jicksta> | well, there is a LGPL package that's similar to what I'm describing |
| 05:03:38 | <dons> | it does sound like an erlangy job then : fault tolerant reloading, that kind of thing. |
| 05:03:39 | <Jicksta> | not so much a proxy -- more like a full app server |
| 05:04:02 | <dons> | you probably could get a faster system in ghc haskell, though. so its a matter of how much you like haskell, i suspect :) |
| 05:04:10 | <Jicksta> | hehe |
| 05:04:18 | <Jicksta> | well, I certainly respect Haskell... never used it before |
| 05:04:30 | <Jicksta> | I've been dabbling with Erlang and do enjoy it |
| 05:04:41 | <dons> | well, its similar to erlang, nicer syntax, native code compilation, good concurrency |
| 05:04:45 | <Jicksta> | though, if Haskell makes that case that it's 50% faster or something it'd justify using it instead |
| 05:05:01 | <dons> | I think 50% faster for string processing would be not unreasonable |
| 05:05:05 | <dons> | if the strings were big enough |
| 05:05:06 | <Jicksta> | Erlang is compiled too by the way... |
| 05:05:10 | <Jicksta> | not sure if it's native code or bytecode |
| 05:05:23 | <dons> | yeah, i know, (see the benchmark link i posted) |
| 05:05:38 | <dons> | but these dyamically typed languages suffer since they're hard to compile efficiently |
| 05:05:46 | <dons> | and you insert all these runtime checks into the code, slowing things down |
| 05:05:55 | <Jicksta> | yeah |
| 05:05:59 | <Jicksta> | though look at smalltalk :) |
| 05:06:08 | <dons> | smalltalk and SBCL are rather good, yeah |
| 05:06:09 | <Jicksta> | something like 40% the speed of Java. |
| 05:06:17 | <Jicksta> | and five times faster than Python |
| 05:06:18 | <dons> | java's slow though :) |
| 05:06:24 | <dons> | pythons really slow :) |
| 05:06:27 | <siti> | dons: that's what I was about to say ;) |
| 05:06:40 | <Jicksta> | well, I'm a Ruby developer -- I know what slow code's like :) |
| 05:06:42 | <dons> | we tend to compare Haskell against C, for some reason |
| 05:06:49 | <Jicksta> | sometimes it just doesn't f'ing matter, honestly :) |
| 05:06:54 | <dons> | yeah |
| 05:06:56 | <Jicksta> | except in cases when you're making a proxy, for example :) |
| 05:07:03 | <dons> | but you think performance will be important for this project? |
| 05:07:12 | <Jicksta> | yeah, definitely |
| 05:07:17 | <siti> | ghc is much much faster (will in my testing) when the minimum heap size is increased for the GC |
| 05:07:43 | <dons> | avoiding GC is always good |
| 05:07:43 | <Jicksta> | what does Haskell concurrency look like? |
| 05:07:52 | <dons> | there's several forms |
| 05:07:57 | <siti> | forkIO ;) |
| 05:07:57 | <Jicksta> | in Erlang we just spawn a process, giving it a function |
| 05:08:01 | <dons> | explicit threads, implicit threads, transactoinal memory |
| 05:08:04 | <dons> | yeah, that's the basic form |
| 05:08:07 | <dons> | :t forkIO |
| 05:08:09 | <lambdabot> | Not in scope: `forkIO' |
| 05:08:12 | <dons> | :t Control.Concurent.forkIO |
| 05:08:14 | <lambdabot> | Couldn't find qualified module. |
| 05:08:20 | <Cale> | :t Control.Concurrent.forkIO |
| 05:08:21 | <siti> | ACTION hits lambdabot |
| 05:08:21 | <dons> | :t Control.Concurent.forkIO |
| 05:08:23 | <lambdabot> | Couldn't find qualified module. |
| 05:08:23 | <lambdabot> | IO () -> IO GHC.Conc.ThreadId |
| 05:08:25 | <Jicksta> | does Haskell have green threads? |
| 05:08:33 | <Cale> | *cough* two r's :) |
| 05:08:36 | <dons> | lightweight threads, that will use other cores if you have them |
| 05:08:49 | <Jicksta> | cool |
| 05:09:24 | <dons> | see haskell versus erlang benchmarks here: http://shootout.alioth.debian.org/gp4/benchmark.php?test=all&lang=ghc&lang2=hipe |
| 05:09:26 | <lambdabot> | Title: Haskell GHC benchmarks | Gentoo : Intel® Pentium® 4 Computer Lang ..., http://tinyurl.com/28d6h2 |
| 05:10:01 | <Jicksta> | looking at that now... |
| 05:10:03 | <Cale> | To go along with that basic form of concurrency, there are two systems for thread communication which are currently in GHC. |
| 05:10:04 | <dons> | ?docs Control.Concurrent |
| 05:10:04 | <lambdabot> | http://haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent.html |
| 05:10:17 | <dons> | is the low level concurrency layer, good to get the best performance |
| 05:10:37 | <Jicksta> | hmmm |
| 05:10:49 | <Cale> | The first, which is simpler, is based on something called an MVar, which is a mutable cell that can be empty or full. Reading from an empty MVar or writing to a full one blocks. |
| 05:10:59 | <dons> | there's lots of concurrency demos and so on haskell.org too, fwiw |
| 05:11:21 | <Cale> | In terms of that, there are various simple structures like channels, quantity semaphores and so on |
| 05:11:35 | <Cale> | Then there's a transactional thread communication library called STM |
| 05:11:57 | <Cale> | STM actions mutate shared thread variables and act as if they occur atomically. |
| 05:12:01 | <Cale> | and you can compose them |
| 05:12:22 | <Jicksta> | well, since I've no immediate use for concurrency, perhaps the best solution would be to implement a very efficient Haskell proxy and, in the future as necessary, implement the concurrency |
| 05:12:30 | <Jicksta> | so, I have to ask... |
| 05:12:48 | <Jicksta> | are there any other languages that you may recommend that're faster than Haskell? |
| 05:12:53 | <dons> | if you're just reading text data off a socket, yeah, i'd expect ghc to win. |
| 05:13:03 | <dons> | hmm, ocaml is a good one, otherwise you're down to C or C++ |
| 05:13:11 | <Cale> | Or Clean, perhaps? |
| 05:13:19 | <dons> | pretty dead project though |
| 05:13:22 | <Cale> | hmm |
| 05:13:25 | <Jicksta> | well, I'm staying away from C/C++ |
| 05:13:31 | <Jicksta> | not my idea of a high level language :) |
| 05:14:03 | <dibblego> | I know someone who is *convinced* that C is a high level language |
| 05:14:09 | <dons> | right. Haskell or OCaml then. for text processing off sockets, I'd probably go with Haskell, because of bytestrings. |
| 05:14:11 | <Jicksta> | oh, me too |
| 05:14:19 | <siti> | well "high" is relative |
| 05:14:25 | <Figs> | C and C++ are mid-level languages |
| 05:14:33 | <Jicksta> | I was with Mark Spencer once and he exclaimed to me seriously "You know what I love about C? It's just so simple" |
| 05:14:40 | <dibblego> | siti, that's my point as well, to no avail |
| 05:14:40 | <Cale> | If you're going to use Haskell, you probably want to give yourself at least a little time to get accustomed. :) Even though lots of stuff should be familiar from Erlang, there will also be quite a lot of new ideas, I suspect. |
| 05:15:03 | <Adamant> | using C is pretty simple. being correct with C is a fair bit harder |
| 05:15:13 | <Jicksta> | right |
| 05:15:21 | <dons> | that's true. you would want to learn it , write other programs, before betting the company on your haskell skillz :) |
| 05:15:23 | <Jicksta> | well, at any rate I won't be doing much of the coding myself... |
| 05:15:25 | <siti> | Jicksta: is he the guy that wrote asterisk? or am I getting confused? |
| 05:15:25 | <weitzman> | Jicksta: SML compiled with MLton is pretty fast |
| 05:15:31 | <shachaf> | Cale: Is Clean generally faster than Haskell? |
| 05:15:39 | <Jicksta> | likely be pulling in a developer from the community for consulting work |
| 05:15:48 | <dons> | shachaf: the Clean compiler seems to be rather good, yep. |
| 05:15:52 | <Cale> | shachaf: It has a rather fast IO system, from what I've seen. |
| 05:15:54 | <Jicksta> | siti: author of Asterisk, Gaim, L2TP, and others |
| 05:15:58 | <siti> | ok |
| 05:15:59 | <Jicksta> | CTO of Digium |
| 05:16:04 | <dons> | shachaf: there is also a haskell to clean translator, but its about half and half there. some things get faster, others get slower |
| 05:16:11 | <Jicksta> | "creator" I should say |
| 05:16:30 | <Cale> | shachaf: unfortunately, not a very abstract IO system -- you pass the 'world' around explicitly. |
| 05:16:31 | <Jicksta> | looking at the OCaml benchmarks |
| 05:16:37 | <siti> | Jicksta: I have heard rather bad things about the asterisk code :p I have had a look at some modules and well... it's crazy |
| 05:16:39 | <shachaf> | dons: Are the languages that close? |
| 05:16:53 | <dons> | Jicksta: that's a good idea. if you're looking to do this stuff commercially, talk to the Haskell companies (like Galois) or seek consultants on the mailing list |
| 05:16:56 | <shachaf> | Cale: Yes, that's about all I know about it. :-) |
| 05:17:01 | <dons> | shachaf: indeed, clean is really a `fork' of haskell |
| 05:17:16 | <dons> | well, its a fork that never merged back in. and then the community around it died |
| 05:17:27 | <weitzman> | Jicksta: Plus MLton supports continuations, if you're into that kind of thing |
| 05:17:29 | <shachaf> | dons: So they forked Haskell and took monadic IO out? |
| 05:17:34 | <shachaf> | dons: Why? |
| 05:17:46 | <shachaf> | dons: Just for performance, or for other reasons too? |
| 05:17:49 | <Jicksta> | weitzman: no need whatsoever for continuations for this project... |
| 05:17:54 | <shachaf> | dons: (Or is this an earlier Haskell?) |
| 05:18:10 | <dons> | its earlier. it didn't get merged into haskell , when all the other lazy pure research languages did |
| 05:18:22 | <dons> | though the authors were on the original haskell comittee |
| 05:18:38 | <dons> | its about 5 years older than ghc |
| 05:18:39 | <Cale> | Haskell 1.0 didn't have monadic IO yet, iirc. |
| 05:18:46 | <Jicksta> | found an interesting comparison... D is even faster than OCaml |
| 05:18:59 | <dons> | oh, D yes, that's another option. C++ improved |
| 05:19:14 | <weitzman> | Jicksta: Some people like having "cool" theoretical features around even if they serve no purpose |
| 05:19:16 | <dons> | not really the same kind of language as erlang, haskell or ocaml though. so depends on what you like |
| 05:19:29 | <Jicksta> | right |
| 05:19:44 | <shachaf> | Isn't D a much lower level than O'Caml? |
| 05:19:49 | <dons> | yes. |
| 05:19:51 | <shachaf> | ACTION has not looked much into it. |
| 05:19:59 | <dons> | its a C++-ish |
| 05:20:16 | <Jicksta> | yeah. kinda takes features from C++ and Objective C |
| 05:20:18 | <dons> | but designed, rather than growing in a bucket of primordial language soup |
| 05:20:33 | <Jicksta> | though, they have the most retarded marketing... they say they match the productivity of Ruby |
| 05:20:42 | <dons> | heh |
| 05:20:45 | <Jicksta> | clearly they have NO IDEA what Ruby is beyond its name... |
| 05:20:52 | <glguy> | lol, the productivity of ruby |
| 05:22:09 | <dons> | Jicksta: do let us know how you go, and what you decide upon. |
| 05:22:20 | <Jicksta> | I have a few months to make any decisions |
| 05:22:21 | <dons> | if you pick haskell, there's people around here who'll happily help, or point you to consultants. |
| 05:22:33 | <dons> | ah good. so you can get a feel for the design space |
| 05:22:34 | <Cale> | Jicksta: and make sure you hang around here lots if you're learning Haskell, since we like beginners :) |
| 05:22:42 | <Jicksta> | hehe :) |
| 05:22:48 | <Jicksta> | glad to see Haskell community is so supportive :) |
| 05:22:50 | <Heffalump> | especially with sugar on ;-) |
| 05:23:06 | <bos> | the guy behind D has an ... interesting personality. |
| 05:23:42 | <Korollary> | and almost a total lack of familiarity with non-algol syntax languages |
| 05:24:15 | <bos> | well, that could describe about 99.5% of programmers :-) |
| 05:24:31 | <Korollary> | it shouldnt describe language designers |
| 05:25:22 | <Cale> | "Note: all D users agree that by downloading and using D, or reading the D specs, they will explicitly identify any claims to intellectual property rights with a copyright or patent notice in any posted or emailed feedback sent to Digital Mars." |
| 05:25:24 | <weitzman> | D has some language design ideas that are pretty interesting regardless |
| 05:25:35 | <Cale> | That's a confusing remark :) |
| 05:25:51 | <dancor> | in general is something like mapM_ putStrLn ls or putStrLn $ unlines ls better |
| 05:26:05 | <dancor> | do you pay per io start |
| 05:26:19 | <dancor> | or are they the same |
| 05:26:20 | <Cale> | dancor: I'd expect them to be similar. |
| 05:26:35 | <shachaf> | dancor: (You'd use putStr in this case, though that doesn't answer your question.) |
| 05:27:16 | <shachaf> | dancor: How big is the list? |
| 05:28:06 | <dancor> | shachaf: no matter, for any particular case i can just test it. i was just wondering about paying per io |
| 05:28:59 | <dancor> | another q: "why" can't i have (++ " " ++) for (\ x y -> x ++ " " ++ y) |
| 05:29:05 | <dancor> | but e.g. (*) is ok |
| 05:29:10 | <Cale> | dancor: Well, mapM_ has a little more structure to it than just a plain putStr, so it's possible that you pay a little more. |
| 05:30:11 | <bos> | dancor: the syntax for (*) is special. |
| 05:30:22 | <bos> | to write what you want, you'd need to do this. |
| 05:30:29 | <bos> | @pl (\ x y -> x ++ " " ++ y |
| 05:30:30 | <lambdabot> | (line 1, column 25): |
| 05:30:30 | <lambdabot> | unexpected end of input |
| 05:30:30 | <lambdabot> | expecting letter or digit, variable, "(", operator, ":", "++" or ")" |
| 05:30:30 | <Cale> | @pl (\ x y -> x ++ " " ++ y) |
| 05:30:30 | <lambdabot> | (. (" " ++)) . (++) |
| 05:30:33 | <bos> | @pl \ x y -> x ++ " " ++ y |
| 05:30:33 | <lambdabot> | (. (" " ++)) . (++) |
| 05:30:40 | <bos> | @quote stereo |
| 05:30:40 | <lambdabot> | Cale says: Welcome to #haskell where your questions are answered in majestic stereo! |
| 05:31:18 | <bos> | dancor: writing something like ("foo"++) or (++"foo") is called a section, and it's special, too. |
| 05:31:19 | <dancor> | lolbdabot |
| 05:31:54 | <dancor> | we should add ++"a"++ to the special things |
| 05:31:59 | <Figs> | bbl |
| 05:32:05 | <bos> | so (++) by itself is special, and ("foo"++) and (++"foo") are special, but those are the only special building blocks you get for this purpose. it doesn't generalise. |
| 05:32:29 | <bos> | dancor: but the specialness isn't limited to the (++) operator. |
| 05:32:32 | <dancor> | > (++"a"++"b") "c" |
| 05:32:34 | <lambdabot> | "cab" |
| 05:32:46 | <Cale> | heh |
| 05:32:53 | <shachaf> | > ("a"++"b"++) "c" |
| 05:32:54 | <lambdabot> | The operator `++' [infixr 5] of a section |
| 05:32:54 | <lambdabot> | must have lower preced... |
| 05:33:00 | <bos> | you can have a section with a missing parameter on the left, or on the right, but not both. |
| 05:33:03 | <dancor> | omg |
| 05:33:05 | <shachaf> | It's just because ++ is infixr. |
| 05:33:24 | <dancor> | how dare ("a"++"b"++) not work |
| 05:33:29 | <Cale> | (++"a"++"b") = (++("a"++"b")) |
| 05:33:39 | <Cale> | because ++ is right associative |
| 05:33:49 | <opqdonut> | and (++) is not a section but a "functionized" version of ++ in essence |
| 05:34:16 | <Cale> | You have to write (("a"++"b")++) if you want that |
| 05:34:21 | <dancor> | is this a case where the arbitrarity of the result to the uninitiated is important for some coding safety |
| 05:34:26 | <dancor> | or is it just completely insane |
| 05:34:35 | <dancor> | and now all of you are too for being like "this is fine" |
| 05:35:10 | <Cale> | Well, sections are hard to read when they get too complicated anyway |
| 05:35:57 | <shachaf> | dancor: It makes sense, because the "new parens" in (++"a"++"b") are added as (++{"a"++"b"}), but in ("a"++"b"++) They're added as ("a"++{"b"++)}. |
| 05:35:58 | <Cale> | (++) is deceptive too, because it's an associative operator |
| 05:36:35 | <dancor> | shachaf: oh have no doubt that it makes sense, but so does perl |
| 05:36:43 | <Cale> | > (3/7/) 5 |
| 05:36:45 | <lambdabot> | 8.571428571428572e-2 |
| 05:37:09 | <shachaf> | > ((3/7)/5) |
| 05:37:10 | <lambdabot> | 8.571428571428572e-2 |
| 05:37:11 | <Cale> | > (3/7/) 1 :: Rational |
| 05:37:12 | <lambdabot> | 3%7 |
| 05:37:30 | <Cale> | > (3/(7/1)) :: Rational |
| 05:37:31 | <lambdabot> | 3%7 |
| 05:37:36 | <Cale> | heh, bad example |
| 05:37:43 | <Cale> | > (3/(7/2)) :: Rational |
| 05:37:45 | <lambdabot> | 6%7 |
| 05:37:58 | <Cale> | > (3/7/) 2 :: Rational |
| 05:37:59 | <lambdabot> | 3%14 |
| 05:38:06 | <shachaf> | > (/7/2) 3 |
| 05:38:07 | <lambdabot> | The operator `/' [infixl 7] of a section |
| 05:38:07 | <lambdabot> | must have lower precede... |
| 05:38:21 | <shachaf> | > (\x -> x/7/2) 3 |
| 05:38:22 | <lambdabot> | 0.21428571428571427 |
| 05:38:25 | <Cale> | > (/(7/2)) 3 |
| 05:38:27 | <lambdabot> | 0.8571428571428571 |
| 05:39:06 | <Cale> | Which one would you expect (/7/2) 3 to mean? 3/7/2 or 3/(7/2) ? |
| 05:39:30 | <bos> | march the 7th 2002! |
| 05:39:40 | <dancor> | :: unsafeDateCoerce |
| 05:39:41 | <shachaf> | Cale: It's infixl, so I'd say the first one. |
| 05:39:41 | <bos> | ahem. sorry. |
| 05:40:15 | <shachaf> | bos: No, 2nd of July, year 3. |
| 05:40:16 | <Cale> | It would be doable, but I think it's sort of tricky to the point where it's worth making people write a lambda. |
| 05:40:55 | <shachaf> | @pl \x -> x/7/2 |
| 05:40:56 | <lambdabot> | (/ 2) . (/ 7) |
| 05:41:03 | <shachaf> | That's also pretty clear. |
| 05:41:20 | <Cale> | People have also wanted funny syntax with "blanks" to avoid lambdas, but I don't think it's worth it. |
| 05:41:44 | <Cale> | Like, lambda is there for a reason, after all :) |
| 05:41:52 | <shachaf> | Cale: You mean in that "burn" language? |
| 05:42:40 | <shachaf> | Cale: The "Business Objects Gem Cutter" email on -cafe is the only one I've seen. |
| 05:42:43 | <Cale> | I mean like (foldr (:) _ xs) to mean (\z -> foldr (:) z xs) |
| 05:43:16 | <shachaf> | Cale: That's quite ambiguous. |
| 05:43:33 | <shachaf> | ACTION would probably not like that. |
| 05:43:36 | <Cale> | yeah, there are lots of problems with stuff like that |
| 05:44:02 | <edward2> | cale: do you think that rebinding Eq, And, Or, etc. so that you can say things like filter (isAlpha || isDigit) "foo12" would be too scary to end users? I already let you add functions etc, so it seems like the next logical step |
| 05:44:30 | <Cale> | There were long discussions about things like that on -cafe a while back and the consensus was basically that they're too tricky. |
| 05:44:34 | <shachaf> | filter (liftM2 (||) isAlpha isDigit) ['a','1',' '] |
| 05:44:37 | <shachaf> | > filter (liftM2 (||) isAlpha isDigit) ['a','1',' '] |
| 05:44:39 | <lambdabot> | "a1" |
| 05:44:41 | <edward2> | cale: =/ |
| 05:44:54 | <Cale> | edward2: sorry, that wasn't to you |
| 05:44:55 | <edward2> | shachaf: yeah i know |
| 05:44:59 | <edward2> | cale: whew =) |
| 05:45:17 | <edward2> | shachaf: its just in my toy prelude i'm going with the most general type signatures for everything =) |
| 05:45:40 | <Cale> | edward2: Well, go for it and see :) |
| 05:45:57 | <Cale> | edwardk: Your monad stuff is already pretty scary :) |
| 05:46:03 | <edwardk> | its already in, i just thought i'd check and see if there was some great moral reason others could think of against it ;) |
| 05:46:06 | <edwardk> | heh |
| 05:46:17 | <shachaf> | Cale: Which "monad stuff"? |
| 05:46:20 | <edwardk> | the version i'm currently inclined to include is just generalized, not parameterized |
| 05:46:26 | <edwardk> | shachaf: http://comonad.com/reader |
| 05:46:40 | <lambdabot> | Title: The Comonad.Reader |
| 05:46:41 | <Cale> | The strange join :: m (m' a) -> m'' a thing |
| 05:46:44 | <edwardk> | type-parameterized monads by just letting the monad type vary |
| 05:47:12 | <edwardk> | class ... => Bind m m' m'' where (>>=) :: m a -> (a -> m' b) -> m'' b |
| 05:47:54 | <edwardk> | my current prelude just uses the oleg trick though, because it preserves type inference while the type-parameterized version requires the occasional 'go' to be inserted |
| 05:48:36 | <edwardk> | that and mixing type-parameterized and generalized monads yields a LOT of typeclasses. to the point where you'd need template haskell to practical define an instance =) |
| 05:48:59 | <edwardk> | which i'm actually kind of considering at this point given where my numerical type hierarchy has gone |
| 05:49:10 | <Cale> | Hehe, I have the small satisfaction that I actually came up with Oleg's trick a while before him, but I didn't post it, because I thought it was too ugly. |
| 05:49:21 | <edwardk> | fair enough |
| 05:49:34 | <Cale> | Well, depending on whether he posted his trick immediately, of course :) |
| 05:49:52 | <edwardk> | i just wish GHC's do sugar wasn't monomorphic in the monad type |
| 05:50:22 | <Cale> | mm... I kind of think it makes sense for it to be |
| 05:50:34 | <edwardk> | given the current implementations, sure =) |
| 05:51:15 | <Cale> | You want to permit things like using STM actions as IO actions, right? |
| 05:51:24 | <edwardk> | it kind of mucks up my examples like do x <- [1..]; y <- if even x then Just x else Nothing mixing monad cases |
| 05:51:38 | <shachaf> | edwardk: On that post, you have: |
| 05:51:39 | <shachaf> | class Bind m m' m'' | m m' -> m'' where (>>=) :: m p a -> (a -> m' a) -> m'' a |
| 05:51:45 | <edwardk> | er |
| 05:51:57 | <edwardk> | i mucked up that version, it should be p p' p'' | p p' -> p'' |
| 05:52:11 | <edwardk> | i backed into it from the actual version, i'll fix |
| 05:52:23 | <edwardk> | and whoa that one is messed |
| 05:52:27 | <Cale> | Perhaps it would be better to have a class that defined how to lift one monad to another, and allow do-notation to insert lifts when appropriate instances of that class were available? |
| 05:52:52 | <Cale> | The open-class problem is a little unsettling in that regard though. |
| 05:53:09 | <edwardk> | what i'm currently using for my security monads which i'll blog up in a day or two as soon as i get all the lattice product stuff done is class Rebind m m' m'' ... so that the normal monad sugar is untouched. |
| 05:53:33 | <edwardk> | its not as fun, but it has the right properties and doesn't need ghc's behavior to change to be useful |
| 05:53:52 | <Cale> | How does that work? |
| 05:54:00 | <edwardk> | the rebind stuff? |
| 05:54:43 | <edwardk> | one sec |
| 05:54:49 | <edwardk> | i'll clean something up and you can peek |
| 05:55:45 | <edwardk> | http://comonad.com/haskell/security-policy/src/Control/Monad/Security.hs |
| 05:55:47 | <lambdabot> | http://tinyurl.com/3atx79 |
| 05:55:53 | <edwardk> | its not quite ready to check out |
| 05:56:07 | <edwardk> | 'SecurityLattice' is the 'Rebind' in question |
| 05:56:55 | <edwardk> | where I treat monads as security levels, with a meet-semilattice between different monads in a policy, and rely on the control over the export of the policy type to keep people from extending and subverting the policy |
| 05:57:34 | <edwardk> | http://comonad.com/haskell/security-policy/test/Policy.hs shows the current version in practice |
| 05:58:02 | <edwardk> | what i'm doing now is defining various semilattice products to make it easier to actually define policies |
| 05:58:31 | <Cale> | Who are you working for? :) |
| 05:58:31 | <edwardk> | no one, its my own toy |
| 05:58:38 | <Cale> | ah, "If I told you, I'd have to kill you", would be more interesting :) |
| 05:58:53 | <edwardk> | I do work for a Raytheon subcontractor doing defense work though during the day though =) |
| 05:58:59 | <Cale> | :) |
| 05:59:08 | <Cale> | canHasStdio :) |
| 05:59:13 | <edwardk> | =) |
| 05:59:35 | <edwardk> | http://comonad.com/haskell/security-policy/test/Main.hs shows the actual kind of code that would use that policy |
| 05:59:55 | <edwardk> | i was planning on blogging this up this weekend, but i haven't had time to resolve all of the 'how-to-cut-down-boilerplate' issues yet |
| 06:00:29 | <edwardk> | so it'll probably be Tuesday before i get a nice writeup |
| 06:00:50 | <Cale> | I wonder how well class aliases would help. |
| 06:01:04 | <Cale> | Someone really really ought to implement them already :) |
| 06:01:24 | <edwardk> | well, its one reason why my prelude is so much easier in my language than haskell |
| 06:01:39 | <edwardk> | because dictionaries there are just polymorphic records, so you can define them all in one go usually |
| 06:01:50 | <edwardk> | here it gets piecemealed when i break them apart |
| 06:03:05 | <edwardk> | anyways, the basic idea is you can dump the policy into one module or package and never expose it, then the way the rest of the system is designed without cheating with unsafe tricks you can't access the data in a higher security level, so you get a form of security monad, except with compile time checks using the parameterization trick from the other day |
| 06:03:30 | <Cale> | Speaking of potential defence contracts for Raytheon, have you seen that google video presentation on electrostatic containment fusion reactors? |
| 06:03:33 | <bos> | i wonder where ABC got its use of the offside rule from. none of the original ABC papers is online, so i can't see if ISWIM is cited. |
| 06:04:30 | <edwardk> | the only worries I can think of are Bjorn's standalone deriving clauses since i use newtypes everywhere so all the monads self-erase, various IO cast hackery, and the unsoundness of data families and newtypes. In the absence of those it appears to be impossible to subvert the type system to get at the data. |
| 06:04:39 | <edwardk> | not yet |
| 06:04:57 | <shachaf> | Why do people call ((->) e) the Reader monad, instead of the ((->) e) monad? |
| 06:05:07 | <shachaf> | Isn't Reader the Reader monad? |
| 06:05:09 | <Cale> | shachaf: they're isomorphic |
| 06:05:30 | <bos> | because ((->) e) is hard to pronounce, and the two are the same thing. |
| 06:05:54 | <shachaf> | Cale, bos: OK, it makes sense. |
| 06:06:08 | <shachaf> | (Why can't it be called the (e ->) monad, by the way?) |
| 06:06:20 | <Cale> | We should really allow sections for infix type constructors |
| 06:06:34 | <Cale> | But that's something which was left out of the syntax |
| 06:06:40 | <edwardk> | er and that version there won't compile because the test is broken, as it was written before i transformed policies into monads themselves in order to define lattice sums. |
| 06:06:58 | <edwardk> | you can't construct partial infix applications at the type level shachaf, thats basically why |
| 06:07:26 | <shachaf> | edwardk: It's just a matter of syntax, though. |
| 06:07:36 | <edwardk> | not entirely because its not symmetric |
| 06:07:51 | <shachaf> | edwardk: What do you mean? |
| 06:08:00 | <edwardk> | you can define the functor (e->) but not the contrafunctor (->a) |
| 06:08:22 | <edwardk> | because the latter isn't just 'partially' applied, its applied to a later argument. |
| 06:08:40 | <edwardk> | so fully supporting it, would extend what the type system can do |
| 06:08:52 | <shachaf> | ACTION also wants flip and friends on the type level, though. :-) |
| 06:09:12 | <Cale> | shachaf: You probably want type lambdas, but they really make type inference hard. |
| 06:09:19 | <edwardk> | sure, one of the things i want in my toy language, the problem is they play hell with type inference and typeclasses, etc. |
| 06:09:32 | <shachaf> | Cale: Yes, I do, and yes, I'd guess they would. :-) |
| 06:09:50 | <edwardk> | basically you lose a lot of the benefits of haskell typeclasses with them =/ |
| 06:09:53 | <dblhelix> | shachaf: be careful what you ask for: we do not want to find ourselves lost in a system that requires higher-order unification ;-) |
| 06:10:02 | <edwardk> | i can't seem to figure out how to get MPTCs to survive in their presence |
| 06:10:52 | <edwardk> | actually there was a good paper on a limited form of them by neubauer and thiemann i think |
| 06:11:02 | <edwardk> | http://citeseer.ist.psu.edu/neubauer02type.html <-- ahh there it is |
| 06:11:04 | <lambdabot> | Title: Type Classes With More Higher-Order Polymorphism - Neubauer, Thiemann (ResearchI ... |
| 06:11:27 | <Cale> | Basically, the Haskell approach has been to extend things in ways which are mostly conservative, but which allow for fancy types, with an attempt to minimise the additional type signatures you have to use to get them. |
| 06:11:34 | <edwardk> | showing how to deal with a limited form of inference by making a deterministic choice for flex-flex. |
| 06:11:35 | <dblhelix> | edwardk: the problem with introducing a limited form of type lambdas is that you have to be very careful to keep the language understandable |
| 06:11:40 | <edwardk> | yep |
| 06:12:24 | <shachaf> | Why limited? Let's have a full Haskell on the type level! :-) |
| 06:12:38 | <edwardk> | in my case i kind of let the type-level functions have their wicked way then build up typeclasses off of the fully reduced forms |
| 06:12:40 | <Cale> | shachaf: I think Cayenne might do that |
| 06:12:49 | <dons> | shachaf: makes the types too hard |
| 06:12:52 | <edwardk> | shachaf: again, my goal more or less |
| 06:12:54 | <dons> | and you can't do inference anymore |
| 06:13:03 | <dblhelix> | there are nights that I don't sleep too well wondering if a language with gadts, mptcs with fds etc. is still suitable for novice programmers |
| 06:13:16 | <dons> | fds, no. |
| 06:13:27 | <dons> | gadts don't seem too bad |
| 06:13:28 | <edwardk> | you can do inference, but its tricky to get the staging right and you need a form of pointedness in the type checker to guarantee termination |
| 06:13:30 | <Cale> | gadt's aren't so bad |
| 06:13:39 | <dblhelix> | ASTs are a lot better indeed, especially for novices |
| 06:14:07 | <dons> | i suspect associated types will be newbie friendly, in comparison to FDs |
| 06:14:12 | <dblhelix> | still, what I like about Haskell 98 is that is can still envision it as the first programming language one learns |
| 06:14:23 | <dons> | since its obvious how to add extra types to your class, and have themvary on a per-instance basis |
| 06:14:36 | <shachaf> | ACTION definitely counts as a novice. :-) |
| 06:14:37 | <Cale> | dblhelix: Well, novices manage to learn perl. |
| 06:14:50 | <Cale> | (somehow) |
| 06:14:55 | <dons> | what novices don't know won't hurt them more than once a week, eh? :) |
| 06:14:58 | <dblhelix> | Cale: why are you trying to depress me? ;-) |
| 06:15:19 | <Cale> | hehe |
| 06:15:19 | <edwardk> | My current approach is if the function is unpointed then you can use it at the type level, if it isn't the typechecker will give it a window in which to run speculatively to a normal form, and if it fails I give up Cayenne style. |
| 06:15:21 | <dblhelix> | dons: I used to think that too... and maybe I still do |
| 06:15:33 | <dons> | dblhelix: seen the hackathon page yet? (or did i mention that already?) |
| 06:15:38 | <dons> | http://haskell.org/haskellwiki/Hac_2007_II |
| 06:15:39 | <lambdabot> | Title: Hac 2007 II - HaskellWiki |
| 06:15:53 | <Cale> | dblhelix: What do you think of the idea of 'language levels'? |
| 06:15:57 | <dblhelix> | dons: I've seen it... still can't make it though |
| 06:16:14 | <dblhelix> | Cale: we've been seriously considering it to be incorporated in helium |
| 06:16:14 | <edwardk> | where polymorphic unpointed total functions can in general be used in what i would have to call a "poly-sorted" fashion. |
| 06:16:19 | <dons> | we need someone from Utrecht ! :) |
| 06:16:29 | <edwardk> | problem is i lose phantom types =( |
| 06:16:31 | <dons> | you guys still write haskell, right? :) |
| 06:16:41 | <dons> | can't let chalmers take over everything |
| 06:16:42 | <dblhelix> | dons: afaik all the utrecht guys are leaving after cufp |
| 06:17:04 | <dblhelix> | most of us arrive before ifl already, you know |
| 06:17:05 | <shachaf> | ACTION wishes more (any) Haskell-ish events were around here. |
| 06:17:07 | <dons> | yeah |
| 06:17:17 | <shachaf> | I guess Oregon counts as pretty close. |
| 06:17:22 | <Cale> | I think it might be worthwhile have a -101 flag in GHC. While we're at it, let's provide for multiple base libraries, so that progress can be made while retaining compatibility. |
| 06:17:28 | <Cale> | to* |
| 06:17:40 | <dblhelix> | dons: we still write haskell, indeed |
| 06:18:03 | <dons> | just teasing. ;) |
| 06:18:11 | <dblhelix> | I know |
| 06:18:12 | <Cale> | Southern Ontario needs more Haskell events :) |
| 06:18:12 | <dblhelix> | :-) |
| 06:18:28 | <shachaf> | Cale: Are you sure having separate libraries is a good idea? |
| 06:18:41 | <bos> | heck, we can't even manage any haskell events in the san francisco area, and we have about a dozen haskellers here. |
| 06:18:54 | <Cale> | shachaf: Well, it's better than being stuck with the Haskell 98 prelude forever. |
| 06:18:56 | <dons> | we'll have to do something about that, bos. |
| 06:19:01 | <shachaf> | Cale: A "learning mode" is one thing, but actually using Haskell with two very different libraries is another. |
| 06:19:02 | <dblhelix> | shachaf: helium already has two preludes: one with overloading, one without |
| 06:19:25 | <dblhelix> | but admittedly, in some cases having two preludes also adds to the confusing |
| 06:19:32 | <dblhelix> | it's really hard to get these things right |
| 06:19:33 | <shachaf> | Cale: For example, if fmap was called map in one but not the other, it would break a lot of code. |
| 06:19:43 | <shachaf> | Cale: And that's just a simple example. |
| 06:19:50 | <Cale> | There's a fundamental conflict of interest between providing compatibility and developing the language. |
| 06:19:59 | <Cale> | shachaf: Of course, that's the point. |
| 06:20:09 | <Cale> | shachaf: Provide compiler flags to choose. |
| 06:20:15 | <dblhelix> | jurriaan is sliding towards empirical research more and more... just to find out what is effective and what is not when teaching haskell to undergraduates |
| 06:20:27 | <shachaf> | Cale: But what if one piece of code does one thing and another does another? |
| 06:20:51 | <shachaf> | It'd be like working with multiple browsers... |
| 06:21:14 | <Cale> | Well, you just agree to version things. |
| 06:21:36 | <shachaf> | Cale: (I do think it's a good idea, though, if it can be made to work.) |
| 06:21:54 | <Cale> | If I want to write in Haskell 2 and you want to write in Haskell '98, then maybe we can't load each other's modules. |
| 06:22:05 | <Cale> | But then again, perhaps something could be made to work. |
| 06:22:22 | <Cale> | Still, kind of doubtful that the classes would work out. |
| 06:23:14 | <Cale> | We'll likely need something soon along these lines anyway if Haskell 98 is going to co-exist with Haskell'. |
| 06:23:46 | <shachaf> | How big a change is Haskell'? |
| 06:24:13 | <Cale> | Not big relative to stuff already in GHC, but I'm fairly sure some breakage is being considered. |
| 06:24:25 | <Cale> | It's supposed to mostly be a subset of what's already in GHC. |
| 06:24:38 | <shachaf> | Will it have MonadZero/monad comprehensions? |
| 06:24:52 | <Cale> | So no new fancy untested record system, for instance. |
| 06:24:58 | <Cale> | I don't think that's been decided. |
| 06:25:07 | <Cale> | But it would be nice. |
| 06:25:16 | <Cale> | I really hope it has MonadZero. |
| 06:26:08 | <Cale> | Personally, I think we should do one major world-breaking change and not too far into the future, because Haskell is getting more popular, and this sort of thing only gets harder and harder to do. |
| 06:26:11 | <opqdonut> | monad comprehensions <3 |
| 06:26:11 | <shachaf> | Will map/fmap/(.)/mapMaybe/(<$>)/etc. be consolidated? |
| 06:26:35 | <opqdonut> | shachaf: consolidated how? |
| 06:26:44 | <shachaf> | opqdonut: They're all the same function. |
| 06:26:49 | <Cale> | Then again, major world-breaking changes might be just the thing to bring popularity down ;) |
| 06:27:00 | <opqdonut> | shachaf: yeah they're all fmap :) |
| 06:27:09 | <opqdonut> | i think the multiple names aren't a problem |
| 06:27:22 | <Cale> | I think we should keep (.) and map, but have them both mean fmap. |
| 06:27:28 | <shachaf> | opqdonut: Will they all have type (Functor f) =>, at least? |
| 06:27:42 | <Cale> | Simply because sometimes you want infix and sometimes you want prefix. |
| 06:28:06 | <shachaf> | Will the class hierarchy be Functor => Applicative => Monad? |
| 06:28:19 | <Cale> | shachaf: I think these are all unresolved questions. |
| 06:28:22 | <opqdonut> | that'd be nice |
| 06:28:45 | <shachaf> | Cale: These are just various changes I've heard rumors of, that would be nice to see. |
| 06:29:13 | <Cale> | In the current draft, it looks like the Monad class hasn't been touched. |
| 06:29:32 | <Cale> | neither has Functor |
| 06:29:40 | <opqdonut> | where is the current draft? |
| 06:29:47 | <Cale> | http://darcs.haskell.org/haskell-prime-report/report/haskell-report-html/index.html |
| 06:29:49 | <lambdabot> | Title: The Haskell Prime Language Report, http://tinyurl.com/2pdmj9 |
| 06:30:50 | <shachaf> | Hmm, are all the modules still flat (Monad instead of Control.Monad)? |
| 06:31:40 | <sjanssen> | I don't think the report has been changed much at all |
| 06:32:47 | <Cale> | aha |
| 06:32:50 | <Cale> | http://hackage.haskell.org/trac/haskell-prime/wiki/Status%27 |
| 06:32:51 | <lambdabot> | Title: Status' - Haskell Prime - Trac |
| 06:33:05 | <Cale> | That lists the Definitely-in and Probably-in changes. |
| 06:33:17 | <Cale> | Mostly pretty uncontroversial stuff :) |
| 06:33:36 | <edwardk> | cale: i'm currently just using (.) in my toy prelude |
| 06:34:10 | <edwardk> | @type <$> |
| 06:34:10 | <Cale> | edwardk: The trouble comes when you want to write map f in the middle of a chain of compositions |
| 06:34:12 | <lambdabot> | parse error on input `<$>' |
| 06:34:16 | <shachaf> | @ty (<$>) |
| 06:34:18 | <lambdabot> | forall a b (f :: * -> *). (Functor f) => (a -> b) -> f a -> f b |
| 06:34:23 | <shachaf> | (<$>) = fmap |
| 06:34:35 | <edwardk> | er yeah =) |
| 06:34:37 | <Cale> | stuff . (f .) . otherStuff looks kind of strange |
| 06:34:40 | <shachaf> | @src (<$>) |
| 06:34:40 | <lambdabot> | f <$> a = fmap f a |
| 06:34:47 | <Cale> | or you could do (.) f |
| 06:34:51 | <Cale> | but that's also ugly |
| 06:34:55 | <edwardk> | ok, i can accept map as a prefix . |
| 06:34:58 | <Cale> | Sometimes you really want the prefix one. |
| 06:35:40 | <shachaf> | ACTION sees how code could get confusing if (.) is fmap. You'd have to be careful... |
| 06:35:52 | <edwardk> | i rather like the resulting code though |
| 06:36:11 | <shachaf> | edwardk: Yes, it's nice. |
| 06:36:47 | <edwardk> | ok, map is in my toy prelude but its explicitly defined outside of the Map typeclass so it has to mean the same as (.) |
| 06:37:26 | <shachaf> | edwardk: Map = Functor? |
| 06:37:52 | <edwardk> | (Map and Functor are currently separate) Map is the restricted version class Map f a b where (.) :: (a -> b) -> f a -> f b |
| 06:38:03 | <edwardk> | so you can do restricted-functor tricks |
| 06:38:56 | <Cale> | There are also very strange things which can happen due to associativity. |
| 06:39:00 | <edwardk> | i may roll it back together |
| 06:39:20 | <Cale> | But it is a cool thing. :) |
| 06:39:23 | <shachaf> | Cale: I hadn't thought of that. fmap isn't associative, is it? |
| 06:39:33 | <Cale> | shachaf: not at all |
| 06:39:39 | <edwardk> | thats what parens are for =) |
| 06:39:48 | <Cale> | But (.) for the (e ->) functor is. |
| 06:39:51 | <shachaf> | Cale: Yes, that wouldn't make any sense. :-) |
| 06:40:42 | <edwardk> | the lack of associativity for fmap is the first good reason against joining everything that looks like it together that i've seen. |
| 06:41:02 | <Cale> | yeah, it's the only one I could come up with |
| 06:41:08 | <shachaf> | edwardk: I'd agree. |
| 06:41:34 | <Cale> | Certainly at *least* map should be functor application |
| 06:41:57 | <dolio> | @quote bulat |
| 06:41:57 | <lambdabot> | No quotes match. Have you considered trying to match wits with a rutabaga? |
| 06:42:00 | <Cale> | Function composition and functor application are basically the two most important operations in functional programming. |
| 06:42:14 | <opqdonut> | and they can be viewed as the same operation, right? |
| 06:42:22 | <edwardk> | yeah |
| 06:42:23 | <Cale> | While it's *really* nice that they can be seen as the same thing, one wonders if they're too important to be unified. |
| 06:42:31 | <edwardk> | right now i think i'll leave them conflated though |
| 06:42:36 | <opqdonut> | Cale: yeah it could be confusing |
| 06:42:37 | <dolio> | @remember bulat instances are standard answer. they are as viruses, imperceptibly filtering through any import lists :) |
| 06:42:37 | <lambdabot> | Done. |
| 06:42:57 | <opqdonut> | > fmap (+1) (+2) $ 0 |
| 06:42:59 | <lambdabot> | 3 |
| 06:43:35 | <opqdonut> | ghci throws me a No instance for (Functor ((->) a)) |
| 06:43:49 | <edwardk> | opqdonut :m + Control.Monad.Reader |
| 06:44:06 | <opqdonut> | ah, Reader defines all those ((->) r) instances? |
| 06:44:10 | <shachaf> | edwardk: Not Control.Monad.Instances? |
| 06:44:28 | <edwardk> | er. oh yeah did it move? |
| 06:45:12 | <edwardk> | looks like its there now |
| 06:45:22 | <shachaf> | Can someone give me an example of a mostly-trivial comonad (Identity is completely trivial, but anything else, like the [] or Maybe monads)? |
| 06:45:35 | <edwardk> | shachaf ((,)e) |
| 06:45:53 | <edwardk> | extract (e,a) = a |
| 06:46:03 | <edwardk> | duplicate (e,a) = (e,(e,a)) |
| 06:46:16 | <dons> | shachaf: http://www.eyrie.org/~zednenem/2004/hsce/Control.Comonad.html |
| 06:46:35 | <dons> | some here too http://www.cs.helsinki.fi/u/ekarttun/comonad/ |
| 06:46:35 | <lambdabot> | Title: Comonads and Haskell |
| 06:46:44 | <edwardk> | extend ea@(e,a) f = (e,f ea) |
| 06:47:34 | <Cale> | Oh, one thing I should point out to everyone about monad comprehensions. If they get added, I think they really ought to have a new kind of defaulting, like that for the Num class. |
| 06:47:47 | <shachaf> | Cale: For lists? |
| 06:47:51 | <Cale> | Right. |
| 06:47:53 | <Figs> | hi |
| 06:47:54 | <Figs> | me again |
| 06:47:59 | <shachaf> | Cale: That makes sense. |
| 06:48:19 | <edwardk> | if monad comprehensions go in, i think the same flag should let you use more general [foo..bar] enums for arbitrary MonadPlus instances ;) |
| 06:48:20 | <Cale> | Their removal last time was due to the fact that students would type in monad comprehensions which you couldn't actually tell were list comprehensions and get confusing errors. |
| 06:48:32 | <Figs> | I have more weird left-recursion |
| 06:48:40 | <Cale> | edwardk: This is something that I'm actually not too keen on, for some reason. |
| 06:48:45 | <Nopik> | hi there.. |
| 06:48:53 | <Nopik> | i have small problem installing libraries |
| 06:48:55 | <shachaf> | Figs: When will you rewrite all this in Haskell? :-) |
| 06:49:03 | <Cale> | edwardk: Lists are very very special in a way that MonadPlus instances aren't necessarily. |
| 06:49:04 | <Figs> | when I understand haskell |
| 06:49:04 | <edwardk> | its consistent with the changing of [...] to support arbitrary monads |
| 06:49:16 | <Cale> | edwardk: That's true. |
| 06:49:20 | <Nopik> | i wanted to use gd library.. its setup says that DAta.Binary.Base cannot be found.. i figured out that fps library do have this... |
| 06:49:23 | <Figs> | believe me, it's not much fun writing this in C++ :) |
| 06:49:31 | <Figs> | but I need to make progress |
| 06:49:35 | <Nopik> | then i setup configure/build/install fps library, all of it went correctly |
| 06:49:36 | <shachaf> | @where binary |
| 06:49:36 | <lambdabot> | http://www.cse.unsw.edu.au/~dons/binary.html |
| 06:49:47 | <Nopik> | now gd still says that Data.ByteString.Base cannot be found |
| 06:49:48 | <edwardk> | and could make for some really nice Set comprehensions =) |
| 06:49:49 | <Cale> | edwardk: However, it's easy enough to write option = msum . map return and use that :) |
| 06:49:55 | <edwardk> | when you add in restricted monads |
| 06:50:13 | <Cale> | edwardk: I really wish there was a better way to do restricted monads. |
| 06:50:15 | <Nopik> | run setup with -v reveals the ghc command which it is using |
| 06:50:19 | <Figs> | I think I might have a weird scheme that would allow me to switch what type of parser I am using |
| 06:50:28 | <Figs> | basically, let's say I have a pattern like |
| 06:50:30 | <Cale> | edwardk: Without the loss of naturality guarantees. |
| 06:50:37 | <edwardk> | well, one reason why i like the excessively general versions of things is they don't require a degree in advanced mathematics to understand what they do when they work =) |
| 06:50:37 | <shachaf> | ACTION wonders if monad comprehensions should use some other syntax than [], which feels like lists. |
| 06:50:39 | <Figs> | M = ref(M)|E >> T |
| 06:50:39 | <Nopik> | when i run the command manually, i get the same error.. but it includes -hide-all-packages argument.. when i remove it, it works |
| 06:50:43 | <Nopik> | but not from setup |
| 06:50:51 | <Figs> | err |
| 06:50:54 | <Nopik> | any ideas? |
| 06:50:56 | <Figs> | M = (ref(M)|E) >> T |
| 06:50:58 | <Figs> | make it more clear |
| 06:51:02 | <Nopik> | or should i use the binary library? |
| 06:51:22 | <edwardk> | shachaf: everything else is taken =/ |
| 06:51:29 | <shachaf> | Nopik: What program are you using, that depends on the library? (And which version of GHC?) |
| 06:51:34 | <Cale> | edwardk: Er, except that, let's say you have a monad instance which doesn't obey the monad laws -- those can be *really* confusing. |
| 06:51:37 | <Figs> | if you were trying to do ETTTTT.... it would basically fail |
| 06:51:46 | <Figs> | it'd just match ET |
| 06:51:53 | <edwardk> | shachaf: i ran into the same issue in my toy language. i had no symbols left in the ascii character set, so i started having to reuse notations |
| 06:52:08 | <shachaf> | edwardk: Unicode to the rescue! |
| 06:52:10 | <Nopik> | shachaf: i am trying to install gd library (as i want to use it in my own programs), ghc 6.4.2 |
| 06:52:26 | <shachaf> | Nopik: GHC 6.6 might make it easier, if you can do that. |
| 06:52:29 | <Cale> | edwardk: To see this, you only need to consider what happens when the monad laws fail. :) |
| 06:52:29 | <edwardk> | cale: well the writer should be shot, then strung up as an example to all those who profane the monad laws =) |
| 06:52:34 | <Figs> | but you could say, enable for that pattern a specific type of rearrangement |
| 06:52:40 | <Figs> | like |
| 06:52:45 | <Cale> | edwardk: I think losing naturality could be even worse. |
| 06:52:51 | <Figs> | check_left( sequential_pattern ) |
| 06:52:55 | <edwardk> | unless it breaks it only in minor ways like Data.Set ;) |
| 06:53:01 | <Cale> | edwardk: Imagine a 'bind' that did something different for Integers :) |
| 06:53:09 | <Nopik> | shachaf: i'll see if my distro includes it ;p |
| 06:53:14 | <Figs> | that would start from the end of the string working <--- to match the string in reverse |
| 06:53:16 | <shachaf> | Nopik: Which distribution? |
| 06:53:24 | <edwardk> | cale: data families probably already have that for you ;) |
| 06:53:32 | <Figs> | until it gets one that goes to the start of the string or fails |
| 06:53:50 | <Nopik> | shachaf: gentoo |
| 06:54:00 | <Figs> | shachaf, does that make sense? |
| 06:54:13 | <shachaf> | Nopik: I'm sure you'll fine it. |
| 06:54:22 | <shachaf> | Nopik: Might take a while to compile, though. |
| 06:54:25 | <Cale> | edwardk: hmm... I somehow doubt it's possible to write an instance of Monad for data families as it stands |
| 06:54:38 | <shachaf> | s/fine/find/ -- I find it surprising that I did that. |
| 06:54:58 | <Figs> | the alternative is to check right recursion first |
| 06:55:03 | <Figs> | and then check left recursion after |
| 06:55:12 | <edwardk> | even so if its imposible to write directly, i think its possible for it to delegate some aspect of a computation to something that involves them |
| 06:55:12 | <Nopik> | shachaf: yeah, i tried to compile ghc 6.4.2, but given up and installed precompiled version.. now i see that precompiled is available for 6.4.2 only, and 6.6.1 is available in sources, but marked as unstable.. lets try |
| 06:55:16 | <Figs> | or pray I can think of a way to translate one into another |
| 06:55:16 | <Figs> | :) |
| 06:55:31 | <shachaf> | Figs: Why are you asking me? |
| 06:55:56 | <Figs> | I thought you knew? |
| 06:56:13 | <shachaf> | Figs: Knew what? |
| 06:56:20 | <Figs> | what I'm doing :P |
| 06:56:57 | <shachaf> | Figs: Probably not... Do you have a latest-and-greatest @paste? |
| 06:57:17 | <Figs> | I don't have any recent pastes |
| 06:57:20 | <Cale> | edwardk: data instances are always monomorphic applications of the type constructor, right? |
| 06:57:31 | <Figs> | unless you want me to call up my math example from earlier |
| 06:58:06 | <shachaf> | Figs: What are you trying to do now? |
| 06:58:26 | <Figs> | I'm trying to figure out how I can make things like |
| 06:58:32 | <Figs> | M = (M|E) >> T |
| 06:58:33 | <Figs> | work |
| 06:58:41 | <quicksilver> | Cale: is it right that a given 'Applicative', if it is in fact a monad, is uniquely so? I.e. at most one bind definition can be compatible with a given <*> definition? |
| 06:58:42 | <edwardk> | i'm not so well acquainted with them, i just remember some weirdness about using them to delegate out special handling of different particular cases |
| 06:58:51 | <Figs> | which is equivalent to E >> T* |
| 06:58:53 | <Figs> | err *T |
| 06:59:12 | <edwardk> | quicksilver: there are multiple valid applicative instances for list |
| 06:59:18 | <Cale> | quicksilver: I doubt it, but it might take me a minute to come up with an example :) |
| 06:59:29 | <Figs> | except that left recursion tends to produce associations to the left |
| 06:59:38 | <Figs> | which causes other issues if it's expected... |
| 06:59:39 | <edwardk> | check the original applicative paper it makes the case for why you might want different applicative and monad behavior |
| 06:59:54 | <Figs> | I can't just translate left-recursion into right recursion automatically (even if I knew how) |
| 06:59:59 | <quicksilver> | edwardk: that wasn't quite my conjecture, though |
| 07:00:09 | <Cale> | edwardk: Yeah, but only one of those is induced by a monad |
| 07:00:13 | <edwardk> | hrmm |
| 07:00:14 | <quicksilver> | edwardk: my conjecture was once you have fixed the appliciative.. |
| 07:00:21 | <quicksilver> | edwardk: there is (at most) one monad |
| 07:00:35 | <edwardk> | @type ap |
| 07:00:37 | <lambdabot> | forall (m :: * -> *) a b. (Monad m) => m (a -> b) -> m a -> m b |
| 07:00:38 | <edwardk> | hrmm |
| 07:00:45 | <shachaf> | @src Applicative |
| 07:00:46 | <lambdabot> | class Functor f => Applicative f where |
| 07:00:46 | <lambdabot> | pure :: a -> f a |
| 07:00:46 | <lambdabot> | (<*>) :: f (a -> b) -> f a -> f b |
| 07:01:10 | <edwardk> | thanks for reminding me that i'd forgotten ap =) |
| 07:01:18 | <quicksilver> | it seems to me (arguing purely intruitively) that for a generic 'container' structure, working how to define <*> is much like working out how to make it a monad |
| 07:01:21 | <Figs> | even though xpressive doesn't really do what I want... maybe the boost people will have an answer... |
| 07:02:03 | <shachaf> | Figs: I wonder where you got the idea that I can help you. :-) |
| 07:02:11 | <shachaf> | ACTION is no expert on this. |
| 07:02:17 | <Figs> | you responded to me :) |
| 07:02:25 | <Figs> | 10[23:48:58] shachaf: 01Figs: When will you rewrite all this in Haskell? :-) |
| 07:02:26 | <shachaf> | Figs: Oh. |
| 07:02:36 | <quicksilver> | it's equivalent to saying that a monad is defined by its liftMn, for all n |
| 07:02:40 | <shachaf> | Does someone else feel like responding? |
| 07:02:47 | <shachaf> | quicksilver: And its return. |
| 07:02:50 | <Figs> | lol, it's ok... |
| 07:02:50 | <edwardk> | so, each bind gives rise to a natural notion of ap, but you want to know does the converse hold when the notion of bind exists? |
| 07:02:57 | <Figs> | although, if anyone knows... :) |
| 07:03:13 | <quicksilver> | shachaf: yes, indeed |
| 07:03:22 | <Cale> | Figs: I don't actually have any idea what you're doing, but from the bits that were happening in between the other conversations I was having, it has something to do with left-recursive grammars? |
| 07:03:37 | <Figs> | sort of |
| 07:03:45 | <Figs> | I'm writing a C++ regex library |
| 07:04:10 | <Cale> | okay |
| 07:04:14 | <Figs> | I came here earlier and someone (I think it was ddarius) pointed out that my system had a flaw where left-recursion would screw it up since I was doing recursive descent |
| 07:04:41 | <Figs> | simply finding infinite loops in my code isn't too hard, I think |
| 07:04:49 | <Figs> | except in a few cases |
| 07:05:00 | <Cale> | how do you write a recursive regex? |
| 07:05:10 | <Figs> | some thing like... |
| 07:05:28 | <Cale> | (hint: it should be impossible) |
| 07:05:29 | <Figs> | foo = term( "(" ) >> by_ref(foo)|middle >> term( ")"); |
| 07:05:50 | <Cale> | that's not a regular language |
| 07:05:57 | <Figs> | it's at least context free, probably context sensitive |
| 07:06:12 | <Figs> | but if I said cfxp |
| 07:06:14 | <Figs> | of csxp |
| 07:06:22 | <Figs> | no one would have a clue wtf I was talking about |
| 07:06:27 | <Cale> | Yeah, it looks more like a PEG |
| 07:06:33 | <Figs> | PEG? |
| 07:06:42 | <Cale> | parsing expression grammar |
| 07:06:46 | <mm_freak> | where's the (^) operator? |
| 07:06:48 | <edwardk> | @src ap |
| 07:06:48 | <lambdabot> | ap = liftM2 id |
| 07:06:49 | <Figs> | that might be a better term, yes |
| 07:07:05 | <Figs> | I haven't heard that one |
| 07:07:19 | <Figs> | anyway, right now, it does recursive descent |
| 07:07:41 | <edwardk> | well, if ap and return would uniquely define a monad, thats a much stronger statement than the earlier one about LiftMn and return, no? |
| 07:08:01 | <edwardk> | since then effectively LiftM2 and return would define the monad |
| 07:08:02 | <mm_freak> | @src (^) |
| 07:08:02 | <lambdabot> | Source not found. I've seen penguins that can type better than that. |
| 07:08:11 | <mm_freak> | @help |
| 07:08:12 | <lambdabot> | help <command>. Ask for help for <command>. Try 'list' for all commands |
| 07:08:12 | <Figs> | I can do a lot of unusual things with the system so far, for example... |
| 07:08:17 | <Cale> | Figs: I think that's fine, so long as you provide some other mechanism to handle those cases where you seem to need left-recursion. |
| 07:08:18 | <mm_freak> | @help list |
| 07:08:18 | <lambdabot> | list [module|command] |
| 07:08:19 | <lambdabot> | show all commands or command for [module]. http://www.cse.unsw.edu.au/~dons/lambdabot/COMMANDS |
| 07:08:19 | <shachaf> | @src liftA2 |
| 07:08:20 | <lambdabot> | liftA2 f a b = f <$> a <*> b |
| 07:08:37 | <Figs> | foo = (S[0] << +A) >> replace(S[0],A,B); |
| 07:08:37 | <edwardk> | (^) : (MulMonoid a, EuclideanNearRig b, Eq b) -> a -> b -> a; a ^ b = expT (b .* (Log a)) |
| 07:08:40 | <shachaf> | That's the same as liftM2, isn't it? |
| 07:08:43 | <edwardk> | woops, wrong Prelude =) |
| 07:08:47 | <opqdonut> | liftA? |
| 07:08:48 | <Figs> | or |
| 07:09:09 | <mm_freak> | does anyone know, in which class (^) is defined? |
| 07:09:13 | <edwardk> | er s/expT/exp/ |
| 07:09:17 | <Cale> | Figs: oh, it has mutation? :) |
| 07:09:23 | <shachaf> | @info (^) |
| 07:09:23 | <lambdabot> | (^) |
| 07:09:27 | <opqdonut> | Prelude.(^):: (Num a, Integral b) => a -> b -> a |
| 07:09:29 | <edwardk> | its Num |
| 07:09:30 | <Figs> | basically it's extensible |
| 07:09:33 | <edwardk> | and Integral |
| 07:09:44 | <Figs> | you can write new pattern matches pretty easily |
| 07:09:47 | <Figs> | or, that's the hope |
| 07:10:00 | <mm_freak> | edwardk: nope, it's neither Num, nor Integral |
| 07:10:06 | <Figs> | the regular operators will serve for most purposes, but if you wanted say to do |
| 07:10:11 | <Cale> | mm_freak: it's not a class member |
| 07:10:13 | <Figs> | A^n B^n C^n D^n ... |
| 07:10:15 | <mm_freak> | seems to be a classless function |
| 07:10:18 | <mm_freak> | yeah |
| 07:10:19 | <Figs> | it would be easy |
| 07:10:29 | <mm_freak> | that sucks |
| 07:10:30 | <edwardk> | well, it uses them, but doesn't get defined in either yeah |
| 07:10:36 | <edwardk> | same as in my version =) |
| 07:10:40 | <Figs> | just take s[0] by reference and write a function to generate the part to match against |
| 07:10:52 | <shachaf> | @help info |
| 07:10:52 | <lambdabot> | help <command>. Ask for help for <command>. Try 'list' for all commands |
| 07:11:05 | <Cale> | mm_freak: What, were you going to define it somehow differently than the Num and Integral instances would make it? |
| 07:11:05 | <opqdonut> | :i (^) |
| 07:11:14 | <opqdonut> | ?i (^) |
| 07:11:15 | <lambdabot> | Maybe you meant: id ignore index instances instances-importing irc-connect . v |
| 07:11:22 | <opqdonut> | ?info (^) |
| 07:11:23 | <lambdabot> | (^) |
| 07:11:25 | <edwardk> | btw, speaking of which |
| 07:11:25 | <opqdonut> | yep, broken :) |
| 07:11:26 | <edwardk> | @hpaste |
| 07:11:26 | <Cale> | (**) is a class member |
| 07:11:27 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 07:11:46 | <mm_freak> | cale: i'm writing a Mod type for modular arithmetic… the basics are done, now i just need modular exponentiation |
| 07:11:52 | <Figs> | if I wanted to reverse something, I could write a reverse function that took the S object by reference and returned a parser for the reverse pattern |
| 07:11:57 | <Figs> | and do |
| 07:12:01 | <Cale> | mm_freak: oh, so you wanted to write a more efficient version |
| 07:12:09 | <Figs> | foo = (S[0] << A) >> reverse(S[0]); |
| 07:12:09 | <mm_freak> | cale: yes |
| 07:12:19 | <Figs> | Hello!!olleH |
| 07:12:26 | <mm_freak> | but i guess, i'll drop it all and implement it as a monad |
| 07:12:30 | <Figs> | >>><<< etc |
| 07:12:32 | <opqdonut> | ?src (^) |
| 07:12:33 | <lambdabot> | Source not found. Maybe if you used more than just two fingers... |
| 07:12:50 | <mm_freak> | looks like that's going to be the easiest |
| 07:13:02 | <Figs> | if you wanted to write a module to search a dictionary, you could do |
| 07:13:12 | <Cale> | mm_freak: er, you could just give your new operator the same name and not import the prelude one, if you wanted |
| 07:13:18 | <hpaste> | edwardk pasted "are these too strange?" at http://hpaste.org/1708 |
| 07:13:26 | <mm_freak> | cale: IMO that's bad style |
| 07:13:26 | <Cale> | Or else you could give it a completely new name :) |
| 07:13:28 | <opqdonut> | mm_freak: huh? monad? modular arithmetic? |
| 07:13:41 | <edwardk> | using those as a way to convert between multiplicative and additive monoids, etc. |
| 07:13:43 | <Figs> | foo = (S[0] << A) >> dictionary_begins_with(S[0]); |
| 07:13:44 | <opqdonut> | can't see how that'd work |
| 07:13:53 | <mm_freak> | opqdonut: yes… the monad could just apply the modulo after each computation |
| 07:13:58 | <ski> | edwardk : EuclideanNearRig ? |
| 07:14:15 | <opqdonut> | mm_freak: but that'd place restraints on the type parameter? |
| 07:14:17 | <edwardk> | mm_freak: have you seen Oleg's modular arithmetic typeclass styff? |
| 07:14:19 | <edwardk> | er stuff |
| 07:14:23 | <mm_freak> | such that the type does not hold any ring member anymore, but solely the modulus |
| 07:14:33 | <mm_freak> | edwardk: nope |
| 07:14:33 | <edwardk> | stefan: eucliean algorithm works, but almost everything else isn't guaranteed basically |
| 07:14:44 | <mm_freak> | opqdonut: the type parameter has to be Integral anyway |
| 07:15:00 | <mm_freak> | and since i'm not gonna work with small numbers, i've even speciailized it to Integer |
| 07:15:01 | <ski> | (edwardk : was that to me ?) |
| 07:15:01 | <Figs> | what you can't do though is something like ... |
| 07:15:04 | <Cale> | mm_freak: how would it do that? The value being operated on is a state parameter? |
| 07:15:19 | <Figs> | (S[0] << A) >> lookup(S[1]) >> (S[1] << B); |
| 07:15:24 | <mm_freak> | cale: the modulus being the state |
| 07:15:29 | <edwardk> | ski: an example would be the Naturals. i lack additive inverses, but i can divmod in it. |
| 07:15:33 | <Figs> | because it's recursive descent |
| 07:15:38 | <Figs> | left to right |
| 07:15:41 | <edwardk> | ski: er yeah |
| 07:16:07 | <Figs> | well meh |
| 07:16:09 | <Figs> | I need to go |
| 07:16:14 | <Figs> | I'll bb tomorrow though ;) |
| 07:16:18 | <Figs> | g'night |
| 07:16:26 | <Cale> | Figs: at some point, I'll show you how this sort of thing might be done in Haskell |
| 07:16:33 | <Figs> | cool |
| 07:16:34 | <Figs> | :) |
| 07:16:44 | <Figs> | I'll hold you to it ;) |
| 07:16:49 | <Figs> | cya |
| 07:16:53 | <Cale> | later |
| 07:17:06 | <edwardk> | ski: the typeclasses underlying are a little more general than normal, but the ideas there can be applied to Num with some hackery. |
| 07:17:24 | <mm_freak> | cale: like: (>>=) (Mod a n) f = f (mod a n) |
| 07:17:43 | <ski> | ACTION just doen't have a good picture of how all variants of ring, etc fits together |
| 07:17:59 | <Cale> | mm_freak: I don't see how that works type-wise. |
| 07:18:16 | <opqdonut> | yeah, me neither |
| 07:18:36 | <Cale> | Remember that n could be of any type at all. |
| 07:18:37 | <mm_freak> | dunno… hold on, i'll try it out |
| 07:18:44 | <Cale> | n could be a String |
| 07:18:45 | <Cale> | or () |
| 07:18:49 | <Cale> | or an IO action |
| 07:18:51 | <Cale> | or a function :) |
| 07:18:59 | <opqdonut> | or ur mom, even |
| 07:19:07 | <opqdonut> | :) |
| 07:19:10 | <Cale> | yep, even your mom |
| 07:19:13 | <ski> | or 'RealWorld' |
| 07:19:13 | <edwardk> | ski: basically its an euclidean domain, with the guarantee of the lack of zero divisors removed (so you can use it over Ints rather than Integers, and the guarantee of additive inverses removed |
| 07:19:16 | <mm_freak> | cale: well, i'll need to restrict that somehow |
| 07:19:27 | <mm_freak> | unfortunately Monad needs * -> * |
| 07:19:31 | <opqdonut> | restricted monads don't work |
| 07:19:31 | <Cale> | right |
| 07:19:32 | <opqdonut> | yep |
| 07:19:52 | <mm_freak> | hmm |
| 07:19:58 | <ski> | edwardk : euclidean domain ? :) |
| 07:20:24 | <mm_freak> | cale: but the idea could actually work |
| 07:20:46 | <edwardk> | mm_freak: http://www.cs.rutgers.edu/~ccshan/prepose/prepose.pdf is the paper I was mentioning about how Oleg and CC Shan encoded moduli in types, very nice trick |
| 07:20:57 | <edwardk> | ski: a euclidean domain is basically something with 'divMod' =) |
| 07:21:10 | <ski> | a ring with some extra things ? |
| 07:21:32 | <dolio> | Using type-level naturals is the way to go for modular arithmetic, if you ask me. |
| 07:21:42 | <mm_freak> | edwardk: thanks |
| 07:21:57 | <dolio> | (^) will automatically be the standard good algorithm, that way. |
| 07:22:15 | <edwardk> | divMod :: { x : a } -> { y : non-zero a } -> { (q,r) : x = y*q + r && valuation r < valuation y || valuation y == 0 } |
| 07:22:28 | <edwardk> | where valuation maps from your domain into the naturals |
| 07:22:34 | <edwardk> | and acts as sort of a measure |
| 07:22:49 | <edwardk> | quotRem and divMod are artifacts of different valuations over the integers. |
| 07:23:35 | <mm_freak> | dolio: you're right… it performs pretty well |
| 07:23:46 | <Cale> | If you really want a fast powerMod operation, you probably want to work with the binary representation of the exponent directly. |
| 07:23:47 | <mm_freak> | ok, no need to write an own function =) |
| 07:23:59 | <mm_freak> | cale: that's what i'm doing |
| 07:24:10 | <mm_freak> | modexp (!b) !e !p !n | (e == 0) = p | (even e) = modexp (mod (b*b) n) (shiftR e 1) p n | otherwise = modexp b (e-1) (mod (p*b) n) n |
| 07:24:14 | <mm_freak> | aaaaaah |
| 07:24:16 | <mm_freak> | damned |
| 07:24:30 | <mm_freak> | but you get the point =) |
| 07:24:37 | <ski> | edwardk : hm, shouldn't 'r' be an element of a quotient type ? |
| 07:24:43 | <Cale> | That's fine. |
| 07:24:53 | <edwardk> | er { (q,r) : (a,a) | x = ... } |
| 07:24:58 | <Cale> | mm_freak: That should all parse as one line, I think. |
| 07:25:02 | <mm_freak> | cale: (^) seems to work the same way |
| 07:25:11 | <edwardk> | would be the concrete syntax |
| 07:25:13 | <Cale> | Oh, interesting. |
| 07:25:22 | <Cale> | I suppose that's why it needs an Integral :) |
| 07:25:25 | <mm_freak> | cale: it's actually multiple lines, but i've configured my client to join indented lines |
| 07:25:45 | <mm_freak> | cale: yeah… Floating provides a separate function, which doesn't use Integrals |
| 07:26:29 | <Cale> | mm_freak: right, because it provides a completely different kind of exponentiation :) |
| 07:26:54 | <mm_freak> | not different, but generalized =) |
| 07:27:05 | <edwardk> | ski: the (q,r) pair is in a subset type, not a quotient type as you can check correctness of subsets and i'm not sure what the quotient would be in this case, grouping them by valuation isn't the right answer because divmod gives back a particular r not the equivalence class =) |
| 07:27:24 | <Cale> | mm_freak: Also, de-generalised |
| 07:27:24 | <mm_freak> | actually both generalized (to arbitrary exponents) and specialized (to numbers) |
| 07:27:31 | <Cale> | right |
| 07:27:35 | <ski> | edwardk : i wanted 'r' to be in a quotient |
| 07:27:51 | <edwardk> | the problem is if you take a quotient over it, you can't compute with it concretely |
| 07:27:55 | <ski> | (and then '(q,r)' could be in a subtype, as well) |
| 07:28:13 | <mm_freak> | now my Mod type is an instance of (Eq, Show, Num, Fractional) |
| 07:28:47 | <edwardk> | so i'm not sure how a quotient over a of all values with the same valuation (which i presume is the quotient you mean) helps |
| 07:28:54 | <ski> | edwardk : hm .. why do you express this property in the result type of the function at all ? to be able to take inverse of the function ? |
| 07:29:05 | <mm_freak> | is there a predefined extended GCD function? i've written it myself, but probably someone has already written a more optimized version |
| 07:29:38 | <ski> | edwardk : an example quotient would be Z/5Z |
| 07:29:49 | <ski> | (for division by '5') |
| 07:30:15 | <ski> | Z ~= Z * Z/5Z |
| 07:30:44 | <edwardk> | well, in this case, the definition that says how a euclidean domain extends a ring is it adds a valuation and divMod function where the divMod function satisfies that law. if it doesn't, then it isn't a euclidean domain. that gives the compiler the ability to try to prove the correctness of your instance |
| 07:31:47 | <edwardk> | ski: the problem i have with that is if i'm using divMod its not because i want to change rings, its because i want to know the remainder in the ring i have. [4]_Z/5Z means a very different thing when projected back into Z. |
| 07:31:56 | <ski> | ok .. so you just wanted to shorten and make it neater, by folding the function and the property into the same "thing" |
| 07:31:59 | <ski> | ? |
| 07:32:12 | <edwardk> | yeah more or less |
| 07:32:27 | <ski> | (i don't complain about that :) |
| 07:32:54 | <Cale> | edwardk: [4]_Z ? |
| 07:32:54 | <edwardk> | and it keeps you from implementing a fake version of the class that doesn't satisfy the laws without the compiler complaining at you =) |
| 07:33:04 | <ski> | '[4]_Z/5Z' ? |
| 07:33:17 | <edwardk> | 4 in Z/5Z i should have said |
| 07:33:38 | <ski> | edwardk : but you could have made a separate property member in the class, yes ? |
| 07:33:52 | <Cale> | 4 + 5Z :) |
| 07:33:53 | <edwardk> | the law? |
| 07:33:56 | <edwardk> | yeah |
| 07:34:00 | <edwardk> | er |
| 07:34:06 | <edwardk> | the yeah was to Cale =) |
| 07:34:31 | <ski> | "means a very different thing when projected back into Z" ? |
| 07:34:44 | <edwardk> | the 'separate property in the class' is awkward because its best for me to check laws about results in the subset type system because then they are flow directed. |
| 07:35:20 | <ski> | ah .. the run-time checking |
| 07:35:25 | <edwardk> | 9 `divMod` 5 = (1,4) the 4 is intended as an actual member of the euclidean domain D, not of some equivalence class formed over it. |
| 07:35:48 | <ski> | do you need that ? |
| 07:35:49 | <edwardk> | well, actually its compile time checked by default, the flow in question is the abstract interpretation =) |
| 07:36:01 | <edwardk> | http://en.wikipedia.org/wiki/Euclidean_domain read the definition =) |
| 07:36:02 | <lambdabot> | Title: Euclidean domain - Wikipedia, the free encyclopedia |
| 07:36:09 | <ski> | (ok, compile-time run-time :) |
| 07:37:30 | <edwardk> | we are interested in 4 not all the other things that happen to have the same remainder modulo our particular divisor. your version would cost us trivial invertability and require an explicit projection back into the original ring in order to continue to use it for GCDs, etc. |
| 07:37:47 | <edwardk> | so the utility of the notion of divMod would be compromised |
| 07:39:11 | <edwardk> | i'm perfectly ok with another mod operator that does something like that, but I don't think they are the same |
| 07:39:46 | <iakovz> | hello |
| 07:40:59 | <shachaf> | iakovz: Hello. |
| 07:43:31 | <ski> | edwardk : does 'valuation' only map '0' to '0' ? |
| 07:43:42 | <ski> | s/only map/map only/ |
| 07:44:02 | <moritz> | hi |
| 07:44:07 | <ski> | hello there |
| 07:44:15 | <moritz> | I have some problems with installing ghc 6.6.1 on debian... |
| 07:44:43 | <moritz> | I have debian etch (aka stable), and recompiled 6.6.1 from the testing sources |
| 07:44:59 | <Cale> | That would have taken a while :) |
| 07:45:07 | <moritz> | and these are the problems I get when installing ghc6-doc: http://sial.org/pbot/26329 |
| 07:45:08 | <lambdabot> | Title: Paste #26329 from "moritz" at 84.148.35.162 |
| 07:45:15 | <Cale> | I'd have probably just installed the generic binary |
| 07:45:30 | <edwardk> | ski: not sure about that, some euclideandomains could be a little weird. the practical ones i can think of do |
| 07:45:44 | <Cale> | moritz: Which version of haddock do you have installed? |
| 07:45:48 | <moritz> | Cale: but can I get that as a debian packages? |
| 07:45:59 | <moritz> | Cale: 0.8-2 |
| 07:46:08 | <moritz> | Cale: recompiled from testing sources as well |
| 07:46:16 | <Cale> | oh, hmm |
| 07:46:49 | <moritz> | and I had some problems deisntalling two of the libghc6-*-dev packages due to broken prerm-packages ;) |
| 07:47:06 | <ski> | edwardk : i parse 'a = bq + r and either r = 0 or v(r) < v(b)' as 'a = b*q + r /\ (r = 0 \/ v r < v b)' .. how do 'x = y*q + r && valuation r < valuation y || valuation y == 0' parse ? |
| 07:47:34 | <edwardk> | hrmm, i wonder if it could actually be beneficial to define some form of template haskell type hackery that understood how to unravel a bunch of [d| |] blocks into their appropriate typeclasses and built the right instances when you said 'Field' and gave the definitions for the operators |
| 07:48:13 | <Cale> | I don't think I've ever successfully recompiled a package from a newer version of debian, but that could just be bad luck on my part. |
| 07:48:17 | <edwardk> | that was just rattled off my cuff, you got the right interpretation =) |
| 07:48:30 | <Cale> | The generic linux binary would work, but it wouldn't be a debian package. |
| 07:48:40 | <quicksilver> | edwardk: no, I don't think it's any stronger |
| 07:49:01 | <shachaf> | moritz: Can't you use the generic binary with checkinstall or similar? |
| 07:49:04 | <quicksilver> | edwardk: return is liftM0, fmap is liftM1, and ap is (definable using) liftM2 |
| 07:49:05 | <Cale> | You could also possibly just move to testing. |
| 07:49:13 | <moritz> | Cale: normally it works... I'd install the binaries from testing, but that is compiled against a newer libc6 :( |
| 07:49:23 | <quicksilver> | edwardk: so the liftMi claim is the same as the 'ap' claim |
| 07:49:25 | <edwardk> | quicksilver: then doesn't your question devolve to if liftM2 and return can uniquely define the bind operation? |
| 07:49:39 | <edwardk> | since you can define ap in terms of liftM2? |
| 07:49:39 | <quicksilver> | edwardk: yes |
| 07:49:49 | <ski> | edwardk : actually, i'm wondering why the domain of 'v' is restricted to not include '0' (e.g. in that WP article) |
| 07:49:55 | <edwardk> | thats all i was saying, the other claim was that if you knew liftMn for all n, no? |
| 07:50:03 | <quicksilver> | yes |
| 07:50:07 | <mm_freak> | edwardk: that paper is very interesting, thank you |
| 07:50:12 | <quicksilver> | that was just a more elegant way of expressing it |
| 07:50:13 | <moritz> | shachaf: I'll try that |
| 07:50:17 | <quicksilver> | I agree it's no more minimal |
| 07:50:50 | <edwardk> | mm_freak: no problem. i found it to be a really neat trick myself =) |
| 07:50:51 | <moritz> | Cale: moving to testing is not an option... I have to keep my system as close as possible to an existing server (that runs stable) |
| 07:51:00 | <Cale> | moritz: ah |
| 07:51:17 | <shachaf> | moritz: I know someone who used the generic binary on Ubuntu before they had 6.6, and it worked. |
| 07:51:29 | <shachaf> | moritz: I'd guess this would be similar. |
| 07:51:29 | <mm_freak> | edwardk: yeah… i don't understand it fully from the first example, but i guess, it'll clarify things later =) |
| 07:51:32 | <Cale> | I've used the generic binary on Ubuntu. |
| 07:52:47 | <shachaf> | mm_freak: "yeah⦠" -- is this on my side or on yours? |
| 07:52:59 | <edwardk> | mm_freak: the basic trick is you abuse polymorphism to carry around a term value reified into a type, then they show you can encode anything in haskell into a type that way, to get a form of implicit parameter passing with a way to enforce the same terms are being used in different locations. i.e. that you are always computing w.r.t the same modulus |
| 07:53:08 | <ski> | quicksilver : are you arguing that '(>>=)' is definable by the 'liftM' functions ? |
| 07:53:19 | <shachaf> | mm_freak: I've been wondering, this isn't my regular terminal. |
| 07:53:28 | <quicksilver> | ski: I was speculating, yes |
| 07:53:37 | <moritz> | if I do a "runghc Setup.hs install" of a cabal package, can I do an unistall in the same way? |
| 07:53:50 | <mm_freak> | shachaf: on your side… i'm using UTF-8 |
| 07:53:54 | <shachaf> | quicksilver: Are you saying every Applicative is a Monad? |
| 07:53:55 | <quicksilver> | ski: more precisely, my conjecture was that any Applicative instance is compatible with at most one Monad instance |
| 07:54:03 | <mm_freak> | those weird characters should actually be an ellipse ("...") |
| 07:54:06 | <quicksilver> | shachaf: no no. 'at most one'. |
| 07:54:11 | <shachaf> | quicksilver: Yes, that's what I understood before. |
| 07:54:17 | <shachaf> | mm_freak: Oh. |
| 07:54:18 | <edwardk> | ski: the speculation in question as i understand it is if given a definition for ap and return, if there is only one definition of bind that is compatible. i.e. one way to transform an applicative into a monad. |
| 07:54:33 | <edwardk> | er at most one |
| 07:54:43 | <shachaf> | ACTION wishes his computer worked, so he could use urxvt again. |
| 07:54:54 | <Cale> | I really really doubt that, but I don't have a counterexample on hand :) |
| 07:54:56 | <mm_freak> | edwardk: i've understood the semantics, but i couldn't do it myself yet |
| 07:55:41 | <Cale> | At least, it would be extremely surprising to me if there weren't some applicative functor that was a monad in two different ways. |
| 07:55:57 | <edwardk> | mm_freak: i toyed with using that to pass around command-line flags in my compiler |
| 07:57:23 | <edwardk> | ACTION is striding down a slippery slope very fast |
| 07:57:51 | <shachaf> | moritz: I don't think so. |
| 07:58:24 | <shachaf> | moritz: There's unregister, but I've always deleted the files manually when necessary (probably a bad idea). |
| 07:58:55 | <moritz> | shachaf: I noticed it installs to /usr/local/*, so I don't mind ;) |
| 07:58:56 | <mm_freak> | edwardk: yeah, command line flags are my current problem |
| 07:58:57 | <edwardk> | ok, so i accepted that if 'a' is a monoid/magma/etc it should also be the case that (b -> a) is a monoid/magma. similarly if (==) :: a -> a -> b for some a and b, then (==) :: (c -> a) -> (c -> a) -> (c -> b) should also be allowed |
| 07:59:10 | <mm_freak> | it already starts with a simple "verbosity" value, which i really need to pass almost everywhere |
| 07:59:12 | <edwardk> | similarly for (&&), (||), etc. |
| 07:59:28 | <ski> | edwardk : environment ? |
| 07:59:34 | <edwardk> | yeah |
| 07:59:42 | <edwardk> | trivially lifting them into the reader monad basically |
| 07:59:52 | <ski> | hm, that latter '(==)' looks a bit strange :) |
| 07:59:54 | <edwardk> | since it is unambiguous |
| 08:00:09 | <edwardk> | it does give some nice things like |
| 08:00:16 | <edwardk> | filter (isAlpha || isDigit) |
| 08:01:05 | <ski> | possibly one can think of it as a construct where objects are carriers^c |
| 08:01:15 | <edwardk> | and I went and said that my main goal is to preserve type inference, so i'll allow class ExpOp a b | a -> b, b -> a where exp :: a -> b sort of things, so i can use Log and Exp type classes to map additive foo to multiplicative foo |
| 08:02:32 | <edwardk> | which i thought was particularly clean, and can similarly handle the environment. but then when you get to things like fst and snd, they start to call out to lift as well ;) |
| 08:04:14 | <edwardk> | (f `divMod` g) given f :: b -> a, g :: b -> a, EuclideanNearRig a returns a pair of functions to be consistent with the rest of the numerical hierarchy, which then says i should allow myself to apply fst and snd to functions ;) |
| 08:04:30 | <edwardk> | just not quite sure where this ends =) |
| 08:04:44 | <ski> | what if 'b' is 'Bool' ? |
| 08:05:03 | <ski> | do you get point-wise application over tuples ? |
| 08:05:18 | <moritz> | Cale, shachaf: thanks for your help |
| 08:05:27 | <shachaf> | moritz: It works? |
| 08:05:33 | <edwardk> | (f + g) True = f True + g True right now |
| 08:05:50 | <edwardk> | divMod is the one i'm not sure of the right semantics for |
| 08:05:53 | <ski> | fst (f + g) = fst f + fst g |
| 08:06:17 | <ski> | (a,b) + (c,d) = (a + c,b+d) -- i.e. |
| 08:06:17 | <moritz> | shachaf: sadly not. the generic binary needs readline 4, which I can't find |
| 08:06:33 | <moritz> | shachaf: I decided to live without ghc6-doc for the moment |
| 08:06:39 | <shachaf> | moritz: Oh, I remember reading about people who had that problem. |
| 08:06:42 | <edwardk> | i have lifting of magmas etc over tuples already |
| 08:06:45 | <edwardk> | so the latter works |
| 08:06:55 | <edwardk> | the fst case i haven't got implemented yet |
| 08:07:25 | <shachaf> | moritz: Does Debian not have a readline4 package? |
| 08:07:32 | <edwardk> | fst f = fst . f ? |
| 08:07:38 | <mm_freak> | what confuses me all the time… what is a "first-class object"? |
| 08:07:41 | <ski> | no |
| 08:07:51 | <ski> | edwardk : 'f' was a pair there .. i.e. a function from 'Bool' |
| 08:07:59 | <moritz> | shachaf: not in stable. I haven't looked at oldstable |
| 08:08:02 | <quicksilver> | mm_freak: something which can be passed around the language as a 'normal value' |
| 08:08:19 | <mm_freak> | quicksilver: an example of a non-first-class object? |
| 08:08:23 | <edwardk> | where in that the assumption is i'm using f to refer to a function |
| 08:08:23 | <ski> | f : (b : Bool) -> if b then a1 else a0 |
| 08:08:35 | <quicksilver> | mm_freak: in C or Java, functions are not first-class |
| 08:08:45 | <mm_freak> | ah k |
| 08:08:46 | <quicksilver> | mm_freak: in haskell, patterns are not first class |
| 08:08:53 | <quicksilver> | or modules |
| 08:08:54 | <edwardk> | not sure where you are going with the bool thing |
| 08:08:55 | <mm_freak> | thank you |
| 08:09:03 | <shachaf> | moritz: Yes, it's in oldstable. |
| 08:09:09 | <shachaf> | (According to debian.org.) |
| 08:09:16 | <mm_freak> | what is a higher-order function? a function, that returns another function? |
| 08:09:19 | <edwardk> | you want (a,a) to be sort of indexed by True,False? |
| 08:09:22 | <ski> | in C "functions" are first-class |
| 08:09:32 | <mm_freak> | ski: function pointers are, not functions themselves |
| 08:09:49 | <ski> | edwardk : as an example .. needn't be exactly 'Bool', though |
| 08:09:54 | <quicksilver> | mm_freak: typically a higher order function is a function that takes a function as a parameter |
| 08:10:06 | <edwardk> | doesn't fit really well with the rest of my system i think |
| 08:10:14 | <ski> | mm_freak : just terminology :) |
| 08:10:14 | <edwardk> | this is actually haskell code right now =) |
| 08:10:44 | <mm_freak> | ski: nope, there is a technical difference between the two =) |
| 08:10:47 | <ski> | edwardk : the exponential above, too ? |
| 08:10:59 | <edwardk> | the ExpOp case? |
| 08:11:15 | <edwardk> | yeah using a toy prelude i've been porting over from my compiler and working on as i go |
| 08:11:25 | <mm_freak> | calls via function pointers are translated to indirect calls in opcode |
| 08:11:34 | <ski> | (mm_freak : yeah .. which was why i said "\"functions\"" ..) |
| 08:11:53 | <ski> | (mm_freak : and how does 'map' call its argument ?) |
| 08:11:54 | <edwardk> | i just break out each operator separately into a typeclass |
| 08:11:59 | <edwardk> | its making for instance hell |
| 08:12:02 | <edwardk> | but its not all that bad |
| 08:12:35 | <edwardk> | i'm kind of tempted right now to put together some template haskell magic for stringing together the right instances given the definitions of all the functions that go into them |
| 08:12:38 | <ski> | istr Clean had more separated numeric classes |
| 08:12:41 | <mm_freak> | ski: let's call them procedures =) |
| 08:12:44 | <ski> | s/had/has/ |
| 08:13:30 | <ski> | mm_freak : (i can't recall the term rn, but) let's call them first-order procedures, then |
| 08:13:58 | <mm_freak> | ski: most likely via indirect calls, but that's not so easy to predict |
| 08:14:01 | <edwardk> | @hpaste |
| 08:14:01 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 08:14:36 | <mm_freak> | now what is a first-order function? a function that takes only values? |
| 08:15:09 | <JKnecht> | same as 1st order formula I would guess |
| 08:15:31 | <ski> | what i wanted to express, but can't recall term for was : not being able to use local variables defined outside a function .. i.e. no closures |
| 08:15:32 | <hpaste> | edwardk pasted "misc. algebraic classes" at http://hpaste.org/1709 |
| 08:16:09 | <ski> | the type being '[](a -> b)' with '[]' being a "neccisity" modal operator |
| 08:16:18 | <quicksilver> | mm_freak: yes, first order means it takes only values as parameters |
| 08:17:00 | <mm_freak> | quicksilver: what's the difference between second-order and third-order? |
| 08:17:21 | <edwardk> | as you can see to define a Num takes like 7 typeclasses now, hence why i'm thinking the TH wizardry might not be a bad idea |
| 08:17:32 | <dolio> | secondOrder :: (a -> b) -> c, thirdOrder :: ((a -> b) -> c) -> d |
| 08:17:42 | <ski> | (n+1)th-order things can take nth-order things as arguments |
| 08:18:01 | <ski> | (0-order things doesn't take arguments) |
| 08:18:19 | <mm_freak> | ok, thanks |
| 08:18:57 | <edwardk> | $(additiveGroup [ [d|zero = ...|], [d|(+) = ... |], [d|negate = ...|] ]) |
| 08:19:04 | <ski> | ACTION had some omega-order functions in a project |
| 08:22:02 | <edwardk> | at present i'm using a lot of CPP stuff to prepopulate those from the traditional prelude |
| 08:22:05 | <edwardk> | which isn't ideal |
| 08:22:35 | <edwardk> | though it does have the advantage that things can be defined and used in the same file |
| 08:25:08 | <edwardk> | so, next question |
| 08:25:32 | <edwardk> | I implicitly lift (+) , etc into the reader monad. these also make sense lifted into other monads. would that be too weird? |
| 08:25:50 | <edwardk> | @hpaste |
| 08:25:50 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 08:28:27 | <dolio> | I've seen it suggested before. |
| 08:29:21 | <hpaste> | edwardk pasted "monadic math" at http://hpaste.org/1710 |
| 08:29:44 | <edwardk> | in my case its a little easier coz i don't have spurious Show and Eq requirements everywhere |
| 08:30:01 | <dolio> | Indeed. |
| 08:31:13 | <hpaste> | edwardk annotated "monadic math" with "fixed typos" at http://hpaste.org/1710#a1 |
| 08:31:28 | <shachaf> | Hmm. Would something similar to "instance Monad a where x >>= f = f x; return = id" be possible/a good idea? |
| 08:31:49 | <ski> | (edwardk : hm .. you don't have loops or moups ?) |
| 08:32:02 | <edwardk> | shachaf: it doesn't work at last check |
| 08:32:07 | <quicksilver> | shachaf: http://haskell.org/ghc/docs/latest/html/libraries/mtl/Control-Monad-Identity.html ? |
| 08:32:09 | <lambdabot> | http://tinyurl.com/ydy84p |
| 08:32:16 | <dolio> | 'a' isn't a type constructor there. |
| 08:32:27 | <shachaf> | quicksilver: Yes, except without thee Identity part. |
| 08:32:30 | <shachaf> | dolio: Hmm. |
| 08:32:33 | <edwardk> | ski: i stuck to defining the points in the hierarchy that have operational meaning to haskell. where a new operator was introduced basically. |
| 08:32:48 | <ski> | instance Monad (\a -> a) -- not allowed by haskell |
| 08:32:59 | <quicksilver> | shachaf: without the identity part it isn't a type constructor any more, so it can't be a monad? |
| 08:33:00 | <shachaf> | Well, you know what I mean, anyway. Is something similar possible, at all? |
| 08:33:11 | <ski> | edwardk : ok |
| 08:33:19 | <shachaf> | quicksilver: I guess. |
| 08:33:22 | <edwardk> | shachaf: you need the Identity constructor in there |
| 08:33:46 | <shachaf> | ACTION wonders what he means, exactly. :-) |
| 08:33:57 | <shachaf> | ACTION should go to sleep. |
| 08:34:28 | <edwardk> | shachaf: Monad m expects m :: * -> * your a has kind * |
| 08:35:08 | <shachaf> | edwardk: Yes, I know. |
| 08:35:12 | <edwardk> | to get something of kind * -> * you'd need a type, newtype or data declaration that took an argument, the type thing would appear to work at first glance, except you can't use 'type's as arguments to typeclasses. |
| 08:35:41 | <shachaf> | edwardk: Why not, by the way? |
| 08:35:53 | <edwardk> | because they reduce themselves to normal form silently on you, so they aren't there for the typeclass or instance to look at |
| 08:36:19 | <edwardk> | type Foo a b = a -> b when used as Foo a b is indistinguishable from a -> b |
| 08:36:48 | <edwardk> | so type MyIdentity a = a seems at first like it might work, but when the compiler gets around to looking at it its already an a, no longer a 'MyIdentity a' |
| 08:37:12 | <shachaf> | OK, that makes sense. |
| 08:37:34 | <edwardk> | I have kind of wondered if a much much lazier compiler could keep those around longer =) |
| 08:38:04 | <edwardk> | but i don't think its practical and it would rely on letting the compiler redo a lot of work to get consistent semantics, etc. |
| 08:38:14 | <quicksilver> | edwardk: but it might be a bit surprising, you could accidently 'erase' a type by passing through 'id' |
| 08:38:19 | <edwardk> | yep |
| 08:38:31 | <quicksilver> | id :: [Char] -> [Char] would 'anonymise' a String |
| 08:38:35 | <quicksilver> | e.g. |
| 08:39:37 | <edwardk> | yeah, i played with it, but couldn't come up with any sort of consistent semantics |
| 08:40:41 | <edwardk> | hrmm, wondering what weird effects you get from the monadic math stuff now that i'm looking at now just readers and writers, etc. |
| 08:40:42 | <dolio> | You could do some crazy stuff that way. |
| 08:41:10 | <dolio> | type ComposeT f g m a = f (g m) a |
| 08:41:45 | <dolio> | instance (MonadTrans f, MonadTrans g) => MonadTrans (ComposeT f g) where lift = lift . lift |
| 08:42:07 | <ski> | edwardk : istr ghc allows type-synonyms in instance heads .. not partially applied, though |
| 08:42:42 | <ski> | s/not partially/only fully/ |
| 08:42:50 | <kolmodin> | @yarr! -- morning |
| 08:42:50 | <lambdabot> | Swab the deck! |
| 08:42:59 | <ski> | indeed! |
| 08:43:25 | <edwardk> | ski: sure, because then they know they can reduce them fully, and won't wind up with any weird 'holes' in the middle of the type |
| 08:43:38 | <ski> | right. no lambda types |
| 08:43:45 | <edwardk> | > liftM2 (*) [1,2,3] [4,5,6] |
| 08:43:46 | <lambdabot> | [4,5,6,8,10,12,12,15,18] |
| 08:43:49 | <edwardk> | hrmm |
| 08:44:02 | <edwardk> | is that the semantics we'd want a [1,2,3] * [4,5,6] to have? |
| 08:44:22 | <ski> | > liftM2 (+) [100,200,300] [4,5,6] |
| 08:44:24 | <lambdabot> | [104,105,106,204,205,206,304,305,306] |
| 08:44:38 | <ski> | if we want left-to-right evaluation of the effects, yes |
| 08:44:55 | <quicksilver> | > zipWith (*) [1,2,3] [4,5,6] |
| 08:44:56 | <lambdabot> | [4,10,18] |
| 08:44:58 | <dolio> | You could define it for arbitrary Applicatives. |
| 08:45:06 | <ski> | (in the list monad, i forgot to say :) |
| 08:45:08 | <quicksilver> | anand then again, maybe I'd ratehr have that one :) |
| 08:45:10 | <edwardk> | i'd kind of hoped to use + for the natural list append monoid. that hope appears to be gone =) |
| 08:45:11 | <dolio> | Then you could choose between [] and ZipList. |
| 08:45:17 | <edwardk> | but this is more consistent |
| 08:45:19 | <quicksilver> | as dolio says |
| 08:46:41 | <edwardk> | well, the reader monad is natural, writer, state, and blech even IO works, its just list that sticks in my craw a bit |
| 08:47:39 | <edwardk> | and of course that becomes rather funny when mixed with the parameterized monad stuff from the other day =) |
| 08:47:49 | <edwardk> | Just 2 * [1,2,3] etc =) |
| 08:48:31 | <edwardk> | though that doesn't work =( |
| 08:48:37 | <edwardk> | it would cost us type inference for * |
| 08:50:18 | <edwardk> | it does work nicely for the set and bag restricted monads though, giving a proper everything-to-everything operation |
| 08:51:14 | <ClaudiusMaximus> | @hoogle finalizer |
| 08:51:15 | <lambdabot> | Foreign.Marshal.Alloc.finalizerFree :: FinalizerPtr a |
| 08:51:15 | <lambdabot> | Foreign.ForeignPtr.FinalizerPtr :: type FinalizerPtr a |
| 08:51:15 | <lambdabot> | Foreign.Concurrent.addForeignPtrFinalizer :: ForeignPtr a -> IO () -> IO () |
| 08:51:36 | <edwardk> | but it changes the meaning of (==) in a weird way, (==) for the reader monad lacks an alternative interpretation, but when you talk about lists or sets or bags it has a clear interpretation |
| 08:51:45 | <edwardk> | =( |
| 08:52:05 | <quicksilver> | yes |
| 08:52:20 | <quicksilver> | that's why we (sometimes) want to distinguish between foo and liftM2 foo :) |
| 08:52:36 | <edwardk> | heh |
| 08:52:52 | <quicksilver> | distinguishing between ++ and liftM2 ++, too.... |
| 08:53:00 | <edwardk> | i realize, but until i moved from Reader to a general monad i didn't have a good counter example =) |
| 08:53:32 | <quicksilver> | you're doing some really cool magic, but sometimes cool magic can become confusin |
| 08:54:03 | <edwardk> | so, one answer might be to define a class Monad m => MonadMath m |
| 08:54:09 | <edwardk> | then use the magic math stuff that way |
| 08:54:44 | <edwardk> | i.e. iff there is no reasonable interpretation of the mathematical operators in another way lift them |
| 08:55:01 | <edwardk> | but if you have something like lists etc, don't lift them by default |
| 08:55:07 | <wli> | edwardk: sounds interesting; what's going on here? |
| 08:55:20 | <edwardk> | playing with the stuff from my toy prelude some more |
| 08:55:33 | <quicksilver> | edwardk is pushing back the boundaries of sugar |
| 08:55:40 | <edwardk> | wli: the current question has to do with automatic lifting of mathematical operations into various monads. |
| 08:55:48 | <wli> | edwardk: Seen Oleg's BinaryNumber.hs? |
| 08:56:13 | <edwardk> | i already accepted the notion that given say a Monoid instance for 'a' then you should get a Monoid for b -> a, which is the reader monad |
| 08:56:33 | <edwardk> | so the question arose if it just make sense to define (+) = LiftM2 (+) for all monads |
| 08:56:50 | <edwardk> | similarly (==), (&&), (||), etc lift nicely |
| 08:57:03 | <edwardk> | but then it compromises the notion of equality comparison directly on lists |
| 08:57:09 | <wli> | edwardk: Built-in syntactic sugar or Oleg's BinaryNumber.hs would be very spiffy. |
| 08:57:10 | <edwardk> | even though it works nicely in the reader monad |
| 08:57:17 | <edwardk> | which one is that? |
| 08:57:21 | <wli> | s/sugar or/sugar for/ |
| 08:57:40 | <edwardk> | wli: heh, have you seen my version of that sort of thing? |
| 08:57:49 | <wli> | edwardk: no |
| 08:58:14 | <quicksilver> | edwardk: your pain would be allayed, somewhat, by syntax for choosing among alternative instances |
| 08:58:21 | <edwardk> | http://comonad.com/haskell/type-int/src/Data/Type/ |
| 08:58:22 | <lambdabot> | Title: Index of /haskell/type-int/src/Data/Type |
| 08:58:41 | <quicksilver> | edwardk: then it wouldn't matter that there were two instances for Eq [a], etc |
| 08:58:42 | <edwardk> | the Binary/ directory is the one of interest in the current discussion |
| 08:58:46 | <edwardk> | yeah |
| 08:59:23 | <edwardk> | in my toy compiler i allow dictionary passing by name, which plays some weird games with the semantics for dictionaries and typeclass inference i'm not QUITE sure i like yet |
| 08:59:54 | <edwardk> | sort .by anotherordinstance ... |
| 09:00:25 | <wli> | ACTION sees |
| 09:00:38 | <wli> | good stuff in the numbers |
| 09:00:39 | <quicksilver> | edwardk: yes. Have you seen the paper on that? |
| 09:00:43 | <edwardk> | sort :: (.by : Ord a) => [a] -> (result : [a] | sorted result) |
| 09:00:44 | <edwardk> | yeah |
| 09:00:46 | <quicksilver> | edwardk: they used the syntax '#' for application |
| 09:00:49 | <edwardk> | wli: thanks |
| 09:00:57 | <edwardk> | wli: the hex one is the scary part |
| 09:01:01 | <wli> | Totally reasonable. |
| 09:01:08 | <edwardk> | derives about 5 megs of haskell =) |
| 09:01:20 | <quicksilver> | although I favour some kind of lexical approach myself |
| 09:01:46 | <wli> | edwardk: Does it boil down to decently small programs despite 5M of source? |
| 09:02:10 | <edwardk> | quicksilver: yeah, what i'm using is .foo for named field dereference, and i've conflated the notion of functions and records so that accessing a named argument is looking up a named field in the function, which returns a new function pushing that argument to the front |
| 09:02:33 | <edwardk> | wli: they don't seem to be any worse than normal haskell programs |
| 09:02:40 | <edwardk> | wli: its just a huge library in the middle |
| 09:03:50 | <edwardk> | quicksilver: then i just allow the implicit dictionaries to be made explicit by passing them by name, requires a few more type annotations to be able to pass one in by name, which i'm not happy with but i think it may be the way i have to go |
| 09:04:03 | <quicksilver> | ACTION nods |
| 09:04:17 | <quicksilver> | edwardk: I like the idea of a language construct |
| 09:04:34 | <quicksilver> | using MonoidFromMonadPlus { ... expr ... } |
| 09:04:48 | <quicksilver> | edwardk: then, inside that scope, the notion of 'default' dictionary is changed |
| 09:04:56 | <edwardk> | thought about it, but the syntax is horrible =) |
| 09:05:14 | <edwardk> | and what is inside the scope, everything written in the scope or everything called by anything written in the scope |
| 09:05:26 | <edwardk> | what if i call into that scope is it dynamically of lexically bound, etc. |
| 09:05:59 | <edwardk> | to steal a quote from dan friedman 'scope is everything' =) |
| 09:06:19 | <quicksilver> | edwardk: lexical, not dynamic, obviously |
| 09:06:27 | <quicksilver> | edwardk: dynamic scopes are the work of the devil |
| 09:07:37 | <edwardk> | well, thats somewhat problematic still, because what if the compiler elides the dictionary for a few calls of depth knowing it can rederive it later? so now this interferes with optimizations? =) this is actually a spurious argument becausse i currently require myself to compile two versions, one optimized one for explicit calls ;) |
| 09:08:30 | <edwardk> | dynamic scopes have their place. i never thought i'd say it but i think oleg won me over with some of the dynamic binding + delimited control use cases. |
| 09:08:32 | <quicksilver> | edwardk: well obviously it can't elide dictionaries if they have been explicitly chosen as a non-default |
| 09:08:49 | <quicksilver> | edwardk: at least, it can't do that upfront |
| 09:08:51 | <dolio> | Yeah, I thought that was an interesting paper, too. |
| 09:09:08 | <quicksilver> | edwardk: after it's parsed + type checked everthing, then it can elide all kinds of dictionaries, cos they're mostly compile-time-constant |
| 09:09:11 | <dolio> | I hadn't thought of Reader as dynamic scoping before, but I suppose you can look at it like that. |
| 09:09:24 | <edwardk> | yeah |
| 09:09:28 | <quicksilver> | dolio: I would look at it as 'dynamic scoping done right', though |
| 09:09:38 | <vincenz> | moin |
| 09:09:43 | <wli> | I'm much stodgier about these things. |
| 09:09:44 | <dolio> | His dynamically scoped variables are different than you see in, say, old lisps, though. |
| 09:09:45 | <quicksilver> | dolio: dynamic scoping but 'explicit' in the types so you can see what's happening |
| 09:10:21 | <dolio> | Since you need to get a name for the scoped variable from someone. You can't just use an arbitrary name that happens to change depending on where you're called. |
| 09:10:23 | <edwardk> | wli: anyways the type integers there are largely inspired by oleg tricks, i just needed some that actually were fully fleshed out |
| 09:10:50 | <wli> | edwardk: I presume they're sugared in the source language? |
| 09:11:09 | <edwardk> | because while Oleg is brilliant, the man doesn't exactly spend his time polishing his ideas beyond a point before he goes off to do something else =) |
| 09:11:22 | <dolio> | Heh. |
| 09:11:57 | <edwardk> | wli: there are sugared witnesses for them, tAdd foo bar. and $(hexE 123) gives you a compile time generated numeric term. |
| 09:13:04 | <edwardk> | show (tAdd $(hexE 123) $(hexE (-123))) should output "$(hexE 0)" |
| 09:13:34 | <edwardk> | and the witnesses type infer values in all possible directions |
| 09:14:38 | <edwardk> | i mostly did it because i wanted to think through infinite precision 2s complement arithmetic |
| 09:14:54 | <edwardk> | i find the adder becomes amazingly symmetrical in that setting, etc. |
| 09:15:20 | <wli> | witnesses? |
| 09:16:10 | <edwardk> | well, the idea of type level arithmetic is you usually don't have members of your types, right? other than undefined that is. so you supply term-level functions for passing around those differently typed undefineds to perform calculations at the type level |
| 09:16:48 | <edwardk> | those term-level functions that reify the type-level calculations down from typeclasses to the term syntax are what I was calling witnesses. |
| 09:17:16 | <wli> | You could have a single member for each. |
| 09:19:04 | <edwardk> | result = tAdd $(hexE 3) $(hexE 64) is a fancy way of saying the constraint result :: TAdd (X3 F) (X4 (XF F)) z => z; result = undefined |
| 09:19:47 | <edwardk> | wli: you COULD, but then the compiler can't fully erase the types and then you have to deal with the implicit bottom member as opposed to the explicit member etc. |
| 09:20:04 | <edwardk> | its generally better form to not allow a singleton member in a witness if you can get away with it |
| 09:20:15 | <edwardk> | empty data declarations state intent to erase quite nicely =) |
| 09:21:01 | <wli> | edwardk: What's a witness? |
| 09:21:06 | <roconnor> | @where monad laws |
| 09:21:07 | <lambdabot> | I know nothing about monad. |
| 09:21:27 | <edwardk> | a witness is just a term level function like tOdd :: TOdd a b => a -> b; tOdd = undefined |
| 09:21:47 | <edwardk> | for a type level relation like: class TOdd a b | a -> b; instance (LSB a b c, TNot b b') => TOdd a b' |
| 09:22:53 | <edwardk> | tOdd takes one argument and returns its answer, its argument's value is never looked at just its type, and it generates an answer whose type is purely dependent on the type of the argument through the functional dependency in TOdd's definition |
| 09:23:33 | <edwardk> | tOdd 'witnesses' the relationship that TOdd creates between a number and a boolean value, by allowing you to write it at the term level rather than the type level. |
| 09:23:48 | <wli> | okay |
| 09:24:05 | <edwardk> | they are the sugar you mentioned =) |
| 09:24:08 | <wli> | I didn't know there was a name for that. |
| 09:24:34 | <edwardk> | the only problem is that you can't overload the normal (+) to manipulate the type level terms or you lose type inference for the normal use cases =( |
| 09:25:09 | <edwardk> | ideally i'd go back and make a consistent convention, like (+:) or something |
| 09:25:12 | <wli> | edwardk: I was thinking more of the compiler/interpreter translating type names written with decimal digits to the binary/whatever strings. |
| 09:25:45 | <edwardk> | wli: thats what the template haskell $(hexE 123891) expressions are for |
| 09:26:32 | <dblhelix> | are there any standard arrows implemented in the hierarchical libraries? reader arrows, writer arrows, state arrows, etc.? |
| 09:26:53 | <wli> | dblhelix: I wish. I've not seen anything of the sort. |
| 09:26:54 | <edwardk> | $(hexE 255) returns the equivalent of having written (undefined :: XF (XF F)) |
| 09:27:17 | <edwardk> | and $(hexT 255) returns the type itself XF (XF F) for use in type-level expressions |
| 09:27:18 | <dblhelix> | we need an arrow template library! |
| 09:27:30 | <wli> | edwardk: Some sort of lexical construct that expands to that would be nice. |
| 09:28:09 | <wli> | TypeNat123 etc. |
| 09:28:19 | <edwardk> | wli: $(hexE 123) _is_ that lexical construct =) thats the only escape we can get right now. |
| 09:28:36 | <dblhelix> | wli: what about http://hackage.haskell.org/cgi-bin/hackage-scripts/package/arrows-0.2 |
| 09:28:39 | <lambdabot> | http://tinyurl.com/2z6ftm |
| 09:29:13 | <wli> | dblhelix: Looks interesting. |
| 09:30:31 | <wli> | edwardk: Punching a hole in the type namespace for it and generating that from the name string shouldn't be hard. |
| 09:30:59 | <edwardk> | robert dockins also has a typenat library, though his has fewer directions of inference (because his is naturals, not integers, not so many things are closed) in his case the naming sugar is the kind of scary 'two `hundred` sixty four' |
| 09:31:37 | <opqdonut> | :D |
| 09:31:39 | <opqdonut> | nice |
| 09:32:27 | <edwardk> | wli: an interesting problem, GHC doesn't offer that sort of user directed name management at the moment. i've thought about something in the same general sphere to allow for user-managed int syntax, etc for my own use but i haven't found a good way to let the library hook into the parser |
| 09:32:38 | <wli> | edwardk: Naturals and integers are easy. Primes, polynomials (esp. irreducible ones), etc. |
| 09:33:16 | <edwardk> | heh, i just needed them to check array bounds at compile time, etc. |
| 09:34:08 | <edwardk> | ints and nats are more than sufficient for those needs. =) i'm actually in the process of defining arbitrary type-level meet-semilattices, and their products, sums, disjoint unions, etc. for another project though. so maybe i'll drift back towards that =) |
| 09:34:09 | <wli> | GF(p^n), Q_p, Z[a] for algebraic integers a, etc. |
| 09:35:24 | <wli> | I'm not sure how to do primes yet. Irreducible polynomials look even hairier. |
| 09:36:13 | <edwardk> | anyways i can catch about an hour and a half nap before work, so i'm going to wander off. |
| 09:36:23 | <quicksilver> | @localtime edwardk |
| 09:36:32 | <wli> | If you can get a large enough fragment of logic going within your types to check those sorts of things I think you can still be decidable. |
| 09:37:31 | <edwardk> | wli: right now i just need a logical ^ meet operator for security levels, not in a hurry to do RSA at the type level =) |
| 09:46:27 | <oerjan> | @bot |
| 09:46:27 | <lambdabot> | :) |
| 09:53:04 | <Nopik> | damn.. ghc was compiling for 2 hours and it failed due to lack of disk space ;( |
| 09:53:36 | <dons> | oops |
| 09:53:39 | <dons> | can you just use a binary? |
| 09:55:15 | <Nopik> | yeah, i would like to.. though my distro somehow refuses to notice the fact that ghc-bin 6.6 exists and forces 6.4.2.. |
| 10:13:52 | <mm_freak> | nopik: gentoo? |
| 10:38:43 | <dons> | ?users |
| 10:38:43 | <lambdabot> | Maximum users seen in #haskell: 355, currently: 319 (89.9%), active: 5 (1.6%) |
| 10:39:33 | <quicksilver> | ooh :( |
| 10:39:39 | <quicksilver> | dropping |
| 10:40:46 | <dozer> | is there a cleaner way to write this: flip (foldl (flip $ uncurry M.insert)) assocList |
| 10:41:05 | <dozer> | where assocList is [(k, v)] |
| 10:42:00 | <Nopik> | mm_freak: yeah |
| 10:42:07 | <quicksilver> | fromList? |
| 10:42:17 | <mm_freak> | nopik: GHC 6.6 is masked in gentoo… you need to unmask it |
| 10:42:19 | <quicksilver> | dozer: is that M.fromList? |
| 10:42:31 | <Nopik> | mm_freak: i've unmasked 6.6.1 sources and remerging them once again (after freeing 500mb of disk space ;d) |
| 10:42:45 | <dozer> | well, it is a functio that adds all the things in assocList to its argument |
| 10:42:47 | <Nopik> | mm_freak: yes, but there is no ebuild for ghc-bin 6.6.x |
| 10:43:21 | <mm_freak> | oh, i see |
| 10:43:22 | <dozer> | quicksilver: it's still waiting for a map to add all those things to |
| 10:43:42 | <quicksilver> | dozer: M.union (M.fromList assocList) |
| 10:44:10 | <mm_freak> | ok, then you'll need to merge ghc-bin-6.4.2, then ghc-6.6.1, then unmerge ghc-6.4.2 and finally remerge ghc-6.6.1 =) |
| 10:44:35 | <mm_freak> | the point is compiler performance… compiling GHC using GHC 6.6.1 makes it run a lot faster |
| 10:44:46 | <quicksilver> | dozer: and isn't flip ( foldl ( flip just foldr? |
| 10:45:23 | <dozer> | quicksilver: that union/fromlist thing is probably what I was after |
| 10:45:41 | <wli> | flip . foldr . flip == foldl? |
| 10:47:01 | <DRMacIver> | Wrong type signature isn't it? |
| 10:47:08 | <DRMacIver> | @type flip . foldr . flip |
| 10:47:10 | <lambdabot> | forall b c. (c -> b -> c) -> [b] -> c -> c |
| 10:47:11 | <DRMacIver> | @type foldl |
| 10:47:13 | <lambdabot> | forall a b. (a -> b -> a) -> a -> [b] -> a |
| 10:47:27 | <quicksilver> | well you don't necessarily need that last flip |
| 10:47:34 | <DRMacIver> | @type foldr . flip |
| 10:47:35 | <quicksilver> | it does all depend what you're trying to acheive, exactly |
| 10:47:36 | <lambdabot> | forall b c. (c -> b -> c) -> c -> [b] -> c |
| 10:47:49 | <DRMacIver> | Hm. I guess not. |
| 10:47:57 | <quicksilver> | of course, they're not the same, in the sense that they do the calculation in a different order |
| 10:48:18 | <quicksilver> | you need to add a 'reverse' in to get the same ordering |
| 10:48:20 | <quicksilver> | if that matters |
| 10:48:31 | <wli> | looks like it yeah |
| 10:48:44 | <quicksilver> | the guideline is to use foldr if in doubt, though |
| 10:51:57 | <DRMacIver> | I'm never entirely clear how lazy Data.Map manages to be. |
| 10:52:20 | <wli> | Me neither. |
| 10:52:54 | <wli> | Maybe there should be a Data.RadixTree as they're obvious to make fully lazy. |
| 10:52:56 | <DRMacIver> | I mean, I can see the potential for some opportunities for laziness, but most of them look like "Only if you're lucky in the data you try to use". |
| 10:53:00 | <oerjan> | DRMacIver: someone said it is strict in the spine of the map |
| 10:53:40 | <DRMacIver> | Hm. I'm not totally sure what that means. :) |
| 10:53:46 | <DRMacIver> | What's the spine of the map? |
| 10:53:58 | <oerjan> | the shape of the tree |
| 10:54:37 | <DRMacIver> | Ah |
| 10:56:02 | <quicksilver> | DRMacIver: totally lazy in values, I'm sure |
| 10:56:07 | <quicksilver> | DRMacIver: it would be daft to be any other way |
| 10:56:20 | <wli> | How would it do comparisons if so? |
| 10:56:24 | <quicksilver> | DRMacIver: most Ord instances you can imagine would make it strict in the keys |
| 10:56:42 | <quicksilver> | DRMacIver: although you can imagine an Ord instance which falls short of completely strict |
| 10:56:55 | <quicksilver> | > 'a' : undefined < 'b' : undefined |
| 10:57:01 | <oerjan> | quicksilver: keys that are lists |
| 10:57:03 | <lambdabot> | True |
| 10:57:06 | <wli> | Ord on a record only comparing some fields. |
| 10:57:08 | <quicksilver> | including that one :) |
| 10:57:09 | <quicksilver> | right |
| 10:57:23 | <quicksilver> | however it's always going to be 'somewhat' strict in the keys |
| 10:57:39 | <oerjan> | (but then you probably want a trie) |
| 10:57:41 | <DRMacIver> | quicksilver: Yeah, I realised it was always lazy in the values. I was wondering about key strictness. |
| 10:57:52 | <kolmodin> | dons: you've got mail |
| 10:58:38 | <DRMacIver> | But you're right that some strictness is obviously neccessary. I was just curious how much. :) |
| 10:58:40 | <wli> | ACTION ponders composition/chaining of Mealy machines. |
| 10:59:20 | <quicksilver> | DRMacIver: I believe it is maximally lazy, in practice |
| 10:59:25 | <DRMacIver> | What on earth is a Mealy machine? |
| 10:59:36 | <quicksilver> | DRMacIver: the only strictness is that which is implied by your choice of Ord instance |
| 10:59:46 | <DRMacIver> | ok |
| 10:59:48 | <dozer> | DRMaclvier: it's an inside-out more machine |
| 11:00:13 | <DRMacIver> | What on earth is a more machine? :) |
| 11:00:25 | <quicksilver> | DRMacIver: an inside-out mealy machine |
| 11:00:26 | <wli> | DRMacIver: A Mealy machine is a finite automaton that produces output during state transitions. |
| 11:00:26 | <blackdog_> | it's an outside-in mealy machine... |
| 11:00:32 | <oerjan> | quicksilver: that is not what i heard. i heard it computed the entire shape of the tree (and was translated from Ocaml) |
| 11:00:38 | <quicksilver> | oerjan: that's true too |
| 11:00:40 | <DRMacIver> | quicksilver: I new you would say that. :) |
| 11:00:45 | <quicksilver> | DRMacIver: sorry :P |
| 11:00:48 | <DRMacIver> | knew |
| 11:00:55 | <wli> | DRMacIver: A Moore machine is a finite automaton that produces output on entering states. |
| 11:01:00 | <quicksilver> | oerjan: well, 'insert' doesn't force the spine AFAIk |
| 11:01:02 | <DRMacIver> | ok |
| 11:01:05 | <quicksilver> | oerjan: but accessing an element does |
| 11:01:59 | <quicksilver> | oerjan: so in practice the spine gets forced fairly 'soon' |
| 11:02:18 | <quicksilver> | I don't know for sure if it forces the whole spine, though |
| 11:02:29 | <wli> | It shouldn't. |
| 11:02:33 | <quicksilver> | if you head down the left branch, the other thunks might just get pushed right |
| 11:02:40 | <wli> | Just what's required in the lookup path. |
| 11:02:41 | <quicksilver> | and not evaluated further than needed to push them right |
| 11:03:08 | <DRMacIver> | Hm. Any good functional programming related podcasts? |
| 11:03:14 | <oerjan> | forcing the whole spine may help against space leaks, i suspect |
| 11:03:22 | <DRMacIver> | (Otherwise good podcasts are also welcome :) ) |
| 11:03:40 | <quicksilver> | oerjan: I could imagine that, but I don't see any explicit forcing in the code |
| 11:03:54 | <quicksilver> | oerjan: so I think it's just demand-driven |
| 11:03:57 | <ekidd> | Good morning. |
| 11:05:24 | <oerjan> | oh, it's actually obvious: there are strictness tags on the Map data definition |
| 11:06:55 | <quicksilver> | oerjan: oh. stupid me :) |
| 11:07:20 | <quicksilver> | oerjan: didn't think to look there :) |
| 11:07:30 | <oerjan> | easy to do :) |
| 11:07:46 | <quicksilver> | I searched the file for 'seq' and Iread the source for insert and balance |
| 11:09:05 | <kjdf> | could someone give me some pointers on how to do dynamic programming in haskell? |
| 11:09:13 | <kjdf> | (and/or memoization) |
| 11:09:21 | <quicksilver> | oerjan: I don't understand the algorithm in detail, but I *think* that the !Size annotation is enough to strictify the whole spine |
| 11:09:29 | <|Steve|> | I just wrote a macro in scheme that will memoize any function. |
| 11:09:34 | <quicksilver> | oerjan: since that forces all the sizes everywhere and that forces the whole shape? |
| 11:21:42 | <malcolmw> | dcoutts, dcoutts_: ping? |
| 11:22:17 | <fasta> | Is there free software which implements a propositional logic simplifier? |
| 11:22:56 | <oerjan> | quicksilver: i think rebalancing can be lazy in some of the shape even while calculating the total sizes. |
| 11:24:00 | <oerjan> | (in principle) |
| 11:24:25 | <malcolmw> | fasta: clausify? (in the nofib suite) |
| 11:24:52 | <malcolmw> | fasta: I think ndm has a propositional simplifier as well |
| 11:24:55 | <fasta> | malcolmw: I prefer something which is an actual apt-gettable program. |
| 11:26:16 | <wli> | fasta: You want something like a command interpreter that accepts propositional logic expressions as input and produces simplified expressions as replies? |
| 11:26:24 | <fasta> | wli: right |
| 11:26:37 | <fasta> | Probably coq does that |
| 11:26:41 | <wli> | Sounds like a fun project. |
| 11:26:50 | <wli> | coq probably does everything. |
| 11:27:26 | <fasta> | wli: It's just that it's easy to let the machine do the simplifications then to do by hand, although I rarely write redundant logic. |
| 11:28:37 | <wli> | Sort of like a reducer for Prolog. |
| 11:30:32 | <quicksilver> | or, sort of like prolog itself :) |
| 11:30:37 | <quicksilver> | sort of like a prolog engine |
| 11:30:54 | <quicksilver> | I'm not aware of an out-of-the-box solution myself |
| 11:31:01 | <quicksilver> | although surely all the decent CA packages can do it |
| 11:31:10 | <quicksilver> | and ndm did write something like that you're right |
| 11:33:03 | <malcolmw> | http://www-users.cs.york.ac.uk/~ndm/proposition/ |
| 11:33:05 | <lambdabot> | Title: Neil Mitchell - Proposition |
| 11:38:36 | <fasta> | Another program I would love to see is a compiler from Haskell to a boolean circuit. |
| 11:39:06 | <fasta> | Or rather a boolean formula. |
| 11:39:17 | <fasta> | (to be more precise) |
| 11:44:02 | <profmakx> | hmm |
| 11:46:15 | <dons> | would an FPGA compiler do? |
| 11:46:36 | <profmakx> | i thought of something like that too, fasta :) |
| 11:48:36 | <Nopik> | i have a question about monad types.. i am a beginner haskeller, so most likely i confuse some ideas here.. but, on a tutorials about a monads, they says that monad typing convention is seamlessly using existing haskell syntax, so things like "IO String" are already in the language.. but how to understand the "IO String" or "MyType OtherType" syntax? |
| 11:49:16 | <quicksilver> | "IO String" means : computation, which probably involves some I/O or other interaction with the outside world, and finally produces a result of type String |
| 11:49:18 | <Nopik> | I can write data Point a b = Point Double Double for example (or something like this :D).. which seems the same syntax to me |
| 11:49:29 | <earthy> | nopik: exactly so. |
| 11:49:29 | <mauke> | Nopik: it is |
| 11:49:31 | <quicksilver> | it is the same syntax |
| 11:49:40 | <quicksilver> | there is nothing spcial about them, in that sense |
| 11:49:44 | <quicksilver> | they're just another data type |
| 11:49:50 | <quicksilver> | their meaning is the interesting part |
| 11:49:52 | <Nopik> | ok, then, I cannot write method of type IO String -> String, right? |
| 11:50:00 | <quicksilver> | you can, in fact |
| 11:50:07 | <quicksilver> | but you can't write the method you wanted to write :) |
| 11:50:08 | <mauke> | right, because you don't know how IO looks internally |
| 11:50:11 | <earthy> | but we like to hide that fact. :) |
| 11:50:11 | <Nopik> | but I can write method Point Double Double -> (Double, Double) |
| 11:50:17 | <quicksilver> | correct |
| 11:50:29 | <quicksilver> | because 'IO String' doesn't actually *include* that value of type String |
| 11:50:36 | <quicksilver> | rather, it contains the instructions on how to calculate it |
| 11:50:45 | <quicksilver> | until that calculation/computation is carried out |
| 11:50:49 | <quicksilver> | the String result doesn't exist |
| 11:50:58 | <Nopik> | ok, but if IO internals were exposed to me, I would be able to extract String from IO String and export it without IO monad.. is that right? |
| 11:51:05 | <mauke> | not really |
| 11:51:06 | <quicksilver> | and you can't know in advance what the answer is going to be |
| 11:51:12 | <mauke> | you'd still have to actually do the I/O somehow |
| 11:51:18 | <quicksilver> | well computing the answer might involve connecting to another computer over the internet |
| 11:51:22 | <quicksilver> | or asking for user input |
| 11:51:26 | <quicksilver> | or various other things |
| 11:51:26 | <Nopik> | yeah |
| 11:51:47 | <roconnor> | or formating your hard drive |
| 11:51:59 | <Nopik> | but once one function returns something of type IO String to me, I should be able to extract plain String from it? |
| 11:52:23 | <mauke> | there is no plain string there |
| 11:52:30 | <mauke> | consider data Spork a b = Spork (a -> b -> Ordering) |
| 11:52:38 | <mauke> | then I hand you Spork Double Double |
| 11:52:46 | <mauke> | can you extract (Double, Double) from that? |
| 11:52:55 | <Nopik> | hm, ok |
| 11:52:57 | <Nopik> | good point |
| 11:53:32 | <Nopik> | so it is more like c++ template argument |
| 11:53:44 | <roconnor> | indeed. |
| 11:53:44 | <mauke> | right |
| 11:54:06 | <Nopik> | ok, thanks for explaination |
| 11:54:14 | <mauke> | in fact, there is no requirement that a data type actually uses the type parameters it gets |
| 11:54:25 | <mauke> | data Wtf a = Wtf String -- valid |
| 11:54:32 | <Nopik> | yeah, i know |
| 11:55:33 | <quicksilver> | even if the type is there in the type, it may not be there in every value, too |
| 11:55:40 | <quicksilver> | 'Nothing' is a valid value of type 'Maybe Int' |
| 11:55:47 | <quicksilver> | but there really isn't an integer in there, to get out :) |
| 11:55:48 | <fasta> | A program-simplifier could also have some value. |
| 11:55:58 | <Nopik> | ;) |
| 11:56:02 | <quicksilver> | Nopik: this is actually a good example, since Maybe is also a monad |
| 11:56:03 | <fasta> | E.g. if a < b then a else b should be min a b |
| 11:56:12 | <Nopik> | quicksilver: indeed |
| 11:56:30 | <quicksilver> | Nopik: the analogy with IO is that an action of type IO String might actually throw an exception |
| 11:56:36 | <quicksilver> | Nopik: so it might never return a string after all |
| 11:56:51 | <Nopik> | ACTION did not read about exceptions yet ;p |
| 11:57:21 | <mauke> | fail "zomg" :: IO String |
| 11:57:37 | <fasta> | dons: I just want an AST consisting of NOT, AND and OR gates taking respectively 1, 2 and 2 arguments. |
| 11:57:49 | <Nopik> | yeah, i have seen 'fail' usage few times, but no comprehensive text about them |
| 11:57:53 | <fasta> | dons: if an FPGA can do that, I would be most happy. |
| 11:57:59 | <quicksilver> | malcolmw: interesting. ndm's Data.Proposition abuses Show. |
| 11:58:10 | <quicksilver> | malcolmw: I wonder if this is still considered abuse, or if it's become acceptable |
| 11:58:13 | <fasta> | dons: FPGA compiler* |
| 11:58:19 | <mauke> | Nopik: that's probably because 'fail' is a hack :-) |
| 11:58:27 | <Nopik> | mauke: :) |
| 11:58:36 | <kjdf> | RWS monad is just a combined reader, writer and state? |
| 11:58:43 | <mauke> | yes |
| 11:58:56 | <quicksilver> | kjdf: yes. I believe it's intended more as an instructive example than a useful thing in itself |
| 11:58:57 | <Nopik> | i'll write my first 'real' program first, then i'll know what i need to read about on the next stage ;p |
| 11:59:27 | <mauke> | maybe it predates monad transformers |
| 11:59:33 | <roconnor> | quicksilver: I used the RWS monad. |
| 11:59:38 | <dons> | quicksilver: how is it abused, the Show instance? |
| 11:59:45 | <dons> | to wrap IO and render it harmless? |
| 11:59:51 | <roconnor> | Monad tranformers confuse me a bit. |
| 11:59:52 | <scook0> | RWST is a great way to accidentally introduce space leaks :/ |
| 12:00:12 | <quicksilver> | dons: No. It's just he makes an instance for a 'convenient human readble display' |
| 12:00:17 | <quicksilver> | dons: but it doesn't produce parseable haskell |
| 12:00:23 | <roconnor> | I never know if i want ListT State or StateT List. |
| 12:00:27 | <quicksilver> | dons: which is the unofficial Show invariant :) |
| 12:00:32 | <dons> | oh, i guess its ok outside of the base lib |
| 12:00:58 | <quicksilver> | dons: I find that very annoying, during debugging |
| 12:01:02 | <dons> | yeah, read . show is supposed to work. as is pasting code into src |
| 12:01:14 | <quicksilver> | dons: I often generate counter-examples in ghci |
| 12:01:20 | <roconnor> | scook0: how does RWST introduce space leaks? |
| 12:01:21 | <quicksilver> | dons: and copy them into code from my terminal, to make a test |
| 12:01:31 | <dons> | yeah |
| 12:01:48 | <quicksilver> | dons: show the Show -> copy/paste -> .hs file loop is very important to me |
| 12:01:54 | <dons> | tell him to use a Pretty class for that, not Show :) |
| 12:01:55 | <quicksilver> | s/show the/so the/ |
| 12:01:57 | <quicksilver> | ACTION nods |
| 12:02:02 | <scook0> | roconnor: a lazy writer part accumulates thunks like mad |
| 12:02:08 | <quicksilver> | I've tried to bring this up with him once |
| 12:02:11 | <scook0> | even if you aren't using it |
| 12:02:14 | <quicksilver> | he didn't understand my point, I don't think |
| 12:02:22 | <quicksilver> | I probably didn't explain it well |
| 12:02:40 | <quicksilver> | dons: but I wonder if this invariant should be better documented or discussed |
| 12:02:56 | <earthy> | really the point is that there's 'moderately readable serialisation, acceptable to the GHC parser' and 'pretty printing' |
| 12:03:23 | <roconnor> | scook0: does that apply equally to the WriterT? |
| 12:03:33 | <earthy> | where the latter may degenerate into calls to the former |
| 12:03:36 | <quicksilver> | earthy: absolutely |
| 12:03:38 | <earthy> | but not the other way 'round |
| 12:03:39 | <scook0> | roconnor: if it's lazy, I presume so |
| 12:03:44 | <quicksilver> | earthy: well said |
| 12:04:05 | <roconnor> | @type runWriter |
| 12:04:07 | <lambdabot> | forall w a. Writer w a -> (a, w) |
| 12:04:08 | <earthy> | unfortunately, the distinction isn't available in the prelude |
| 12:04:16 | <scook0> | actually, I have no idea whether either is *guaranteed* to leak space |
| 12:04:38 | <roconnor> | scook0: If uses the list Monoid, then the size of the thunks is about the size of the resulting list? |
| 12:04:40 | <earthy> | which makes the new prelude goals laudable. :) |
| 12:05:48 | <scook0> | after upgrading to ghc 6.6 I spent ages tracking down a space leak caused by a lazy RWST making heaps of 'mappend' thunks on () |
| 12:05:51 | <quicksilver> | @src Writer (>>=) |
| 12:05:51 | <lambdabot> | Source not found. My mind is going. I can feel it. |
| 12:06:04 | <quicksilver> | the problem, as I see it, is there in Writer |
| 12:06:15 | <quicksilver> | @src (Writer w) (>>=) |
| 12:06:15 | <lambdabot> | Source not found. Just what do you think you're doing Dave? |
| 12:06:24 | <quicksilver> | m >>= k = Writer $ let |
| 12:06:24 | <quicksilver> | (a, w) = runWriter m |
| 12:06:24 | <quicksilver> | (b, w') = runWriter (k a) |
| 12:06:24 | <quicksilver> | in (b, w `mappend` w') |
| 12:06:40 | <quicksilver> | note the `mappend` is "always" called |
| 12:06:48 | <quicksilver> | even if the action 'm' generated no output |
| 12:07:06 | <quicksilver> | so for a long writer action, which generates no output at all |
| 12:07:27 | <quicksilver> | you get this silly thunk mempty `mappend` mempty `mappend` mempty `mappend` .... |
| 12:07:46 | <quicksilver> | scook0: is that your understanding of the problem? |
| 12:07:51 | <scook0> | quicksilver: pretty much |
| 12:08:15 | <scook0> | the worst thing was that my space profiling gave totally misleading results |
| 12:08:21 | <scook0> | since the leak was in the monad itself |
| 12:08:46 | <quicksilver> | seems to be true even of Writer.Strict |
| 12:08:50 | <quicksilver> | unless I'm misreading the code |
| 12:09:22 | <chessguy> | so who's got the cryptic messages about ICFP07 figured out? |
| 12:09:23 | <scook0> | well, in my case I just ditched the writer, since I wasn't using it |
| 12:10:08 | <mauke> | @source Control.Monad.Writer |
| 12:10:09 | <lambdabot> | http://darcs.haskell.org/packages/mtl/Control/Monad/Writer.hs |
| 12:10:55 | <quicksilver> | seems that let w'' = w `mappend` w' in w'' `seq` (b,w'') might be better |
| 12:10:58 | <quicksilver> | but I'm not sure |
| 12:11:14 | <mauke> | wtf |
| 12:11:15 | <quicksilver> | given a monad instance which has a fairly simple instance for 'mempty' |
| 12:11:25 | <mauke> | is Writer.Strict identical to Writer.Lazy? |
| 12:11:43 | <quicksilver> | mauke: no, it's strict in the typle |
| 12:11:47 | <quicksilver> | mauke: tuple |
| 12:12:05 | <mauke> | meh |
| 12:12:20 | <wli> | I've not gotten the hang of what writers are used for. |
| 12:12:26 | <quicksilver> | wli: logging |
| 12:12:35 | <mauke> | table building |
| 12:12:37 | <wli> | Examples? |
| 12:12:41 | <quicksilver> | wli: like sprinkling 'putStrLns' through your code |
| 12:12:47 | <quicksilver> | only they aren't actually putStrLns really |
| 12:12:52 | <quicksilver> | just log messages collected in a big list |
| 12:12:53 | <mauke> | I've used it in an interpreter |
| 12:13:09 | <wli> | mauke: How did you use it there? |
| 12:13:23 | <mauke> | I wanted to transform a parse tree into an easier interpretable form |
| 12:13:29 | <wli> | quicksilver: I'm looking for things more like mauke is talking about. |
| 12:13:40 | <roconnor> | quicksilver: ugh, that's terrible. |
| 12:13:40 | <quicksilver> | ACTION nods |
| 12:13:41 | <mauke> | specifically, I wanted to resolve function calls |
| 12:13:42 | <wli> | mauke: What sort of form was that? |
| 12:14:23 | <wli> | Well, I already have an example where I output the various row operations used in Gaussian elimination. |
| 12:15:00 | <wli> | It seems vastly more general than outputting mere sequences so I've something of a failure of imagination as to how it's used more generally. |
| 12:15:28 | <quicksilver> | wli: well, think of more exciting monoids, then |
| 12:15:29 | <mauke> | the original version used runtime table lookups because all function calls were done on strings |
| 12:15:40 | <quicksilver> | wli: 'accumulating summary data' |
| 12:16:01 | <mauke> | the improved "compiler" had to immediately resolve symbols while compiling them |
| 12:16:14 | <roconnor> | maybe my RWS monad code worked well because I demaned the results of my writer monad in the middle of using it. |
| 12:16:20 | <mauke> | i.e. it had to resolve symbols that weren't even compiled yet |
| 12:16:23 | <quicksilver> | roconnor: that will stop the leak, yes |
| 12:16:30 | <wli> | quicksilver: So it could, in principle, be used to sum numbers. |
| 12:16:36 | <quicksilver> | roconnor: just keep demanding the write from time to time |
| 12:16:51 | <quicksilver> | @instances Monoid |
| 12:16:55 | <lambdabot> | (), (a -> b), (a, b), (a, b, c), All, Any, Dual a, Endo a, Ordering, Product a, Sum a, [a] |
| 12:17:02 | <wli> | mauke: IOW single-pass compilation? |
| 12:17:13 | <mauke> | right |
| 12:17:40 | <roconnor> | Ordering is a Monoid? |
| 12:17:48 | <wli> | mauke: So you built up a forward reference table of symbols to be resolved once encountered? |
| 12:17:52 | <roconnor> | > Lt `mappend` Gt |
| 12:17:53 | <lambdabot> | Not in scope: data constructor `Gt' |
| 12:17:57 | <roconnor> | > LT `mappend` GT |
| 12:17:59 | <lambdabot> | LT |
| 12:18:05 | <roconnor> | ? |
| 12:18:44 | <mauke> | everytime it encountered a function, it would compile it and 'write' it (the name and compiled code) to the log |
| 12:19:07 | <Botje> | @pl \v m -> M.insert k v m |
| 12:19:07 | <lambdabot> | ((M .) .) . insert k |
| 12:19:11 | <mauke> | hmm |
| 12:19:14 | <Botje> | @pl \v m -> insert k v m |
| 12:19:14 | <lambdabot> | insert k |
| 12:19:20 | <Botje> | doh |
| 12:19:21 | <Nopik> | yeah... ghc 6.6.1 finally compiled, after 2h20m and 1GB of disk space ;p |
| 12:19:23 | <Botje> | that was silly. |
| 12:19:43 | <mauke> | am I misreading this code? |
| 12:20:01 | <quicksilver> | > runWriter . sequence_ . map (tell . Sum) $ [1..5] |
| 12:20:02 | <lambdabot> | ((),Sum {getSum = 15}) |
| 12:20:04 | <chessguy> | -- lexicographical ordering |
| 12:20:04 | <chessguy> | instance Monoid Ordering where |
| 12:20:04 | <chessguy> | mempty = EQ |
| 12:20:04 | <chessguy> | LT `mappend` _ = LT |
| 12:20:04 | <chessguy> | EQ `mappend` y = y |
| 12:20:05 | <chessguy> | GT `mappend` _ = GT |
| 12:20:08 | <quicksilver> | wli: like that ^^ |
| 12:20:09 | <chessguy> | roconnor, ^^ |
| 12:20:51 | <quicksilver> | wli: or, if you prefer to multiply the numbers, take a different Monoid instance |
| 12:20:58 | <quicksilver> | > runWriter . sequence_ . map (tell . Prouct) $ [1..5] |
| 12:20:59 | <lambdabot> | Not in scope: data constructor `Prouct' |
| 12:21:02 | <quicksilver> | > runWriter . sequence_ . map (tell . Product) $ [1..5] |
| 12:21:03 | <lambdabot> | ((),Product {getProduct = 120}) |
| 12:21:36 | <Nopik> | do anyone here happen to have simple/small examples of using gd library? |
| 12:21:45 | <chessguy> | gd? |
| 12:22:12 | <wli> | Not sure what lambdabot command to look up Sum |
| 12:22:20 | <quicksilver> | it's just a newtype over numbers |
| 12:22:23 | <Nopik> | chessguy: this is library for manipulating images |
| 12:22:31 | <fasta> | gd is an image library, popular with PHP programmers. |
| 12:22:33 | <quicksilver> | to give it the obvious Monoid instance using (+) |
| 12:22:42 | <wli> | quicksilver: Where is it? |
| 12:22:50 | <quicksilver> | not sure |
| 12:23:03 | <fasta> | Nopik: what makes you think this library has Haskell bindings? |
| 12:23:10 | <quicksilver> | http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Monoid.html |
| 12:23:12 | <lambdabot> | http://tinyurl.com/y5qk9n |
| 12:23:15 | <quicksilver> | wli: there ^^ |
| 12:23:36 | <quicksilver> | 'IntSet' is another interesting Monoid instance |
| 12:23:42 | <quicksilver> | you can accumulate sets of stuff |
| 12:23:50 | <wli> | Endo hmm. |
| 12:23:51 | <quicksilver> | this has obvious applications for things like 'privileges' |
| 12:23:55 | <Nopik> | fasta: because i have downloaded the bindings from haskell.org and runghc Setup.hs configure/build/install worked? |
| 12:23:59 | <mauke> | wli: apparently I misremembered my own code. the "log" is just a set of strings (symbol names) |
| 12:24:11 | <fasta> | Nopik: URL? |
| 12:24:19 | <fasta> | And define: |
| 12:24:22 | <fasta> | @where gd |
| 12:24:22 | <lambdabot> | I know nothing about gd. |
| 12:25:00 | <Nopik> | fasta: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/gd-3000.3.0 |
| 12:25:02 | <lambdabot> | http://tinyurl.com/2wuz44 |
| 12:25:24 | <fasta> | @where+ gd http://hackage.haskell.org/cgi-bin/hackage-scripts/package/gd-3000.3.0 |
| 12:25:24 | <lambdabot> | Done. |
| 12:25:35 | <mauke> | wli: the magic is in the compiler functions that use this set to build a symbol map that is then returned and so it can be passed in as a reader environment for the compiler functions |
| 12:25:53 | <Nopik> | though bindings are quite badly documented :( |
| 12:26:09 | <fasta> | Nopik: if you just look at the module interface, it's quite clear. |
| 12:26:18 | <fasta> | loadJpegFile, loadJpegData, loadJpegByteString, |
| 12:26:18 | <fasta> | -- ** PNG |
| 12:26:18 | <fasta> | loadPngFile, loadPngData, loadPngByteString, |
| 12:26:18 | <fasta> | -- ** GIF |
| 12:26:20 | <fasta> | loadGifFile, loadGifData, loadGifByteString, |
| 12:26:23 | <fasta> | Etc |
| 12:26:32 | <fasta> | That seem pretty sane names. |
| 12:26:57 | <dons> | looks nice. what lib is that? |
| 12:27:04 | <dons> | gd-3000 ? |
| 12:27:05 | <fasta> | @where gd |
| 12:27:06 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/gd-3000.3.0 |
| 12:27:08 | <fasta> | dons: yes |
| 12:27:18 | <dons> | cool, must recommend that when people come looking for .png loading libs |
| 12:27:20 | <Nopik> | fasta: yeah.. though i am extremely new at haskell, so even such things leave a little puzzlement for me :) but well, lets get some experience ;) |
| 12:27:24 | <fasta> | I wasn't aware of its existence. |
| 12:27:43 | <fasta> | Nopik: I only touched really simple libraries written by other people. |
| 12:27:58 | <Nopik> | i was looking for image manipulation library, this is the only library listed on haskell.org to claim to be able to do such thing ;p |
| 12:27:59 | <fasta> | Nopik: partly, because everything I need doesn't exist yet. |
| 12:28:27 | <Nopik> | fasta: yeah, tell me about it ;p |
| 12:28:29 | <wli> | Sum/Product are really just biendomorphism instances. |
| 12:28:42 | <fasta> | Nopik: GTK2HS also contains an image manupulation monad. |
| 12:28:57 | <kjdf> | and what do you need, fasta? |
| 12:29:06 | <fasta> | manipulation* |
| 12:29:11 | <quicksilver> | dons: is it possible for hacakge to automatically put the haddock online? |
| 12:29:23 | <fasta> | kjdf: are you asking for suggestions? |
| 12:29:24 | <quicksilver> | dons: that's what CPAN does, and I suspect that's one of the most important features |
| 12:29:36 | <Botje> | ACTION is writing a small webserver in haskell |
| 12:29:37 | <Botje> | it's nice :) |
| 12:29:41 | <wli> | You probably need instances on higher kinds. |
| 12:29:52 | <HairyDude> | is it intentional in GHC that Ord defaults to ()? |
| 12:29:58 | <kjdf> | fasta: yes |
| 12:30:09 | <quicksilver> | > () < () |
| 12:30:11 | <lambdabot> | False |
| 12:30:23 | <HairyDude> | > () <= () |
| 12:30:24 | <lambdabot> | True |
| 12:30:32 | <fasta> | kjdf: I am interested in a program that given a program written in Haskell transforms that to an abstract syntax tree consisting of boolean nodes(NOT, AND, OR). |
| 12:30:51 | <wli> | A biendomorphism is a function f : X x X -> X |
| 12:30:54 | <Nopik> | heh.. it seems that gd have load image, save image, set pixel, but no get pixel function ;p |
| 12:30:54 | <fasta> | kjdf: it should of course be easy to extend to other programming languages. |
| 12:31:18 | <quicksilver> | wli: I'm not sure that your observation is all that interesting |
| 12:31:18 | <HairyDude> | it seems useless and counterintuitive |
| 12:31:34 | <quicksilver> | wli: isn't monoid multiplication always a bi-endomorphism |
| 12:31:41 | <HairyDude> | this is ghc 6.7 btw |
| 12:31:43 | <roconnor> | @check (<=) |
| 12:31:45 | <lambdabot> | Add a type signature |
| 12:31:51 | <mauke> | HairyDude: what do you mean? |
| 12:31:53 | <roconnor> | @check (<=)::(() -> () -> Bool) |
| 12:31:54 | <lambdabot> | OK, passed 500 tests. |
| 12:31:59 | <fasta> | kjdf: does that keep you busy for the next month? |
| 12:31:59 | <roconnor> | @scheck (<=)::(() -> () -> Bool) |
| 12:32:01 | <lambdabot> | Completed 1 test(s) without failure. |
| 12:32:13 | <wli> | quicksilver: The thought was to be able to somehow parametrize over the biendomorphism. |
| 12:32:32 | <kjdf> | I don't think so. It's not my league yet :) |
| 12:32:33 | <fasta> | Is there also a triendomorphism? |
| 12:32:51 | <wli> | fasta: n-endomorphisms even, of course. |
| 12:33:06 | <scsibug> | Nopik: it should be fairly straightforward to add getPixel to GD (I added setPixel awhile back when the wrapper didn't even have that..) |
| 12:33:07 | <fasta> | Those words are great with Scrabble! |
| 12:33:31 | <quicksilver> | wli: I just don't really think the jargon adds much |
| 12:33:34 | <fasta> | morph -> morphism -> endomorphism -> nendomorphism |
| 12:33:40 | <quicksilver> | wli: normally we call these binary operations |
| 12:33:51 | <quicksilver> | wli: and all you've done is re-stated what Monoid is |
| 12:34:02 | <hpaste> | HairyDude pasted "Ord defaults to () in ghc 6.7" at http://hpaste.org/1711 |
| 12:34:03 | <quicksilver> | (Monoid is a class with an identity and a binary operation, such that...) |
| 12:34:15 | <mauke> | @seen augustss |
| 12:34:15 | <lambdabot> | I saw augustss leaving #haskell 2d 1h 45m 17s ago, and . |
| 12:34:32 | <wli> | quikcksilver: The thought was to cast it in a more general context. |
| 12:34:51 | <HairyDude> | oddly 'insert' is fully polymorphic but 'isort' isn't |
| 12:35:01 | <wli> | quicksilver: So the restatement is deliberate. |
| 12:36:15 | <oerjan> | HairyDude: perhaps () is just the first default for anything it fits |
| 12:36:30 | <oerjan> | it _does_ seem intuitive for that |
| 12:37:30 | <HairyDude> | well I believe it goes against the Report, since that says defaulting only happens for numeric types |
| 12:37:39 | <oerjan> | > let isort = foldr insert [] in isort |
| 12:37:41 | <lambdabot> | <[Integer] -> [Integer]> |
| 12:37:54 | <HairyDude> | yes, in ghc 6 it default to Integer |
| 12:37:55 | <kilimanjaro> | A Java programmer and a Haskell programmer are handed the same project. The Java programmer spends 5 days working on the project, and is at least successful in getting it handed off to somebody else. The Haskell programmer finishes up a prototype in 30 minutes, argues with his boss over a bit of vocabulary, and then listens to Mozart while surfing IRC |
| 12:38:06 | <oerjan> | HairyDude: ghc has an "extended defaulting" mechanism? |
| 12:38:27 | <HairyDude> | I'd only expect that to be turned on with -fglasgow-exts |
| 12:38:35 | <wli> | kilimanjaro: You don't even want to think about what the C programmer goes through. |
| 12:38:35 | <HairyDude> | or some other switch |
| 12:38:43 | <mauke> | maybe it's a bug |
| 12:38:48 | <oerjan> | HairyDude: report a bug then |
| 12:40:56 | <ddarius> | magma |
| 12:41:42 | <HairyDude> | ah, it seems the defaulting is turned on in GHCi for convenience... but I would expect it to default to something numeric instead of () |
| 12:42:16 | <ddarius> | Anyone do Claus' Mux exercise from the list? |
| 12:44:23 | <|Steve|> | kilimanjaro: Funny. I've been a TA for classes that taught Java for the first time and I've been a TA for classes that taught Haskell and now Scheme for the first time. By the end of the quarter, the Java students could write little programs. By the end of the quarter, the functional programming students could do small math calculations and _maybe_, just maybe map a function over a list. |
| 12:44:49 | <|Steve|> | Well, I'm not at the end of the Scheme quarter yet, so I'll let you know in 3 weeks. |
| 12:44:58 | <quicksilver> | that sounds a bit odd? |
| 12:45:04 | <integral> | Are the classes teaching as fast as possible? |
| 12:45:09 | <quicksilver> | surely you can do small math calculations at the end of your first 10 minutes? |
| 12:45:14 | <quicksilver> | how does that take a quarter? |
| 12:45:14 | <scook0> | hmm, if I have [a->b] and [a], and I want a list of all the possible results, |
| 12:45:20 | <scook0> | that's just "ap" in [], right? |
| 12:45:21 | <quicksilver> | > 1 + 2 * 5 |
| 12:45:24 | <quicksilver> | scook0: right |
| 12:45:29 | <|Steve|> | quicksilver: Yeah, but there isn't a whole lot of progression after that. |
| 12:45:29 | <lambdabot> | 11 |
| 12:45:30 | <integral> | sturgeon's law applies to students I guess |
| 12:45:55 | <kilimanjaro> | |Steve|, so they are no longer a risk to the health of themselves and others around them. Really I'd say that's a success |
| 12:46:28 | <|Steve|> | Writing a tail-recursive version of log-time exponentiation was more than many of them could handle. It's less than 10 lines of scheme. |
| 12:46:45 | <kilimanjaro> | You go from sticking forks into outlets all the way to sitting down, dressed, typing math calculations. That's like a complete transformation |
| 12:47:42 | <|Steve|> | And this scheme class is supposedly upper division. The java class was the slow java class for freshman who've never programmed anything before. |
| 12:47:57 | <Saizan> | is haskell the first programming course? or they have to unlearn all that OO and imperativeness? |
| 12:48:18 | <Nopik> | scsibug: yeah, i was looking at the source code and indeed it is mostly a wrapper to foreign call |
| 12:48:19 | <|Steve|> | Haskell was actually a bit of an experiment (a failed one, I might add) to combine haskell and discrete math. |
| 12:48:23 | <matt__r> | steve: I have to say my experience is the opposite |
| 12:48:30 | <Nopik> | scsibug: do you happen to have any small program using gd in haskell? |
| 12:48:41 | <quicksilver> | certainly |Steve|'s experience doesn't conform with my knowledge of the Imperial first term Miranda course |
| 12:48:46 | <|Steve|> | I was hoping to hear about matt's experience... |
| 12:48:47 | <earthy> | nopik: doesn't the gd lib binding have examples? |
| 12:48:55 | <Nopik> | earthy: unfortunately, not ;( |
| 12:49:01 | <kilimanjaro> | |Steve|, haha yea, that sounds like something a professor would find cool. Take two classes that, on their own, most students would have trouble with, and blend them into one orgy of confusion |
| 12:49:02 | <quicksilver> | admittedly I didn't teach or take that course, but I spoke to people who did |
| 12:49:18 | <earthy> | hm. |
| 12:49:30 | <earthy> | the exif lib also suffers that fate. |
| 12:49:31 | <scsibug> | there should be a few example programs included with GD, if that is what you mean |
| 12:49:46 | <quicksilver> | kilimanjaro: I could see an argument for teaching haskell in your first term, then discrete math in your second. And using haskell for the discrete maths labs. |
| 12:49:56 | <scsibug> | nopik: http://scsibug.com/2007/04/21/mandelbrot-hs/ |
| 12:49:57 | <lambdabot> | Title: scsibug.com » Fractal-hs |
| 12:50:02 | <kilimanjaro> | What's a math lab? |
| 12:50:10 | <quicksilver> | kilimanjaro: if you did that right then (a) the haskell would make the abstract stuff in discrete math seem more concrete |
| 12:50:22 | <quicksilver> | and (b) it would be an example of 'stuff you can do' with haskell |
| 12:50:27 | <quicksilver> | which might stop them forgetting it all :) |
| 12:50:32 | <scsibug> | http://www.scsibug.com/haskell-gd/examples/ |
| 12:50:33 | <lambdabot> | Title: Index of /haskell-gd/examples |
| 12:50:35 | <quicksilver> | kilimanjaro: exercise classes or whatever secondary tuition there is |
| 12:50:42 | <quicksilver> | kilimanjaro: to back up the lectures |
| 12:50:46 | <Philippa_> | kilimanjaro: and no doubt in half the time... |
| 12:50:56 | <|Steve|> | I can't see any argument for using haskell to teach math. |
| 12:51:03 | <kilimanjaro> | I personally think Scheme is a better first language than Haskell, there are less things to think about |
| 12:51:06 | <earthy> | quicksilver: you mean much like http://homepages.cwi.nl/~jve/HR/ |
| 12:51:08 | <lambdabot> | Title: The Haskell Road |
| 12:51:13 | <mauke> | I can |
| 12:51:34 | <|Steve|> | I could see teaching people to program in a functional language for their first language. I'd like to give that a shot like Berkeley or MIT do. |
| 12:51:39 | <kilimanjaro> | Like half of an intro to programming class is getting students to understand syntax |
| 12:51:47 | <|Steve|> | Right. |
| 12:51:48 | <quicksilver> | earthy: probably, yes |
| 12:51:53 | <quicksilver> | earthy: along those lines, at least |
| 12:51:57 | <ddarius> | kilimanjaro: I agree but not for that reason. |
| 12:52:16 | <kilimanjaro> | ddarius, for what reason then? |
| 12:52:25 | <quicksilver> | I think haskell is a better language than scheme for a first language, because I think type inference is very valuable pedagogically |
| 12:52:26 | <matt__r> | steve: http://journals.cambridge.org/action/displayAbstract;jsessionid=D9E3845B38ED3F5E88511B049D7314E3.tomcat1?fromPage=online&aid=192401 |
| 12:52:29 | <lambdabot> | Title: CJO - Abstract - The risks and benefits of teaching purely functional programmin ..., http://tinyurl.com/33fnmo |
| 12:52:47 | <ddarius> | It has much more and better introductory material. Learning to deal with unbounded side-effects is also important. |
| 12:52:48 | <quicksilver> | having a good instinct for typing is really important in becoming a good programmer |
| 12:52:59 | <mauke> | one of our assignments was about deciding whether various symbolic statements were true or not |
| 12:53:00 | <earthy> | uhuh |
| 12:53:00 | <kilimanjaro> | If it's your first time programming, type inference is 100% magic and it will probably cause you strife |
| 12:53:08 | <mauke> | like ø \elem N |
| 12:53:19 | <mauke> | about 80% of them were "type errors" :-) |
| 12:53:42 | <quicksilver> | anyhow, speculating about teaching styles is terribly easy. Actually designing a good course and giving it is not ;( |
| 12:53:46 | <Philippa_> | type inference is magic anyway unless you've already met unification |
| 12:54:15 | <ddarius> | So teach Prolog as an introduction to Haskell. |
| 12:54:15 | <quicksilver> | to be clear, what i mean really is that strong typing is valuable pedagogically |
| 12:54:23 | <HairyDude> | http://hackage.haskell.org/trac/ghc/ticket/1539 |
| 12:54:24 | <MyCatSchemes> | Philippa_: whut? How so? |
| 12:54:25 | <lambdabot> | Title: #1539 (Ord should not default to ()) - GHC - Trac |
| 12:54:25 | <|Steve|> | matt__r: Looks interesting, but I'm not paying $20 for it. |
| 12:54:29 | <quicksilver> | but type inference is a very helpful tool for coping with strong typing |
| 12:54:47 | <|Steve|> | But you can write the Z combinator in scheme! |
| 12:54:51 | <matt__r> | steve: there should be copies all over the joint and most unis will have access to the journal |
| 12:54:55 | <Philippa_> | MyCatSchemes: because unless you've already met at least an instance of unification, you're being handed something you've no idea how it works. You don't know how to follow the inference process |
| 12:54:59 | <ddarius> | Z, not Y. |
| 12:55:07 | <|Steve|> | matt__r: Okay, I'll grab it in my office tomorrow. |
| 12:55:15 | <matt__r> | I think it is about the only work on teaching functional programming to anyone, let alone first years |
| 12:55:17 | <quicksilver> | |Steve|: there's a preprint at http://www.cse.unsw.edu.au/~chak/papers/CK02a.html |
| 12:55:17 | <lambdabot> | Title: Research Papers of Manuel Chakravarty |
| 12:55:30 | <kilimanjaro> | The ones who want to learn will learn, the ones who don't care will end up writing Java code anyways |
| 12:55:35 | <matt__r> | dons: I don't suppose you were ever one of those first years were you? |
| 12:55:36 | <MyCatSchemes> | Philippa_: the basic idea would seem simple enough even without knowing Prolog. Students can quite happily imagine the compiler walking the parse tree of a piece of code and assigning tags to everything unlabelled. |
| 12:55:48 | <Philippa_> | MyCatSchemes: I didn't mention Prolog |
| 12:56:03 | <|Steve|> | matt__r: I'd be surprised if it were the only one. I've spoken to other people about this and they said that it's been studied before. |
| 12:56:05 | <Philippa_> | and "walking the parse tree" is definitely not a good concept for someone who's only just started programming |
| 12:56:28 | <MyCatSchemes> | Philippa_: oh, my bad. But still, anyway. Haskell's type inference was my first introduction to unification and I don't think I've ever had any problem with it, is all. |
| 12:56:29 | <matt__r> | |Steve|: yeah - I could be wrong. |
| 12:56:50 | <|Steve|> | quicksilver: Oh, thanks. |
| 12:57:06 | <matt__r> | |Steve|: I have been interested in it though - why did it click so well with me, but is such an uphill struggle with many otherwise wonderful computing students/practitioners? |
| 12:57:19 | <quicksilver> | googling for 'teaching functional programming' shows quite a lot of study og it |
| 12:57:22 | <MyCatSchemes> | Philippa_: true, but it's just chasing pointers recursively. That should be, like, practically instinctive by the time you're halfway through a CS introductory unit. |
| 12:57:31 | <matt__r> | |Steve|: I think the bottom line is the person teaching you :) |
| 12:57:53 | <matt__r> | |Steve|: I was rather lucky in that regard |
| 12:57:58 | <|Steve|> | matt__r: Could be. But I've learned every language I know (except for Java I suppose...) on my own. |
| 12:58:15 | <MyCatSchemes> | matt__r: your theory breaks down when applied to autodictats. ;) |
| 12:58:29 | <Philippa_> | MyCatSchemes: Hahahaha. No. |
| 12:58:37 | <|Steve|> | I was introduced to scheme and haskell during my ugrad PL class, but what I know now, I know from my own study of the language. |
| 12:58:46 | <quicksilver> | |Steve|: that unfortunately disqualifies you as a useful example, I fear :) |
| 12:58:55 | <Philippa_> | I mean yeah, it should in a magic world where everyone clicks with the concepts first time and doesn't need any time to internalise... |
| 12:58:59 | <Syzygy-> | quicksilver: Example of what, exactly? |
| 12:59:08 | <quicksilver> | |Steve|: you're in the "would have learnt it anyway" category |
| 12:59:13 | <matt__r> | MyCatSchemes: then you are your own teacher - or the text writer is your teacher |
| 12:59:19 | <|Steve|> | Oh, I lied. I learned MIPS entirely in school. |
| 12:59:21 | <MyCatSchemes> | Philippa_: ah, I see what you mean there. |
| 12:59:33 | <ddarius> | Perhaps I'm a good teacher for myself... |
| 12:59:34 | <|Steve|> | (But I don't think assembly counts since I don't program in it, ever.) |
| 12:59:40 | <quicksilver> | Syzygy-: example of what programming languages are good or bad as first languages. |
| 12:59:43 | <kilimanjaro> | I figure your education is too important to be left entirely in the hands of others |
| 12:59:44 | <Syzygy-> | Ah. |
| 12:59:44 | <MyCatSchemes> | matt__r: hence the need for damn good text books. (Three, nay, four cheers for Sussman.) |
| 12:59:49 | <Syzygy-> | I started with GWBasic - does that count? |
| 13:00:07 | <MyCatSchemes> | kilimanjaro: that's an interesting way of putting it. :) |
| 13:00:11 | <Syzygy-> | I also started with 11, so I may be an exception as well. |
| 13:00:23 | <Philippa_> | I learned Java in a few hours when it was going to be the first module at UoN |
| 13:00:26 | <ddarius> | Philippa_: Pictures! |
| 13:00:26 | <wli> | I started with C. |
| 13:00:27 | <MyCatSchemes> | Syzygy-: BASIC does teach a few useful things. |
| 13:00:33 | <matt__r> | MyCatSchemes: I am with you on that one |
| 13:00:44 | <ddarius> | MyCatSchemes: Like what spaghetti code looks like. |
| 13:00:53 | <Philippa_> | ddarius: *cough* |
| 13:00:55 | <|Steve|> | Philippa_: Java was my fourth language and after C, C++, and Objective-C, it was pretty easy to pick up. |
| 13:00:56 | <matt__r> | I started with Pascal :) |
| 13:01:01 | <MyCatSchemes> | Syzygy-: like, when you start using C later, it'll let you realise *immediately* how painful memory management by hand is, instead of a few years down the line when you later start trying better programming languages. |
| 13:01:17 | <Philippa_> | yeah, I already knew C and was making my way through C++ |
| 13:01:33 | <quicksilver> | Syzygy-: yes, you're an exception too. I imagine most people in the channel are, really |
| 13:01:37 | <kilimanjaro> | The nice thing about BASIC is that you don't have to do things the right way, you just get started and through trial and error you can do fun stuff (that's where I got my start as a kid) |
| 13:01:38 | <MyCatSchemes> | |Steve|: I'm curious as to whether you've ever tried Smalltalk? |
| 13:01:42 | <quicksilver> | Syzygy-: the question was about 'typical' first year undergrads |
| 13:01:44 | <|Steve|> | You know, everyone bitches about memory management in C, but it's really not that hard. And in C++, it's even easier. |
| 13:01:50 | <wli> | I didn't find the language to be particularly interesting. I wrote programs to do parallel Runge-Kutta diffeq solving my first week in college. |
| 13:01:57 | <ddarius> | MyCatSchemes: I started on QBASIC and went to a Cish C++ and eventually C++. |
| 13:01:57 | <|Steve|> | MyCatSchemes: You know, I never have. I know it was a precursor to objective-c. |
| 13:02:13 | <quicksilver> | Syzygy-: I.e. you've done no programming before, you turn up at university. What do they teach you in your firs tterm? |
| 13:02:28 | <MyCatSchemes> | |Steve|: it's not impossible, no, but it's still work that isn't actually neccessary for you to tackle by hand outside of a few well defined domains. |
| 13:02:29 | <quicksilver> | |Steve|: I think that just says something about the kinds of programs you have written in C and C++ |
| 13:02:36 | <Philippa_> | of course, I'm talking about Java back in 2000, and minimal library knowledge (I kept bashing out singly-linked list classes in exams too, although at least one was for a module where we were using Java only because not enough people knew C) |
| 13:02:52 | <quicksilver> | |Steve|: memory management is a real pain for a large class of problems. |
| 13:02:54 | <Syzygy-> | quicksilver: Have you ever seen a typical first year undergrad? |
| 13:02:56 | <Syzygy-> | o.O |
| 13:03:01 | <quicksilver> | Syzygy-: yes, a very large number of them. |
| 13:03:08 | <Philippa_> | Smalltalk is well worth some exposure to |
| 13:03:08 | <quicksilver> | Syzygy-: I've both been one, and taught some :) |
| 13:03:14 | <MyCatSchemes> | ddarius: spaghetti code... if you want to see spaghetti code, you need to start looking at peoples' PIC programs. ;) |
| 13:03:16 | <Syzygy-> | Oh dear. ;) |
| 13:03:16 | <quicksilver> | Syzygy-: I even married one... |
| 13:03:34 | <|Steve|> | quicksilver: I've worked as a programmer on an arcade game in C++. |
| 13:03:36 | <ddarius> | quicksilver: A "typical" one? |
| 13:03:39 | <quicksilver> | |Steve|: *ALL* commercially deployed C and C++ programs contain memory leaks. |
| 13:03:40 | <MyCatSchemes> | Then I guess you've probably seen more of them that most. ;_ |
| 13:03:47 | <|Steve|> | It's not like I've been confined to small programs. |
| 13:03:48 | <MyCatSchemes> | ;) |
| 13:03:49 | <quicksilver> | |Steve|: now tell me memory management is easy :) |
| 13:04:07 | <quicksilver> | ddarius: no, I suppose she wasn't very typical ;) |
| 13:04:23 | <|Steve|> | You have memory leaks in Java too. I suspect you get them in Haskell as well. |
| 13:04:28 | <quicksilver> | of course |
| 13:04:37 | <ddarius> | Even computers find it hard. |
| 13:04:38 | <MyCatSchemes> | |Steve|: except that we call 'em "space leaks" instead. ;) |
| 13:04:38 | <quicksilver> | for different kinds of reasons, though :) |
| 13:04:45 | <Nopik> | scsibug: thanks |
| 13:04:47 | <matt__r> | |Steve|: damn right you can (in Haskell and they are probably more insidious that in C++ |
| 13:04:59 | <|Steve|> | Fine, relabel it all you want. |
| 13:05:10 | <matt__r> | perhaps I can ask the wisdom of the list |
| 13:05:12 | <MyCatSchemes> | And yes, but references that're being held on to unneccessarily can be tracked down more easily than memory that's not referred to but still left un-freed. |
| 13:05:14 | <wli> | quicksilver: They also contain buffer overflow exploits, NULL and wild pointer dereferences, and more. |
| 13:05:22 | <|Steve|> | When my c++ program is leaking, I run leaks on it and track'em down. |
| 13:05:26 | <ddarius> | Actually in the nexus of a Haskell program space itself starts growing. |
| 13:05:34 | <Philippa_> | you can get memory leaks in any GCed language if you're careless about references. Haskell has a further bunch of problems due to laziness though - it's not as well understood how to handle that |
| 13:05:59 | <matt__r> | are haskellers ignoring the "space leak" elephant in the room when we evangelise our language. |
| 13:05:59 | <matt__r> | ? |
| 13:06:06 | <|Steve|> | I don't think it matters, you're not really getting the word out about haskell. |
| 13:06:14 | <wli> | You have to program in something without dynamic memory allocation for the space problem to be solvable. |
| 13:06:21 | <|Steve|> | Every time I say I've written something in haskell, or I like haskell, people think I'm saying pascal. |
| 13:06:37 | <kilimanjaro> | Haha |
| 13:06:41 | <Philippa_> | if haskell suddenly gained perl-level "success" we'd rapidly lose what makes the community (and to a large extent the language) worthwhile under a flood of crap libs though |
| 13:06:48 | <ddarius> | matt__r: Programming in a lazy language is more different than programming in an eager language than most people are aware of. |
| 13:06:50 | <wli> | Fortran comes to mind. |
| 13:07:02 | <|Steve|> | Philippa_: That's an...interesting POV. |
| 13:07:09 | <quicksilver> | wli: yeah, they're probably more important |
| 13:07:19 | <MyCatSchemes> | matt__r: no, 'cuz a) the Java crowd have it too and b) space leaks are rather less nasty to track down. |
| 13:07:23 | <matt__r> | ddarius: agreed |
| 13:07:25 | <Philippa_> | |Steve|: it's not commonly stated as directly, but there's a reason "avoid success at all costs" became a catchphrase |
| 13:07:30 | <|Steve|> | I kind of liked programming in ocaml. I only did a tiny bit for my grad pl class. |
| 13:07:41 | <Philippa_> | haskell is what it is partly because we're all picky |
| 13:07:43 | <|Steve|> | Funny, I've never heard that catchphrase... |
| 13:07:51 | <MyCatSchemes> | It's a good one, though. |
| 13:07:53 | <|Steve|> | And I can't wait for Haskell'. |
| 13:07:54 | <kilimanjaro> | |Steve|, sure, just don't tell anyone in #haskell that you like... ohh wait |
| 13:07:59 | <Philippa_> | sure. How long have you been around here? |
| 13:08:03 | <matt__r> | MyCatSchemes: how does the java version manifest itself? |
| 13:08:17 | <|Steve|> | Philippa_: Me? |
| 13:08:20 | <ddarius> | @google "Haskell retrospective" |
| 13:08:22 | <wli> | I'm not remotely interested in language evangelism. Haskell is merely useful to me. |
| 13:08:22 | <lambdabot> | http://research.microsoft.com/~simonpj/papers/haskell-retrospective/index.htm |
| 13:08:22 | <lambdabot> | Title: Wearing the hair shirt: a retrospective on Haskell |
| 13:08:22 | <Philippa_> | (it comes from a retrospective written by Simon Peyton-Jones, btw) |
| 13:08:33 | <ddarius> | |Steve|: Read that, it's entertaining. |
| 13:08:39 | <MyCatSchemes> | matt__r: exactly the same way. Data structures containing references to other data structures and people forgetting to clean up references to them. |
| 13:08:43 | <|Steve|> | ddarius: Will do. |
| 13:09:16 | <MyCatSchemes> | matt__r: apparently a common one is hash tables used for memoization whose references are kept in scope for the whole length of the program when they're only actually used for part of it. |
| 13:09:26 | <|Steve|> | Alas, it's 6 am and I need some sleep. This is by far the best programming language channel I've even been in, so I can't argue with the community aspect. |
| 13:09:40 | <Philippa_> | |Steve|: there isn't a perl-sized user base currently that's picky enough about correctness, good factoring and type-safety. So if we suddenly gained that many users, the haskell community would undergo a radical shift in values |
| 13:10:01 | <matt__r> | MyCatSchemes: aha |
| 13:10:05 | <|Steve|> | I like perl. It's fun. |
| 13:10:11 | <MyCatSchemes> | |Steve|: I concur. Only channels I've tried that hold a candle to this are #scheme and, uh, possibly #nethack. |
| 13:10:31 | <|Steve|> | I haven't tried #scheme. ##c and ##c++ were terrible for the week I spent in them. |
| 13:10:40 | <quicksilver> | Philippa_: which makes me worry, sometimes, about how easy it is to write type-unsafe and/or semantic destroying GHC libraries |
| 13:10:41 | <MyCatSchemes> | |Steve|: though the latter will occasionally merrily tell me to eat Medusa's corpse in order to point and laugh at my YASD message. |
| 13:10:41 | <ddarius> | I've never been to #scheme, thought about it now and again. |
| 13:10:48 | <quicksilver> | Philippa_: using unsafeFOO or RULES |
| 13:11:02 | <quicksilver> | MyCatSchemes: that's part of the charm, though |
| 13:11:05 | <MyCatSchemes> | ddarius: I just tried it once offhand to see what it was like. I got the impression it was pretty similar to here. |
| 13:11:12 | <Philippa_> | quicksilver: yup, and that you won't get /any/ warning that they're being used. A warning flag for 'em would be nice |
| 13:11:36 | <ddarius> | Philippa_: We could easily make "safe" modules and such. |
| 13:11:40 | <MyCatSchemes> | quicksilver: oh yes, of the game, too. It wouldn't be NetHack if my characters ever survived for more than five consecutive minutes. |
| 13:12:47 | <MyCatSchemes> | matt__r: but of course, the thing about space leaks is... those unneccessary references are still hanging around. You can run a debugger over and manually audit all the references in your program, if neccessary. ;) |
| 13:13:13 | <quicksilver> | we may trust dons and dcoutts to write such dangerous code (do we?) but can we trust Random.Hackage.uploader? |
| 13:13:53 | <|Steve|> | Wait, there's a Haskell debugger? |
| 13:13:56 | <ddarius> | quicksilver: No we don't (re dons and dcoutts). We bash their libraries and see what bugs pop out. |
| 13:14:01 | <matt__r> | quicksilver: you always have to trust your lib writer |
| 13:14:10 | <fasta> | |Steve|: there is a broken debugger in 6.7 |
| 13:14:11 | <Philippa_> | matt__r: no, no you don't |
| 13:14:12 | <ddarius> | |Steve|: For several values of "debugger", there're many. |
| 13:14:21 | <wli> | page 54, type classes as logic programs |
| 13:14:27 | <fasta> | ddarius: many? Name 2 |
| 13:14:44 | <quicksilver> | matt__r: in an ideal world you wouldn't, no |
| 13:14:45 | <|Steve|> | And you can't even add print statements. I've never figured out how to debug a haskell program. |
| 13:14:45 | <ddarius> | Buddha, Freya, Hat, HOOD, the GHCi debugger |
| 13:14:57 | <|Steve|> | basically, I just assume that if I can sneak it past the type system, I'm right. |
| 13:14:57 | <matt__r> | Philippa_: so what are the practical techniques for using safe but untrustworty code |
| 13:14:57 | <quicksilver> | |Steve|: by using the REPL |
| 13:15:11 | <quicksilver> | |Steve|: and trying out your component functions one by one |
| 13:15:12 | <|Steve|> | REPL = read eval print loop? |
| 13:15:15 | <matt__r> | ddaruis: is hat working on the latest GHC? |
| 13:15:16 | <quicksilver> | |Steve|: understading hte errors |
| 13:15:17 | <quicksilver> | yeah |
| 13:15:20 | <fasta> | ddarius: ok, two that work for Haskell + all common libraries |
| 13:15:20 | <Philippa_> | matt__r: sufficiently strong typing, sandboxing |
| 13:15:30 | <quicksilver> | I don't find "imperative-style" debuggers a good match fo haskell debugging problems |
| 13:15:35 | <|Steve|> | One cannot always write such modules. |
| 13:15:37 | <ddarius> | matt__r: I don't think Hat ever worked for GHC. It was an NHC thing. |
| 13:15:38 | <quicksilver> | I much rather derive Show instances for my data types |
| 13:15:44 | <quicksilver> | Hat does work for GHC |
| 13:15:52 | <matt__r> | Philippa_: yeah - but you need to bypass the safe typing for just about any working program |
| 13:15:53 | <quicksilver> | malcolmw demonstrated it recently to me |
| 13:15:53 | <fasta> | ddarius: Hat did work at some point |
| 13:15:58 | <quicksilver> | I've not used that |
| 13:16:08 | <Philippa_> | matt__r: no, no you don't |
| 13:16:08 | <wli> | Nice, talking about ML functors vs. Haskell modules, too. |
| 13:16:09 | <malcolmw> | there's an SoC project to rehabilitate Hat with modern ghc + libraries + etc |
| 13:16:11 | <ddarius> | fasta: I was out of the community for a good while. |
| 13:16:11 | <quicksilver> | matt__r: I've written many haskell programs and not once bypassed any of the safety |
| 13:16:12 | <matt__r> | Philippa_: unless you rewrite all hte c librarries we rely on |
| 13:16:15 | <fasta> | ddarius: severly limited to H98, though. |
| 13:16:26 | <wli> | Philippa: This retrospective is awesome. It talks about a bunch of things I think about all the time. |
| 13:16:40 | <quicksilver> | matt__r: well that last is a fair point |
| 13:16:43 | <Philippa_> | that depends how you define "trust". You can ensure that the C libraries are the source of any untrustworthiness, for example |
| 13:16:48 | <quicksilver> | matt__r: but as long as the C libraries don't actually segfault |
| 13:16:51 | <|Steve|> | Okay, I said I was going to sleep and this time I mean it. Goodnight. (I'll read those papers/links when I wake up.) |
| 13:16:55 | <quicksilver> | matt__r: they don't upset the semantics of the haskell code |
| 13:16:57 | <malcolmw> | fasta: Hat is not limited to haskell'98 |
| 13:17:08 | <quicksilver> | (unless someone made a pure binding for a function which isn't really pure) |
| 13:17:09 | <Philippa_> | quicksilver: strictly speaking, even if they do so long as they're in the IO monad |
| 13:17:16 | <matt__r> | just think how to write a safe HDBC, or readline or networking, etc |
| 13:17:17 | <fasta> | malcolmw: or it didn't include all libraries? |
| 13:17:17 | <quicksilver> | but that's the binding author's fault not the libraries |
| 13:17:27 | <quicksilver> | Philippa_: good point |
| 13:17:35 | <fasta> | malcolmw: or I am confusing two tools |
| 13:17:43 | <malcolmw> | fasta: yup, the hierarchical libraries all arrived after the Hat implementation was finished |
| 13:17:46 | <matt__r> | when you are part of a larger stack and you don't know how the code is working, you have to "trust" the library writer |
| 13:17:53 | <ddarius> | Auf wiedersehen. |
| 13:18:04 | <Philippa_> | matt__r: yes. That's a notably weaker statement than your original one though |
| 13:18:28 | <quicksilver> | matt__r: in a strongly typed system, you can be precise about how much trust that is |
| 13:18:28 | <Philippa_> | "you have to trust the substrate system" just isn't the same as "you have to trust libs in your own language" |
| 13:18:41 | <quicksilver> | certainly you have to trust him to write code which terminates |
| 13:18:49 | <quicksilver> | but often it's not much more than that |
| 13:18:56 | <Philippa_> | actually, that can be eliminated with the right type system too |
| 13:19:01 | <quicksilver> | ACTION nods |
| 13:19:23 | <matt__r> | Philippa_: well yeah - so we need to have unsafeperformIO propagate up from where it is used |
| 13:19:39 | <matt__r> | then we can always know when code calls out to something unsafe |
| 13:19:58 | <Philippa_> | matt__r: funny, that's already been proposed in here today |
| 13:20:26 | <matt__r> | Philippa_: I just means losing one or two functions that go IO a -> a right? |
| 13:21:01 | <Philippa_> | it just means knowing when they're called. Whether you then trust them's up to you |
| 13:21:25 | <Philippa_> | I can certainly build useful systems that don't need unsafePerformIO, YMMV |
| 13:22:42 | <tanuk> | Hello, I'm having problems. Stdin seems to be buffered even though I set it to NoBuffering in the start of the program. |
| 13:22:43 | <matt__r> | Philippa_: I am with you on that, but I find myself constantly using code (libs) that does use unsafePerformIO |
| 13:23:13 | <matt__r> | tanuk: hpaste your code |
| 13:23:39 | <Philippa_> | sure. There're some classic uses that can be avoided with a more powerful language though... |
| 13:24:00 | <wli> | Philippa: Which uses and what sort of power? |
| 13:24:16 | <hpaste> | (anonymous) pasted "(no title)" at http://hpaste.org/1712 |
| 13:24:37 | <tanuk> | Uh, I should have given my nick to that... |
| 13:24:39 | <Philippa_> | wli: faking global mutable variables is one that comes to mind - a more powerful module system can handle it |
| 13:25:04 | <hkBst> | does the Haskell code in http://blogs.nubgames.com/code/?p=15 get displayed correctly for anyone? Both in konqueror and firefox it is too wide for the box it is in and not displayed fully. |
| 13:25:06 | <lambdabot> | Title: Nub Games » Haskell — First Impressions |
| 13:25:23 | <Philippa_> | a number of other uses involve mutability too, and could be dealt with via linear types. Yet more could be dealt with if we took a different approach to monadic programming... |
| 13:25:26 | <tanuk> | The program removes parts from the input that comes in stdin and prints it to stdout. |
| 13:26:14 | <nopcode> | how do remove duplicate elements from a list? |
| 13:26:17 | <fasta> | hkBst: drop the italics |
| 13:26:29 | <opqdonut> | nopcode: nub |
| 13:26:52 | <hkBst> | fasta: how can I do that? |
| 13:26:56 | <nopcode> | is that an insult or the name of a function? ;P |
| 13:27:07 | <fasta> | hkBst: is it your webpage? |
| 13:27:09 | <opqdonut> | > nub . take 1000 $ cycle [1,2,3] |
| 13:27:09 | <tanuk> | Every line is examined and if it fulfills the requirement (contains "System exclusive") a part of it is printed. Otherwise it is ignored. |
| 13:27:11 | <lambdabot> | [1,2,3] |
| 13:27:12 | <hkBst> | fasta: no |
| 13:27:26 | <opqdonut> | nopcode: name of the function as you can see :) |
| 13:27:31 | <fasta> | hkBst: oh, it is displayed here fully |
| 13:27:43 | <fasta> | hkBst: the italics are very ugly however(Firefox) |
| 13:27:46 | <Lemmih> | hkBst: It looks fine to me. |
| 13:27:48 | <fasta> | hkBst: Iceweasel* |
| 13:27:57 | <matt__r> | tanuk: sorry - it must be too late for me, I can't get my head around it well enough to give you useful advice. |
| 13:28:12 | <nopcode> | opqdonut: ok thx *G* |
| 13:28:33 | <hkBst> | fasta: histories = takeWhile ((> 0) . length) . unfoldr history . li <rest cutoff> |
| 13:28:41 | <tanuk> | matt__r: Thanks for trying anyway. |
| 13:28:48 | <hkBst> | Lemmih: what browser? |
| 13:28:51 | <tuukkah> | tanuk, did you try with a simple cat? |
| 13:28:55 | <Lemmih> | hkBst: Firefox. |
| 13:29:04 | <fasta> | hkBst: I see lines are last word |
| 13:29:05 | <matt__r> | tanuk: hFlush might helo :0 |
| 13:29:08 | <matt__r> | :) |
| 13:29:11 | <fasta> | hkBst: as* |
| 13:29:41 | <tanuk> | matt__r: I tried to insert hFlush after every putStrLn, but it didn't help. |
| 13:30:12 | <tanuk> | tuukkah: What do you mean. |
| 13:30:14 | <tanuk> | ? |
| 13:30:18 | <hkBst> | fasta: it only gets worse as I increase font size and I seem to be at the minimum :( |
| 13:30:47 | <quicksilver> | tanuk: what OK, and which makes you think the turning off the buffering isn't working? |
| 13:30:49 | <fasta> | hkBst: use no page style or complain to author |
| 13:30:51 | <tuukkah> | tanuk, you can try to make the program as simple as possible and see whether it still has the problem |
| 13:31:08 | <quicksilver> | tanuk: don't you want to turn buffering off on stdout |
| 13:31:14 | <hkBst> | fasta: I would if I could find his email... |
| 13:32:07 | <tanuk> | quicksilver: Yes I want... Thanks for pointing out. |
| 13:32:08 | <tuukkah> | tanuk, besides, please don't make Ctrl-C not exit the program :-) |
| 13:32:15 | <fasta> | hkBst: leave a comment in his commenting system |
| 13:32:43 | <tuukkah> | Ctrl-D doesn't work either but that's a problem in ghc i suppose |
| 13:33:25 | <tanuk> | tuukkah: It still exits, without the handler the buffered part would be discarded, this way at least on exit everything gets written. |
| 13:34:03 | <tuukkah> | doesn't exit here using runghc version 6.6 |
| 13:35:48 | <Lemmih> | tanuk: It seems to do exactly what it's supposed to. |
| 13:36:29 | <Lemmih> | Entering " System exclusive This is a test" gives "This is a test". |
| 13:37:05 | <bringert> | dcoutts: you here? |
| 13:38:02 | <liber> | what exactly do I get if I use "return True" in an application? It isnt a Bool, at least |
| 13:38:09 | <liber> | I get a type error |
| 13:38:25 | <tuukkah> | @ type return True |
| 13:38:27 | <tanuk> | Lemmih: Yeah, it seems to print it fine when getting input from keyboard... |
| 13:38:29 | <tuukkah> | @type return True |
| 13:38:38 | <lambdabot> | forall (m :: * -> *). (Monad m) => m Bool |
| 13:38:39 | <liber> | return True :: (Monad m) => m Bool |
| 13:39:02 | <liber> | Is there a way to typeset that? |
| 13:39:20 | <tuukkah> | you get a Bool in a monad |
| 13:39:38 | <liber> | And I have not gotten to the chapter about Monads yet :) |
| 13:39:47 | <mauke> | liber: then why are you using return? |
| 13:40:04 | <Igloo> | tanuk: What's the problem? |
| 13:40:05 | <quicksilver> | liber: think of it just as a 'structure' |
| 13:40:10 | <quicksilver> | liber: in quite an abstract sense |
| 13:40:19 | <quicksilver> | liber: "return True" returns true embedded in some kind of structure |
| 13:40:20 | <Lemmih> | tanuk: Piping the text with 'echo' gives exactly the same response. |
| 13:40:39 | <EvilTerran> | > (return :: a -> Maybe a) True |
| 13:40:40 | <lambdabot> | Just True |
| 13:40:46 | <EvilTerran> | > (return :: a -> [a]) True |
| 13:40:47 | <lambdabot> | [True] |
| 13:40:59 | <Lemmih> | tanuk: Same with piping it from a file. |
| 13:41:13 | <liber> | mauke: because I want to return a bool from a function |
| 13:41:18 | <tanuk> | Lemmih: The program that the data runs continuously, so EOF doesn't come before ctrl-c. |
| 13:41:21 | <mauke> | liber: that has nothing to do with 'return' |
| 13:41:24 | <opqdonut> | ?src (\\) |
| 13:41:25 | <lambdabot> | (\\) = foldl (flip delete) |
| 13:41:37 | <tanuk> | "the data runs" -> "the data comes from runs" |
| 13:41:40 | <EvilTerran> | liber, ah. you've got completely the wrong end of the stick, i'm afraid. |
| 13:41:41 | <mauke> | liber: think of return x as new Monad(x) |
| 13:41:51 | <liber> | alright |
| 13:41:53 | <vincenz> | mauke++ for proper color usage |
| 13:41:56 | <mauke> | i.e. a constructor call |
| 13:42:02 | <scook0> | liber: to return a value, just write the value ... 'return' is used for something different in Haskell |
| 13:42:14 | <liber> | I havent gotten to that part of the tutorial yet. Just experimenting a bit on my own : |
| 13:42:15 | <liber> | ) |
| 13:42:25 | <quicksilver> | liber: just thiis, is all it takes: |
| 13:42:25 | <dozer> | how do I do this: data Baz (bar foo) foo = ... |
| 13:42:28 | <quicksilver> | my_fun = True |
| 13:42:36 | <quicksilver> | liber: no special keyword for return, in that sense |
| 13:42:47 | <SamB_XP> | dozer: you can't do *that* |
| 13:42:48 | <dozer> | I want Baz parameterised over two types, but the first type must be itself parameterised over the seccond type |
| 13:42:49 | <EvilTerran> | liber, think of the body of a function as an expression, rather than a code block |
| 13:43:03 | <dozer> | SamB_XP: can I get close? |
| 13:43:08 | <liber> | quicksilver: but if I have alot more things, like in a "do"-"block" |
| 13:43:13 | <ski> | dozer : maybe 'data Baz bar foo = ...' is what you want ? |
| 13:43:21 | <SamB_XP> | you could do data Baz bar foo = ... |
| 13:43:22 | <liber> | Do i stull just end the "block" with "True" |
| 13:43:24 | <liber> | ? |
| 13:43:32 | <SamB_XP> | and, in ..., write (bar foo) |
| 13:43:33 | <tuukkah> | or "data (Baz (Bar foo)) = ..." |
| 13:43:41 | <EvilTerran> | "foo x = <expression involving x>" means "whenever you see 'foo <something>', replace that with <expression involving x> except with <something> in place of x" |
| 13:43:44 | <edwardk> | hrmm. so if i have * as multiplication, .* as left scalar multiplication, *. as right scalar multiplication with generalized signatures a -> a -> a, a -> b -> b and b -> a -> b, respectively does having .*. with a -> b -> c | a b -> c seem too specific? with the idea being that the . tells you where type inference will break over the general signature. |
| 13:43:46 | <tanuk> | Lemmih: Do you think if it is possible that the input program checks if the output goes to a terminal, and in that case uses less buffering? |
| 13:43:58 | <scook0> | liber: if you aren't up to monads, you probably shouldn't be using do |
| 13:44:01 | <ski> | liber : if you're in a do-block, then if you just want to return a value at the end, you use 'return' |
| 13:44:03 | <quicksilver> | liber: you need to be a bit more precise about 'other things' |
| 13:44:10 | <dozer> | ah, so in each place I currently use bar in the declaration, actually write (bar foo) instead |
| 13:44:12 | <quicksilver> | liber: you don't want to use 'do' unless you're using monads |
| 13:44:18 | <MyCatSchemes> | scook0: hhgh? |
| 13:44:31 | <liber> | quicksilver: aigtt :) Ill just keep reading the tutorial. Thx guys |
| 13:44:31 | <dozer> | like: data Baz bar foo = BZ (bar foo) foo |
| 13:44:37 | <EvilTerran> | liber, what i just said there is a good way of thinking about things, even tho it's not quite a perfect description of how it really works ;] |
| 13:44:42 | <scook0> | MyCatSchemes: unless you're cargo-culting monadic IO or something |
| 13:44:49 | <quicksilver> | liber: and, from what you're saying, you don't waht to use monads :) |
| 13:45:00 | <quicksilver> | SamB_XP: that' won't work |
| 13:45:00 | <liber> | :D |
| 13:45:00 | <MyCatSchemes> | scook0: jah, precisely. ^^ |
| 13:45:08 | <SamB_XP> | edwardk: that does seem a bit more specifc than needed... |
| 13:45:10 | <quicksilver> | SamB_XP: data types can't have higher-kinded fields |
| 13:45:15 | <quicksilver> | SamB_XP: 'bar' is a type constructor |
| 13:45:21 | <quicksilver> | SamB_XP: if I'm following dozer corectly |
| 13:45:27 | <SamB_XP> | quicksilver: what the heck are you talking about? |
| 13:45:34 | <SamB_XP> | @src StateT |
| 13:45:34 | <lambdabot> | Source not found. Sorry about this, I know it's a bit silly. |
| 13:45:37 | <SamB_XP> | arg. |
| 13:45:43 | <quicksilver> | data Bar (bar foo) foo |
| 13:45:48 | <quicksilver> | bar is a type constructor, I presume |
| 13:45:52 | <quicksilver> | erm |
| 13:45:55 | <SamB_XP> | quasisane: so? |
| 13:45:56 | <SamB_XP> | er. |
| 13:45:56 | <dozer> | quicksilver: yes it is |
| 13:45:57 | <quicksilver> | data Baz (bar foo) foo |
| 13:46:00 | <SamB_XP> | quicksilver: so? |
| 13:46:07 | <quicksilver> | well you can't say 'data Baz bar foo' then |
| 13:46:12 | <quicksilver> | because then bar is a type constructor |
| 13:46:15 | <SamB_XP> | yeah you can... |
| 13:46:29 | <quicksilver> | you can't have higher kinded fields... |
| 13:46:41 | <SamB_XP> | haven't you heard of kinds like (* -> *) -> * -> * before? |
| 13:46:51 | <edwardk> | samb: well, the .* for scalar multiplication gives you things like multiplication by the naturals for peasant multiplication over any semigroup. .*. gives a limited form of type inference to the result, and lets you use that same type to witness type level multiplication |
| 13:46:54 | <quicksilver> | oh hang on |
| 13:47:00 | <quicksilver> | on the left of the = not the right of the =? |
| 13:47:18 | <edwardk> | samb: then typeints, could offer up witnesses in the form (.+.) (.*.), etc. |
| 13:47:18 | <quicksilver> | I thought we were on the right of = |
| 13:47:19 | <quicksilver> | sorry :) |
| 13:47:35 | <SamB_XP> | quicksilver: oh ;-) |
| 13:47:44 | <sieni> | ' |
| 13:48:13 | <SamB_XP> | quicksilver: it's very true that you can't have data of types whose kinds have arrows in them ;-) |
| 13:49:11 | <SamB_XP> | edwardk: well, will it hurt anything for you to add it? |
| 13:49:16 | <edwardk> | samb: though in the case of (.+.) i'd really like to make the inference tridirectional a b -> c, a c -> b, b c -> a, but perhaps thats a bit overzealous, or rather maybe thats best used as the type for (+) with most instances setting them to the same |
| 13:50:08 | <edwardk> | (+) : a -> b -> c | a b -> c, b c -> a, a c -> b (.*) : a -> b -> b (*.) : b -> a -> a (.*.) : a -> b -> c | a b -> c |
| 13:50:23 | <edwardk> | er (*) |
| 13:50:48 | <SamB_XP> | edwardk: hmm, I'm a bit curious. do you use a dictionary-passing or a typecase implementation? |
| 13:51:11 | <edwardk> | then we have the case where type inference always works, probably fails on the left, probably fails on the right, and where it probably fails on both arguments. |
| 13:51:33 | <edwardk> | ironically a bit of both, i have the worst case issues of each =) |
| 13:52:03 | <edwardk> | typecase determines which dictionary to pass around in the event the dictionary wasn't explicitly passed |
| 13:52:05 | <SamB_XP> | what, it's as slow as dictionary passing but has the whole-program-compilation of typecases? |
| 13:52:25 | <edwardk> | and i'm already whole program compiling anyways |
| 13:52:25 | <tanuk> | tuukkah: You asked to try with plain cat, I think I now understood that. I replaced my program with cat and that too doesn't print everything immediately. Is there anything that can be done, or is this completely the source program writer's fault? |
| 13:52:44 | <SamB_XP> | do you do existentials? |
| 13:53:00 | <edwardk> | not yet, they are on the 'would-be-cool' feature list |
| 13:53:13 | <SamB_XP> | hmm. I guess my next question is inapplicable then ;-) |
| 13:53:26 | <edwardk> | i had a version back when it was a simple PTS |
| 13:53:31 | <quicksilver> | SamB_XP: sensible dictionary passing manages to optimise out the dictionary in most cases, though |
| 13:53:33 | <edwardk> | but they got dropped when things got more complicated |
| 13:53:41 | <quicksilver> | SamB_XP: so practical dictionary passing isn't that slow, is it? |
| 13:54:03 | <SamB_XP> | quicksilver: you'd be surprised |
| 13:54:30 | <quicksilver> | SamB_XP: what makes it slow, then? |
| 13:54:34 | <SamB_XP> | sure, when you use >>= and >> and return at statically known types |
| 13:54:37 | <SamB_XP> | that's fine |
| 13:55:15 | <SamB_XP> | quicksilver: as far as I know, GHC doesn't know that there is only one dictionary for each type |
| 13:55:25 | <quicksilver> | I believe it does |
| 13:55:29 | <SamB_XP> | (for a given dictionary constructor) |
| 13:55:45 | <edwardk> | ok, i'll go with the 4 signatures above i think and see if i can use them uniformly used across all binary operators in the prelude (modulo the ==, &&, etc) ones that go a -> a -> b, |
| 13:56:11 | <SamB_XP> | I mean, afaik, it doesn't optimize Core based on that assumption |
| 13:56:21 | <fasta> | A 140 line function, what will the fanboys say to that! |
| 13:56:24 | <quicksilver> | well most methods are inlineable |
| 13:56:38 | <quicksilver> | which means the optimiser can remove the case on the dictionary |
| 13:56:39 | <ski> | fasta : fie on you :) |
| 13:56:41 | <edwardk> | and in my case i can have a lot of dictionaries for a given type =/ |
| 13:57:09 | <edwardk> | since you can pass them by name |
| 13:57:11 | <SamB_XP> | quicksilver: if it knows which dictionary to use, sure |
| 13:57:20 | <dozer> | ok - what about if I wanted to instead say something like: data Baz foo bar | foo -> bar = ... |
| 13:57:43 | <quicksilver> | that's what associated types are for, I believe? |
| 13:58:11 | <SamB_XP> | dozer: hmm. |
| 13:58:15 | <fasta> | I find the associated types less natural to read than fundeps |
| 13:58:36 | <quicksilver> | fasta: this isn't a class, thouh |
| 13:58:43 | <quicksilver> | fasta: it's a data declaration |
| 13:58:50 | <SamB_XP> | dozer: data BazClass foo bar => Baz foo bar = ... ? |
| 13:59:36 | <quicksilver> | SamB_XP: I think you may be underestimating the dictionary passing approach, in the presence of a good optimiser |
| 13:59:47 | <SamB_XP> | fasta: associated type synonyms are nice when you truly just want an associated type... |
| 13:59:47 | <quicksilver> | SamB_XP: have a look at the core generated by -O2 |
| 13:59:48 | <fasta> | quicksilver: oh, I wasn't paying attention and I guess I wanted to say that regardless of it ;) |
| 14:00:23 | <SamB_XP> | fasta: especially if you have already written some code using a class before you added one |
| 14:00:57 | <SamB_XP> | quicksilver: have they recently improved it? |
| 14:01:51 | <hpaste> | tuukkah annotated "(no title)" with "Still buffered..." at http://hpaste.org/1712#a1 |
| 14:02:21 | <tuukkah> | tanuk, could be a problem with getLine |
| 14:03:12 | <tuukkah> | tanuk, if i change that paste to use getChar and putChar, it isn't line-buffered anymore |
| 14:03:37 | <MyCatSchemes> | Philippa: eh, I thought the underscore kinda suited you. ;) |
| 14:03:39 | <SamB> | quicksilver: does it now realize that the Fractional a field in a RealFrac a has the same value as the one in a Floating a? |
| 14:04:03 | <shapr> | Good morning #haskell! |
| 14:04:17 | <SamB> | what does 39 do? |
| 14:04:17 | <blackdog_> | shapr: only by seven minutes |
| 14:04:24 | <tuukkah> | shapr, good evening shapr :-) |
| 14:04:39 | <shapr> | heippa hei tuukkah |
| 14:04:40 | <tanuk> | tuukkah: Maybe I'll try with getChar. It's just that line buffering would be good enough, but the input seems to be buffered more than that. |
| 14:04:42 | <shapr> | g'day blackdog_ |
| 14:04:48 | <Igloo> | tanuk: getLine doesn't return anything until it finds a newline |
| 14:05:04 | <SamB> | quicksilver: well? does it? |
| 14:05:08 | <MyCatSchemes> | shapr: cannot construct contradictory type (EarlyInDay, Doesn'tSuck) at line 1, arising from expression "good morning" |
| 14:05:26 | <blackdog_> | shapr: am writing stupid postgres db code. the filthy, disgusting things i do for money... tell me you're doing something more interesting |
| 14:05:31 | <quicksilver> | SamB: I don't know. I thought it did. |
| 14:05:46 | <tanuk> | Igloo: Sorry for giving code that doesn't accurately tell my intentions. I tried with NoBuffering after LineBuffering didn't work (it should work). |
| 14:06:06 | <Igloo> | tanuk: What should work? |
| 14:06:11 | <tanuk> | Line buffering. |
| 14:06:31 | <shapr> | MyCatSchemes: Try going to sleep earlier ;-) |
| 14:06:33 | <Philippa> | SamB: 39 is basically full ophood |
| 14:06:43 | <Igloo> | ACTION can't work out exactly what program doesn't do what |
| 14:06:47 | <shapr> | blackdog_: Yeah, about to do some HAppS hacking. |
| 14:06:47 | <tuukkah> | tanuk, so can you see the line buffering not working with the simpler program i pasted? |
| 14:06:52 | <MyCatSchemes> | shapr: I do go to sleep early. Early in the morning. |
| 14:07:02 | <shapr> | heh |
| 14:07:17 | <tanuk> | tuukkah: I missed your paste, I'll look it up, one moment. |
| 14:07:47 | <SamB> | wow, standard Haskell has so few types... |
| 14:08:30 | <ski> | SamB : countably infinite isn't enough for you ? |
| 14:08:43 | <SamB> | ski: I meant in the library |
| 14:08:59 | <SamB> | or at least so few class instances for those types |
| 14:09:09 | <mauke> | there's [()], [[()]], [[[()]]], ... |
| 14:09:24 | <SamB> | type constructors, if you will... |
| 14:09:25 | <ski> | mayhaps you mean s/type/type constructor/ ? |
| 14:09:28 | <ski> | (: |
| 14:11:26 | <tanuk> | tuukkah: That's block buffered too. |
| 14:12:03 | <tuukkah> | tanuk, and did you try with both getLine and getChar? |
| 14:12:29 | <tanuk> | tuukkah: No... I'll try. |
| 14:12:33 | <blackdog_> | aurynn: you wouldn't stripe the data? |
| 14:12:46 | <blackdog_> | oops, sorry |
| 14:14:29 | <tanuk> | tuukkah: Output comes still in blocks when piping aseqdump's output to Test. Typing the input from keyboard works. |
| 14:14:52 | <quicksilver> | tanuk: oh, well that's the output sides fault then |
| 14:15:18 | <quicksilver> | tanuk: if aseqdump is block buffering then there is nothing you can do at your end |
| 14:16:48 | <tanuk> | quicksilver: If I don't pipe aseqdump's output, so that it is printed in the terminal, output comes immediately. |
| 14:16:59 | <quicksilver> | again, that's aseqdump's fault |
| 14:17:11 | <quicksilver> | programs which use the stdio C bindings |
| 14:17:19 | <quicksilver> | will exhibit line buffering if stdout is a TTY |
| 14:17:34 | <quicksilver> | but block buffering otherwise |
| 14:17:46 | <quicksilver> | (unless they explicitly choose a different buffering style) |
| 14:17:47 | <tanuk> | quicksilver: Ok, the cause is now clear, thank you. |
| 14:18:33 | <quicksilver> | this is, essentially, an optimisation |
| 14:18:40 | <quicksilver> | it's notably confusing until you understand it though :) |
| 14:18:50 | <tanuk> | quicksilver: Can this be altered externally, or do I have to modify aseqdump's source? |
| 14:18:58 | <SamB> | it can be really annoying at times |
| 14:19:13 | <quicksilver> | if you're really lucky, aseqdump has an option to control it |
| 14:19:22 | <tanuk> | I'm not lucky. |
| 14:19:40 | <SamB> | I wish GHC's RTS would flush it's output buffers at the end of a heap sample... |
| 14:19:57 | <quicksilver> | you could foold aseqdump into thinking it's talking to a tty |
| 14:20:11 | <quicksilver> | by using ioctls possibly? |
| 14:20:15 | <tuukkah> | tanuk, there are gdb scripts for changing the stdout of a running program. you can probably make one that changes the buffering mode too |
| 14:20:17 | <zbrown> | Has anyone had trouble with ghci on Debian etch? Its telling me ghci wasn't built with interactive use? |
| 14:20:23 | <SamB> | quicksilver: or actually hook it up to a TTY |
| 14:20:29 | <quicksilver> | SamB: yes, or that :) |
| 14:20:41 | <SamB> | I don't know if ioctls would work or not |
| 14:20:52 | <SamB> | I don't know much about them |
| 14:21:38 | <tanuk> | With open source there is always the patching way, which seems to be the easiest way this time. |
| 14:22:17 | <Igloo> | zbrown: ghci isn't enabled for arches other than x86 and amd64 |
| 14:22:34 | <benny99> | |Steve|: hey, just found this one here http://en.wikibooks.org/wiki/Haskell/Understanding_monads, maybe you want to try that |
| 14:22:37 | <lambdabot> | Title: Haskell/Understanding monads - Wikibooks, collection of open-content textbooks |
| 14:22:43 | <zbrown> | Igloo: oh. I didn't know that. |
| 14:23:15 | <benny99> | bye again |
| 14:23:17 | <Philippa> | Igloo: could I crib some stuff to try porting to a non-debian linux on arm at some point, btw? |
| 14:23:29 | <Philippa> | still want to get a proper native build on my zaurus sometime |
| 14:24:34 | <crazy_coder> | Hello everyone |
| 14:24:52 | <crazy_coder> | Is it possible to produce multiple side effects in a function ? |
| 14:25:21 | <quicksilver> | yes |
| 14:25:27 | <Lemmih> | crazy_coder: Multiple side-effects? |
| 14:25:36 | <Igloo> | Philippa: How do you mean, "crib some stuff"? |
| 14:25:37 | <quicksilver> | twosideffects = putStrLn "hello" >> putStrLn "world" |
| 14:25:43 | <quicksilver> | that has two side effects |
| 14:25:45 | <crazy_coder> | Like I take in a list and produce another list (by manipulating the given list) and also actually return something |
| 14:25:50 | <quicksilver> | first it prints hello, then it prints world |
| 14:26:12 | <crazy_coder> | What I return is permanent, but the list I modified isn't |
| 14:26:21 | <quicksilver> | crazy_coder: why not just return two things? |
| 14:26:27 | <quicksilver> | crazy_coder: that's the simplest way to do that |
| 14:26:28 | <crazy_coder> | Can we do that ? |
| 14:26:30 | <quicksilver> | sure |
| 14:26:33 | <Philippa> | Igloo: take a poke at the debian arm build, I guess |
| 14:26:36 | <crazy_coder> | How to do it ? |
| 14:26:36 | <SamB> | > (1, 2) |
| 14:26:39 | <lambdabot> | (1,2) |
| 14:26:44 | <SamB> | that's two things |
| 14:26:46 | <mauke> | crazy_coder: return a value composed of two other values |
| 14:26:48 | <crazy_coder> | returning as a tuple ? |
| 14:26:51 | <quicksilver> | yup |
| 14:26:52 | <mauke> | for example |
| 14:26:56 | <crazy_coder> | Oh Ok |
| 14:26:58 | <earthy> | mumblegrumble hat grumble |
| 14:27:05 | <crazy_coder> | But it complicated the code , isn;t it? |
| 14:27:09 | <crazy_coder> | *complicates |
| 14:27:11 | <quicksilver> | I don't think so |
| 14:27:21 | <quicksilver> | just a question of what you're used to, perhaps |
| 14:27:23 | <crazy_coder> | You then have to apply fst, etc |
| 14:27:24 | <malcolmw> | earthy? tell me your Hat woes |
| 14:27:27 | <quicksilver> | no you don't |
| 14:27:31 | <crazy_coder> | To get back the stuff you put in |
| 14:27:34 | <quicksilver> | nope |
| 14:27:38 | <quicksilver> | you pattern match |
| 14:27:39 | <crazy_coder> | How not ? |
| 14:27:47 | <mauke> | > let (x, y) = (1, 2) in x * 10 + y |
| 14:27:49 | <lambdabot> | 12 |
| 14:27:50 | <quicksilver> | let (x,l) = my_cool_fun m |
| 14:28:48 | <earthy> | malcolmw: it won't accept existential types |
| 14:28:56 | <crazy_coder> | Ok , I'll try, but if i use let as above, the x and y are local and not useful outside hte function |
| 14:28:58 | <crazy_coder> | *the |
| 14:28:59 | <earthy> | not even if I want to compile the module containing them as trusted |
| 14:29:00 | <Igloo> | Philippa: I'm still not sure exactly what you want from me. If you mean "what goes in mk/build.mk", then http://hpaste.org/1713 |
| 14:29:16 | <earthy> | (as in: the code I want to trace doesn't contain the existentials explicitly) |
| 14:29:27 | <mauke> | crazy_coder: yes, like all return values |
| 14:29:29 | <crazy_coder> | Oh ok |
| 14:29:32 | <crazy_coder> | I got it |
| 14:29:33 | <malcolmw> | earthy: I'm pretty sure it should accept tham |
| 14:29:53 | <crazy_coder> | something like (x,y) <- Some_function_which_returns_tuples |
| 14:29:59 | <wli> | Are there anything like higher-order classes? |
| 14:30:01 | <crazy_coder> | and then use x and y right ? |
| 14:30:05 | <quicksilver> | crazy_coder: not <-, no |
| 14:30:07 | <malcolmw> | earthy: the Hat parser is ripped from nhc98, which supported existentials since 1996 |
| 14:30:11 | <quicksilver> | crazy_coder: just let (x,y) = |
| 14:30:15 | <crazy_coder> | quicksilver: Its a monad |
| 14:30:22 | <quicksilver> | crazy_coder: ah, well then yes :) |
| 14:30:23 | <crazy_coder> | IO (Int,Int) say |
| 14:30:29 | <earthy> | class Applicable rule term where |
| 14:30:29 | <earthy> | apply :: rule -> term -> term |
| 14:30:29 | <earthy> | -- apply' :: forall m . (Monad m) => rule -> term -> m term |
| 14:30:29 | <earthy> | applicable :: rule -> term -> Bool |
| 14:30:30 | <quicksilver> | exactly |
| 14:30:35 | <earthy> | the commented line wasn't accepted |
| 14:30:36 | <crazy_coder> | Thanks |
| 14:31:00 | <malcolmw> | earthy: that's not an existential in the classic sense |
| 14:31:03 | <Philippa> | Igloo: I wasn't actually asking anything right this moment, but yeah, that's a good start |
| 14:31:05 | <crazy_coder> | actually i am trying to write a stack class |
| 14:31:13 | <earthy> | nope, true. |
| 14:31:22 | <crazy_coder> | which has pop and push functions |
| 14:31:30 | <mauke> | crazy_coder: that's just a linked list |
| 14:31:37 | <mauke> | push is (:), pop is tail |
| 14:31:45 | <Philippa> | but basically, give you a yell when I know what I'm after? |
| 14:31:46 | <crazy_coder> | So in pop I have to return an element as well as modify the lsit |
| 14:31:53 | <malcolmw> | earthy: and I'll bet that ghc has only supported that since GADTs were added |
| 14:31:58 | <quicksilver> | mauke: but maybe it's interesting for crazy_coder to write it his way? :) |
| 14:32:10 | <crazy_coder> | Thanks quicksilver |
| 14:32:11 | <quicksilver> | crazy_coder: yes, returning a tuple of the two would be a common idiom |
| 14:32:35 | <crazy_coder> | Also one thing more |
| 14:32:45 | <crazy_coder> | When I write class Stack a where .... |
| 14:32:47 | <mauke> | if you're doing it in IO, you can use data Stack a = Stack (IORef [a]) |
| 14:33:02 | <crazy_coder> | Then I have to define all instances of Class manually |
| 14:33:10 | <earthy> | malcolmw: I could do without that btw. |
| 14:33:13 | <earthy> | what I can't do without is |
| 14:33:13 | <earthy> | newtype RealParser state s p a = P(forall r' r'' . (a -> r'' -> r') -> |
| 14:33:16 | <earthy> | (state -> Steps r'' s p) -> state -> Steps r' s p) |
| 14:33:19 | <crazy_coder> | Is there something like derive which will do it automatically ? |
| 14:33:21 | <mauke> | crazy_coder: whoa. how many instances do you need? |
| 14:33:39 | <crazy_coder> | Char,String, anything should go it |
| 14:33:41 | <earthy> | it doesn't grok the ( before the forall somehow |
| 14:33:42 | <crazy_coder> | *in it |
| 14:33:53 | <mauke> | crazy_coder: that has nothing to do with classes |
| 14:33:59 | <mauke> | just make a parametrized type |
| 14:33:59 | <earthy> | and that, IIRC, is existential in the classic sense. |
| 14:34:11 | <shapr> | ACTION boings cheerfully |
| 14:34:29 | <malcolmw> | earthy: not an existential, that is rank-2 polymorphism |
| 14:34:38 | <crazy_coder> | mauke: you mean when I declare it like class Stack a where....... , I don't have to define all instances for it ? |
| 14:34:52 | <earthy> | uhm. yah. |
| 14:34:57 | <mauke> | no, you shouldn't make it a class at all |
| 14:35:05 | <earthy> | ACTION is not awake *at*all* either |
| 14:35:17 | <earthy> | which makes me even more grumbly. sorry for that. |
| 14:35:29 | <earthy> | but the unfortunate issue is I can't use hat |
| 14:35:30 | <crazy_coder> | mauke: why not ? |
| 14:35:45 | <earthy> | even though I think I should be able to when I want to trust this code |
| 14:35:50 | <malcolmw> | earthy: so, if you move the forall outside the constructor, does it still mean the same thing? `cos then you could get it through Hat |
| 14:36:08 | <mauke> | crazy_coder: what's the point? |
| 14:36:55 | <crazy_coder> | mauke: I can store it in a module called Stack and use it whenever I want to use a stack |
| 14:36:56 | <earthy> | you mean RealParser state s p a = forall r' r'' . P ((a -> r'' -> r') -> (state -> Steps r'' s p) -> state -> Steps r' s p) ? |
| 14:37:02 | <mauke> | crazy_coder: no, you can't |
| 14:37:07 | <mauke> | crazy_coder: a class is just an interface |
| 14:37:07 | <earthy> | lemme think about that one for a bit |
| 14:37:15 | <malcolmw> | earthy: yep |
| 14:37:16 | <mauke> | crazy_coder: you'd still have to write a concrete stack |
| 14:37:49 | <quicksilver> | crazy_coder: yeah, this doesn't need to be a class |
| 14:37:51 | <tuukkah> | crazy_coder, you know tail? it works for any type of list since its type is [a] -> [a] |
| 14:37:59 | <quicksilver> | crazy_coder: a class is for when the instances are different, for different a |
| 14:38:06 | <quicksilver> | crazy_coder: you can use the same code for any a |
| 14:38:16 | <quicksilver> | crazy_coder: so this is just a plain old polymorphic function |
| 14:38:31 | <quicksilver> | crazy_coder: from what you've told me so far, your stack doesn't need to be in IO, either |
| 14:38:35 | <quicksilver> | crazy_coder: sounds like it is pure code |
| 14:38:53 | <crazy_coder> | When do we use a class ? |
| 14:39:08 | <quicksilver> | when you need to write different code for different types |
| 14:39:09 | <crazy_coder> | To put all methods together |
| 14:39:30 | <mauke> | crazy_coder: when you need a common interface to different types |
| 14:39:37 | <quicksilver> | you'd use a class if you had a completely different way to implement a stack of ints, from a stack of strings |
| 14:39:51 | <quicksilver> | but for this case, the same implementation works for all, and that's nice |
| 14:39:57 | <crazy_coder> | How would push and pop be associated with stack |
| 14:40:03 | <pharm> | I've always seens classes in Haskell as more like Java interfaces. |
| 14:40:04 | <crazy_coder> | If i use just functions |
| 14:40:12 | <mauke> | crazy_coder: they wouldn't |
| 14:40:18 | <quicksilver> | by their types perhaps |
| 14:40:18 | <mauke> | what do you mean by "associated"? |
| 14:40:22 | <quicksilver> | or by the module they were in |
| 14:40:26 | <quicksilver> | or by their documentation |
| 14:40:28 | <quicksilver> | (or all three)\ |
| 14:41:21 | <crazy_coder> | I mean when I should be able to use pop and push only on certain lists(which are actually stacks) and not all |
| 14:41:40 | <mauke> | but all lists are stacks |
| 14:41:44 | <tuukkah> | in object-oriented programming data and methods are contained in object. but haskell isn't object-oriented and haskell doesn't have objects |
| 14:42:09 | <quicksilver> | crazy_coder: if you want to do that, you'd make a 'newtype' for Stack |
| 14:42:10 | <mauke> | you could make a new Stack type that doesn't support list operations |
| 14:42:22 | <quicksilver> | crazy_coder: underneath it would actually be a list |
| 14:42:23 | <Toxaris> | crazy_coder: you could use data Stack a = Stack [a], but why should you? |
| 14:42:31 | <quicksilver> | crazy_coder: but the newtype would tag it as a stack |
| 14:42:42 | <quicksilver> | so that you can only pass it to functions that want stacks |
| 14:42:55 | <crazy_coder> | Oh I see, Now I get some important stuff |
| 14:42:59 | <quicksilver> | but, as mauke and Toxaris say, why would you do that? all lists are stacks. |
| 14:43:14 | <quicksilver> | seems unnecessary to restrict your instance |
| 14:43:17 | <quicksilver> | erm |
| 14:43:18 | <crazy_coder> | I really was confused with when to use what.. |
| 14:43:21 | <quicksilver> | restrict your types |
| 14:43:21 | <quicksilver> | :) |
| 14:43:22 | <crazy_coder> | hmm |
| 14:43:28 | <crazy_coder> | I see the point |
| 14:43:40 | <mauke> | class Stack s where {empty :: s a; push :: a -> s a -> s a; nstruct :: b -> (a -> s a -> b) -> s a -> b} -- just because I can |
| 14:44:15 | <jedai> | quicksilver: He could want to be really sure his 'stack' is never used as a list as it would invalidate some invariant he would like to have in his application |
| 14:44:23 | <crazy_coder> | Ok one more thing, If I want to produce a side effect, I suppose one doesn;t have to return IO type right ? |
| 14:44:34 | <mauke> | yes, you do |
| 14:44:43 | <quicksilver> | well that depends what kind of side-effect |
| 14:44:50 | <mauke> | (ignoring ST) |
| 14:45:00 | <jedai> | crazy_coder: You don't want to produce a side effect |
| 14:45:10 | <quicksilver> | there are other monads which are designed to encapsulate particular styles of effectful programming |
| 14:45:17 | <crazy_coder> | If I just want to modify a list permanently , how to do it without IO ? |
| 14:45:18 | <Toxaris> | jedai: but a stack is isomorphic to a list? |
| 14:45:22 | <jedai> | crazy_coder: If you really want to though you need to return a IO or cheat |
| 14:45:39 | <quicksilver> | crazy_coder: it is totally impossible to modify a list permanently. You never want to do that :) |
| 14:45:49 | <mauke> | crazy_coder: you can't modify lists anyway |
| 14:46:39 | <crazy_coder> | like thats my side effect .. change the list (function takes in a list and gives another) . But I want to actually call the function in a do block |
| 14:46:57 | <mauke> | that doesn't change the list, it just returns a different list |
| 14:47:04 | <mauke> | and you can call anything from a do block |
| 14:47:19 | <quicksilver> | crazy_coder: call it in a do block or not, you still can't (and don't want to) modify the list |
| 14:47:33 | <Toxaris> | crazy_coder: do {x; y; let newlist = fun oldlist; z } |
| 14:47:34 | <jedai> | Toxaris: Yes it is, but his functions could add an invariant, for example never get over a certain length (well it isn't a canonical stack anymore but you get my point) |
| 14:47:51 | <crazy_coder> | Ok |
| 14:48:42 | <crazy_coder> | Sometimes its a bit complicated. Do requires you to have return type IO x of every statement, if the last expression is IO () say Right ? |
| 14:48:50 | <Toxaris> | jedai: ok, if he want an ADT, he could use newtype or data :) |
| 14:49:02 | <quicksilver> | crazy_coder: do requires every statement to be in the same monad yes |
| 14:49:02 | <mauke> | crazy_coder: yes |
| 14:49:16 | <quicksilver> | crazy_coder: I don't think you want 'do' at all, though, for the program you're describing |
| 14:49:20 | <mauke> | crazy_coder: except not :-) |
| 14:49:33 | <mauke> | crazy_coder: you can use let statements of any type |
| 14:49:43 | <jedai> | Toxaris: That was my point, but I think we agree anyway, it was just to say "restricting a type" is a valid need. |
| 14:49:55 | <crazy_coder> | Then in this case if I have my function x :: [Int]->[Int] and if I call it in a do block without let, I am going to get some errors Right ? |
| 14:50:28 | <quicksilver> | nope |
| 14:50:30 | <quicksilver> | yes |
| 14:50:31 | <mauke> | if that is the whole statement, yes |
| 14:50:32 | <quicksilver> | sorry that's right |
| 14:50:42 | <crazy_coder> | No these are the general conceptual problems I face :) |
| 14:50:54 | <crazy_coder> | Nothing to do with my stack program |
| 14:51:04 | <mauke> | crazy_coder: it might be easier to learn >>, return and >>= first, just for IO |
| 14:51:08 | <jedai> | crazy_coder: Yes, but why would you call it without let ? If it hasn't side-effects then without a let or a return it won't serve any purpose anyway ? |
| 14:51:08 | <earthy> | right. drat. |
| 14:51:12 | <quicksilver> | each 'statement' in a do block must be in the same monad |
| 14:51:25 | <quicksilver> | however each 'statement' is, actually, just a haskell expression |
| 14:51:25 | <mauke> | then 'do' can be explained in terms of >>= |
| 14:51:36 | <quicksilver> | as such it can contain all kinds of components (sub expressions) |
| 14:51:42 | <quicksilver> | and there is no such constraint on their type |
| 14:51:46 | <crazy_coder> | Was not really understanding it, sometimes one has to change the return type of a function to make it fit in the whole scheme of things |
| 14:52:00 | <quicksilver> | they, simply, must be the right type for the function they're being used in |
| 14:52:01 | <mauke> | crazy_coder: really? |
| 14:52:47 | <crazy_coder> | like to incorporate a function , i had to change a functions return type and then that caused errors somewhere else, then i had to fix that too ! |
| 14:52:48 | <earthy> | malcolmw: any chance that simply adding support for the syntax of rank-n polymorphism would allow generation of 'trusted' trace library code? |
| 14:53:08 | <mauke> | crazy_coder: how did you change the return type? |
| 14:53:17 | <earthy> | or is there a fundamental problem that makes that A Hard Thing? |
| 14:53:18 | <malcolmw> | earthy: yes, I think that would be quite a reasonable expectation |
| 14:53:21 | <crazy_coder> | using return ;) |
| 14:53:36 | <mauke> | crazy_coder: no point in changing the original function, then |
| 14:53:38 | <crazy_coder> | maybe I am doing it wrong |
| 14:53:43 | <earthy> | magic words, malcolm, magic words. /me dives into hat's sources |
| 14:54:00 | <mauke> | crazy_coder: you could always say return (f x) when calling it |
| 14:54:03 | <Toxaris> | jedai: all needs are valid. "If any one of you is without needs, let him be the first to say 'you don't want that'" |
| 14:54:03 | <tuxplore1> | is there any CMS written in HAppS? |
| 14:54:06 | <malcolmw> | earthy: most of the type system extensions are purely a matter of leaving them to the underlying compiler, since Hat does not do much with types itself |
| 14:54:08 | <mauke> | and that shouldn't be very common |
| 14:54:15 | <earthy> | ACTION nods |
| 14:54:15 | <tuxplore1> | or using any other haskell technology? |
| 14:54:16 | <Toxaris> | jedai: but yes, we agree |
| 14:54:23 | <earthy> | harlan:/usr/local/src/hat-2.05/src/compiler98 arthurvl$ pwd |
| 14:54:24 | <crazy_coder> | mauke: ok Thanks |
| 14:54:33 | <crazy_coder> | mauke: where do you learn all that ? |
| 14:54:47 | <malcolmw> | earthy: src/compiler98/Syntax.hs |
| 14:54:50 | <mauke> | crazy_coder: remember, "return" doesn't actually return from a function or anything. it's just a constructor call |
| 14:54:53 | <vincenz> | dons: ping |
| 14:54:58 | <vincenz> | @localtime dons |
| 14:54:59 | <lambdabot> | Local time for dons is Tue Jul 17 00:54:58 2007 |
| 14:55:01 | <malcolmw> | earthy: and src/compiler98/Parse.hs |
| 14:55:07 | <mauke> | crazy_coder: I don't remember. tutorials, trying stuff? |
| 14:55:15 | <fberthold> | Hi I have libraries question, is anyone aware of a lightweight time library, or a constructor for teh standard CallendarTime type that does not require advanced knowledge of things like "day of week"? |
| 14:55:20 | <crazy_coder> | mauke: how much time ;) |
| 14:55:23 | <earthy> | thanks, hacking |
| 14:55:33 | <crazy_coder> | @localtime crazy_coder |
| 14:56:08 | <thoughtpolice> | tuxplore1: http://hope.bringert.net/about |
| 14:56:13 | <malcolmw> | earthy: plus, there will be some plumbing needed to ensure that any new syntax gets all the way through and back out the other side |
| 14:56:36 | <malcolmw> | earthy: src/compiler98/Pretty.hs is the "other side" |
| 14:56:46 | <crazy_coder> | @localtime mauke |
| 14:56:47 | <jedai> | crazy_coder: a week ? a month ? several years ? it depends on what you want to know... |
| 14:56:48 | <lambdabot> | Local time for mauke is Mon Jul 16 16:56:48 2007 |
| 14:57:35 | <jedai> | crazy_coder: To learn the base of haskell and most of its syntax I didn't need more than a few days, but I had prior experiences |
| 14:57:59 | <quicksilver> | crazy_coder: would it be helpful to you if I told you that the special function 'return' has nothing at all to do with return types? |
| 14:58:02 | <jedai> | crazy_coder: and I'm far from mastering Haskell (very very far...) |
| 14:58:02 | <tuxplore1> | thoughtpolice: Thanks. would check it out |
| 14:58:12 | <quicksilver> | the two are quite independent |
| 14:58:33 | <quicksilver> | crazy_coder: I haven't actually seen your code but I have a feeling you're using monads in most of your functions when actually only a very small number really need them |
| 14:58:59 | <crazy_coder> | jedai: 'and I'm far from mastering Haskell (very very far...)' I don't believe it ;) |
| 14:59:58 | <crazy_coder> | quicksilver: whenever I start a do block , i convert all functions to monads ;) Not all, some, many ? dont know |
| 15:00:00 | <jedai> | crazy_coder: You better believe it since I began a few months ago and there's still concept I didn't explore |
| 15:00:20 | <crazy_coder> | :) |
| 15:00:31 | <shapr> | jedai: I'm still there after six years. |
| 15:00:42 | <quicksilver> | crazy_coder: (a) only start a do block because you have genuinely monadic stuff to do |
| 15:00:48 | <quicksilver> | (b) don't convert any functions |
| 15:00:52 | <crazy_coder> | Its going to take me years when i'll start helping people on IRC |
| 15:00:52 | <edwardk> | haskell is crazy huge =) |
| 15:00:56 | <shapr> | Truly |
| 15:01:02 | <quicksilver> | just inline the expressions straight into the statements |
| 15:01:04 | <quicksilver> | or use a let |
| 15:01:10 | <shapr> | Haskell is the most nifty language I've ever seen! |
| 15:01:19 | <quicksilver> | crazy_coder: it would be easier to explain if you gave me an example of the kind of conversion you have done |
| 15:01:36 | <shapr> | crazy_coder: Nah, you'll be able to start helping others very soon, but there's still lots of cool stuff to learn! |
| 15:02:00 | <Nafai> | Morning! |
| 15:02:05 | <jedai> | shapr: Yeah, and I expect I'll still be there in a few years too, but I don't even know now the existence of what I'll be trying to understand then (or so I hope) |
| 15:02:42 | <crazy_coder> | quicksilver: i will show you my code, when i get it working ;) |
| 15:03:37 | <shapr> | Good morning Nafai! |
| 15:03:42 | <Nafai> | How are you? |
| 15:03:44 | <shapr> | jedai: Yeah, there's lots of cool stuff. |
| 15:03:55 | <shapr> | Nafai: I'm getting paid to code, life is good! What about you? |
| 15:03:57 | <quicksilver> | the nice thing about shapr is how positive he always is |
| 15:04:01 | <quicksilver> | shapr++ |
| 15:04:04 | <quicksilver> | (even more so now, I guess) |
| 15:04:19 | <Nafai> | Getting paid to code, possibly not as fun as yours, but still life is good! |
| 15:04:51 | <shapr> | quicksilver: I have perspective, I've worked at Subway and various other places. |
| 15:05:46 | <Nafai> | shapr: I got lambdabot running on my local system this weekend! |
| 15:05:48 | <jedai> | crazy_coder: Did you read http://web.cecs.pdx.edu/~antoy/Courses/TPFLP/lectures/MONADS/Noel/research/monads.html , it's pretty good to understand why monads are simple things after all |
| 15:05:50 | <lambdabot> | Title: Online Tutorial: What the hell are Monads?, http://tinyurl.com/n8bqd |
| 15:06:07 | <crazy_coder> | no |
| 15:06:11 | <crazy_coder> | let me check |
| 15:06:16 | <crazy_coder> | jedai: Thanks |
| 15:06:17 | <crazy_coder> | :) |
| 15:06:49 | <crazy_coder> | I read many different tutorials, But I hardly read other peoples code |
| 15:06:52 | <shapr> | Nafai: Cool, any ideas how it could be easier? |
| 15:06:56 | <crazy_coder> | I think it is cheating :p |
| 15:07:05 | <crazy_coder> | But I should learn to do it |
| 15:07:28 | <sjanssen> | @yow! |
| 15:07:28 | <lambdabot> | UH-OH!! I think KEN is OVER-DUE on his R.V. PAYMENTS and HE'S having a |
| 15:07:28 | <lambdabot> | NERVOUS BREAKDOWN too!! Ha ha. |
| 15:07:46 | <mauke> | @quote |
| 15:07:46 | <lambdabot> | AdamPeacock says: Once I looked at the source code, 25000 lines of ASP, I reckoned it would be easier to rewrite it in a real language. |
| 15:08:24 | <crazy_coder> | I actually find it boring too , to read other peoples code.... |
| 15:08:25 | <sjanssen> | that'd a good one |
| 15:08:33 | <crazy_coder> | Maybe I am talking bullshit |
| 15:08:43 | <crazy_coder> | I need some coffee |
| 15:09:51 | <dozer> | Ive gone 3 weeks now without drinking coke while coding!!! |
| 15:10:15 | <mauke> | dude, you should go to sleep immediately!! |
| 15:10:48 | <crazy_coder> | mauke: me ? |
| 15:11:02 | <mauke> | no, dozer |
| 15:11:18 | <_Nucleo> | @src fromJust |
| 15:11:18 | <lambdabot> | fromJust Nothing = undefined |
| 15:11:18 | <lambdabot> | fromJust (Just x) = x |
| 15:11:21 | <crazy_coder> | heh :) Same for me |
| 15:13:01 | <crazy_coder> | btw, is the tuple idea to return for than two things, actually a concept of state transformation ? |
| 15:13:25 | <dozer> | mauke: It hurt for the first week - I had no idea a litre of sugar, phosphoric acid and caffeene could have hooked my body like that |
| 15:13:34 | <crazy_coder> | *return two or more things |
| 15:13:54 | <mauke> | @src State |
| 15:13:55 | <lambdabot> | Source not found. stty: unknown mode: doofus |
| 15:14:14 | <mauke> | blargh |
| 15:14:32 | <mauke> | transform :: state -> (x, state) |
| 15:15:35 | <vincenz> | mauke: stateT |
| 15:17:06 | <crazy_coder> | Anyways, thanks everyone mauke, quicksilver, jedai, shapr |
| 15:18:24 | <earthy> | ACTION has obviously gotten spoiled by parser combinator libraries |
| 15:18:51 | <earthy> | damn. that parser in hat is not easy to read. :) |
| 15:19:20 | <malcolmw> | earthy: it _is_ written using combinators :-) |
| 15:19:28 | <earthy> | malcolmw: I know. :) |
| 15:19:35 | <wli> | I wonder if there are parser combinator libraries that build up state machines from combinatory expressions. |
| 15:19:37 | <earthy> | but the combinators are not the combinators I'm used to. :) |
| 15:19:49 | <earthy> | so I've gotten spoiled by the libraries I'm used to :) |
| 15:20:12 | <earthy> | at least it's a reasonably clear continuation-base combinator lib :) |
| 15:20:15 | <earthy> | +d |
| 15:20:20 | <malcolmw> | ACTION wants to rewrite the parser using polyparse combinators at some point |
| 15:20:34 | <wli> | malcomw: What are polyparse combinators? |
| 15:21:00 | <malcolmw> | earthy: the Hat parser combinators are acutally monadic, believe it or not |
| 15:21:26 | <malcolmw> | wli: http://www.cs.york.ac.uk/cs/fp/polyparse |
| 15:21:42 | <shapr> | malcolmw: Ever tried the http://www.cs.helsinki.fi/u/ekarttun/PArrows/ ? |
| 15:21:44 | <lambdabot> | Title: PArrows |
| 15:21:52 | <wli> | malcomw: 404 |
| 15:21:56 | <quicksilver> | the thing about combinator libraries is that they are, of course, new languages |
| 15:22:06 | <malcolmw> | wli: correction, http://www.cs.york.ac.uk/fp/polyparse |
| 15:22:08 | <lambdabot> | Title: polyparse: alternative parser combinator libraries |
| 15:22:08 | <quicksilver> | OK, they're quite small languages in the grand scheme of things |
| 15:22:18 | <quicksilver> | but still, they need 'learning' |
| 15:22:29 | <earthy> | malcolmw: I'd already gathered that much |
| 15:22:34 | <earthy> | with `into` being >>= |
| 15:22:39 | <quicksilver> | until you learn them, they look a bit mystifying, especially if you're used to a similar one which uses a different form |
| 15:23:04 | <quicksilver> | c.f. the difference between Parsec/ReadP/polyparse |
| 15:23:37 | <wli> | malcolmw: The haddock is a bit sparse. |
| 15:24:04 | <earthy> | but hell, learning a new parser combinator lib in what, 25 minutes, with no docs but source is not trivial |
| 15:24:18 | <quicksilver> | earthy: agreed |
| 15:24:31 | <quicksilver> | earthy: although plenty of examples would help |
| 15:24:42 | <earthy> | well, the only example is a parser for haskell. :P |
| 15:24:52 | <earthy> | at least I've got a clear view by now :) |
| 15:25:05 | <sjanssen> | the combinator is monadic but not 'instance Monad'? |
| 15:25:13 | <earthy> | parseAp =~= <$> |
| 15:25:20 | <sjanssen> | s/combinator/combinator library |
| 15:25:23 | <malcolmw> | wli: polyparse kind of assumes you are familiar with hutton-meijer-style combinators I'm afriad |
| 15:25:24 | <earthy> | parseChk =~= $> |
| 15:25:25 | <wli> | type Parser = String -> [(Tree, String)] hmm. Shouldn't that be a DAG vs. a tree? |
| 15:25:30 | <earthy> | oh, no, <$ |
| 15:25:33 | <earthy> | and so on and so forth |
| 15:25:40 | <SamB> | malcolmw: a strange assumption indeed |
| 15:26:11 | <SamB> | why, dons isn't even familiar with Parsec! |
| 15:26:31 | <malcolmw> | SamB: I don't see the point in replicating the best monadic parsing tutorial in the world... |
| 15:26:57 | <SamB> | malcolmw: maybe you should instead link to it? |
| 15:27:03 | <malcolmw> | but I do agree more documentation is needed. |
| 15:27:32 | <malcolmw> | SamB: there is a link to it? |
| 15:27:34 | <SamB> | with a more attractive link text |
| 15:27:36 | <SamB> | perhaps |
| 15:27:46 | <SamB> | NOTTCS-TR-96-4 isn't very attractive ;-) |
| 15:29:10 | <earthy> | gotcha.! |
| 15:29:15 | <wli> | ACTION barfs on left factoring. |
| 15:29:25 | <earthy> | the forall parser needs to move to the parseContext rule |
| 15:30:05 | <earthy> | but that's for tomorrow |
| 15:30:14 | <earthy> | now to make dinner for the girl |
| 15:33:27 | <SamB> | malcolmw: btw, have you seen my parsely library? |
| 15:33:47 | <wli> | SamB: I want to see it. |
| 15:33:54 | <SamB> | @hackage parsely |
| 15:33:55 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/parsely |
| 15:34:06 | <earthy> | ACTION wonders why chk is not implemented as chk x = parse const `ap` x `ap` |
| 15:34:22 | <earthy> | ACTION wonders why chk is not implemented as chk x y = parse const `ap` x `ap` y |
| 15:34:25 | <earthy> | that is |
| 15:35:26 | <malcolmw> | earthy: probably something to do with precedence of operators |
| 15:35:30 | <earthy> | interesting. |
| 15:35:51 | <earthy> | parsers do seem to suffer from NIH-syndrome a bit in haskell. :) |
| 15:36:06 | <cedricshock> | Can libraries provide Deriving things for Classes? |
| 15:36:32 | <SamB> | cedricshock: no. maybe ten or twenty years from now they will be able to... |
| 15:37:08 | <cedricshock> | SamB: Aww. I hate when the language gets to do something I don't. |
| 15:37:56 | <SamB> | cedricshock: also, probably if that ever happens the "deriving" syntax will work a bit differently -- i.e. there will most likely be a way to say which of several derivings you want to use. |
| 15:38:54 | <SamB> | cedricshock: I don't think there is anyone who specifically doesn't want something like what you describe |
| 15:39:52 | <wli> | ACTION wonders if it'd be possible to shoehorn the happy-GLR back-end behind Hutton-Meijer combinators. |
| 15:40:05 | <SamB> | wli: what the heck? |
| 15:40:22 | <mrd> | what about Drift and Data.Derive? |
| 15:41:00 | <wli> | SamB: Have the parsers build up a GLR state machine etc. instead of whatever LL(1) stuff they now use. |
| 15:42:02 | <SamB> | hey, malcolmw, HuttonMeijerWallace doesn't seem to have a State Transformer in it... besides which, oughtn't that to be an implementation detail? |
| 15:42:30 | <malcolmw> | SamB: HMW predates monad transformers |
| 15:42:52 | <cedricshock> | SamB: That'd be nice to. The derivations I want are pretty much just functions from types to code for functions... |
| 15:43:17 | <SamB> | malcolmw: oh, you mean that meant something else back then? |
| 15:44:07 | <malcolmw> | SamB: a state transformer is a function (s->s) for some state s, that is all |
| 15:44:11 | <wli> | I think it should be possible to do something on the order of building up a grammar from combinators and then doing all the standard parser generator state machine crud "on the fly" (more likely via partial evaluation). |
| 15:44:14 | <SamB> | malcolmw: oh. |
| 15:44:35 | <malcolmw> | then there is the State Transformer monad (the ST monad) |
| 15:44:51 | <malcolmw> | and finally, the StateT monad transformer |
| 15:45:01 | <malcolmw> | which is different again :-) |
| 15:45:12 | <SamB> | malcolmw: perhaps you should change the module description to be less confusing? |
| 15:46:25 | <malcolmw> | SamB: perhaps I cold |
| 15:46:36 | <malcolmw> | s/cold/could |
| 15:46:51 | <SamB> | malcolmw: are you sure HuttonMeijerWallace predates monad transformers? |
| 15:47:01 | <wli> | malcolmw: I get the impression that what the parser combinator libraries end up constructing is typically recursive descent. |
| 15:47:25 | <SamB> | because I see something suspiciously like StateT and ReaderT here... |
| 15:47:30 | <malcolmw> | wli: exactly so |
| 15:47:49 | <SamB> | though for some reason they're called StateM and ReaderM... |
| 15:48:39 | <wli> | malcolmw: Does it make sense to think about building up a grammar and doing the sort of state machine machinations that parser generators like happy/etc. more typically do? |
| 15:48:41 | <malcolmw> | SamB: when did the mtl first appear? |
| 15:49:17 | <malcolmw> | wli: I believe that's what the Utrecht parser combinators do |
| 15:49:29 | <wli> | malcolmw: Very interesting. Googling. |
| 15:49:45 | <quicksilver> | wli: I did on-the-fly-parser generation, almost combinator like, in lua |
| 15:50:09 | <quicksilver> | wli: I used an array of arrays to model the grammar (inner level - concatenation, outer-level alternation) |
| 15:50:25 | <quicksilver> | wli: and then did factoring and left-recursion elimination |
| 15:50:33 | <quicksilver> | and, I think, first-token shortcut table generation |
| 15:51:45 | <SamB> | malcolmw: well, the paper it was inspired by is from 1995 |
| 15:52:02 | <wli> | "The basic parsing technique used follows closely the conventional recursive descent, top-down parsing method." |
| 15:52:34 | <wli> | "Caveat: All parsers must correspond to non-left recursive grammars." |
| 15:52:47 | <malcolmw> | SamB: and the Hutton Meijer combinators date from 1994, but that tells us nothing. |
| 15:53:05 | <wli> | malcolmw: Are you sure it was the Utrecht parser combinators? |
| 15:53:09 | <SamB> | malcolmw: this paper you linked too is for 1996 |
| 15:53:22 | <SamB> | and I see in it what look like monad transformers to me |
| 15:53:35 | <malcolmw> | SamB: it took them a while to get it published |
| 15:53:35 | <cedricshock> | I'm interested in making a derived or template library that does something like darcs on many haskell data types. Anyone know of existing things I should look at, other than darcs itself? |
| 15:53:37 | <SamB> | er. s/too/to/. |
| 15:53:41 | <wli> | That was from http://www.cs.uu.nl/groups/ST/Software/UU_Parsing/Run-OnlyPC.pdf |
| 15:54:05 | <quicksilver> | cedricshock: calculation of 'diffs' and the ability to mix and match versions? |
| 15:54:08 | <malcolmw> | wli: no, I'm not certain. just a vague recollection |
| 15:54:11 | <quicksilver> | cedricshock: that is very interesting |
| 15:54:17 | <quicksilver> | cedricshock: I'm not aware of anything personally |
| 15:54:38 | <wli> | malcolmw: Okay, so it makes sense and has been done before, we're just not entirely sure when. |
| 15:54:45 | <wli> | Or by whom. |
| 15:54:50 | <malcolmw> | wli: in the same way that I recall manuel chakravarty having self-optimising lexer combinators, in the same vein |
| 15:55:19 | <quicksilver> | many people end up not using their parsers in speed-critical situations |
| 15:55:28 | <quicksilver> | especially with the speed of today's machines |
| 15:55:47 | <malcolmw> | wli: table-driven parsing is not necessarily faster than other techniques anyway |
| 15:55:48 | <quicksilver> | so parser performance isn't a priority (for many people) |
| 15:55:59 | <quicksilver> | of course, when it is, it is |
| 15:56:02 | <quicksilver> | to state the obvious |
| 15:56:03 | <cedricshock> | quicksilver: I'd love to be able to do it on types or tuples by field, union types (full replacement), and some of the Data library type things, like lists and sets. This would be the basis for a user interface paradigm. |
| 15:56:07 | <malcolmw> | SamB: |
| 15:56:14 | <wli> | malcolmw: Oh, I'm not interested in performance, but expressiveness. I don't really want to left factor grammars. |
| 15:56:15 | <quicksilver> | cedricshock: yes, that would be lovely |
| 15:56:19 | <quicksilver> | cedricshock: I'm not aware of that |
| 15:56:30 | <quicksilver> | cedricshock: I wrote something recently for a perl application, along those lines |
| 15:56:35 | <wli> | malcolmw: I'd be just as happy with Earley or CYK as GLR. |
| 15:56:35 | <quicksilver> | cedricshock: diff for nested maps, basically |
| 15:56:43 | <quicksilver> | cedricshock: turns out to be quite subtle :) |
| 15:56:50 | <SamB> | malcolmw: how very interesting |
| 15:57:15 | <wli> | er, s/malcolmw/quicksilver/ |
| 15:57:25 | <quicksilver> | :) |
| 15:57:35 | <quicksilver> | SamB: what bit was interesting? |
| 15:57:51 | <SamB> | quicksilver: the part where he said my name with nothing after it ;-) |
| 15:58:03 | <wli> | quicksilver: As table-driven parsers go, things like Earley, CYK, and GLR are dogslow vs. LALR(1) etc. |
| 15:58:06 | <quicksilver> | SamB: ah ;) |
| 15:58:09 | <malcolmw> | SamB: oops, mistyped |
| 15:58:40 | <wli> | quicksilver: We're talking asymptotically inequivalent even, O(n^3) worst-case. |
| 15:58:53 | <malcolmw> | SamB: in any case, the concept of monad transformers has only really gained traction in the last two years, AFAICT |
| 15:58:59 | <cedricshock> | quicksilver: I'm perfectly willing to write it... I think many of the simpler patch types can achieve orthogonality over nested structures, but some of the more interesting operations (like updating everything element in a set) could be a mess. |
| 15:59:29 | <quicksilver> | wli: yes, yes |
| 15:59:36 | <quicksilver> | wli: I had actual, real performance issues |
| 15:59:40 | <quicksilver> | wli: that's what drove me to do it |
| 15:59:47 | <quicksilver> | wli: I didn't do it for the kicks :) |
| 15:59:56 | <quicksilver> | wli: I was doing incremental parsing after every keypress, in a LUA shell |
| 16:00:05 | <quicksilver> | in order to do syntax colouring and auto-complete |
| 16:00:12 | <quicksilver> | (context-sensitive auto-complete) |
| 16:00:18 | <malcolmw> | SamB: and I extended HM to HMW back in 1999, in the days when everyone rolled their own monad, rather than composing them from smaller monads |
| 16:00:30 | <quicksilver> | the table-factoring made it feasible, with naive rec descent it was not viable |
| 16:01:33 | <wli> | quicksilver: I don't have any essential use for Haskell. It could be exchanged for any of a number of scripting languages where I use it for any essential task. |
| 16:02:00 | <SamB> | malcolmw: apparantly Hutton and Meijer were not aware of this back in 1996 |
| 16:03:07 | <malcolmw> | SamB: back then, it was widely recognised that monads were not composable, and that this was a problem yet to be solved adequately |
| 16:03:18 | <wli> | quicksilver: The hope for GLR/etc. is that I can use them on super dirty nasty ultra-ambiguous languages where I throw out possibilities via higher-level semantics. |
| 16:03:23 | <SamB> | malcolmw: that doesn't seem to have stopped them... |
| 16:03:32 | <SamB> | perhaps they were not well-enough read to know that ;-) |
| 16:05:17 | <quicksilver> | It's still not clear to me that monad transformers are very magical |
| 16:05:30 | <SamB> | quicksilver: they aren't magical |
| 16:05:34 | <quicksilver> | well I know |
| 16:05:34 | <SamB> | they're merely convenient |
| 16:05:37 | <quicksilver> | poor choice of words |
| 16:05:40 | <wli> | I'm starting to get the idea behind monads. |
| 16:05:47 | <quicksilver> | it's not even clear to me that they are all *that* convenient |
| 16:05:54 | <quicksilver> | the best part is the MonadFoo instances |
| 16:05:57 | <quicksilver> | now *those* are useful |
| 16:06:03 | <SamB> | yeah. |
| 16:06:05 | <quicksilver> | dispensed with all that nasty lifting crap |
| 16:06:09 | <SamB> | that's the convenient part... |
| 16:06:21 | <wli> | How about arrows? |
| 16:06:29 | <SamB> | wli: how about them/ |
| 16:06:38 | <SamB> | s|/|?| |
| 16:07:00 | <shapr> | Arrows are more general than monads, but lots more trouble to use. |
| 16:07:12 | <SamB> | that pretty much sums it up ;-) |
| 16:08:08 | <wli> | shapr: The automaton arrows look very interesting to me. |
| 16:08:09 | <shapr> | Arrow advantages can be powerful, but you lose those advantages when you need to lift normal functions into an arrow. Arrows only stay powerful when you use them only with other arrows. |
| 16:08:15 | <SamB> | ACTION wants a ProtoArrow class, with no arr/pure method... |
| 16:09:00 | <tuukkah> | tanuk, in case you still need to set line buffering, here's a script using gdb: http://tuukka.iki.fi/tmp/linebuf |
| 16:09:27 | <shapr> | wli: It's worth learning. |
| 16:09:27 | <wli> | shapr: Well, suppose one has parsing automata and wants to compose them... |
| 16:09:54 | <quicksilver> | SamB: that's interesting |
| 16:10:00 | <quicksilver> | SamB: I *think* that's what I want, too |
| 16:10:23 | <quicksilver> | SamB: were you around the other day when I was musing about eDSLs for code generation? |
| 16:10:26 | <shapr> | wli: Parsing was the original motivation for arrows. Arrow-style parsers can short-circuit, monads must either succeed or fail. |
| 16:10:29 | <SamB> | I'm not sure what would happen if you tried to use it for anything useful though |
| 16:10:31 | <Philippa> | SamB: YA me a few years ago AICM5UKP |
| 16:10:34 | <jfincher> | I've got a non-haskell-related question that I can't think of a better place to ask, where more knowledgeable language-oriented people hang out and discuss things :) |
| 16:10:43 | <SamB> | quicksilver: probably not |
| 16:10:57 | <SamB> | Philippa: huh? |
| 16:10:59 | <int-e> | SamB: hmm. but then you'll need extra functions for all the useful isomorphisms between objects (like (A + B) x C = A x C + B x C) |
| 16:11:14 | <wli> | shapr: Interesting. What were the Arrow-based parsersdoing? |
| 16:11:18 | <SamB> | Philippa: is that a game genie code? |
| 16:11:29 | <quicksilver> | SamB: I want an 'm' such that 'm a' means "generate bytecode which calculates a result of type a' |
| 16:11:43 | <int-e> | SamB: in particular desugaring arrow notation will be much harder. |
| 16:11:58 | <SamB> | int-e: so? |
| 16:12:00 | <quicksilver> | SamB: but that definitely isn't an arrow, because I can't turn an arbitrary haskell function (a->b) into one of these |
| 16:12:03 | <Philippa> | SamB: "You Are ... And I Claim My Five Pounds" |
| 16:12:22 | <SamB> | Philippa: I haven't got any pounds |
| 16:12:24 | <quicksilver> | SamB: but that implies I can 'unpick' my haskell function and turn it into bytecode |
| 16:12:30 | <quicksilver> | SamB: which I certainly can't do |
| 16:12:43 | <jfincher> | It seems self-evident to me that given a string of symbols connected according to some grammar, that more than one semantics for the language consisting of that sentence can be defined. Does anyone know of any papers/etc. that might relate to that idea? |
| 16:12:51 | <SyntaxNinja> | y0 |
| 16:13:02 | <SamB> | quicksilver: simililarly, you can't reverse the direction of a function, which a biarrow would need to be able to do... |
| 16:13:13 | <quicksilver> | SamB: yes, agreed |
| 16:13:21 | <Philippa> | jfincher: lisp? |
| 16:13:23 | <int-e> | SamB: it'd be nice to have an ArrowProto class but it wouldn't make arrows easier to use; it'd make it harder. |
| 16:13:29 | <jfincher> | Philippa: any language |
| 16:13:29 | <Philippa> | as in, the entire community? |
| 16:13:51 | <SamB> | int-e: it ought to make them useful for more things though... |
| 16:13:51 | <quicksilver> | SamB: I think I want: Code a b meaning a recipe for generating Code which expects values of type a {on the stack/in predetermined registers} |
| 16:13:52 | <Philippa> | basically, it's trivial - any interpretation is a valid one |
| 16:14:04 | <Philippa> | you might find reading up on abstract interpretation interesting though |
| 16:14:07 | <quicksilver> | SamB: and then you can obviously write compose :: Code a b -> Code b c -> Code a c |
| 16:14:34 | <shapr> | wli: The only way to see if a monadic parser will succeed or fail is to execute it. Arrow-style parsers can hold static properties, so you can factor out common traversals, and/or short circuit around things that will not be parsed. |
| 16:14:37 | <quicksilver> | SamB: and, furthermore, you might hope to be able to write an 'optimising' version of the compose function |
| 16:14:44 | <quicksilver> | SamB: which can eliminate unused registers,e tc |
| 16:15:03 | <int-e> | SamB: yes, I'd have an application for that actually: invertible computations. (they come with an operation invert :: (b ~> c) -> (c ~> b) and have pure :: (b -> c) -> (c -> b) -> (b ~> c) |
| 16:15:18 | <SamB> | int-e: yeah, that's what I meant by "biarrows" |
| 16:15:22 | <int-e> | ah |
| 16:15:33 | <quicksilver> | int-e: my version would come with some 'axioms' :: b ~> c |
| 16:15:40 | <quicksilver> | int-e: but nothing like 'pure' at all |
| 16:15:58 | <quicksilver> | perhaps you'd have 'CodePlus' :: Int ~> Int |
| 16:15:59 | <int-e> | quicksilver: I used pure mostly to define the axioms (as helper functions) |
| 16:16:02 | <quicksilver> | ACTION nods |
| 16:16:05 | <shapr> | wli: In monadic form string "one" <|> string "two" <|> string "three" must go through every alternative before it can fail, and it checks twice whether the string starts with (char 't'). |
| 16:16:20 | <quicksilver> | or mayb you wouldn't use Int, maybe you'd use QSInt |
| 16:16:28 | <quicksilver> | I'm not sure if I want different types or not |
| 16:16:47 | <wli> | sapr: Yeah, that doesn't sound so good. |
| 16:16:53 | <SamB> | quicksilver: perhaps CInt ;-) |
| 16:16:59 | <quicksilver> | SamB: well yes, perhaps |
| 16:17:07 | <wli> | shapr: Sounds awesome. Where do I pick up these arrow parsers? |
| 16:17:29 | <shapr> | wli: http://www.cs.helsinki.fi/u/ekarttun/PArrows/ |
| 16:17:30 | <lambdabot> | Title: PArrows |
| 16:17:34 | <SyntaxNinja> | I uploaded darcs to debian yesterday. folks should try it out and let me know of any problems. |
| 16:17:49 | <wli> | shapr: Ultraspiffitude. |
| 16:20:35 | <olsner> | it'd be awesome to make a [GS]?(LA)?LR(\([0-9]+\))? parser generator working with parser combinators |
| 16:20:59 | <malcolmw> | SyntaxNinja: the wanderer returns! |
| 16:21:01 | <wli> | olsner: GLR interests me most. |
| 16:21:22 | <wli> | olsner: There's a GLR variant of happy. |
| 16:21:41 | <vincenz> | GLR is the only way forward |
| 16:21:44 | <shapr> | y0 SyntaxNinja! |
| 16:21:47 | <olsner> | if the framework is there, it should be easy to generate all kinds of parser from a single specification |
| 16:21:50 | <vincenz> | though I admit I haven't played with GLR of happy yet |
| 16:21:52 | <psykotic> | wli: the original paper on arrows basically just computes FIRST sets and combines them, in parallel to the usual composition of parsing functions. |
| 16:21:57 | <ski> | wli : istr an hughes arrow paper mentioned an arrow(izable ?) parser library .. someone and duponschel or something |
| 16:22:01 | <wli> | olsner: So basically get parser combinators to build up enough crap to feed to whatever the engine behind that is and blow the doors off them. |
| 16:22:09 | <psykotic> | wli: so the FIRST sets function as a static approximation to the dynamic behavior of the parsing functions. |
| 16:22:16 | <wli> | ski: shapr pointed me at it. |
| 16:22:18 | <SyntaxNinja> | heya malcolmw, sha |
| 16:22:20 | <SyntaxNinja> | shapr: |
| 16:22:27 | <ski> | wli : no, not that one |
| 16:22:28 | <SyntaxNinja> | I climbed a mountain the other day. it was high. |
| 16:22:34 | <SyntaxNinja> | but not that high for a mountain |
| 16:22:35 | <shapr> | ski: Swierstra & Duponcheel |
| 16:22:37 | <wli> | ski: Oh, interesting then. |
| 16:22:40 | <ski> | shapr : ty |
| 16:22:44 | <SyntaxNinja> | ACTION will climb St. Helens next week. |
| 16:22:51 | <wli> | psykotic: I think nondeterminism + LR(1) suffices. |
| 16:22:51 | <malcolmw> | SyntaxNinja: got my PM? |
| 16:22:57 | <wli> | psykotic: I think nondeterminism + LR(1) == GLR. |
| 16:23:14 | <ski> | SyntaxNinja : into the caldera ? |
| 16:23:14 | <psykotic> | wli: you don't even need LR(1). i think you can do LR(0). |
| 16:23:33 | <psykotic> | wli: since the nondeterminism makes lookahead needless (efficiency aside). |
| 16:23:41 | <wli> | psykotic: I'm not sure. I think you need LR(1) so the deterministic cases work. |
| 16:24:04 | <SyntaxNinja> | ski: to the edge. |
| 16:24:07 | <wli> | psykotic: Never mind. You're right, though I suspect LR(1) is used anyway. |
| 16:24:18 | <psykotic> | right, it would be silly not to. |
| 16:24:35 | <ski> | ACTION has no idea if there's still any activity there .. |
| 16:24:53 | <psykotic> | last time i implemented GLR i used LR(0) though, since it's a good deal simpler conceptually and in implementation. |
| 16:24:55 | <wli> | psykotic: The tricky part of GLR is of course the resulting expression DAG. |
| 16:25:07 | <ski> | SyntaxNinja : bring back pics ! :) |
| 16:25:28 | <psykotic> | wli: i don't think it's very tricky, is it? it's just dynamic programming/memoization. |
| 16:25:36 | <wli> | psykotic: I don't think the LR(1) vs. LR(0) bits are where one feels the pain in GLR, but anyway. |
| 16:25:40 | <ski> | 'GLR' ? |
| 16:25:44 | <psykotic> | generalized LR |
| 16:25:57 | <wli> | psykotic: Maybe you're right. |
| 16:26:12 | <psykotic> | it essentially just covers the technique of "resolving" conflicts in the LR tables by exploring alternatives in parallel, and sharing structure and parse results using dynamic programming. |
| 16:26:41 | <wli> | psykotic: The same principle as CYK and Earley, except applied to LR parsers instead of chart parsers. |
| 16:26:56 | <ski> | ACTION recalls a breadth-first parse monad claessen showed |
| 16:27:00 | <olsner> | the devil's in the details as usual... I think the trouble with GLR parsers in practice is the number of potential parses you may have to keep track of |
| 16:27:07 | <psykotic> | well, in that those things are dynamic programming, but it's bottom up rather than top down (unlike CYK and earley). |
| 16:27:32 | <wli> | olsner: That's where the dynamic programming and representing the result as a multirooted DAG comes in. |
| 16:27:45 | <wli> | olsner: Common sub-parses are all shared in the DAG. |
| 16:27:57 | <psykotic> | a simple implementation isn't very tricky at all. it really is a textbook application of DP. |
| 16:27:59 | <tanuk> | tuukkah: Thanks. Unfortunately I'm having problems with using the script. Could you provide a quick how-to? |
| 16:28:22 | <edwardk> | @seen mnislaih |
| 16:28:22 | <lambdabot> | mnislaih is in #haskell and #ghc. I last heard mnislaih speak 33m 12s ago. |
| 16:28:25 | <wli> | psykotic: Where does it get complicated? |
| 16:28:37 | <psykotic> | it doesn't, in a simple implementation. |
| 16:28:52 | <wli> | psykotic: Where do implementations get un-simple? |
| 16:28:59 | <vincenz> | why do you need dynamic programming? |
| 16:29:08 | <vincenz> | you just (lazily) duplicate your stack |
| 16:29:09 | <psykotic> | vincenz, to prevent exponential explosion. |
| 16:29:24 | <psykotic> | basically the divergent parses can reconverge |
| 16:29:29 | <mnislaih> | hi edwardk |
| 16:29:30 | <psykotic> | and you don't want them to duplicate work from that point on |
| 16:29:34 | <vincenz> | ah |
| 16:29:38 | <wli> | vincenz: The parser's results can be huge. You have to share ultra-aggressively between different possible parse trees. |
| 16:29:40 | <edwardk> | heya mnislaih. neat stuff |
| 16:29:41 | <vincenz> | yeah, that's when you re-unify your stacks |
| 16:29:51 | <vincenz> | psykotic: looked at elkhound? |
| 16:29:51 | <psykotic> | well, that's what DP is here. |
| 16:30:07 | <vincenz> | they do it both in O'Caml and C++ |
| 16:30:19 | <vincenz> | (they have a c++ parser using the c++ code generated from the GLR-framework elkhound) |
| 16:30:29 | <wli> | vincenz: This would be constructed on the fly by parser combinators, not a parser generator. |
| 16:30:48 | <vincenz> | wli: oic |
| 16:30:51 | <vincenz> | wli: why? |
| 16:30:57 | <psykotic> | wli: as for complexities, i haven't looked at "serious implementations" like elkhound in detail, but i imagine it's the same thing that afflits all "serious implementations": they want to squeeze out as much performance as possible, so they apply every trick in the book. |
| 16:31:05 | <tuukkah> | tanuk, for example: linebuf sed "s/foo/bar/g" | linebuf sed "s/baz/blum/g" |
| 16:31:05 | <vincenz> | "on the fly" and "parser-generator" barely differ |
| 16:31:06 | <wli> | vincenz: Since no one gives a damn how fast their parsers run it would make more sense to be as general as possible. |
| 16:31:25 | <vincenz> | the only difference is that one has a 'language' while the other has a set of 'combinators', again the distinction is subtl |
| 16:32:25 | <wli> | vincenz: Yeah, that's why ripping the front and back ends off happy-GLR (http://www.dur.ac.uk/p.c.callaghan/happy-glr/) and shoving it under the hood of some parsing combinators sounds good to me. |
| 16:32:27 | <lambdabot> | Title: GLR parsing with Happy |
| 16:32:37 | <vincenz> | wli: sounds like a good idea :) |
| 16:32:42 | <vincenz> | wli: though I admit I rather like happy |
| 16:32:52 | <wli> | vincenz: As general as possible wrt. grammars handled, that is. |
| 16:32:54 | <vincenz> | wli: (especially cause it does -not- deal with lexers) |
| 16:33:33 | <vincenz> | wli: btw, if you plan on doing that, something that would be useful is a combinator-generator |
| 16:33:46 | <vincenz> | wli: that would take the input that the frontend of happy takes and produces the code that uses the combinato |
| 16:34:40 | <psi> | i'm getting: 'Symbol's function definition is void: inferior-haskell-load-file' when i go C-c C-l in a haskell-mode buffer. |
| 16:35:05 | <psi> | any clues? i'm using carbon emacs. |
| 16:35:14 | <wli> | vincenz: I'm not sure what you mean there. |
| 16:35:16 | <quicksilver> | psi: you haven't got inf-haskell loaded |
| 16:35:33 | <wli> | vincenz: Anyway I think I found a "project" to learn stuff. |
| 16:35:54 | <vincenz> | wli: well currently happy is a parser-generator, so it takes some nput file (which is close to std yacc stuff). It'd be good that if you moved to combinator to have something that generates the combinator code from the nput that would be used by the parser-generator |
| 16:35:59 | <psi> | quicksilver: woops, I forgot to add the load to my .emacs. |
| 16:36:08 | <quicksilver> | I use this: (autoload 'run-haskell "inf-haskell" "Run interactive haskell interpreter." t) |
| 16:36:20 | <quicksilver> | I think I still have to remmber to do a run-haskell myself, thouh |
| 16:38:46 | <wli> | vincenz: I'll see what I can do about generating parsers on the fly using it. |
| 16:39:58 | <psi> | quicksilver: thanks |
| 16:42:13 | <tanuk> | tuukkah: The problem is that the data source doesn't use line buffering. I tried to change CMDPID=$$ to CMDPID=`pidof aseqdump`, and then running in one terminal "aseqdump -p 20:0 | Sysextract" and in another "./linebuf", that didn't work. aseqdump exits without a message. |
| 16:42:21 | <psi> | quicksilver: here's what i came up with: (add-hook 'haskell-mode-hook (lambda () (load "inf-haskell"))) |
| 16:42:21 | <wli> | vincenz: I've got a bad feeling it just slings around Haskell code as strings. |
| 16:42:29 | <psi> | quicksilver: you don't have to do it manually then. |
| 16:44:53 | <quicksilver> | psi: yeah, that works too |
| 16:45:53 | <tuukkah> | tanuk, if Sysextract is your unbuffered haskell application, this could work: ./linebuf aseqdump -p 20:0 | Sysextract |
| 16:48:02 | <tanuk> | tuukkah: It doesn't work, because CMDPID doesn't get any value. |
| 16:51:13 | <tuukkah> | in bash, $$ should be the pid of the current shell |
| 16:53:14 | <tanuk> | tuukkah: Yeah, but it's aseqdump's pid that we're interested in, if I understand correctly. The script could maybe work this way: first it starts the program (aseqdump) in a separate thread, takes it's pid, then does the gdb magic and then attaches to the program's thread. I don't know how to do this. |
| 16:53:56 | <tuukkah> | tanuk, as aseqdump is started using exec, it gets the same pid as the shell had |
| 16:54:34 | <tuukkah> | on your machine, doesn't it work even with my sed example? |
| 16:55:21 | <tanuk> | tuukkah: The sed example works, but I think that's because the input comes from the shell, therefore CMDPID is assigned the right pid. |
| 16:56:33 | <tuukkah> | if you think that, you can test by adding a third sed in the middle which doesn't receive input from nor produce output for a shell |
| 16:57:52 | <tuukkah> | but anyway, if it doesn't work then it doesn't work and you need some other hack :-( |
| 16:59:43 | <tanuk> | tuukkah: The ./linebuf aseqdump -p 20:0 | Sysextract |
| 17:00:02 | <tanuk> | line exits after a couple of seconds. |
| 17:00:53 | <tanuk> | I'll modify aseqdump. |
| 17:02:00 | <SimonRC> | why aren't fudgets based on arrows? |
| 17:02:04 | <tanuk> | tuukkah: Thanks for your efforts anyway. |
| 17:02:10 | <ddarius> | SimonRC: Because it was made way way before arrows. |
| 17:02:11 | <EvilTerran> | ACTION notes that "let ... = ... in ..." is slightly longer than "| ... <- ... =" |
| 17:02:27 | <tuukkah> | tanuk, nevermind, the gdb script was something i wanted to test some time :-) |
| 17:02:41 | <EvilTerran> | (terseness FTW!) |
| 17:02:53 | <monochrom> | EvilTerran: they also behave different. |
| 17:03:02 | <ski> | SimonRC : probably because the former were invented before the latter |
| 17:03:14 | <SimonRC> | ddarius: I can see that arrows my help; the fudget law feels "wrong" to me |
| 17:03:43 | <EvilTerran> | monochrom, i know pattern guards cause fallthough on pattern match failure, but is there any difference in the case when the thing you're matching against only has one constructor? |
| 17:04:14 | <EvilTerran> | ("foo x = let (y,z) = bar x in ..." versus "foo x | (y,z) <- bar x = ...") |
| 17:04:44 | <monochrom> | > let (y,z) = undefined in "hey" |
| 17:04:45 | <lambdabot> | "hey" |
| 17:04:55 | <monochrom> | That shows the difference. |
| 17:05:25 | <ddarius> | ~(y,z) |
| 17:05:27 | <EvilTerran> | ah. let doesn't HNF the things being bound |
| 17:05:44 | <quicksilver> | WHNF |
| 17:05:48 | <EvilTerran> | yes, that one. |
| 17:05:52 | <quicksilver> | but it's a bit more than that |
| 17:05:54 | <EvilTerran> | @where WHNF |
| 17:05:54 | <lambdabot> | I know nothing about whnf. |
| 17:05:59 | <quicksilver> | a let binding doesn't just WHNF |
| 17:06:06 | <quicksilver> | a let binding reduces it 'as much as it needed to bind' |
| 17:06:13 | <quicksilver> | so let ((x,y),z) = ... |
| 17:06:14 | <monochrom> | Somehow WHNF feels like a swear word to me, up there with WTF and RTFM :) |
| 17:06:27 | <quicksilver> | is going a bit beyond WHNF, because it forces the constructor inside the left side |
| 17:06:32 | <quicksilver> | erm sorry |
| 17:06:35 | <EvilTerran> | yes, i thought of that just after i said it. |
| 17:06:37 | <quicksilver> | pattern binding I meant of course |
| 17:06:45 | <EvilTerran> | but let _doesn't_, pattern binding _does_ |
| 17:06:48 | <quicksilver> | right :) |
| 17:07:01 | <EvilTerran> | because control flow doesn't depend on a let binding successfully, it doesn't try |
| 17:07:09 | <therp> | isn't let lazy per default? |
| 17:07:21 | <quicksilver> | therp: yes |
| 17:07:24 | <ddarius> | therp: It's an irrefutable binding, yes. |
| 17:07:25 | <quicksilver> | therp: what I said was wrong |
| 17:07:26 | <EvilTerran> | therp, that's what we just concluded |
| 17:07:33 | <monochrom> | Control.Monad.State.Lazy and Control.Monad.State.Strict exploit the difference. The former uses let, the later uses case. |
| 17:07:43 | <therp> | ah sorry /me should read the whole discussion before dropping comments |
| 17:07:49 | <EvilTerran> | so "foo x = let (y,z) = bar x in ..." is like "foo x | ~(y,z) <- bar x = ..."? |
| 17:07:58 | <monochrom> | Yeah. |
| 17:08:08 | <quicksilver> | modulo the difference about falling through |
| 17:08:18 | <quicksilver> | ah, no, I'm wrong again |
| 17:08:20 | <quicksilver> | damn I'm on form |
| 17:08:24 | <monochrom> | Hehehehe |
| 17:08:26 | <quicksilver> | a ~ <- binding can't fall through :) |
| 17:08:29 | <quicksilver> | it's irrefutable |
| 17:08:38 | <EvilTerran> | but if the expression is strict in y or z, there's no difference anyway, right? |
| 17:08:57 | <monochrom> | I agree with that one. |
| 17:09:02 | <EvilTerran> | with or without twiddles |
| 17:09:21 | <ddarius> | tilde takes less typing |
| 17:09:36 | <EvilTerran> | "foo (x,y) = x+y" is effectively indistinguishable from "foo ~(x,y) = x+y", i mean |
| 17:10:03 | <Igloo> | For Int etc, yes, but not necessarily for types you define yourself |
| 17:10:06 | <monochrom> | Heh pattern guard still more compact :) |
| 17:10:27 | <ddarius> | Hmm... is foo !(~(Just x)) = 5 valid? |
| 17:10:37 | <Igloo> | Yes |
| 17:10:43 | <ddarius> | What happens? |
| 17:10:45 | <mauke> | does it semant? |
| 17:10:46 | <Igloo> | There was a discussion on the mailing list about what it means recently |
| 17:11:02 | <Igloo> | ACTION can't remember the answer OTTOMH |
| 17:12:02 | <ddarius> | GHC must have fun with things like ~(x,!y) |
| 17:13:17 | <monochrom> | > let ~(x,!y) = (5, undefined) in x |
| 17:13:18 | <lambdabot> | Parse error |
| 17:13:51 | <monochrom> | > let f ~(x,!y) = x in f (5, undefined) |
| 17:13:51 | <lambdabot> | Parse error |
| 17:14:00 | <monochrom> | It not know bangs? |
| 17:14:09 | <sjanssen> | monochrom: correct |
| 17:14:26 | <monochrom> | Anyway, that example shows what happens. |
| 17:14:48 | <ddarius> | There is a fairly "obvious" thing that should happen in all of these cases. |
| 17:14:56 | <quicksilver> | I would expect the semantics to be 'whenever the tuple gets forced at all, y gets forced' |
| 17:14:58 | <ddarius> | I'm not sure if there are "unobvious" cases. |
| 17:15:11 | <quicksilver> | but the tuple itself doesn't get forced immediately cos its irrefutable |
| 17:15:14 | <quicksilver> | is that right? |
| 17:15:25 | <mauke> | seems like it |
| 17:16:03 | <edwardk> | gah, i wish there was a way to say that Foo m is a class iff Bar m a is defined forall a. class Bar m a => Foo m complains about the absence of a in the type, and I can't make instance Foo m => Bar m a without tagging m with a way to keep me from being able to implement Bar m a in other ways. |
| 17:16:27 | <quicksilver> | I would expect (a,(b,!c)) to mean that c gets forced (only) when the inner tuple which directly contains c gets forced |
| 17:16:35 | <edwardk> | er s/keep me from/keep me so I can/ |
| 17:16:51 | <ddarius> | Use those type level predicates? |
| 17:17:11 | <edwardk> | ddarius: the Fc things? |
| 17:18:57 | <_Nucleo> | @src elem |
| 17:18:58 | <lambdabot> | elem x = any (== x) |
| 17:19:06 | <_Nucleo> | @src any |
| 17:19:06 | <lambdabot> | any p = or . map p |
| 17:19:39 | <wli> | vincenz: Hmm. Looks like Alex is nasty enough I'm better off rolling my own. |
| 17:19:52 | <wli> | vincez: s/alex/happy/ |
| 17:20:05 | <wli> | It's Monday. I'm jacking around. |
| 17:20:22 | <SamB_XP> | wli: you don't like the way you have to specify grammars? |
| 17:20:22 | <wli> | Rolling my own would be better exercise anyway. |
| 17:20:37 | <wli> | SamB_XP: No idea what you mean. |
| 17:20:41 | <ski> | edwardk : you want 'instance (forall a. Bar m a) => Foo m' .. (not supported) |
| 17:20:54 | <SamB_XP> | wli: what about happy do you not like? |
| 17:21:24 | <edwardk> | yeah |
| 17:21:52 | <wli> | SamB_XP: I like it well enough. It's that the state machine code is all done up as Haskell code it writes out to a file, which makes it rather tough to interpret some representation of a state machine in-core using any of its code. |
| 17:22:14 | <SamB_XP> | wli: hmm? |
| 17:22:16 | <edwardk> | it'd make it possible to define convenience classes for Monad m, despite implementing monads with a set of restricted monad classes, like Oleg's version. |
| 17:22:26 | <SamB_XP> | oh, you mean you were trying to adapt it's code to do something else? |
| 17:22:32 | <wli> | SamB_XP: Yes. |
| 17:22:40 | <wli> | SamB_XP: Or looking at doing so. |
| 17:22:41 | <edwardk> | I can build monad convenience classes over the parameterized monad stuff, but not over the restricted monads |
| 17:22:49 | <ski> | edwardk : 'instance (forall a. Show a => Show (f a)) => Show (Foo f)' would be handy sometimes, too |
| 17:23:20 | <ski> | (though in that case there is a workaround) |
| 17:23:27 | <SamB_XP> | ski: something's not being supported probably doesn't bother edwardk so much |
| 17:23:48 | <edwardk> | which means that i may have to drop restricted monads from the toy prelude, since they prevent me from having usable mapMs, sequences, etc. |
| 17:23:58 | <edwardk> | they obviously weren't tested beyond the basic idea |
| 17:24:13 | <edwardk> | samb: =) |
| 17:24:39 | <ski> | SamB_XP : well .. it would be interesting if one could get a usable ssystem supporting these things |
| 17:25:49 | <edwardk> | and i don't want to do anything of this sort with explicit rank-n polymorphism because then i have to plumb around a bunch of dictionary-like objects and its not pretty |
| 17:26:25 | <ski> | edwardk : mayhaps you could do an 'class BarForall m','instance BarForall m => Bar m a',etc .. |
| 17:27:12 | <edwardk> | ski: thought about it, but then I can't do instance SomethingElse m => Bar m a kind of things without ghc complaining about the conflict |
| 17:27:25 | <edwardk> | the moment there is a diamond in the inheritance hierarchy all is lost |
| 17:27:37 | <ski> | instance SomethingElse m => BarForall m -- then ? |
| 17:27:51 | <edwardk> | you get one the moment you allow Monad, ParameterizedMonad, RestrictedMonad and ParameterizedRestrictedMonad |
| 17:28:09 | <ski> | ok :/ |
| 17:28:09 | <SamB_XP> | edwardk: I thought you had a toy language ? |
| 17:28:51 | <edwardk> | samb: i do, i started porting a good portion of the standard library over to haskell to get more eyes, and to work out the issues i was running into in my compiler to see if it was the language or the library at fault. |
| 17:29:02 | <SamB_XP> | ah |
| 17:29:53 | <edwardk> | my current goal is a painfully abstract prelude that unifies as many things as possible. backwards compatibility is not a priority, learnability is not a priority. useful or educational unification of ideas is |
| 17:30:04 | <shapr> | ACTION cheers |
| 17:30:29 | <wli> | Equivalence for DPDA's is decidable if and only if it's decidable for "monadic recursion schemes." (Friedman 1977, as cited by Hopcroft and Ullman). |
| 17:30:35 | <SamB_XP> | edwardk: obviously when you make a new Prelude you have to throw most compatibility out the window... |
| 17:30:53 | <edwardk> | minimizing typeclasses is not a priority, current thought is to $(mkMonad "MyMonad" [d| return = ...; m >>= k = ... |]) to recover usable syntax for definitions |
| 17:30:58 | <wli> | What are the odds that this is somehow connected to monadic parsing? |
| 17:31:17 | <wli> | edwardk: Is this a new Prelude or a new language you're working on? |
| 17:31:21 | <edwardk> | wli: yes =) |
| 17:31:26 | <SamB_XP> | wli: both apparantly |
| 17:31:44 | <edwardk> | wli: the prelude is a projection of features for the one i want for my language into haskell. |
| 17:31:46 | <ski> | wli : DPDA ? |
| 17:31:54 | <edwardk> | wli: the language is the things i'd never get haskell to adopt |
| 17:32:04 | <wli> | edwardk: Could you extend the module system so that modules can be parametrized by other modules? |
| 17:32:18 | <wli> | ski: Deterministic Push Down Automaton |
| 17:32:41 | <edwardk> | wli: well, in haskell the idea is that a ML module maps onto a typeclass |
| 17:32:55 | <ski> | not quite |
| 17:33:02 | <shapr> | ACTION makes a t-shirt "DPDAs against Oppression" |
| 17:33:04 | <wli> | edwardk: Doesn't really work out. |
| 17:33:14 | <edwardk> | well, based on the manuel chakravarty paper on modular type classes |
| 17:33:18 | <shapr> | For too long have we been pushed down! |
| 17:33:29 | <wli> | edwardk: Mostly because you want to switch out implementations behind things. |
| 17:33:48 | <ski> | should we push up instead ? |
| 17:33:52 | <edwardk> | anyways, in my setting they are stagedly dependently typed records, but the inference for them is a nightmare because i don't explicitly annotate what is a type and what is a term. |
| 17:34:08 | <edwardk> | wli: i understand =) |
| 17:34:12 | <wli> | ski: It just means that the finite control manipulates a stack. |
| 17:34:28 | <ski> | wli : i know |
| 17:35:16 | <ski> | ACTION implemented function calls on a DPDA sometime ago |
| 17:35:28 | <laz0r> | hi there, its me again... whenever i use 'do x <- something; ...' the something must be of type (a -> b), right? |
| 17:36:05 | <ski> | laz0r : 'something' must be of type 'm a' for any type 'a', and any type 'm' in the class 'Monad' |
| 17:36:09 | <shachaf> | laz0r: The something must be of type (Monad m) => m a |
| 17:36:12 | <edwardk> | laz0r: something can be of type (m a) for any monad type m |
| 17:36:17 | <ski> | @stereo |
| 17:36:18 | <lambdabot> | Unknown command, try @list |
| 17:36:22 | <ski> | @quote stereo |
| 17:36:22 | <lambdabot> | Cale says: Welcome to #haskell where your questions are answered in majestic stereo! |
| 17:36:50 | <glguy> | @quote stereo |
| 17:36:50 | <lambdabot> | Cale says: Welcome to #haskell where your questions are answered in majestic stereo! |
| 17:36:52 | <glguy> | :) |
| 17:37:11 | <SamB_XP> | edwardk: couldn't you just use -fno-implicit-prelude? |
| 17:37:19 | <SamB_XP> | rather than bothering with TH? |
| 17:37:23 | <edwardk> | wli: at present my module system just hands you back a record with some types embedded in it, using the same mechanism i use for objects |
| 17:37:29 | <ski> | dons : we need '@stereo' .. and possibly whatever the corresponding term is for three ! |
| 17:37:30 | <edwardk> | samb: the problem is sheer number of instances |
| 17:37:31 | <kpreid> | laz0r: and note that m can be (b ->), in which case m a *is* b -> a |
| 17:37:47 | <SamB_XP> | edwardk: for do-notation |
| 17:37:48 | <shachaf> | ski: Yes, and one that doesn't beep Cale's IRC client. |
| 17:37:53 | <ski> | indeed |
| 17:38:07 | <glguy> | @quote |
| 17:38:07 | <lambdabot> | joelr says: the learning curve is far steeper with Haskell but it is far more elegant and readable |
| 17:38:08 | <edwardk> | samb: ideally to express things right a Field would take 30-40 =) |
| 17:38:10 | <shachaf> | kpreid: But it's not likely to be. |
| 17:38:25 | <shachaf> | kpreid: In this case. |
| 17:39:07 | <shachaf> | Is there any reason to use Reader instead of the (e ->) monad? |
| 17:39:19 | <ski> | > (do {x <- (*200); y <- (+8); return (x+y)}) 10 |
| 17:39:23 | <lambdabot> | 2018 |
| 17:39:51 | <kpreid> | when you've got a lot of function arrows and the newtype helps make your type errors less baffling? |
| 17:39:54 | <ski> | shachaf : more explicit distictions between working abstractly in the monad, and concretely applying and abstracting actions |
| 17:39:58 | <olsner> | springerlink wants $32 for the paper on monadic recursion schemes though |
| 17:40:01 | <edwardk> | the current thought is to go through and define a redundant set of operators for the more restricted class of actions, and to build a manual set of instance of the more restricted type, but i still can't say that having something implies the existence of the more specific version |
| 17:40:04 | <edwardk> | in general mixing restricted and unrestricted monads seems to force one to become a really bad second class citizen |
| 17:40:07 | <shachaf> | > liftM2 (+) (*200) (+8) 10 |
| 17:40:08 | <lambdabot> | 2018 |
| 17:40:24 | <SamB_XP> | shachaf: ... it's easier to say and harder to mess up the typing? |
| 17:40:53 | <ski> | and also more tedious to type 'Reader' and 'runReader' all the time :) |
| 17:41:06 | <edwardk> | heh i like the Abstract version ((*200) + (+8)) 10 |
| 17:41:40 | <shachaf> | > do { x <- ask; return (x+1) } $ 5 |
| 17:41:42 | <lambdabot> | 6 |
| 17:41:45 | <glguy> | where a -> a is an instance of Num? |
| 17:42:09 | <ski> | `(,(*200) + ,(+8)) 10 |
| 17:42:10 | <edwardk> | glguy: where b -> a is an instance of AddMagma and MulMagma if a is |
| 17:42:50 | <edwardk> | er AddOp and MulOp now, since Magma is scary and would otherwise be all over the place inconsistently |
| 17:42:57 | <SamB_XP> | heh |
| 17:43:04 | <ski> | scary ? |
| 17:43:32 | <edwardk> | well, the problem is this, do I call every binary operator's overarching class a FooMagma? |
| 17:43:50 | <ski> | not if it isn't associative |
| 17:44:03 | <edwardk> | MeetMagma, JoinMagma, etc. |
| 17:44:13 | <ski> | take octonion multiplication, e.g. |
| 17:44:15 | <edwardk> | SemiGroup is associative =) |
| 17:44:21 | <edwardk> | Magma implies no such thing ;) |
| 17:44:36 | <edwardk> | the free magma is a binary tree with labeled leaves |
| 17:44:38 | <ski> | oh, sorry .. i can never remember what magma is :) |
| 17:45:39 | <oerjan> | edwardk: i recall that in Clean, the class corresponding to an operator has the same name as it |
| 17:45:43 | <edwardk> | thats one reason for the explosion of typeclasses to define it right, it'd be nice to be able to say that hey for this op to work the underlying operation you are using it over has to be associative and to give a SemiGroup constraint |
| 17:46:03 | <edwardk> | oerjan: i started there, but Add seemed like a weird typeclass. i may go back to it though |
| 17:46:40 | <edwardk> | especially now that i'm thinking that class Add a b c | a b -> c, b c -> a, a c -> b where (+) :: a -> b -> c |
| 17:46:49 | <edwardk> | which works for type level and term level math |
| 17:47:00 | <edwardk> | er |
| 17:47:07 | <oerjan> | edwardk: i mean the class of (+) is (+) |
| 17:47:10 | <edwardk> | yeah thats right |
| 17:47:14 | <edwardk> | ah |
| 17:47:18 | <edwardk> | can't do that in haskell =) |
| 17:47:25 | <SamB_XP> | yeah. |
| 17:47:34 | <SamB_XP> | you can't use variable names for classes in Haskell |
| 17:48:03 | <edwardk> | and there is no ability to use :+ either since that is only type and data constructors no? |
| 17:48:11 | <wli> | Higher-order classes would be nice. |
| 17:48:24 | <SamB_XP> | edwardk: what? |
| 17:48:26 | <edwardk> | wli: in a haskell setting the problem is type inference |
| 17:48:31 | <roconnor> | ACTION has a Mult class defining a mult operator like that |
| 17:48:33 | <wli> | edwardk: Point. |
| 17:48:34 | <SamB_XP> | I'm fairly certain that :+ is fair game in Haskell |
| 17:48:44 | <SamB_XP> | if it isn't, report a bug! |
| 17:48:46 | <edwardk> | samb: not for a class or instance name though |
| 17:48:48 | <oerjan> | edwardk: i thought you had already abolished the capitalization rules? |
| 17:49:02 | <SamB_XP> | oerjan: not in Haskell |
| 17:49:05 | <edwardk> | oerjan: two distinct settings, my language vs. this current prelude =) |
| 17:49:09 | <edwardk> | the prelude is haskell |
| 17:49:12 | <edwardk> | the language is not |
| 17:49:22 | <oerjan> | oh |
| 17:49:27 | <edwardk> | its a context thing =) |
| 17:49:36 | <edwardk> | you missed the context |
| 17:49:59 | <SamB_XP> | edwardk: yeah, you'd already established the my-new-language context ;-) |
| 17:50:03 | <wli> | edwardk: I really like the idea of formally including laws for classes in the language. |
| 17:50:31 | <edwardk> | samb: anyways even if :+ was legal for a type class name it'd be useless since you want a typeclass for that to be ternary anyways |
| 17:50:58 | <EvilTerran> | "(a :+ b) c" would be clear enough for me |
| 17:51:01 | <olsner> | heh, someone should write a device driver in VB - just for the evil of it! |
| 17:51:03 | <oerjan> | edwardk: i am reminded of Smalltalk syntax... |
| 17:51:05 | <SamB_XP> | I'm fairly certain (:+) supports >=2 args at least |
| 17:51:15 | <edwardk> | samb: can it be used as a typeclass name? |
| 17:51:28 | <SamB_XP> | edwardk: if it can't... |
| 17:51:29 | <SamB_XP> | @bug |
| 17:51:29 | <olsner> | @quote evil |
| 17:51:30 | <lambdabot> | http://hackage.haskell.org/trac/ghc/newticket?type=bug |
| 17:51:30 | <lambdabot> | Philippa says: <TomMD> Cale: I was wondering if something was wrong with the constructor "Red" :-) <Philippa> TomMD: it's supposed to be written EvilCommieBastard, duh |
| 17:52:16 | <oerjan> | allowing operators to be split into several words |
| 17:52:18 | <EvilTerran> | much like writing "container `get` key" leads naturally, imo, to writing "container `put` key $ value" |
| 17:52:25 | <wli> | Ternary operators are usually of the form "x & y @ z" etc. |
| 17:52:27 | <psykotic> | edwardk, i recall that fortress has support for specifying such laws as parts of interfaces/traits. it leaves unspecified how (or if) they are checked--a naive implementation could use some kind of randomized testing, a more sophisticated one could use theorem proving. but even having it there as a purely unchecked form of documentation/heads up would be nice. |
| 17:52:35 | <edwardk> | oerjan: yeah like (a + b = c) ? |
| 17:52:40 | <wli> | Or "(x, y, z)" |
| 17:52:45 | <SamB_XP> | olsner: can VB export functions with sufficiently arbitrary calling conventions and argument types? |
| 17:52:55 | <edwardk> | psykotic: thats actually what I do now more or less |
| 17:52:57 | <wli> | I suppose you could call that an outfix ternary operator. |
| 17:53:25 | <oerjan> | edwardk: words starting with : are continuations of the previous message |
| 17:53:28 | <edwardk> | psykotic: sort :: [a] -> { xs : [a] | sorted xs } the latter subset type is a proof obligation |
| 17:53:32 | <wli> | kind of like "(x, y)" is an outfix binary operator. |
| 17:53:44 | <opqdonut> | hehe outfix |
| 17:53:45 | <olsner> | not sure actually... but I guess you could make some glue code in a C/C++ dll (although that's cheating) |
| 17:53:47 | <SamB_XP> | wli: or you could call it special syntax |
| 17:54:06 | <olsner> | wli: circumfix |
| 17:54:19 | <wli> | SamB_XP: Then the problem of classifying special syntax arises. |
| 17:54:30 | <olsner> | the Vulcan language has circumfix verb conjugations |
| 17:54:39 | <SamB_XP> | olsner: also, I don't think the kernel has the vbvm dlls |
| 17:54:39 | <edwardk> | psykotic: or semigroup+ a = magma+ a with (+) :: a -> a -> a | associative (+) |
| 17:55:12 | <EvilTerran> | class l := r; data l :+ r; instance (a :+ b) := c where ... --? |
| 17:55:37 | <wli> | olsner: Russian has something of that sort, except the prefix is related to something called the "aspect," which is perfective vs. imperfective as opposed to being related to the actor. |
| 17:55:42 | <SamB_XP> | EvilTerran: hahaha |
| 17:55:54 | <EvilTerran> | >:] |
| 17:56:03 | <edwardk> | where associative f = forall a b c. (a + b) + c <%> a + (b + c) (forgive the horrible <%> syntax, but its what i currently have), the associative law can only really be checked randomly right now, but the <%> says this is a rewrite rule that the compiler can use |
| 17:56:19 | <edwardk> | er s/f/(+)/ |
| 17:56:20 | <wli> | olsner: And it is more of a change to the verb's word stem as opposed to a prefix per se. |
| 17:56:31 | <olsner> | SamB_XP: it'll certainly be a challenge ;-) |
| 17:56:37 | <SamB_XP> | edwardk: was <=> taken? |
| 17:56:42 | <edwardk> | evilterran: hrmm, that works |
| 17:57:05 | <edwardk> | samb: yeah ternary comparison in a total order witnessing trichotomy ala perl. =) |
| 17:57:06 | <EvilTerran> | edwardk, aside from that extraneous "where" and probably needing some fundeps, yeah, i think so |
| 17:57:17 | <SamB_XP> | edwardk: what was wrong with `compare` |
| 17:57:29 | <edwardk> | the perl version is clearer =) |
| 17:57:40 | <SamB_XP> | how about <==> |
| 17:57:45 | <EvilTerran> | the intuitive definition of "greater than, equal to, or less than" is amusing ;] |
| 17:58:08 | <SamB_XP> | EvilTerran: you mean x <=> y = True ? |
| 17:58:08 | <edwardk> | and in my case there are two notions of rewrite permissability <%> allows interconversion for unification purposes and %> is a GHC-like one way confluent rewrite rule. |
| 17:58:22 | <SamB_XP> | edwardk: you could use ==> for the other one |
| 17:58:31 | <edwardk> | ==> is implication =) |
| 17:58:47 | <SamB_XP> | --> and <--> ? |
| 17:58:51 | <edwardk> | like i said forgive the horrible notation, it just got crowded into an ugly corner =) |
| 17:58:59 | <edwardk> | that might wind up being the one i use |
| 17:59:21 | <edwardk> | i like those |
| 17:59:23 | <EvilTerran> | SamB, well, x <=> y IFF x < y | x = y | x > y, so it's not always true if the ordering isn't total |
| 18:00:07 | <EvilTerran> | apparently the unicode consortium considered this a sufficiently likely occurance to include "≶" in the maths bit |
| 18:00:42 | <EvilTerran> | I'm not sure how it differs from "≷", tho. |
| 18:01:00 | <Cale> | ⋚ |
| 18:01:14 | <EvilTerran> | sorry, yes, those two omitted equality. I wanted ⋚ and ⋛. |
| 18:01:29 | <opqdonut> | ahh |
| 18:01:36 | <opqdonut> | unicode :) |
| 18:01:44 | <opqdonut> | i just saw question marks and got flummoxed |
| 18:01:51 | <edwardk> | right now i have preorders with <~ >~ and ~, /~, partial orders with <= >= = /=with induced strict orders < and >, and an as yet unsymbolicized incomparable notion, so that pcompare returns something like Maybe Ordering, and total orders which give a trichotomy law <=> where it just returns Ordering |
| 18:02:05 | <EvilTerran> | there's some really funny operators in there... "⋇" aka "divison times" anyone? |
| 18:02:30 | <Cale> | I can't say I've ever needed that one. |
| 18:02:44 | <edwardk> | heh, i could just revert to the unicode operators but reading code with <gt; or whatever the long form is would get weird. |
| 18:03:27 | <EvilTerran> | ...can you use unicode symbols as haskell operators? |
| 18:03:40 | <edwardk> | i believe ghc allows it now |
| 18:03:41 | <edwardk> | hrmm |
| 18:03:49 | <edwardk> | hey i have a new toy for my prelude =) |
| 18:03:52 | <puusorsa> | hooray! |
| 18:04:07 | <edwardk> | not sure its a GOOD idea, but hey |
| 18:04:10 | <Cale> | ∔ -- this one is actually useful occasionally (when you want to talk about both plus and times at the same time) |
| 18:04:29 | <edwardk> | fmap = ċ =) |
| 18:04:33 | <EvilTerran> | ACTION wouldn't mind (≤) = (<=), (≠) = (/=), (×) = (*), etc |
| 18:04:43 | <EvilTerran> | ACTION wanders off for a bit |
| 18:04:43 | <Cale> | f∘g |
| 18:04:46 | <edwardk> | yeah |
| 18:05:05 | <Cale> | ∘ |
| 18:05:09 | <Cale> | \circ |
| 18:05:19 | <edwardk> | would finally get me out of using vim over the network to edit source files |
| 18:05:37 | <EvilTerran> | (i'd have to train my editor with the appropriate keyboard shortcuts, mind) |
| 18:05:46 | <Cale> | edwardk: why's that? |
| 18:06:06 | <Cale> | I just install SCIM. |
| 18:06:07 | <EvilTerran> | edwardk, with a suitably modern terminal, it should work fine. or with gvim. |
| 18:06:15 | <EvilTerran> | anyway. away! |
| 18:06:19 | <Cale> | (and the latex table) |
| 18:06:28 | <edwardk> | evilterran: yeah, my terminal is just not suitably modern for some reason =) |
| 18:06:34 | <EvilTerran> | heh. |
| 18:07:00 | <Cale> | However, I think composition is common enough to warrant having something that's one keypress to type. |
| 18:07:14 | <edwardk> | so in the interest of full obfuscation should i just start throwing unicode operators at problems then? =) |
| 18:07:47 | <shapr> | sure! |
| 18:08:14 | <shapr> | edwardk: But, doesn't ghc explode on unicode? |
| 18:08:30 | <glguy> | ghc 6.6 handles unicode in .hs files |
| 18:08:58 | <edwardk> | one thing i do find missing in haskell is the ability to define an overloaded application when the lhs isn't a function type. i still can't define that [1,2,3] 0 = 1 thats one piece of my prelude i can't port over |
| 18:09:19 | <edwardk> | or similarly for indexing arrays, etc. |
| 18:09:39 | <opqdonut> | yeah overloaded application would be cool |
| 18:09:47 | <opqdonut> | though i guess it could be horribly misused |
| 18:09:52 | <edwardk> | sure |
| 18:10:01 | <edwardk> | and its a pain to figure out how to type infer i'll confess =) |
| 18:10:11 | <glguy> | m |
| 18:11:47 | <edwardk> | i think i tried at one point changing $ for it, but ran afoul of type inference problems |
| 18:12:31 | <edwardk> | oh yeah way back when on ##logic with cale and dons when we came up with the (.) trick |
| 18:12:46 | <wli> | edwardk: Which (.) trick is this? |
| 18:13:03 | <edwardk> | class Functor f where (.) :: (a -> b) -> f a -> f b |
| 18:14:02 | <edwardk> | it started with me trying to come up with really really general signatures for ($) and (.) before i realized my stupidly general signatures weren't inferrable. |
| 18:14:14 | <edwardk> | at the time i was mixing in arbitrary arrows as well. |
| 18:14:25 | <mnislaih> | fwiw, <$> works wonders |
| 18:14:34 | <glguy> | ?where shootout |
| 18:14:35 | <lambdabot> | http://shootout.alioth.debian.org/ |
| 18:15:21 | <glguy> | :-( dylan isn't on the shootout |
| 18:15:56 | <edwardk> | because looking at (.) above one wonders why its a -> on the outside and not an Arrow c a b => c a b -> c (f a) (f b) since functors map arrows after all, then of course they map arrows to arrows so the truly general signature is worse, etc. =) |
| 18:16:30 | <edwardk> | its a very slippery slope that leads to madness |
| 18:17:03 | <_Nucleo> | @src genericTake |
| 18:17:03 | <lambdabot> | Source not found. BOB says: You seem to have forgotten your passwd, enter another! |
| 18:18:04 | <oerjan> | genericTake 0 _ = [] |
| 18:18:04 | <oerjan> | genericTake _ [] = [] |
| 18:18:04 | <oerjan> | genericTake n (x:xs) | n > 0 = x : genericTake (n-1) xs |
| 18:18:04 | <oerjan> | genericTake _ _ = error "List.genericTake: negative argument" |
| 18:18:31 | <Botje> | :t genericTake |
| 18:18:34 | <lambdabot> | forall i a. (Integral i) => i -> [a] -> [a] |
| 18:18:53 | <edwardk> | at the time i was new to haskell and was still kind of obsessed with removing the injective nature of a lot of things. the abuse of type constructors as tags in haskell still bugs me, but i have to admit that the inference it gives rocks. |
| 18:19:24 | <ski> | injective ? |
| 18:19:30 | <_Nucleo> | oerjan: thanks |
| 18:20:19 | <edwardk> | the fact that functors in haskell aren't truly all endofunctors on the category of types, they only act as endofunctors from the 'larger' category of all types into a smaller subset delimited by the typeconstructor of the functor. |
| 18:20:27 | <oerjan> | edwardk: i think of type constructors as all being in essence newtypes, with the main purpose of creating a new type |
| 18:20:54 | <oerjan> | everything else can be desugared to functions :) |
| 18:21:11 | <edwardk> | so in addition to fmap :: (a -> b) -> f a -> f b one would like (g a -> g b) -> a -> b and (f a -> f b) -> g a -> g b at least, or to move to the painfully general arrow notations above that are even less productive |
| 18:22:08 | <opqdonut> | well you could just have some sort of "switch functor" function |
| 18:22:12 | <edwardk> | in the end i came around to the haskell way of thinking but it was a long road =) |
| 18:22:29 | <opqdonut> | those are all it's specializations |
| 18:22:39 | <opqdonut> | *specialisations |
| 18:22:39 | <shapr> | edwardk: Sounds like a good blog post to me. |
| 18:22:46 | <edwardk> | opqdonut: the issue i had at the time is that a functor isn't a fully general functor =) |
| 18:23:13 | <oerjan> | edwardk: missing a lot of categories too... |
| 18:23:14 | <edwardk> | its just the Hom map of an endofunctor into a subset of the category of all types. |
| 18:23:37 | <edwardk> | the Ob map is entirely missing as return isn't part of functor |
| 18:24:22 | <edwardk> | i got used to it though |
| 18:24:54 | <edwardk> | the asymmetry led me to drive cale to distraction I think for a while though when i first showed up here though =) |
| 18:25:43 | <Cale> | edwardk: the Object map isn't missing at all |
| 18:25:50 | <edwardk> | ? |
| 18:25:50 | <Cale> | It's the type constructor. |
| 18:26:06 | <Cale> | That is, the thing which you're making an instance of Functor :) |
| 18:28:02 | <edwardk> | i think calling it the type constructor is conflating two notions though. return seems to me to be really an object map. mapping objects into the same place as you map arrows, you can't move objects with just the type constructor like you can move arrows with map, you can just name what they should move to |
| 18:28:37 | <Cale> | return is a natural transformation from the identity functor to your functor |
| 18:29:14 | <Cale> | Objects are types, the object map of a functor sends types to other types |
| 18:29:59 | <Cale> | Of course, in Haskell, you don't have complete control over what the object map is -- you have to pick something which is in some sense natural. |
| 18:30:13 | <edwardk> | my main issue is ideally i'd like to be able to define a real 'identity functor' and the forced existence of a tag kind of keeps that from happening, but thats the whole haskell mindset of using tags to break apart cases so it can't really be worked around in the context of the system. I agree that in haskell the answer that haskell uses is the right one. in the presence of the ability to pass an explicit dictionary and use type level funct |
| 18:30:15 | <ski> | a functor 'F' from 'C' to 'D' consists of a map 'F.mapObj : C.Obj -> D.Obj' and a map 'F.mapMor : forall A,B :: C.Obj . C.Mor (A,B) -> D.Mor (F.mapObj A,F.mapObj B)' (together with the requirement that those respects identities and composition) |
| 18:31:06 | <Cale> | Hehe, OO syntax :) |
| 18:31:19 | <ski> | just record syntax, yes |
| 18:31:56 | <edwardk> | thats what i use in my toy compiler more or less for them, or rather whats lurking in the prelude waiting for the compiler to successfully parse it ;) |
| 18:35:04 | <ski> | ACTION has been pondering a way to think of morphisms as effectful things (and objects being effectless) .. |
| 18:35:32 | <edwardk> | ski: a tofte and talpin style type and effect system basically? |
| 18:36:20 | <ski> | hm .. maybe a little bit like that .. more related to my ideas about quotation |
| 18:37:41 | <edwardk> | i've been trying to figure out the right way to reflect an effect into a monad and reify the monad back out into an effect, so you can treat the monad as a value, and run the monad to get the effect as an effectful computation, but i haven't come up with anything clean |
| 18:38:16 | <edwardk> | http://www.comp.mq.edu.au/~asloane/pmwiki.php/SAPLING/SAPLING071?action=download&upname=lippmeier-slides071.pdf was a good paper and i'm amused he takes the same kitchen sink approach to features i do (largely the same features even) |
| 18:38:18 | <lambdabot> | http://tinyurl.com/3y7tb7 |
| 18:38:18 | <ski> | e.g. if 'F,G : C -> D', 'eta : F -> G', 'A,B : C' and 'f : A -> B', then '`(,eta ,f) : F A -> G B' which strikes me as a nice way of denoting that diagonal morphism |
| 18:38:45 | <edwardk> | er not paper, presentation i guess |
| 18:38:59 | <ski> | ty for link |
| 18:39:58 | <edwardk> | in that setting note the -(effects)> on the arrows. what i'd like to do is be able to reflect those into a monad parameterized by the effects in question so that the monad when later invoked causes those effects to happen. |
| 18:40:08 | <edwardk> | rather than have the effects happen when crossing the arrow |
| 18:40:19 | <ski> | (more common ways of denoting that diagonal is as 'eta_B . F f' or alternatively (and symmetrically) as 'G f . eta_A') |
| 18:41:19 | <ski> | edwardk : hehe .. that is what i'm doing in my (not completed) monad effect system :) |
| 18:43:07 | <ski> | (if you want elaboration on the diagonal above, just ask) |
| 18:45:11 | <edwardk> | ski: so what i want is something like reify :: m effects a -(effects)> a, and a metalinguistic form of reflect that can capture actions leading to effects, then you can get haskell like separation of evaluation and execution |
| 18:46:17 | <ski> | ACTION gets separation of evaluation and execution in his system .. that being one of the design goals |
| 18:46:56 | <edwardk> | because it seems that ben's system above has the problem that a lot of those sorts of systems have, that they conflate reduction to normal form with running the effects involved. |
| 18:47:12 | <ski> | ACTION nods |
| 18:47:15 | <edwardk> | its one of the more elegant points in haskell's and forsythe's design that people often over look =) |
| 18:47:54 | <ski> | i'd say its one of the main point of bothering with monads |
| 18:48:23 | <edwardk> | i find it funny that you were talking about this a few months ago, and I largely ignored you because I couldn't figure out what you were rambling on about until I encountered the same problem and puzzled it out for myself =P |
| 18:48:36 | <ski> | ACTION smiles |
| 18:50:38 | <edwardk> | btw- i still want to find a practical way to exploit some of the ideas of the hoare type theory separation logic monad in a practical language though. |
| 18:51:08 | <ski> | ACTION attempts to recall what that was .. again |
| 18:51:09 | <edwardk> | seems like a lot of the 'is this monad commutative' questions can be answered by an approach like that |
| 18:51:19 | <shapr> | Is it better than nanevski's stuff? |
| 18:51:23 | <edwardk> | { P } t { Q} |
| 18:51:31 | <edwardk> | it kind of half-is nanevski's stuff =) |
| 18:51:47 | <edwardk> | since at last check he was doing a post-doc or something working with greg morrisett at harvard on it |
| 18:51:56 | <ski> | (>>=) :: m o p a -> (a -> m p q b) -> M o q b -- ? |
| 18:52:00 | <mattam> | what would be the other half ? |
| 18:52:21 | <shapr> | salut mattam |
| 18:52:24 | <edwardk> | well, iirc amal ahmed, and greg morrisett were working on it, not sure who else |
| 18:52:33 | <ski> | shapr : good evening |
| 18:52:40 | <shapr> | tjenare ski! |
| 18:52:58 | <mattam> | yep the Y_0 team |
| 18:53:04 | <shapr> | ski: Hej Herr Stefan! |
| 18:53:12 | <edwardk> | heh, i moved out here to within about 3 miles of harvard and I've yet to actually have an excuse to set foot on the campus. |
| 18:53:22 | <ski> | ACTION feels a bit too excited .. even though he ought to go to sleep |
| 18:54:22 | <edwardk> | hrmm actually closer to a mile |
| 18:54:24 | <mattam> | Hmm, it seems there's a good team of plt people there, aren't you acquainted with anyone there ? |
| 18:55:03 | <edwardk> | I met Fluet, Ahmed and Nanevski briefly at the ICFP last year, but I doubt they remember be beyond me being the 'crazy comonad guy' =) |
| 18:55:10 | <edwardk> | er remember me |
| 18:55:28 | <mattam> | hehe |
| 18:55:34 | <edwardk> | and at last check all but nanevski had fled the area to go to TTI in chicago |
| 18:55:55 | <chrisamaphone> | anyone here know anything about type theory/logic schools that aren't in the u.s.? |
| 18:56:07 | <ski> | (oh, right .. i think my system can be applied to comonads, maybe arrows, .. and also in a way to equality proofs :) |
| 18:56:47 | <chrisamaphone> | (i'm currently an undergrad in cs at cmu.) |
| 18:56:52 | <ski> | chrisamaphone : Chalmers/Gothenburg University has Haskell research |
| 18:57:24 | <chrisamaphone> | ski: ok, i've been meaning to look into chalmers. |
| 18:57:33 | <ski> | ACTION is currently an undergrad at chalmers/GU |
| 18:57:44 | <mattam> | chrisamaphone: There's a good master program in Paris |
| 18:57:56 | <chrisamaphone> | inria? |
| 18:58:09 | <edwardk> | ski: anyways the pre and post conditions in those hoare type theory monads just specify the pre and post conditions for the heap in which they can run, so you get sort of runs of things that can happen in parallel rather than a purely sequential composition. |
| 18:58:12 | <chrisamaphone> | i've actually found a bunch of interesting stuff in sweden. |
| 18:58:19 | <mattam> | http://mpri.master.univ-paris7.fr/english/index.html |
| 18:58:19 | <shapr> | Me too! |
| 18:58:31 | <chrisamaphone> | i just don't know anyone with firsthand experience with any of it. |
| 18:58:37 | <mattam> | They even have an english translation :) |
| 18:58:41 | <shapr> | Chalmers is awesome, if you can get in. |
| 18:58:44 | <ski> | edwardk : was my '(>>=)' type signature related to that or not ? |
| 18:59:22 | <quicksilver> | edwardk: I have some vague ideas about using seperation logic to optimise query languages |
| 18:59:27 | <chrisamaphone> | mattam: i'd ideally go into a phd program, but this does look interesting. |
| 18:59:39 | <edwardk> | ski: close, but think of two actions {P} x : t {Q} and {P'} y : t2 {Q'} as being able to operate in parallel as long as their conditions don't conflict. |
| 18:59:53 | <edwardk> | i.e. if they mention different portions of the heap |
| 18:59:57 | <mattam> | There are links to most doctoral studies schools around |
| 18:59:57 | <quicksilver> | edwardk: help you find out how to divide a query between threads or indeed machine, safely |
| 19:00:26 | <ski> | edwardk : ok .. more arrowic, then ? |
| 19:01:14 | <mattam> | well, the separation logic stuff can be separated from the Hoare type theory somehow. |
| 19:01:55 | <edwardk> | well, if two actions are disjoint they can be run in parallel. that reminds me I need to slap together that Par monad. |
| 19:02:50 | <ski> | ? |
| 19:02:55 | <ski> | resumptions ? |
| 19:03:20 | <jameysharp> | sjanssen: ping? |
| 19:03:51 | <ski> | data Resumption a = Return a | Yield (Resumption a) |
| 19:03:56 | <edwardk> | given something :: { P } x : t { Q}; somethingelse :: { P' } y : t' { Q'}, something >> somethingelse can just both be executed in parallel if the operation { P } x : t {Q} doesn't mention the same stuff in the heap as { P'} y : t' {Q'} |
| 19:04:47 | <edwardk> | resumptions being the Par monad thing? |
| 19:04:49 | <glguy> | STRef IORef MVar TVar TMVar, am I missing any? |
| 19:05:04 | <ski> | edwardk : that was supposed to be my query, yes |
| 19:05:16 | <edwardk> | the Par monad was just a stupid newtype Par a = Par { runPar :: a }; with Par m >>= k = m `par` k m |
| 19:05:32 | <ski> | glguy : 'SampleVar' ? |
| 19:05:35 | <edwardk> | an identity monad that sparks speculation |
| 19:05:36 | <glguy> | oh yeah |
| 19:05:58 | <edwardk> | glguy: building a MonadRef kind of library? |
| 19:06:03 | <oerjan> | @index SampleVar |
| 19:06:03 | <lambdabot> | Control.Concurrent.SampleVar, Control.Concurrent |
| 19:06:09 | <glguy> | ACTION is tired of not having a modifyRef |
| 19:06:13 | <edwardk> | heh |
| 19:06:13 | <glguy> | swapRef |
| 19:06:45 | <ski> | should there be any fundeps in it, if so, which direction ? |
| 19:07:01 | <edwardk> | yeah, though i admit the big three of IO/IORef, ST/STRef STM/TVar would be good enough for me, and it gives fundeps |
| 19:07:19 | <edwardk> | and fundeps are problem. |
| 19:07:27 | <glguy> | fundeps wouldn't be needed if you use newIORef |
| 19:07:31 | <glguy> | and then switch to the generic functiosn |
| 19:07:55 | <edwardk> | yeah but then i can't parameterize my hash table off of the type of monad its designed for =) |
| 19:07:56 | <ski> | 'newRef' ! |
| 19:08:03 | <edwardk> | not so easily |
| 19:08:17 | <SamB> | ACTION just joined facebook for some reason |
| 19:08:27 | <glguy> | myspacebook? |
| 19:08:34 | <SamB> | facebook! |
| 19:08:42 | <ski> | ACTION built a 'LogVar' parameterized over an arbitrary 'ref' in 'MonadRef' |
| 19:08:55 | <glguy> | previous attempts at a Data.Ref were killed because people couldn't agree on how to do it |
| 19:09:05 | <glguy> | so I'm thinking that I'd rather have it than not |
| 19:10:08 | <SamB> | how can it work if you don't parameterize the datastructure |
| 19:10:11 | <edwardk> | so would the right answer on a fresh slate be to newtype IO, etc. so that under the correct newtype you got the MVar version of things for instance? |
| 19:10:40 | <edwardk> | samb: type family, one parameter of the monad thats it |
| 19:11:09 | <edwardk> | or a fundepped MonadRef kind of class |
| 19:11:49 | <ski> | exists :: (Quantifiable ref a,MonadRef ref m) => (a -> Logic m b) -> Logic m b |
| 19:11:49 | <edwardk> | withMVarRefs $ do ... |
| 19:12:19 | <ski> | bound :: MonadRef ref m => a -> Logic m (LogVar ref a) |
| 19:12:22 | <ski> | (etc) |
| 19:12:41 | <quicksilver> | edwardk: if you newtype IO aren't you in lifting hell every time you try to do any other IO operation? |
| 19:12:59 | <quicksilver> | edwardk: (until the *entire* standard library is rewritten with MonadIO primitives instead of IO ones) |
| 19:13:11 | <edwardk> | quicksilver: the setting being a new prelude in which IO is modular and all methods in it lift somehow |
| 19:13:20 | <quicksilver> | oh, I see |
| 19:13:34 | <quicksilver> | right, sounds plausible to me :) |
| 19:13:38 | <ski> | it'd be nice to have someting a bit like hugs restricted type synonyms .. but openable at will later |
| 19:14:20 | <edwardk> | quicksilver: well, i';m thinking a huge chunk of template haskell =) |
| 19:14:35 | <ski> | ('newtype f Foo = MkF (f Bar)' could be nice, as well) |
| 19:14:39 | <edwardk> | and a preprocessing job to pull in a good chunk of the library |
| 19:15:04 | <edwardk> | right now i do something like that to steal numeric types |
| 19:17:00 | <edwardk> | foreign imports would be second class citizens without some form of template magic as well though =( |
| 19:17:51 | <edwardk> | gah the IO monad is really cemented into Haskell's worldview isn't it |
| 19:18:20 | <ski> | the sin-bin |
| 19:18:24 | <edwardk> | yeah |
| 19:18:53 | <edwardk> | its just bolted in there good though |
| 19:18:59 | <Cale> | I don't see it as a sin-bin, personally. |
| 19:19:15 | <Cale> | Of course, perhaps at present, it might have a few things in it which it shouldn't. |
| 19:20:02 | <Cale> | But generally, I think using some form of combinator library to deal with IO is the right way to go, and if that combinator library happens to be a monad, there's no reason not to make it one. |
| 19:20:10 | <shapr> | SamB: What's your facebook email? |
| 19:20:23 | <edwardk> | so the trick would have to be something like $(importForeign ...) where that automatically made the wrapper that took an arbitrary MonadIO instance and made it able to run this |
| 19:20:24 | <ski> | what is "IO" ? |
| 19:21:15 | <edwardk> | and that would leave the ugly side effect that you couldn't use the action you just imported in the same module you just imported it into unless you dealt with lift hell. |
| 19:26:07 | <Nopik> | hi again |
| 19:26:50 | <Nopik> | heh, the topic should say: "The Haskell programming language: fit infinite lists into few bytes" :D |
| 19:27:09 | <Nopik> | .. just as linux is doing infinite loops in 5 seconds :D |
| 19:27:22 | <shapr> | BogoLists? |
| 19:29:50 | <glguy> | there really can't be a functional dependency in "MonadRef" since things like TVar can be created in multiple monads (IO and STM) and muliple Ref Types can be created in a single monad (MVar IORef) so that makes it easy to decide |
| 19:33:08 | <ihope> | Nopik: Haskell can do that too! |
| 19:33:11 | <ihope> | > last (repeat ()) |
| 19:33:16 | <lambdabot> | Terminated |
| 19:33:20 | <ihope> | Okay, maybe it can't. |
| 19:33:23 | <ihope> | > let x = x in x |
| 19:33:24 | <Nopik> | hehe :) |
| 19:33:24 | <lambdabot> | Exception: <<loop>> |
| 19:34:43 | <_Nucleo> | @src LiftM2 |
| 19:34:43 | <lambdabot> | Source not found. It can only be attributed to human error. |
| 19:34:46 | <quicksilver> | > concat . repeat $ [] |
| 19:34:47 | <lambdabot> | Exception: <<loop>> |
| 19:34:47 | <_Nucleo> | @src liftM2 |
| 19:34:47 | <lambdabot> | liftM2 f m1 m2 = do { x1 <- m1; x2 <- m2; return (f x1 x2) } |
| 19:35:15 | <glguy> | liftM2 f x y = return f `ap` x `ap` y |
| 19:35:28 | <_Nucleo> | @src ap |
| 19:35:28 | <lambdabot> | ap = liftM2 id |
| 19:35:33 | <_Nucleo> | heh |
| 19:35:43 | <Nopik> | damn.. i have installed gd library, but when I try to import Graphics.GD in my code, runghc says: can't load .so/.DLL for: pthread (/usr/lib64/libpthread.so: invalid ELF header) |
| 19:37:08 | <Nopik> | i tried to run plain ghc, but it throws bunch of undefined references.. any ideas what option i should add to ghc to add proper library to link with? |
| 19:37:14 | <EvilTerran> | have you got the pthreads dynamic library files (in a place GHC can find 'em)? |
| 19:38:05 | <EvilTerran> | s/can/should be able to/ |
| 19:38:58 | <_Nucleo> | @undo do { x1 <- m1; x2 <- m2; return (f x1 x2) } |
| 19:38:58 | <lambdabot> | m1 >>= \ x1 -> m2 >>= \ x2 -> return (f x1 x2) |
| 19:39:38 | <Nopik> | well, my system uses pthread all the time, and i did not moved them at all :) |
| 19:39:59 | <oerjan> | m1 >>= \ x1 -> m2 >>= \ x2 -> return (f x1 x2) |
| 19:40:46 | <quicksilver> | EvilTerran: that wasn't file not found |
| 19:40:50 | <quicksilver> | EvilTerran: it was invalid ELF header |
| 19:41:05 | <quicksilver> | Nopik: I think you have a mixed 64bit/32bit system and something has gone awry? |
| 19:41:08 | <oerjan> | @pl m1 >>= \ x1 -> m2 >>= \ x2 -> return (f x1 x2) |
| 19:41:08 | <lambdabot> | (`fmap` m2) . f =<< m1 |
| 19:41:37 | <Nopik> | quicksilver: well, i am working on amd64, everything should be 64bit |
| 19:41:41 | <Nopik> | unless something is not :D |
| 19:41:42 | <oerjan> | @pl \m1 m2 -> m1 >>= \ x1 -> m2 >>= \ x2 -> return (f x1 x2) |
| 19:41:42 | <lambdabot> | liftM2 f |
| 19:41:43 | <EvilTerran> | huh. well, it was just a thought. i don't know what an ELF header |
| 19:41:47 | <EvilTerran> | is |
| 19:41:53 | <quicksilver> | could be the GD library wasn't 64 bit clean |
| 19:42:02 | <Nopik> | linux executables are in ELF format |
| 19:42:08 | <quicksilver> | or the FFI bindings used by the haskel-gd binding aren't 64 bit clean |
| 19:42:11 | <Nopik> | quicksilver: maybe.. though i just compiled it minute ago |
| 19:42:23 | <ski> | @redo m1 >>= \ x1 -> m2 >>= \ x2 -> return (f x1 x2) |
| 19:42:23 | <lambdabot> | do { x1 <- m1; x2 <- m2; return (f x1 x2)} |
| 19:42:54 | <msouth> | but isn't it saying that the .so has something it isn't expecting? like it's for wrong architecture? |
| 19:43:44 | <Nopik> | heh, but when i run ghc -v option, it displays gcc command.. if i copy/paste, add proper -L -l, it works |
| 19:44:16 | <Nopik> | but manually running gcc is not what user is meant to do, i bet ;p |
| 19:46:21 | <Nopik> | ok, managed to run via ghc using the same -L -l options |
| 19:46:33 | <Nopik> | now, the question is how to run the same thing using runghc ;p |
| 19:56:35 | <Nopik> | ok, next bit in this pthread puzzle: /usr/lib64/libpthread.so is a ld script on my system.. strace shows that runghc looks at /usr/local/lib/gd-3000.3.0/ghc-6.6.1/libpthread.so before going into /usr/lib*, so i copied /lib64/libpthread.so.0 (which is proper ELF file) into /usr/local/lib/gd-3000.3.0/ghc-6.6.1/libpthread.so and it works |
| 19:56:59 | <SamB> | Nopik: what? no symlinks? |
| 19:57:15 | <Nopik> | SamB: yeah ;P |
| 19:57:43 | <EvilTerran> | ACTION meditates on unsafeCoerce# |
| 19:58:07 | <Nopik> | http://hpaste.org/1717 |
| 19:58:52 | <fasta> | It seems the popularity of unsafe operations is on the rise... |
| 19:59:23 | <EvilTerran> | wow. nice name there -- GHC.Prim.reallyUnsafePtrEquality# |
| 20:00:01 | <Cale> | EvilTerran: Yeah, just 'unsafe' wasn't discouraging enough, I suppose. |
| 20:00:03 | <EvilTerran> | fasta, i'm merely thinking about it, not seriously intending to use it. i'm sure i'm missing something, and that probably wouldn't fix it |
| 20:00:46 | <fasta> | EvilTerran: I do unsafe things all the time, and my machine didn't explode :) |
| 20:01:02 | <fasta> | EvilTerran: although, some stuff did break between 6.6 and 6.7 |
| 20:01:23 | <fasta> | I don't recommend unsafe for nuclear reactors, though. |
| 20:01:31 | <EvilTerran> | okay. well, as i said, i don't intend to really use it. best stay safe if at all possible, eh. |
| 20:02:46 | <glguy> | is the next adjective: dangerous, as in dangerousPtrEquality# |
| 20:02:52 | <glguy> | or maybe disasterous |
| 20:03:13 | <glguy> | unwise? |
| 20:03:46 | <EvilTerran> | hazardous? |
| 20:03:51 | <oerjan> | wmd |
| 20:03:55 | <EvilTerran> | omg? |
| 20:03:57 | <SamB> | dasasterous probably |
| 20:04:07 | <SamB> | for that particular one |
| 20:04:08 | <fasta> | How about "tryme"? |
| 20:04:23 | <SamB> | probablyWrongPtrEquality#? |
| 20:04:33 | <EvilTerran> | bigRedButtonPtrEquality# |
| 20:04:39 | <fasta> | Nice and short, just like people who like shooting themselves in the foot like. |
| 20:04:46 | <glguy> | notReallyPtrEquality |
| 20:04:48 | <ski> | willMakeYouInsanePointerEquality# |
| 20:04:51 | <SamB> | seqFirstIfYouWantInterestingResultsPtrEquality#? |
| 20:05:00 | <EvilTerran> | iahIahCthulhuPtrEquality# |
| 20:05:06 | <ski> | ;) |
| 20:05:15 | <wli> | Try pointer inequalities. |
| 20:05:17 | <fasta> | "used_as_source_of_randomness_by_some" |
| 20:05:40 | <wli> | p - q <= 2*(p' - q') etc. |
| 20:05:45 | <EvilTerran> | schrödingerPtrEquality#, complete with umlaut to really be difficult. |
| 20:05:50 | <SamB> | wli: those are positively wrong |
| 20:06:08 | <wli> | Don't forget screwed up pointer differencing semantics. |
| 20:06:09 | <newsham> | so icfp contest is run by a bunch of haskell zealots this year? |
| 20:06:10 | <SamB> | wrongPtrGTE |
| 20:06:12 | <newsham> | that should bode well |
| 20:06:28 | <fasta> | newsham: nice troll |
| 20:06:34 | <newsham> | no troll intended. |
| 20:06:49 | <ski> | haskell libs should have more really long identifiers |
| 20:06:53 | <newsham> | I'm not a haskell zealot, but i'm 50% of the way there. |
| 20:07:02 | <ski> | (like 'call-with-current-continuation' in scheme) |
| 20:07:05 | <wli> | I have no idea how people can get so worked up about languages as to be zealots about them, but I've seen it happen. |
| 20:07:24 | <fasta> | newsham: I think it were run by Scheme "zealots" last year. |
| 20:07:38 | <SamB> | fasta: hah |
| 20:07:42 | <newsham> | wli: some people are prone to zealotry, in other situations its a reflection of the competition more than the language itself ;-) |
| 20:07:49 | <Cale> | 'CentralizerInAssociativeGaussianMatrixAlgebra' |
| 20:07:51 | <SamB> | then why did they use an ML variant to write the codex? |
| 20:08:01 | <newsham> | fasta: it was a good set of problems, though. |
| 20:08:09 | <fasta> | SamB: that's a diversion |
| 20:08:12 | <Cale> | 'AbelianNumberFieldByReducedGaloisStabilizerInfo' |
| 20:08:22 | <ski> | Cale : ty |
| 20:08:28 | <Cale> | I love GAPs long identifiers :) |
| 20:08:30 | <SamB> | fasta: do you think this because they never parodied scheme? |
| 20:08:34 | <wli> | That hair shirt retrospective thing said the next version of ML was going to adopt typeclasses. |
| 20:08:45 | <wli> | Or was it monadic IO? |
| 20:08:57 | <SamB> | wli: how do you take one without the other? |
| 20:09:12 | <SamB> | where "one" is monadic IO |
| 20:09:17 | <wli> | SamB: I'm not sure. It only said one and I'm inferring the other. |
| 20:09:42 | <fasta> | Type classes... is that like Jaaavaaa? |
| 20:10:08 | <SamB> | fasta: stop it before I call you a 2d lover! |
| 20:10:10 | <opqdonut> | no, that's like haskell :) |
| 20:10:25 | <wli> | fasta: I wish they'd have been called something else like "qualified types" or "type qualifiers" or "modal types" or something. |
| 20:10:31 | <SamB> | or... worse... an o'cult lover! |
| 20:10:54 | <newsham> | a rose by any other name would smell as sweet |
| 20:11:15 | <SamB> | wli: but then what would we call "methods"? |
| 20:11:55 | <wli> | SamB: Something else. Domain-restricted polymorphic functions? |
| 20:12:22 | <SamB> | wli: and *that* is as good a reason as any to call typeclasses that ;-) |
| 20:12:32 | <ski> | SamB : "qualified-type-properties" ? |
| 20:12:44 | <opqdonut> | interfaces? |
| 20:12:46 | <opqdonut> | ;) |
| 20:12:54 | <SamB> | also it doesn't distinguish methods from functions that *use* methods |
| 20:13:00 | <EvilTerran> | i've got it! interestingPtrEquality# ! |
| 20:13:12 | <SamB> | EvilTerran: how about boringPtrEquality# |
| 20:13:13 | <EvilTerran> | oh, wait... the conversation's moved on. ignore me. ;] |
| 20:13:23 | <SamB> | since it usually returns False |
| 20:13:35 | <glguy> | it usually returns an Int# |
| 20:13:38 | <opqdonut> | how about totallySafeAndEntirelyHarmleePtrRquality# |
| 20:13:41 | <SamB> | glguy: oh. |
| 20:13:44 | <opqdonut> | *Harmless |
| 20:14:11 | <EvilTerran> | samb, it's a reference (to PTerry, iirc); allegedly a traditional curse is "may you live in interesting times!" |
| 20:14:28 | <ski> | safePtrEquality :: Execution a -> Execution b -> Possibly (Equal a b) |
| 20:14:53 | <ski> | ('Possibly' being a monad a bit like 'Maybe') |
| 20:15:13 | <opqdonut> | Remotely (Possibly (Equal a b)) |
| 20:15:44 | <newsham> | data PLZ a = AWSUM_THX a | O_NOES String |
| 20:15:45 | <dozer> | EvilTerran: usually people under that curse say something like: "It was never booring" after their third wisky |
| 20:16:00 | <EvilTerran> | hehe |
| 20:16:01 | <ski> | runPossibly :: Possibly a -> Nondet (Maybe a) |
| 20:16:09 | <newsham> | http://www.haskell.org/pipermail/haskell-cafe/2007-May/026142.html |
| 20:16:11 | <lambdabot> | Title: [Haskell-cafe] data PLZ a, http://tinyurl.com/2my4vu |
| 20:16:57 | <ski> | runNondet :: Nondet a -> IO a |
| 20:17:17 | <ski> | unsafePeekExecution# :: a -> Execution a |
| 20:17:37 | <newsham> | unsafeGuessAtAnswer |
| 20:17:51 | <Nopik> | ok, there is: mapM_ (\x -> setPixel (x, 10) red pic) [0..w] how to make it work over 2 dimensional array (like [0..w] [0..h])? |
| 20:17:55 | <opqdonut> | unsafeOptimize |
| 20:17:57 | <newsham> | stand back, I'm going to try SCIENCE |
| 20:18:00 | <Nopik> | should i make mapM_ nested? |
| 20:18:09 | <Nopik> | or, there is simpler way? |
| 20:18:12 | <ski> | (where 'Execution a' is a representation of a thunk, or something like that .. so you can check if it's been forced yet, e.g.) |
| 20:18:18 | <SamB> | ACTION tries to figure out how JHC treats Bool as being "data Bool = Bool# Bool__" (or something like that) when it is declared "data Bool = False | True" |
| 20:18:22 | <opqdonut> | Nopik: well, nested mapM_ would work |
| 20:18:42 | <mattam> | newsham: you're not too far from being a geek if not a zealot anyway :) |
| 20:18:49 | <ski> | @index forM_ |
| 20:18:49 | <lambdabot> | bzzt |
| 20:18:56 | <newsham> | mapM_ func [(w,h) | w<-[0..w], h<-[0..h]] |
| 20:18:57 | <Nopik> | i just want nested for loop :P |
| 20:19:15 | <ski> | forM_ = flip mapM_ |
| 20:19:20 | <ski> | do ... |
| 20:19:21 | <newsham> | yes, forM_ superior |
| 20:19:35 | <Nopik> | why superior? |
| 20:19:40 | <ski> | forM [0..w] $ \w -> |
| 20:19:41 | <newsham> | why nest loops when you can cross-product |
| 20:19:46 | <ski> | forM [0..h] $ \h -> do |
| 20:19:59 | <Nopik> | hm, let me try |
| 20:19:59 | <newsham> | nopik: because I program in #python, and forM is like my imperative friend |
| 20:20:00 | <ski> | func (w,h) |
| 20:20:42 | <ski> | (s/forM /forM_ /) |
| 20:21:07 | <EvilTerran> | Nopik, if mapM_ does what i think it does, i'd be tempted to do a list comprehension over the two lists, and then sequence_ it |
| 20:21:09 | <Nopik> | not in scope forM_ ? |
| 20:21:25 | <Nopik> | EvilTerran: yeah, i'm trying to do so |
| 20:21:29 | <newsham> | import Control.Monad |
| 20:21:32 | <EvilTerran> | ?type sequence [setPixel (x, y) red pic | x <- [0..w], y <- [0..h]] |
| 20:21:34 | <lambdabot> | Not in scope: `setPixel' |
| 20:21:34 | <lambdabot> | |
| 20:21:34 | <lambdabot> | <interactive>:1:26: Not in scope: `red' |
| 20:21:45 | <EvilTerran> | hm |
| 20:21:47 | <ski> | ACTION once made a monad so he could say 'do {w <- for_list [0..w]; h <- for_list [0..h]; func (w,h)}' :) |
| 20:21:57 | <Cale> | ?type sequence [?setPixel (x, y) ?red ?pic | x <- [0..w], y <- [0..h]] |
| 20:21:58 | <lambdabot> | Not in scope: `w' |
| 20:21:59 | <lambdabot> | |
| 20:21:59 | <lambdabot> | <interactive>:1:61: Not in scope: `h' |
| 20:22:03 | <Cale> | ?type sequence [?setPixel (x, y) ?red ?pic | x <- [0..?w], y <- [0..?h]] |
| 20:22:05 | <lambdabot> | Not in scope: `..?' |
| 20:22:05 | <lambdabot> | |
| 20:22:05 | <lambdabot> | <interactive>:1:49: Not in scope: `w' |
| 20:22:09 | <Cale> | er, right |
| 20:22:12 | <Cale> | ?type sequence [?setPixel (x, y) ?red ?pic | x <- [0.. ?w], y <- [0.. ?h]] |
| 20:22:14 | <lambdabot> | forall t t1 (m :: * -> *) a t2 t3. (Num t2, ?w::t2, Enum t2, Num t3, ?h::t3, Enum t3, ?setPixel::(t2, t3) -> t -> t1 -> m a, ?red::t, ?pic::t1, Monad m) => m [a] |
| 20:22:17 | <Cale> | hehe |
| 20:22:33 | <ski> | (but for some strange reason the laboration examiner thought it was overkill for solving sudoku ...) |
| 20:22:34 | <EvilTerran> | the significant component of that being the thoroughly uninteresting "m [a]" |
| 20:22:43 | <Nopik> | hm, now i have forM_, list comprehension etc. it compiles, but i see no result ;p |
| 20:22:48 | <Nopik> | just like iterating over empty list |
| 20:22:50 | <newsham> | > do { w <- [0..2]; h <- [0..2]; return (show w ++ " " ++ show h) } |
| 20:22:50 | <EvilTerran> | ski, does that differ from the list monad? |
| 20:22:51 | <lambdabot> | ["0 0","0 1","0 2","1 0","1 1","1 2","2 0","2 1","2 2"] |
| 20:22:55 | <ski> | I HAD so much FUN ! |
| 20:23:15 | <ski> | EvilTerran : it was based on a continuation monad (transformer) with shift/reset |
| 20:23:18 | <Nopik> | ok, my mystake ;p |
| 20:23:37 | <EvilTerran> | Nopik, the _ indicates it shouldn't return a result |
| 20:23:39 | <ski> | Nopik : now do IO in the body |
| 20:24:00 | <Nopik> | EvilTerran: no, i had \x -> setPixel (w,h) while i should have \(w,h) -> ... |
| 20:24:03 | <glguy> | > sequence ["012"," ","012"] |
| 20:24:04 | <lambdabot> | ["0 0","0 1","0 2","1 0","1 1","1 2","2 0","2 1","2 2"] |
| 20:24:05 | <EvilTerran> | ahh |
| 20:24:12 | <Nopik> | works now |
| 20:24:21 | <Nopik> | my first nested for in haskell :) |
| 20:24:42 | <oerjan> | :t forM |
| 20:24:44 | <lambdabot> | forall a (m :: * -> *) b. (Monad m) => [a] -> (a -> m b) -> m [b] |
| 20:24:48 | <Nopik> | though it iterates 500x500 for 1.5 sec ;p |
| 20:25:13 | <ski> | actually .. to say the truth i couldn't use the 'do' syntax but instead 'bindC' and 'returnC', since i had more general types .. |
| 20:26:26 | <SamB> | ski: -fno-implicit-prelude |
| 20:26:27 | <SamB> | ;-P |
| 20:27:11 | <Nopik> | ok, how to write thing like [0..(w/2)] ? |
| 20:27:31 | <SamB> | > 25 `div` 2 |
| 20:27:32 | <Nopik> | div w 2 ;) |
| 20:27:33 | <lambdabot> | 12 |
| 20:27:36 | <newsham> | "my first nested for in haskell" is amusing cause most idiomatic haskell coders dont use nested fors |
| 20:27:47 | <hpaste> | (anonymous) pasted "Imperative Hoare" at http://hpaste.org/1718 |
| 20:27:57 | <Nopik> | newsham: my first nested for equivalent? :) |
| 20:28:21 | <newsham> | what i mean is -- you're probably doing things "the imperative way" when you could do it nicer "the haskell way" |
| 20:28:25 | <newsham> | (I do that all the time myself) |
| 20:28:39 | <Nopik> | newsham: maybe |
| 20:28:49 | <SamB> | newsham: what's a nicer way to do a cross product? |
| 20:28:49 | <ski> | loopCT :: (QuantifiableCollection f,Monad m) => f a -> Cont2T (f b) b m a -- this appears to have been my general looping construct |
| 20:29:15 | <Nopik> | newsham: so, how to iterate function over 2 dimensional array in 'haskel way'? |
| 20:29:35 | <SamB> | Nopik: the other way is list comprehensions, I guess... |
| 20:29:41 | <quicksilver> | Nopik: 2 dimensional array or 2d list? |
| 20:29:43 | <ski> | Haskell is the worlds finest imperative language ! |
| 20:29:43 | <newsham> | you could use sequence, as above |
| 20:29:46 | <Nopik> | SamB: i am using list comprehension now |
| 20:29:47 | <quicksilver> | Nopik: 2d list is just map.map |
| 20:29:52 | <quicksilver> | :t map.map |
| 20:29:54 | <lambdabot> | forall a b. (a -> b) -> [[a]] -> [[b]] |
| 20:30:00 | <newsham> | ski: so how come you have to manually select monads? |
| 20:30:09 | <newsham> | my other imperative languages pick my monads for me |
| 20:30:24 | <quicksilver> | no, your other imperative languages only have 1 monad |
| 20:30:24 | <Nopik> | yeah, i was considering map.map, though this way felt better for me ;p |
| 20:30:25 | <newsham> | no lifting |
| 20:30:27 | <SamB> | newsham: most languages have at most one usable monad |
| 20:30:30 | <quicksilver> | and they use that for everything |
| 20:30:38 | <ski> | newsham : yes, you can't decide yourself which monad you want .. e.g. a parsing monad |
| 20:30:38 | <quicksilver> | haskell lets you give more precise types to your functions/actions |
| 20:30:45 | <bulio|> | would haskell be advisable for a new programmer to learn? |
| 20:30:59 | <quicksilver> | so you can understand what kinds of computational effect they have |
| 20:30:59 | <ski> | bulio| : i believe so |
| 20:31:13 | <quicksilver> | bulio|: it's a controversial point, but I also think it is, like ski |
| 20:31:21 | <xsdnyd> | hi, how can i compute the number: 2^(1/3) in haskell? the ^ operator only allows integers as second parameter... :-\ |
| 20:31:33 | <quicksilver> | > 2 ** (1/3) |
| 20:31:34 | <lambdabot> | 1.2599210498948732 |
| 20:31:39 | <quicksilver> | xsdnyd: comme ca |
| 20:31:52 | <SamB> | bulio|: some are of the opinion that it might discourage further study (they say something like "who would want to learn another language after haskell?"). I don't see how it could work that way though ;-) |
| 20:31:59 | <newsham> | right, which is why when I want to add debugging printfs into my program in most imperative languages I don thave to reengineer my code. |
| 20:32:05 | <glguy> | xsdnyd: actually, the ^ operator only allows non-negative integrals :) |
| 20:32:05 | <xsdnyd> | quicksilver, i need the number as Rational |
| 20:32:09 | <newsham> | I love haskell, but I strongly disagree with "best imperative language" |
| 20:32:26 | <quicksilver> | xsdnyd: well, in the first place, cube roots aren't normally rational :) |
| 20:32:26 | <SamB> | newsham: Debug.Trace is your friend |
| 20:32:31 | <glguy> | xsdnyd: fractional exponents don't generate rationals :) |
| 20:32:31 | <Nopik> | bulio|: haskell is quite hard, and not directed toward newbie programmers |
| 20:32:33 | <newsham> | i know debug trace. |
| 20:32:38 | <newsham> | that was just one of many examples |
| 20:32:41 | <ihope> | Is sum strict? |
| 20:32:41 | <caust1c> | hi |
| 20:32:42 | <newsham> | debug.trace does not generalize |
| 20:32:46 | <ski> | (newsham : note btw that that above was a quote :) |
| 20:32:50 | <SamB> | newsham: so? |
| 20:32:53 | <xsdnyd> | glguy, yeah, i only want the third root of 2... |
| 20:32:56 | <EvilTerran> | ihope, could it not be strict? |
| 20:32:59 | <newsham> | what if I want to keep statistics in my code that wasnt designed to keep state? |
| 20:33:02 | <caust1c> | does ghc always produce C code from haskell code and compiles it? |
| 20:33:09 | <EvilTerran> | @src sum |
| 20:33:10 | <lambdabot> | sum = foldl (+) 0 |
| 20:33:11 | <newsham> | there's no "debug.trace" like thing for that |
| 20:33:12 | <SamB> | newsham: you should have newtyped your monad |
| 20:33:12 | <quicksilver> | xs xs |
| 20:33:18 | <opqdonut> | yep |
| 20:33:20 | <ihope> | foldl isn't strict, is it? |
| 20:33:22 | <glguy> | xsdnyd: that isn't a rational |
| 20:33:23 | <oerjan> | ihope: no |
| 20:33:30 | <opqdonut> | ihope: foldl' is |
| 20:33:31 | <ihope> | Why isn't it strict? |
| 20:33:35 | <newsham> | samb: i'm aware of how to do this. its just not a trivial modification. |
| 20:33:38 | <ihope> | sum, I mean. |
| 20:33:38 | <xsdnyd> | quicksilver, how do i calculate a cube root, even as float or double? |
| 20:33:40 | <quicksilver> | xsdnyd: syou can get an approximate answer, of course |
| 20:33:47 | <quicksilver> | xsdnyd: I just showed you |
| 20:33:48 | <quicksilver> | > 2 ** (1/3) |
| 20:33:50 | <lambdabot> | 1.2599210498948732 |
| 20:33:51 | <newsham> | where as coding imperative style in other languages makes this a trivial operation |
| 20:33:56 | <sjanssen> | ihope: I call it an oversight |
| 20:33:59 | <quicksilver> | if you want that as an approximation Rational, then: |
| 20:34:01 | <SamB> | newsham: or at least made a type synonym for it... |
| 20:34:02 | <newsham> | coding in an imperative style in haskell leaves something to be desired |
| 20:34:04 | <quicksilver> | > toRational (2 ** (1/3)) |
| 20:34:05 | <lambdabot> | 5674179970822795%4503599627370496 |
| 20:34:09 | <SamB> | hmm. |
| 20:34:11 | <SamB> | this is true. |
| 20:34:14 | <EvilTerran> | ihope, the foldl forces it to be a non-bottom list, and then the (+) forces each element to be a non-bottom number |
| 20:34:16 | <newsham> | (but it has other strengths that more than compensate) |
| 20:34:18 | <quicksilver> | but that's not very pretty |
| 20:34:32 | <SamB> | it does, indeed, leave something to be desired |
| 20:34:35 | <ski> | newsham : yes .. i agree some things could be better on that front |
| 20:34:48 | <SamB> | however I must point out that this does not mean that it is not the world's finest imperative language |
| 20:34:51 | <xsdnyd> | quicksilver, thanks that fit my needs :) |
| 20:34:55 | <MarcWeber> | Do you think the haskell community is interested in links such as www.noooxml.org ( open standards etc ) ? |
| 20:35:04 | <SamB> | ... it just means that there is probably room for improvement |
| 20:35:10 | <ihope> | Noooooxml? |
| 20:35:11 | <EvilTerran> | i imagine it's possible to write a Num instance in which (+) is non-strict in one argument, but it would not follow the laws of most numbers |
| 20:35:13 | <wli> | You can always represent elements of algebraic number fields by indices into roots of their minimal polynomials and linear combinations with rational coefficients thereof. |
| 20:35:32 | <ihope> | EvilTerran: easier to write one in which (*) is non-strict in one argument :-) |
| 20:35:43 | <ski> | > "N" ++ repeat 'o' ++ "xml" -- ? |
| 20:35:44 | <lambdabot> | "Noooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo... |
| 20:35:45 | <EvilTerran> | 0 * _ = 0 |
| 20:36:03 | <SamB> | EvilTerran: how about signed magnitude based on Nats? |
| 20:36:06 | <EvilTerran> | (Inf + _) = Inf ? =P |
| 20:36:32 | <wli> | Significant nonstrictness can occur in the case of multiplying sparse elements of GL_n(R) for various rings R. |
| 20:36:36 | <EvilTerran> | SamB, i don't know what you mean |
| 20:36:55 | <Nopik> | ok, next question.. i have setPixel :: Point -> Color -> Image -> IO() and getPixel :: Point -> Image -> IO Color now i want to copy pixel: setPixel (10,10) (getPixel (20, 20) image) image and it says that IO Color do not match Color... how to fix that? |
| 20:36:56 | <SamB> | data Nat = Zero | Succ Nat |
| 20:36:56 | <newsham> | sequence (do {x <- [0..w]; y <- [0..h]; setPixel x y red pic}) |
| 20:37:34 | <newsham> | sequence [setPixel x y red pic| x <- [0..w], y <- [0..h]] |
| 20:37:35 | <SamB> | data NatAndSign = Negative Nat | Positive Nat |
| 20:37:46 | <SamB> | well, obviously that leaves you with tow kinds of zero... |
| 20:37:51 | <Nopik> | @src sequence |
| 20:37:52 | <lambdabot> | sequence ms = foldr k (return []) ms |
| 20:37:52 | <lambdabot> | where |
| 20:37:52 | <lambdabot> | k m m' = do { x <- m; xs <- m'; return (x:xs) } |
| 20:37:53 | <quicksilver> | Nopik: setPixel (10,10) =<< getPixel (20,20) image |
| 20:38:07 | <SamB> | but if you don't make that observable you're fine |
| 20:38:08 | <ski> | Nopik : do color <- getPixel (20, 20) image; setPixel (10,10) color image |
| 20:38:12 | <opqdonut> | Nopik: getPixel (20,20) image >>= \x -> setPixel (10,10) x image |
| 20:38:14 | <quicksilver> | Nopik: because getPixel is monadic you have to 'bind' the value in place |
| 20:38:22 | <Nopik> | ok, thanks |
| 20:38:30 | <quicksilver> | ACTION thinks his answer is the prettiest |
| 20:38:36 | <quicksilver> | although perhaps the least easily generalised |
| 20:38:55 | <oerjan> | quicksilver: it is also wrong, alas |
| 20:38:56 | <Nopik> | quicksilver: i was just going to ask about >>= version :) |
| 20:39:03 | <quicksilver> | oerjan: is it? |
| 20:39:11 | <MarcWeber> | ihope, ski: This page reveals some bad things about the office open XML format which Microsoft wants to make an ISO standard. |
| 20:39:13 | <quicksilver> | :t (=<<) |
| 20:39:13 | <ski> | quicksilver : missing 'image' |
| 20:39:16 | <lambdabot> | forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> m a -> m b |
| 20:39:25 | <quicksilver> | ski: ah. good point |
| 20:39:27 | <quicksilver> | ACTION cries |
| 20:39:35 | <quicksilver> | beauty does not always prevail, alas :( |
| 20:39:35 | <EvilTerran> | SamB, data Nat = One | Succ Nat; data Int' = Negative Nat | Zero | Positive Nat --? |
| 20:40:04 | <ihope> | MarcWeber: well, if it's not Haskell-related... |
| 20:40:08 | <ski> | MarcWeber : ok (hm, i didn't know *Microsoft* wanted to make OpenOffice things standard ..) |
| 20:40:19 | <ihope> | Not to say that people who are interested in Haskell are interested only in Haskell. |
| 20:40:25 | <ski> | quicksilver : maybe with 'ReaderT' ? |
| 20:40:41 | <EvilTerran> | still, even with that aside, addition must surely be strict in both arguments for it to continue to be "addition" in any intuitive sense? |
| 20:40:49 | <wli> | EvilTerran: data PositiveNat = One } TwoN PositiveNat | TwoNPlusOne PositiveNat please. |
| 20:41:00 | <ski> | EvilTerran : why ? |
| 20:41:12 | <quicksilver> | ski: yeah, although I find readerT is only worth the effort in rather special circumstances |
| 20:41:19 | <EvilTerran> | well... because addition depends on both arguments... =/ |
| 20:41:32 | <ski> | quicksilver : .. yes |
| 20:41:32 | <quicksilver> | ski: because lifting all the non-readerT-parts is annoying... |
| 20:41:38 | <ski> | (indeed) |
| 20:41:40 | <SamB> | wli: isn't that significantly less lazy? |
| 20:41:43 | <MarcWeber> | ihope, ski You are propably right |
| 20:41:44 | <newsham> | zero not natural? |
| 20:42:01 | <EvilTerran> | addition on any field or vector space does, anyway, if i'm not completely confused. |
| 20:42:08 | <wli> | SamB: Not sure how so. |
| 20:42:09 | <SamB> | EvilTerran: but if you had fix (Succ) for the first argument... |
| 20:42:10 | <Nopik> | heh, the only good thing from exposing newbie programmer to haskell is that he will find all other languages very easy ;) |
| 20:42:20 | <Nopik> | very limited, too, perhaps ;p |
| 20:42:38 | <EvilTerran> | SamB, then how would you tell that this were the case without running forever? |
| 20:42:40 | <SamB> | but he will have a toolkit with which to design his own language... |
| 20:42:49 | <newsham> | nopik: depends. if you show newbie pure functional stuff (ie. two dozen short lessons in haskell), its all quite easy and makes more sense than most programming languages |
| 20:42:50 | <xsdnyd> | i get an "No instance for (Floating Rational)" error, when using this code: "target :: Rational -> Rational" and "target x = toRational (x ** (1/3))"... i don't know how to fix this :-\ may someone give me a hint? ;) |
| 20:42:53 | <SamB> | EvilTerran: you wouldn't. |
| 20:42:57 | <newsham> | its just all this wacky real-world stuff like doing IO :) |
| 20:42:59 | <ski> | Zero + y = y; Succ x + y = Succ (y + x) |
| 20:43:02 | <EvilTerran> | i mentioned Inf + _ = Inf earlier, anyway. |
| 20:43:04 | <quicksilver> | ski: I often think about the kind of implicit lifting you'd need to make ReaderT reduce noise rather than adding it |
| 20:43:06 | <SamB> | but you also would never notice if you tried to add it to _|_ |
| 20:43:17 | <quicksilver> | ski: but I can't think of anything sane |
| 20:43:20 | <EvilTerran> | ...because the answer would be _|_ |
| 20:43:26 | <SamB> | uh, no |
| 20:43:28 | <Nopik> | SamB: btw. any good example (tutorial-like) about writing own languages like this? i have seen few tutorials describe that this is possible, but none of them explained how ;P |
| 20:43:36 | <EvilTerran> | "const undefined" is strict, etc |
| 20:43:38 | <SamB> | because you'd never get to the _|_ |
| 20:43:38 | <wli> | EvilTerran: Direct sums of various sorts are partially lazy depending on how you represent them. |
| 20:43:47 | <newsham> | ?google two dozen haskell |
| 20:43:49 | <Nopik> | SamB: i suppose that monads do offer easy way to construct your own dsl.. |
| 20:43:50 | <lambdabot> | http://www.cs.ou.edu/cs1323h/textbook/haskell.shtml |
| 20:43:50 | <lambdabot> | Title: Two Dozen Short Lessons in Haskell |
| 20:44:06 | <ski> | @type (**) |
| 20:44:08 | <lambdabot> | forall a. (Floating a) => a -> a -> a |
| 20:44:14 | <SamB> | Nopik: we have parsers. we have algebraic datatypes. we have numerous language implementations to look at... |
| 20:44:18 | <EvilTerran> | ohhh, i see. (fix Succ) + undefined could still be (fix Succ), if addition were appropriately defined. |
| 20:44:19 | <EvilTerran> | i get it now. |
| 20:44:20 | <Heffalump> | does hsql have a darcs repo? |
| 20:44:23 | <wli> | EvilTerran: Sparse vectors, for instance, don't need to examine anything more than indices except where they collide in the elements being summed. |
| 20:44:26 | <newsham> | nopik: there's "build scheme in 48 hrs" |
| 20:44:27 | <EvilTerran> | **facepalm** |
| 20:44:43 | <Nopik> | yeah, but this is just a parser |
| 20:44:45 | <EvilTerran> | ACTION hides. |
| 20:44:46 | <Heffalump> | ah, google finds it, ask a silly question.. |
| 20:44:53 | <Nopik> | c++ also have parsers ;) |
| 20:45:01 | <SamB> | we have *nice* parsers |
| 20:45:10 | <Nopik> | ;) |
| 20:45:10 | <SamB> | and algebraic datatypes to use for the results |
| 20:45:15 | <ski> | xsdnyd : maybe .. s/x **/fromRational x **/ |
| 20:45:24 | <Nopik> | SamB: what is algebraic datatype? |
| 20:45:27 | <wli> | EvilTerran: Addition of things like power series is also necessarily lazy. |
| 20:45:31 | <ski> | @src Bool |
| 20:45:31 | <lambdabot> | data Bool = False | True deriving (Eq, Ord) |
| 20:45:36 | <ski> | @src Maybe |
| 20:45:36 | <lambdabot> | data Maybe a = Nothing | Just a |
| 20:45:38 | <ski> | @src [] |
| 20:45:38 | <lambdabot> | data [] a = [] | a : [a] |
| 20:45:45 | <SamB> | @src HsExpr |
| 20:45:46 | <lambdabot> | Source not found. This mission is too important for me to allow you to jeopardize it. |
| 20:45:46 | <newsham> | you can make nice ASTs with "data" |
| 20:45:52 | <SamB> | @hoogle HsExpr |
| 20:45:52 | <lambdabot> | No matches found |
| 20:45:54 | <Nopik> | newsham: ok |
| 20:45:55 | <SamB> | @hoogle Expr |
| 20:45:56 | <lambdabot> | Text.ParserCombinators.Parsec.Expr :: module |
| 20:45:56 | <lambdabot> | Text.ParserCombinators.Parsec.Expr.buildExpressionParser :: OperatorTable tok st a -> GenParser tok st a -> GenParser tok st a |
| 20:45:58 | <SamB> | aww. |
| 20:46:06 | <newsham> | blah, use a real parser generator. |
| 20:46:16 | <newsham> | ?where happy |
| 20:46:17 | <lambdabot> | http://www.haskell.org/happy/ |
| 20:46:20 | <EvilTerran> | wli, i have already acknowledged that i was talking rubbish. jeez. ;] |
| 20:46:28 | <SamB> | newsham: I was looking for an example of an AST :-( |
| 20:46:34 | <oerjan> | xsdnyd: http://en.wikipedia.org/wiki/Gelfond-Schneider_theorem |
| 20:46:36 | <_Nucleo> | > Nothing >>= (\ x -> if (x == 0) then fail "zero" else Just (x + 1) ) |
| 20:46:36 | <lambdabot> | Title: Gelfond–Schneider theorem - Wikipedia, the free encyclopedia |
| 20:46:37 | <lambdabot> | Nothing |
| 20:46:40 | <oerjan> | ;) |
| 20:46:57 | <oerjan> | (in other words, 2^(1/3) is _not_ rational) |
| 20:47:02 | <Nopik> | newsham: ok |
| 20:47:22 | <newsham> | data If = If Expr Stmt Stmt |
| 20:47:25 | <oerjan> | oh wait |
| 20:48:20 | <newsham> | data Expr = Plus Expr Expr | ... | Var String | Val Integer |
| 20:48:24 | <oerjan> | :t fromRational |
| 20:48:26 | <lambdabot> | forall a. (Fractional a) => Rational -> a |
| 20:48:31 | <ski> | data Expr = Var String | Lam String Expr | App Expr Expr |
| 20:48:44 | <oerjan> | xsdnyd: you need to use fromRational x |
| 20:49:29 | <xsdnyd> | oerjan, thanks that solved it!! |
| 20:49:46 | <wli> | data RadicalNumber = Sum [(Rational {- linear coefficient -}, Rational {- exponent it's raised to -}, RadicalNumber)] | JustRational Rational ? |
| 20:50:11 | <newsham> | stmt = If (Gte (Var "x") (Val 5)) (Print (Var x)) (Print (Val 2)) |
| 20:50:41 | <newsham> | (assuming Print is a Stmt) |
| 20:52:34 | <psi> | anyone got this on os x? /usr/bin/ld: can't locate framework for: -framework GMP |
| 20:52:44 | <psi> | i have it in ~/Library/Frameworks |
| 20:52:57 | <psi> | oh, when using ghc. |
| 20:54:47 | <Nopik> | newsham: nice |
| 20:54:59 | <psi> | ok, /Library/Frameworks worked. although the installation instruction said both would be ok... |
| 20:57:40 | <newsham> | nopik: as you can imagine, its really easy to build those up during parsing. |
| 20:58:03 | <newsham> | and with pattern matching, really easy to deconstruct and walk over the results |
| 20:58:29 | <newsham> | eval (Plus e1 e2) = eval e1 + eval e2 |
| 20:58:33 | <newsham> | eval (Val x) = x |
| 20:58:34 | <newsham> | etc.. |
| 20:59:09 | <_Sketch_> | Any recommended projects to learn haskell with? |
| 20:59:22 | <wli> | _Sketch: Write an interpreter. |
| 20:59:29 | <newsham> | sketch: the problems in two dozen short lessons? |
| 20:59:53 | <Nopik> | newsham: yeah, quite powerfull |
| 21:00:35 | <ski> | http://www.haskell.org/~pairwise/intro/intro.html -- might be useful if you know C |
| 21:00:35 | <lambdabot> | Title: Haskell for C Programmers |
| 21:00:47 | <shapr> | SamB: Want to be my facebook friend? What address are you using? |
| 21:00:47 | <Nopik> | _Sketch_: i have just gone through 2-3 tutorials, found them quite handy |
| 21:00:52 | <ski> | @where yaht |
| 21:00:52 | <lambdabot> | http://darcs.haskell.org/yaht/yaht.pdf |
| 21:00:56 | <kaol> | how do I output arbitrary debug output in the middle of code? (ie. I want to do some printf debugging) |
| 21:01:02 | <_Sketch_> | Wow, so much attention! :) Thank you all. |
| 21:01:08 | <Nopik> | _Sketch_: yaht and 'gentle introduction to haskell' (in that order) |
| 21:01:16 | <SamB> | shapr: naesten at gmail dot com |
| 21:01:18 | <ski> | _Sketch_ : yaht above people say is quite good |
| 21:01:35 | <_Sketch_> | ski: is there a non-PDF..? |
| 21:01:51 | <Nopik> | _Sketch_: and when you will stuck at monads, try reading 'you could have invented monads' tutorial ;) |
| 21:01:52 | <ski> | _Sketch_ : i'm not sure .. :/ |
| 21:02:06 | <ski> | @google you could have invented monads |
| 21:02:06 | <newsham> | kaol: Debug.Trace |
| 21:02:08 | <lambdabot> | http://sigfpe.blogspot.com/2006/08/you-could-have-invented-monads-and.html |
| 21:02:08 | <lambdabot> | Title: A Neighborhood of Infinity: You Could Have Invented Monads! (And Maybe You Alrea ... |
| 21:02:35 | <ski> | ACTION thinks http://web.cecs.pdx.edu/~antoy/Courses/TPFLP/lectures/MONADS/Noel/research/monads.html is not so bad for monads, either |
| 21:02:37 | <lambdabot> | Title: Online Tutorial: What the hell are Monads?, http://tinyurl.com/n8bqd |
| 21:03:06 | <ski> | _Sketch_ : but one thing at a time ! monads *after* handling the basics |
| 21:03:59 | <shapr> | Binkley: That was fast |
| 21:04:09 | <Binkley> | heh |
| 21:04:18 | <ski> | kaol : 'Debug.Trace.trace' ? |
| 21:06:51 | <wli> | pdx.edu? I live in pdx. |
| 21:06:56 | <jedai> | Could we use a "data" definition in GHCi |
| 21:07:08 | <jedai> | ?? |
| 21:07:11 | <shapr> | jedai: hs-plugins? |
| 21:07:13 | <Binkley> | wli: are you looking for an ICFP contest team, by chance? :-) |
| 21:07:41 | <jedai> | shapr: You mean there's no way actually but it could be added ? |
| 21:08:10 | <newsham> | jedai: :load ? :) |
| 21:08:11 | <wli> | Binkley: No, I'm not likely to participate. I'm also not all that good a programmer. |
| 21:08:17 | <shapr> | wli: I disagree. |
| 21:08:36 | <newsham> | shapr: what's your team? |
| 21:08:37 | <SamB> | wli: do you by any chance mean that *fast* a programmer? |
| 21:08:48 | <glguy> | is a + in a URI always a space? or only after the '?' ? |
| 21:08:53 | <shapr> | ICFP is next weekend, right? |
| 21:08:59 | <SamB> | shapr: indeed |
| 21:09:03 | <jedai> | newsham: Of course, but I'm searching for a way to define it directly in GHCi |
| 21:09:06 | <newsham> | http://www.kingsrook.com/icfp/countdown.html |
| 21:09:37 | <Heffalump> | ACTION has no time for the contest :-( |
| 21:09:55 | <wli> | SamB: No. As in capable of putting together larger programs, working with other people's code, code review, finding bugs, etc. Just shitting out code is not very meaningful. |
| 21:09:58 | <shapr> | I've sacrificed my ICFP weekend to spend time with my Swedish girlfriend. I won't get to spend more than a few days with her for the next six months. |
| 21:10:05 | <jedai> | newsham: It's not really a preoccupation for me (I use haskell-mode in emacs), but some have others idea |
| 21:10:09 | <SamB> | wli: ah. |
| 21:10:24 | <SamB> | wli: how do you even know this is going to be a "larger programs" contest" |
| 21:10:27 | <SamB> | s/"// |
| 21:10:32 | <SamB> | last one wasn't really |
| 21:10:47 | <shapr> | wli: If I were part of a team, I'd gladly invite you :-) |
| 21:10:55 | <shapr> | newsham: What team are you on? |
| 21:10:58 | <wli> | SamB: That aspect of being a good programmer isn't necessarily pertinent to ICFP. The others are more so. |
| 21:11:05 | <Nafai> | When is the ICFP contest? |
| 21:11:09 | <shapr> | Nafai: Upcoming weekend. |
| 21:11:14 | <Nafai> | Ah |
| 21:11:51 | <SamB> | wli: perhaps you should join my team? |
| 21:12:07 | <SamB> | ACTION is thinking of trying to attack the contest problem after the contest is ofver |
| 21:12:09 | <newsham> | shapr: flying solo (unless some of my friends decide to help out) |
| 21:12:10 | <wli> | SamB: I don't think it's a good idea. |
| 21:12:19 | <newsham> | also gotta help someone move half of saturday,s o i my not complete |
| 21:12:29 | <Nopik> | lets assume that there is image, and you have getPixel :: Point -> Image -> IO Color is it possible to write findPixel :: Color -> Point without any IO infection? |
| 21:12:33 | <wli> | newsham: Is what you're doing an interpreter assignment somewhere? |
| 21:12:53 | <newsham> | wli: no, talking with nopik about ASTs in haskell |
| 21:13:01 | <scsibug> | Nopik: did you ever implement getPixel for GD? |
| 21:13:04 | <Nafai> | wli: Why isn't it a good idea to try it later? |
| 21:13:10 | <Nopik> | scsibug: yeah, it was straightforward |
| 21:13:20 | <SamB> | wli: with what I just /me'd in mind, do you still think it sounds like a bad idea? |
| 21:13:38 | <Nopik> | scsibug: just copy/paste from setPixel and slightly modify argument list |
| 21:13:45 | <scsibug> | Nopik: make sure you darcs send your changes to bringert |
| 21:14:01 | <wli> | SamB: My day job is demanding enough I can't really focus on anything, though right now I'm just letting compiles spin. |
| 21:14:05 | <Nopik> | scsibug: i would need to setup darcs first ;p |
| 21:14:24 | <wli> | SamB: (and, of course, partially blowing things off) |
| 21:14:29 | <SamB> | last contest I think I had my UM working maybe an hour after the contest was over (I started beforre it was ove ;-) |
| 21:14:37 | <scsibug> | Nopik: just sending a simple patch would probably be fine |
| 21:14:45 | <Nopik> | scsibug: yeah, i think so |
| 21:15:05 | <Nopik> | scsibug: going back to my problem.. do i need to infect all my functions with IO? |
| 21:15:31 | <scsibug> | Nopik: not sure what your problem was (just got back from work), but if you are talking about GD, then yes, most likely |
| 21:15:36 | <ski> | Nopik : what should 'findPixel :: Color -> Point' do ? |
| 21:15:45 | <scsibug> | anything that directly messes with images |
| 21:16:19 | <SamB> | scsibug: so why would anyone want ot use GD then?? |
| 21:16:27 | <Nopik> | ski: just find any pixel with given color and return its position (ok, Maybe Point as return could do) |
| 21:16:51 | <ski> | Nopik : any pixel in which image ? |
| 21:16:56 | <Nopik> | ski: actually it doesnt matter, i was just asking if i can get rid of IO in function |
| 21:17:06 | <Nopik> | ski: of given color, if such exists |
| 21:17:21 | <ski> | (sorry .. in *which*image* ?) |
| 21:17:39 | <Nopik> | ah, findPixel :: Color -> Image -> Maybe Point |
| 21:17:56 | <Nopik> | ski: though it is not related to my question :D |
| 21:18:00 | <SamB> | Nopik: wouldn't it be far cleaner to just return an Image Bool? |
| 21:18:10 | <scsibug> | SamB: I'm not sure what you mean... |
| 21:18:13 | <Nopik> | Image Bool ? |
| 21:18:13 | <msouth> | _Sketch_: didn't see if anyone got you this: http://en.wikibooks.org/wiki/Haskell/YAHT |
| 21:18:13 | <ski> | Nopik : ok .. well, in case the underlying image referred to by 'Image' is immutable, then yes, otherwise no. i think |
| 21:18:15 | <lambdabot> | Title: Haskell/YAHT - Wikibooks, collection of open-content textbooks |
| 21:18:46 | <Nopik> | ski: i just want to read image, do not need to mutate it |
| 21:19:06 | <ski> | Nopik : ok, if you never mutate the image, then it should be ok |
| 21:19:32 | <SamB> | ACTION is making things up |
| 21:20:20 | <scsibug> | ACTION is a bit lost too... Nopik, is there a specific question you had that you could repeat? |
| 21:20:52 | <Nopik> | scsibug: yeah.. i was just asking if i can write functions operating on plain Color instead of IO Color |
| 21:21:04 | <Nopik> | which probably is true as i can always lift those |
| 21:21:09 | <scsibug> | indeed |
| 21:21:24 | <scsibug> | I've got functions in my fractal program which work on Color types |
| 21:21:39 | <Nopik> | hm, let me see |
| 21:22:06 | <scsibug> | http://scsibug.com/fractal-hs/burning_ship.hs |
| 21:22:19 | <scsibug> | there are a couple pure functions in there involving color |
| 21:24:18 | <Nopik> | scsibug: though most probably drawPlot accepts plain Color and draws it |
| 21:24:55 | <scsibug> | drawPlot takes a function mapping coordinates to colors (which is pure) |
| 21:25:18 | <Nopik> | scsibug: yeah, though this is simpler case than mine |
| 21:25:18 | <scsibug> | so drawPlot does handle all the nasty IO interaction with GD |
| 21:25:47 | <Nopik> | anyway i'll try do my way, at the worst i will have just more questions :) |
| 21:26:03 | <Nopik> | though most likely i will do it tomorrow - as it is time to sleep for me ;p |
| 21:26:11 | <scsibug> | ok, take care, and good luck |
| 21:26:31 | <Souwh> | Hello |
| 21:26:40 | <scsibug> | howdy |
| 21:26:42 | <shapr> | hi Souwh |
| 21:28:37 | <hpaste> | ski pasted "not safe for program" at http://hpaste.org/1719 |
| 21:28:53 | <ski> | Nopik : ^ |
| 21:31:19 | <shapr> | Souwh: Written any Haskell code lately? |
| 21:32:48 | <scsibug> | has anyone successfully gotten wxWidgets/wxHaskell working on OS X lately? |
| 21:33:43 | <scsibug> | I can get everything to compile, but I get unresolved symbols when I actually try to run a program :( |
| 21:39:14 | <_Nucleo> | did the old wiki just disappear? |
| 21:42:36 | <monochrom> | The old wiki cannot disappear yet. But it's no longer updated. |
| 21:42:55 | <Figs> | hi |
| 21:43:12 | <_Nucleo> | for some reason I get 404s, e.g. here: http://haskell.org/hawiki/TailRecursive |
| 21:43:45 | <SamB> | if i has disappered, some mainmiogns are in order |
| 21:43:50 | <SamB> | s/i/it/ |
| 21:44:01 | <Figs> | does anyone understand left-recursion well? |
| 21:45:02 | <shapr> | Looks like someone got rid of the old hawiki entirely. |
| 21:45:08 | <shapr> | "The requested URL /hawiki/ was not found on this server." |
| 21:45:13 | <_Nucleo> | yeah, that's not good. |
| 21:45:16 | <SamB> | maimings! |
| 21:45:43 | <shapr> | kolmodin: I'm confused about this whole "you have been a member of haskell since year X" bit on Facebook. |
| 21:45:46 | <monochrom> | Hrm! All of hawiki has 404ed! |
| 21:45:46 | <SamB> | unless it was an accident |
| 21:45:50 | <Igloo> | We had 2 people getting confused by old, incorrect info on old pages in 2 days, so I removed the alias |
| 21:45:56 | <Figs> | ACTION takes that as a 'not at the moment.' |
| 21:46:02 | <SamB> | Igloo: "alias"? |
| 21:46:04 | <Figs> | ok, bbl |
| 21:46:14 | <Vulpyne> | figs: I'd go ahead and ask the question if I were you. |
| 21:46:19 | <Igloo> | Alias /hawiki /mumble/moinmoin.cgi |
| 21:46:21 | <Figs> | it's kind of OT |
| 21:46:22 | <_Nucleo> | mm, sure hope it's coming back |
| 21:46:33 | <Vulpyne> | Ah. |
| 21:46:33 | <Figs> | or I should say "really" OT :) |
| 21:47:04 | <monochrom> | http://www.haskell.org/mumble/moinmoin.cgi still doesn't work |
| 21:47:16 | <SamB> | Igloo: so we can find it at www.haskell.org/mumble/moinmoin.cgi?TailRecursive ? |
| 21:47:38 | <Figs> | basically, I'm working on a C++ parser library, and when I came to get feedback from people here yesterday (since you guys usually have a different perspective on things) ddarius, I think it was, pointed out that since I'm using recursive descent, left-recursion will fail. |
| 21:47:56 | <Igloo> | No, "mumble" just means I can't remember what it was. But the old wiki was dead anyway. It was announced that it would be removed ages ago |
| 21:47:57 | <SamB> | Igloo: I think you should place a script there that will redirect people after subjecting them to a blinking disclaimer |
| 21:48:18 | <SamB> | Igloo: and we still haven't managed to copy much over... |
| 21:48:32 | <SamB> | largely because of license issues, afaik |
| 21:48:37 | <Igloo> | http://groups.google.com/group/fa.haskell/browse_thread/thread/94212312bd35555d |
| 21:48:38 | <lambdabot> | Title: HaWiki closing in one month; migrate content to HaskellWiki now! - fa.haskell | ..., http://tinyurl.com/2nx5sw |
| 21:48:47 | <CosmicRay> | gtk2hs is so awesome. this is the first time I've ever enjoyed gui programming. |
| 21:48:50 | <Igloo> | If you haven't managed by now, you probably never would have done |
| 21:48:51 | <Vulpyne> | Figs: I'm not smart enough to help you, unfortunately. |
| 21:48:59 | <Figs> | Ah :( |
| 21:49:12 | <CosmicRay> | http://hg.complete.org/gtkrsync/raw-file/44d245cdab4d/screenshot2.png |
| 21:49:12 | <_Nucleo> | So that content is gone, then. |
| 21:49:14 | <lambdabot> | http://tinyurl.com/35y6rg |
| 21:49:18 | <Cale> | http://en.wikipedia.org/wiki/Left_recursion |
| 21:49:19 | <lambdabot> | Title: Left recursion - Wikipedia, the free encyclopedia |
| 21:49:25 | <Figs> | I've read it cale :) |
| 21:49:36 | <kolmodin> | shapr: in the haskell group? |
| 21:49:43 | <kolmodin> | or what I said? |
| 21:50:11 | <Figs> | but it doesn't help me much thinking about Z = A >> ( opt(by_ref(Z)) >> B) >> C unfortunately |
| 21:50:27 | <Figs> | or I should say opt(by_ref(Z)) << B |
| 21:50:41 | <shapr> | kolmodin: Your response said "member of haskell community since 2005" and I can't tell whether that applies to me, you, or both. |
| 21:51:01 | <Figs> | Z = A >> (opt(by_ref(Z)) << B) >> C |
| 21:51:03 | <Figs> | that's what I meant |
| 21:51:16 | <monochrom> | Eh? What's wrong with Z = A >> ( opt(by_ref(Z)) >> B) >> C? |
| 21:51:28 | <Figs> | I'm talking about left recursion |
| 21:51:32 | <SamB> | I found some interesting informmation on the old wiki just the other day... |
| 21:51:37 | <monochrom> | That is not left recursion. |
| 21:51:41 | <kolmodin> | it's where we met. or at least that's how I interpret how it works |
| 21:51:46 | <Figs> | A (Z b) c |
| 21:51:50 | <shapr> | kolmodin: Ok, works for me. |
| 21:51:53 | <Cale> | Could be if A is nullable |
| 21:51:54 | <_Nucleo> | SamB: I'll mostly miss the quotes page ;) |
| 21:51:57 | <Figs> | a (a Z b c) b c |
| 21:52:05 | <kolmodin> | shapr: it was actually you who introduced me to this channel :D |
| 21:52:13 | <Figs> | aa(a Z bc)bc |
| 21:52:22 | <kolmodin> | shapr: a little more than two years ago... |
| 21:52:37 | <Cale> | Figs: that's okay, so long as A doesn't match the empty string |
| 21:52:49 | <kolmodin> | when waern and me and others where working on haste |
| 21:52:56 | <kolmodin> | hi waern :D |
| 21:53:03 | <Figs> | well, even supposing that A did match it, |
| 21:53:12 | <Figs> | the opt() would ensure it terminates |
| 21:53:18 | <monochrom> | The input string to parse cannot contain infinitely many 'a's |
| 21:53:20 | <shapr> | kolmodin: Wow, cool! |
| 21:53:31 | <waern> | kolmodin: hi there |
| 21:53:34 | <Figs> | exactly |
| 21:53:42 | <Figs> | so as long as it has |
| 21:53:56 | <Figs> | bcbcbcbcbc... for a finite number |
| 21:53:57 | <monochrom> | The recursion is no deeper than the number of 'a's present at the beginning of the input string. |
| 21:54:08 | <Figs> | it should still match regardless of whether A is "" or not |
| 21:54:10 | <kolmodin> | shapr: you asked what I was doing, more or less. I told you guys about haste and there was great excitement :D |
| 21:54:42 | <Cale> | Figs: I generally think it's okay to make people rewrite grammars so they're not left-recursive. |
| 21:55:03 | <Cale> | Though you can provide tools to help with that. |
| 21:55:08 | <Figs> | how to deal with the left-associativity issue? |
| 21:55:45 | <waern> | kolmodin: how's code? |
| 21:56:11 | <SamB> | Igloo: a lot of good it does to declare our posts to the old wiki SPL'd if you take it down days later :-( |
| 21:56:32 | <kolmodin> | waern: not much haskell the past months I'm afraid :( |
| 21:57:06 | <kolmodin> | waern: much more gentoo work. we have made yet a turn to get ghc 6.6 and 6.6.1 into the tree, yet a new master plan :D |
| 21:57:23 | <Cale> | For example, in parsec, there's a combinator called chainl such that (chainl p op x) parses zero or more occurrences of p, separated by op, returning a left associative application of all functions returned by op to the values returned by p (using x when there are zero occurrences of p) |
| 21:57:52 | <Cale> | (p and op are parsers) |
| 21:58:36 | <Cale> | So that helps eliminate left recursion whenever it would have come up. |
| 21:58:38 | <kolmodin> | shapr: hit the Friends link at the top. under details you will see: You have been members of Haskell Community since 2005. |
| 21:59:01 | <Cale> | http://legacy.cs.uu.nl/daan/download/parsec/parsec.html#chainl -- see the example here |
| 21:59:31 | <kolmodin> | waern: how about you? |
| 21:59:42 | <kolmodin> | code progressing? :) |
| 21:59:42 | <waern> | kolmodin: heh... will 6.8 take less time to package? :) |
| 21:59:51 | <kolmodin> | haha :D yes |
| 22:00:00 | <waern> | kolmodin: mostly exjobb |
| 22:00:00 | <kolmodin> | we will have fought the major fight by then :D |
| 22:00:10 | <Figs> | ok |
| 22:00:32 | <Figs> | it might just make more sense for me to write a special left parser |
| 22:00:36 | <kolmodin> | the "trouble" has been that ghc split out many libs into separate packages |
| 22:00:49 | <kolmodin> | and that we then decided to do a few more changes we have been thinking of |
| 22:01:01 | <kolmodin> | neither of us are working full time on this :) |
| 22:01:50 | <Cale> | Figs: Automatically rewriting parsers so that they avoid left-recursion takes quite a bit of introspection, and so it's only typically done by tools which generate parsers statically, if at all. |
| 22:02:15 | <Figs> | Cale, I can just do something like this: |
| 22:02:16 | <waern> | kolmodin: ok |
| 22:02:26 | <Figs> | foo >> left(A << B << C) >> X; |
| 22:02:49 | <kolmodin> | waern: so how is the exjobb progressing? haskell? |
| 22:03:08 | <waern> | kolmodin: ok I guess. haskell :) |
| 22:03:22 | <kolmodin> | aw maaaj gaaad! I wish I could have used haskell too :D |
| 22:03:44 | <Cale> | exjobb? |
| 22:03:46 | <waern> | well.. it's pretty boring anyway |
| 22:03:51 | <kolmodin> | exjobb = master thesis |
| 22:04:04 | <Cale> | ah |
| 22:04:06 | <Figs> | I think the left recursion object would be very slow though in my parser |
| 22:04:20 | <kolmodin> | waern: imagine boring master thesis + java. compare that to boring master thesis + haskell. make your choice! |
| 22:04:32 | <waern> | hehe |
| 22:04:39 | <kolmodin> | see? you have to put things in perspective :D |
| 22:07:47 | <Figs> | ok, well thanks |
| 22:07:51 | <Figs> | I'm going to go play with it for a while |
| 22:07:53 | <Figs> | bbl |
| 22:09:45 | <ddarius> | ACTION owns "Categories for the Working Mathematician" now. |
| 22:16:08 | <astrolabe> | I've got one too. I just need to read it. |
| 22:20:21 | <ddarius> | Oh, I'll read it. |
| 22:23:36 | <Binkley> | ?quote |
| 22:23:37 | <lambdabot> | ihope says: Laziness is free, but it doesn't always pay off. |
| 22:24:16 | <ihope> | Whoa, it's my quote! |
| 22:24:18 | <ihope> | :-P |
| 22:27:56 | <kjdf> | how does "newtype" differ from "data" declaration? |
| 22:31:12 | <EvilTerran> | kjdf, given "newtype Foo a = Foo a; data Bar a = Bar a", Foo undefined is indistinguishable from undefined, but Bar undefined can still match a pattern of the form "Bar x" |
| 22:31:32 | <EvilTerran> | you can only have one constructor of one argument on a newtype |
| 22:32:32 | <EvilTerran> | (these are both caused by "Foo a" being effectively just "a" at runtime) |
| 22:33:07 | <kjdf> | and Bar is wrapped around? |
| 22:33:16 | <Saizan> | also case undefined of Foo _ -> 0 == 0, case undefined of Bar _ -> 0 == undefined |
| 22:33:19 | <EvilTerran> | and GHC can derive anything for a newtype that's instantiated by the argument |
| 22:33:56 | <kjdf> | hm |
| 22:34:05 | <EvilTerran> | kjdf, yes, at runtime, "Bar x" would be stored differently from just "x" |
| 22:34:15 | <kjdf> | and what do you mean by derive? |
| 22:34:43 | <EvilTerran> | newtype MyInt = MyInt Int deriving (Eq, Ord, Integral, Num, Ix...) |
| 22:34:58 | <kjdf> | and with data it is not possible? |
| 22:35:24 | <EvilTerran> | you can't normally say "deriving Num" (for example), but GHC lets you in the case of a newtype |
| 22:35:35 | <EvilTerran> | you may need -fglasgow-exts for this, i forget. |
| 22:36:04 | <kjdf> | ok |
| 22:36:06 | <kjdf> | thanks |
| 22:36:14 | <EvilTerran> | np =) |
| 22:37:25 | <EvilTerran> | BTW, another way of thinking about my first point (and Saizan's point) is that a newtype constructor is strict in its argument |
| 22:37:30 | <EvilTerran> | i think |
| 22:42:22 | <sioraiocht> | is parsec a recursive descent parser? |
| 22:43:20 | <oerjan> | it can be used that way. |
| 22:44:06 | <oerjan> | but it can also do arbitrary backtracking |
| 22:45:47 | <SamB> | ACTION wonders about the utility of this "Poke her" link on his sister's facebook page. |
| 22:45:56 | <oerjan> | er, i'm not sure whether recursive descent includes that. but parsec parsers are generally written recursively. |
| 22:46:01 | <SamB> | ACTION thinks if he wanted to poke her... he would just poke her... |
| 22:47:18 | <oerjan> | SamB: one day, you will be on a different continent than her, and then that link will be very useful. |
| 22:47:22 | <monochrom> | More generally, you should wonder the utility of facebook altogether. But I digress. |
| 22:47:52 | <SamB> | monochrom: well you can get away with writing on the walls without getting in any trouble or having to clean it up |
| 22:47:55 | <Philippa> | oerjan: "recursive descent with backtracking" is sometimes considered to come under the general heading of "recursive descent" anyway |
| 22:48:17 | <oerjan> | Philippa: that was what i was wondering, thanks |
| 22:52:07 | <newsham> | poke her? sister? ewww. |
| 22:52:42 | <EvilTerran> | what's the matter, newsham? it's not your business if he happens to like nuns... |
| 22:53:01 | <newsham> | blue nuns of the revolution? |
| 22:54:39 | <EvilTerran> | ACTION tries to envisage "nun of revolution" as in "surface of revolution" |
| 23:02:47 | <SamB> | so... it looks like JHC is adopting PNG format for it's object files ;-) |
| 23:03:24 | <oerjan> | creative. |
| 23:03:46 | <SamB> | well, actually, *adapting* |
| 23:05:51 | <monochrom> | @quote undefined |
| 23:05:51 | <lambdabot> | No quotes match. It can only be attributed to human error. |
| 23:09:27 | <oerjan> | @quote undefined |
| 23:09:28 | <lambdabot> | No quotes match. I've seen penguins that can type better than that. |
| 23:10:14 | <oerjan> | @quote quotes.match |
| 23:10:14 | <lambdabot> | No quotes match. My pet ferret can type better than you! |
| 23:10:23 | <oerjan> | @quote quotes.match |
| 23:10:24 | <lambdabot> | No quotes match. That's something I cannot allow to happen. |
| 23:11:33 | <SamB> | apparantly John believes that such a format will lazy reading? |
| 23:11:36 | <SamB> | er. |
| 23:11:40 | <SamB> | insert "enable" |
| 23:14:27 | <oerjan> | persistent laziness? |
| 23:16:16 | <chessguy> | @undo do { b <- o; if b then (e x) else (e y) } |
| 23:16:16 | <lambdabot> | o >>= \ b -> if b then (e x) else (e y) |
| 23:16:44 | <chessguy> | @pl e x y = o >>= \ b -> if b then (e x) else (e y) |
| 23:16:44 | <lambdabot> | e = fix ((((o >>=) .) .) . (flip =<< (((.) . flip . flip if') .))) |
| 23:19:08 | <chessguy> | @pl f x n xs = take (n-1) xs ++ x ++ drop n xs |
| 23:19:09 | <lambdabot> | f = ap (ap . ((++) .) . take . subtract 1) . (. drop) . (.) . (++) |
| 23:29:27 | <msouth> | read "5" gives me an error in ghci |
| 23:29:38 | <msouth> | but read "5" + 3 works |
| 23:29:49 | <oerjan> | > read "5" |
| 23:29:51 | <lambdabot> | 5 |
| 23:29:52 | <msouth> | and lambdabot is happy with read "5" |
| 23:30:05 | <newsham> | > read "5" :: Int |
| 23:30:06 | <lambdabot> | 5 |
| 23:30:16 | <newsham> | try giving it a hint about what you want |
| 23:30:20 | <msouth> | that works |
| 23:30:20 | <Excedrin> | msouth: what error? (it's obv because you need to add a type annotation) |
| 23:30:22 | <oerjan> | msouth: there was someone today complaining that 6.7 defaults to () |
| 23:30:41 | <newsham> | ?type read |
| 23:30:43 | <lambdabot> | forall a. (Read a) => String -> a |
| 23:31:09 | <msouth> | so the + 3 hints that I want some kind of number |
| 23:31:12 | <newsham> | ?type read "5" |
| 23:31:14 | <lambdabot> | forall a. (Read a) => a |
| 23:31:35 | <newsham> | ?type read "5" + 3 |
| 23:31:37 | <lambdabot> | forall a. (Read a, Num a) => a |
| 23:31:38 | <Excedrin> | + 3 causes type inference to constrain the result of read to (Num a) |
| 23:32:08 | <oerjan> | which removes the possible () default option |
| 23:32:09 | <newsham> | > read "5" :: Char |
| 23:32:10 | <lambdabot> | Exception: Prelude.read: no parse |
| 23:32:55 | <oerjan> | msouth: try let x = read "5" and then :t x |
| 23:33:00 | <Excedrin> | > read "'5'" :: Char |
| 23:33:01 | <lambdabot> | '5' |
| 23:33:07 | <oerjan> | then you can see what type it defaults to |
| 23:33:31 | <msouth> | ambiguous |
| 23:33:35 | <msouth> | type variable |
| 23:33:37 | <msouth> | it says |
| 23:33:48 | <msouth> | at least it's consistent |
| 23:34:08 | <oerjan> | oh, so you are not getting a "no parse" error? |
| 23:34:44 | <msouth> | @paste Prelude> let x=read "5" |
| 23:34:44 | <msouth> | <interactive>:1:6: |
| 23:34:44 | <msouth> | Ambiguous type variable `a' in the constraint: |
| 23:34:44 | <msouth> | `Read a' arising from use of `read' at <interactive>:1:6-13 |
| 23:34:44 | <msouth> | Probable fix: add a type signature that fixes these type variable(s) |
| 23:34:45 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 23:34:47 | <msouth> | sorry |
| 23:35:33 | <hpaste> | msouth pasted "read "5" question" at http://hpaste.org/1720 |
| 23:35:34 | <Excedrin> | I'm not sure why you'd use let and then check the type.. |
| 23:35:38 | <oerjan> | sounds like you have _no_ defaulting |
| 23:35:44 | <Excedrin> | you can definitely use :t read "5" |
| 23:35:51 | <Excedrin> | or just :t read |
| 23:35:57 | <msouth> | yes |
| 23:36:15 | <oerjan> | Excedrin: i thought that would not give the defaulting result |
| 23:37:19 | <msouth> | is it better for me to run with -fglasgow-exts |
| 23:37:20 | <msouth> | ? |
| 23:37:40 | <oerjan> | msouth: what ghci version? |
| 23:38:02 | <msouth> | GHC Interactive, version 6.6, for Haskell 98. |
| 23:38:13 | <msouth> | I'm on os x if that matters |
| 23:38:14 | <Excedrin> | if you need exts :) |
| 23:38:40 | <oerjan> | i'm not knowledgable enough for that :| |
| 23:38:49 | <msouth> | well, I'm just wondering because the type stuff comes out differently |
| 23:38:59 | <msouth> | like is it better for me to be used to that forall a. stuff. |
| 23:39:17 | <msouth> | my understanding is still pretty limited as I just started this a couple of days ago. |
| 23:39:18 | <oerjan> | the type stuff might be without applying the monomorphism restriction and defaults |
| 23:39:52 | <oerjan> | however, it _should_ default to Integer, and work, as far as i know |
| 23:40:37 | <Excedrin> | hmm, in what context does read default to Integer? |
| 23:41:18 | <Excedrin> | (or is that not what you meant...) |
| 23:41:24 | <oerjan> | Excedrin: when bound by a simple pattern binding, you get the m.r. and (Integer,Double) is the default defaulting |
| 23:42:26 | <shapr> | SamB: I wonder if facebook needs a #haskell group |
| 23:42:33 | <Binkley> | good idea |
| 23:44:01 | <Nafai> | I joined a Haskell group earlier |
| 23:44:11 | <Nafai> | But I would join a #haskell group |
| 23:44:28 | <Excedrin> | oerjan: I see, but that's for the default type of numbers, not related to read's type |
| 23:44:28 | <SamB> | ditto |
| 23:44:37 | <SamB> | where by "earlier", I mean "earlier today" |
| 23:44:37 | <oerjan> | oh right. |
| 23:44:53 | <oerjan> | ah, i forgot that. |
| 23:45:15 | <oerjan> | msouth: what you got is actually the "correct" behavior! |
| 23:45:20 | <SamB> | oerjan: however lambdabot uses stronger defaulting, I think it's the same rules as GHCi |
| 23:45:27 | <Nafai> | SamB: yes :) |
| 23:45:30 | <Binkley> | I created a #haskell group |
| 23:45:30 | <Excedrin> | and yes, "let x = 4" followed by ":t x" results in x::Integer |
| 23:45:33 | <Binkley> | join away :-) |
| 23:45:53 | <oerjan> | you may want to start with an option -fextended-defaulting-rules or something like that |
| 23:46:05 | <SamB> | man that was easy |
| 23:46:05 | <Excedrin> | can you change the default types in ghci interactively? |
| 23:46:10 | <SamB> | I didn't even have to search for it |
| 23:46:33 | <SamB> | *Science*? |
| 23:47:07 | <SamB> | wait, shapr just made one... |
| 23:47:10 | <oerjan> | i think there is a command to set flags. :f maybe? |
| 23:47:14 | <shapr> | SamB: And you already joined! |
| 23:47:56 | <SamB> | yes. but where is binkley's? |
| 23:48:01 | <shapr> | I dunno |
| 23:48:06 | <Excedrin> | there's -<flags> but I'm not sure if there's a way to do: "default (Int,Float)" via a flag |
| 23:48:17 | <shapr> | Already joined |
| 23:48:23 | <Binkley> | I'll put a link to the other one in mine |
| 23:48:26 | <Binkley> | we don't need two :-) |
| 23:48:47 | <oerjan> | Excedrin: msouth's problem is not about that setting though |
| 23:48:54 | <SamB> | whoo |
| 23:48:57 | <SamB> | I'm an admin |
| 23:48:59 | <Excedrin> | I know, just curious about defaults in general |
| 23:49:30 | <Nafai> | Yay! |
| 23:50:27 | <oerjan> | i recall i saw just today something when browsing the manual about ghci not using the defaults from the module. |
| 23:50:28 | <SamB> | @tell sjanssen we just formed a #haskell group on facebook |
| 23:50:28 | <lambdabot> | Consider it noted. |
| 23:51:03 | <Binkley> | haha, I hadn't seen the photo of SPJ on a unicycle |
| 23:51:30 | <shapr> | ACTION grins |
| 23:51:34 | <shapr> | On *my* unicycle even! |
| 23:52:08 | <SamB> | who's that on the right? |
| 23:52:24 | <shapr> | dcoutts |
| 23:52:34 | <shapr> | The photo should have names. |
| 23:52:44 | <SamB> | yes! who will caption it? |
| 23:53:13 | <shapr> | Hm, I added names of the people, dunno why it doesn't show up. |
| 23:53:57 | <msouth> | so :t - read "5" has type (Num a, Read a) => a, that means....here's my guess--the thing in quotes must be something in the Num family of types and also in the Read family of types, and it's going to give me back one of those? |
| 23:54:17 | <msouth> | and it was because of the - that it added the Num on there? |
| 23:54:34 | <msouth> | you guys will kickban me if I ask too many annoying newbie questions, right? |
| 23:55:03 | <SamB> | oops. |
| 23:55:11 | <SamB> | now we have two sets of captions... |
| 23:55:17 | <Binkley> | silly facebook |
| 23:55:18 | <SamB> | but I put in the IRC nicks |
| 23:55:27 | <shapr> | msouth: Nah, we'll just promote you. |
| 23:55:28 | <Botje> | msouth: you are correct, and no, you won't get kicked. ask away :) |
| 23:55:50 | <shapr> | msouth: Once we've answered enough of your questions, you get promoted to "able to answer questions for others." |
| 23:56:14 | <Binkley> | is that John Hughes in the other photo? |
| 23:56:21 | <monochrom> | read "5" alone has type (Read a) => a. If you also have Num it is due to other context. |
| 23:56:23 | <msouth> | first I'll be promoted to "thinks he knows the answers and gets them almost right then has to be corrected" |
| 23:56:29 | <shapr> | Binkley: Yup |
| 23:56:56 | <monochrom> | @type read |
| 23:56:59 | <lambdabot> | forall a. (Read a) => String -> a |
| 23:59:08 | <shapr> | edwinb: Mind if I steal and republish some of your photos? |
| 23:59:24 | <edwinb> | ACTION spots photos of unicyclists |
| 23:59:34 | <edwinb> | shapr: no problem, I was just digging out some to uplaod ;) |
Back to channel and daily index: content-negotiated html turtle