Available formats: content-negotiated html turtle (see SIOC for the vocabulary)
Back to channel and daily index: content-negotiated html turtle
These logs are provided as an experiment in indexing discussions using IRCHub.py, Irc2RDF.hs, and SIOC.
| 00:00:05 | <Peaker> | vininim: well, stop that :) |
| 00:00:36 | <vininim> | but, most of the mutation is inside packedmatrix inplace mutation |
| 00:01:06 | <Peaker> | Haskell performance is indeed a "black art" -- it takes quite a while before understanding the various techniques required to get fast Haskell. So much so that I think I would downplay Haskell performance claims, as they are even misleading. Not "nearly as fast as C", but just "Much faster than Python/et al" |
| 00:01:31 | <Peaker> | it can be nearly as fast as C, for specific programs or if you are a black arts master |
| 00:01:45 | <Cale> | I don't know about it being a black art. |
| 00:02:04 | <aavogt> | doesn't writing the benchmark C take skill too? |
| 00:02:08 | <vininim> | I dont have goats :/ |
| 00:02:11 | <Cale> | It's just that lazy evaluation is sufficiently different to strict evaluation that your existing knowledge about how to make strict programs perform well doesn't apply. |
| 00:02:37 | <Cale> | So it's just something that you have to learn. |
| 00:04:51 | <Peaker> | Cale: C encourages programs that perform well by correlating pretty well programs that are fast with programs that are short/easy |
| 00:05:12 | <Cale> | Usually short programs are the fast ones in Haskell too. |
| 00:05:15 | <vininim> | well, even with the overhead it's way better than octave for what I'm doing. =P |
| 00:05:30 | <Peaker> | Cale: Knowing enough C to write correct programs and a bit of CS is enough to get fast-executing C. Knowing enough Haskell to write denotationally correct Haskell programs and a bit of CS is not enough to write fast-performing Haskell programs |
| 00:05:41 | <Cale> | I disagree on that first point. |
| 00:05:58 | <Peaker> | Cale: how come? |
| 00:05:59 | <Twey> | ACTION ponders the possibility of ever knowing enough C to write correct programs |
| 00:06:20 | <Cale> | Because I realise that it actually took me a long time to learn how to write good-performing imperative programs. |
| 00:06:28 | <Peaker> | Twey: if you use a subset of C in very strict ways -- its possible |
| 00:06:32 | <vininim> | it would be better if we just didn't get in the way of the compiler and enhance it =P |
| 00:06:42 | <Twey> | But not Turing-complete :-P |
| 00:06:50 | <Cale> | A number of years at least. |
| 00:06:55 | <Twey> | vininim: *nods* |
| 00:06:56 | <Peaker> | Cale: well, much of CS focuses on well-performing imperative algorithms -- so knowing some CS covers that.. |
| 00:07:00 | <A1kmm> | Hi, has anyone here managed to get ghc parallel Haskell to work for them and get a program to speed up? I have even tried writing a very simple, trivially parallelisable test program and parallel Haskell slows it down. |
| 00:07:15 | <Cale> | It took me about the same amount of time to learn how to write programs which perform well in Haskell. |
| 00:07:48 | <Cale> | A1kmm: I don't have a multiprocessor, but I can take a look and see if I can guess at why it's slower. |
| 00:07:57 | <vininim> | I hope it's less than 10 years (perfomance tunning 3 hours per day) |
| 00:08:02 | <Cale> | A1kmm: You might be creating too many sparks. |
| 00:08:03 | <Peaker> | Twey: well, the subset being used is indeed not turing complete most of the time. When you do recurse or loop over things that are difficult to show as simply finite, you are far more careful and use a different subset of C, could say a different language, that is turing complete |
| 00:08:10 | <A1kmm> | Cale: I started with: |
| 00:08:16 | <A1kmm> | import Numeric.GSL.Special.Psi (psi) |
| 00:08:18 | <A1kmm> | digammas = [1..100000000] |
| 00:08:19 | <A1kmm> | result = sum digammas |
| 00:08:21 | <A1kmm> | main = putStrLn $ ((showString "Result = ") . (shows result)) "" |
| 00:08:32 | <A1kmm> | changed this to: |
| 00:08:37 | <A1kmm> | import Numeric.GSL.Special.Psi (psi) |
| 00:08:39 | <A1kmm> | import Control.Parallel.Strategies |
| 00:08:40 | <A1kmm> | digammas = map psi [1..100000000] |
| 00:08:42 | <A1kmm> | result = sum (parBuffer 10000 rnf digammas) |
| 00:08:43 | <A1kmm> | main = putStrLn $ ((showString "Result = ") . (shows result)) "" |
| 00:08:54 | <Peaker> | Cale: what example of a badly performing C program do you mean? In Haskell, there are tons of ways to make a program perform badly, in C, I think there are less so - and the ones that do - are explicit (explicitly copying stuff shows to the programmer that its expensive) |
| 00:09:14 | <Peaker> | Cale: C has far more transparent operational semantics on imperative computers, much easier to grok what's cheap and what's expensive |
| 00:09:32 | <A1kmm> | and timings are: first program: 30.202s |
| 00:09:35 | <Cale> | Peaker: There are a lot of ways to choose the wrong datastructure or the wrong algorithm. |
| 00:09:37 | <newsham> | peaker: you know people who know enough C to write correct code? :) |
| 00:09:42 | <newsham> | please have them send resume! |
| 00:09:50 | <A1kmm> | second program without -threaded: 56.136s |
| 00:09:51 | <Twey> | ACTION laughs. |
| 00:09:54 | <Peaker> | Cale: that's CS more than C, though |
| 00:10:09 | <A1kmm> | second program with -threaded and -N1: 6m24.522s |
| 00:10:20 | <vininim> | woah |
| 00:10:23 | <Peaker> | newsham: You don't need to know "enough" C, you need to limit yourself to a strict subset of C and rigourously enforce it by conventions |
| 00:10:37 | <Cale> | Peaker: The choices we make about datastructures and algorithms have to be different according to the evaluation model. |
| 00:10:59 | <Peaker> | newsham: I've worked in a C shop where non-trivial modules were bug-less to the best of our knowledge, and we had far far more extensive testing than any other place I know |
| 00:11:17 | <Peaker> | newsham: and by "bugless" I mean - the very extensive testing found almost nothing to begin with |
| 00:11:22 | <Cale> | Peaker: I'm not really contrasting C and Haskell, I'm contrasting strict/imperative or strict/functional programming with lazy/functional. |
| 00:11:23 | <Peaker> | newsham: (after the code reviews) |
| 00:11:43 | <A1kmm> | Cale: with -N10 -g10 on a 22 CPU shared memory system: 7m50s |
| 00:11:47 | <newsham> | [14:05] < Peaker> Cale: Knowing enough C to write correct programs and a bit of CS is enough to get fast-executing C. |
| 00:12:16 | <Peaker> | Cale: the thing is - the lazy/functional model maps less directly to our current hardware - its less transparent what the costs of operations are |
| 00:12:24 | <Cale> | A1kmm: Why are you using parBuffer? |
| 00:12:51 | <Peaker> | Cale: so given today's Von neumann imperative computers -- there's a bias for strict/imperative in terms of transparent operational semantics |
| 00:13:01 | <newsham> | "reasoning about time and space of lazy programs is not always easy." |
| 00:13:03 | <A1kmm> | So the map is evaluated ahead in parallel - is there a better approach? |
| 00:13:04 | <Cale> | A1kmm: How about something like parListChunk ? |
| 00:13:26 | <newsham> | anyway, I just wanted to bring that somewhat interesting blog to channel's attention |
| 00:13:35 | <Peaker> | newsham: if we used total languages -- it could mean we switch to strict evaluation - and maybe that would make things easier |
| 00:13:49 | <Cale> | Peaker: But it's still not hard to have a good model in your head which approximates the actual behaviour. |
| 00:14:04 | <Cale> | Peaker: Graph reduction is a reasonably good mental model, to start with. |
| 00:14:53 | <A1kmm> | Cale: I'm trying to sum over a big list... I think that would force the whole list to be kept in memory. |
| 00:14:55 | <Peaker> | Cale: I find it really difficult to reason in my head about how graph reduction is going to behave in a large program. I only have 1 year of Haskell-toying experience, barely any real work, though |
| 00:16:03 | <Cale> | Peaker: Yeah, it takes some time before it really gets ingrained into the way you picture things. |
| 00:16:55 | <newsham> | peaker: you're implying that the only reason to use lazy evaluation is because it increased convergence |
| 00:17:01 | <newsham> | but do you really believe that? |
| 00:17:08 | <Cale> | A1kmm: hmm, I suppose that's true, the contents of that list actually probably can't all fit in memory at once. |
| 00:17:52 | <vininim> | How does one make cabal install profiling versions of a library? |
| 00:18:25 | <Peaker> | newsham: I think it increases code-reuse in some (relatively rare, possibly) cases |
| 00:18:43 | <Cale> | A1kmm: I imagine that the problem is that the work necessary to compute one element of the list is dwarfed by the scheduling cost of a spark. |
| 00:19:52 | <EvilTerran> | ACTION 's main reason for liking lazy evaluation is that infinite or partial data structures allow some very snazzy idioms |
| 00:20:08 | <newsham> | *shrug* theres lots of reasons why lazy evaluation is attractive... |
| 00:20:25 | <Peaker> | newsham: what are they? |
| 00:20:30 | <A1kmm> | Cale: I guess there is a need for somehow combining chunking with only working to a certain distance ahead |
| 00:20:45 | <EvilTerran> | i guess my reason follows from the increased convergence |
| 00:20:45 | <Peaker> | EvilTerran: I like most the (take k . sort) example |
| 00:20:47 | <newsham> | it provides a clean way to separate out parts of the code that are usually intertwined. |
| 00:21:12 | <newsham> | in some cases it offers increased performance |
| 00:21:38 | <EvilTerran> | maximising convergence of your evaluation strategy maximises the choice of correct, terminating code within a given syntax |
| 00:22:03 | <Peaker> | newsham: yeah, though maybe lazy shouldn't be a default, I'm not sure |
| 00:22:05 | <newsham> | et: peaker's argument that is if your languae is total, the convergence is the same |
| 00:22:09 | <EvilTerran> | so allowing as many "snazzy idioms" as possible |
| 00:22:16 | <newsham> | peaker: perhaps not.. I'm not gonna argue that because I dont know |
| 00:22:44 | <Cale> | Peaker: If lazy isn't default, then you tend to get libraries with lots of strict functions which are less composable. |
| 00:23:06 | <EvilTerran> | newsham, well, yeah... if my language is total, though, surely evaluation order is irrelevant to semantics |
| 00:23:06 | <Cale> | (That is, strict, even though it would not hurt for them to be lazy) |
| 00:24:18 | <newsham> | excellent troll, btw. ;-) |
| 00:24:24 | <Peaker> | Cale: Yeah, I guess lazy is the better default. The trade-off between composability and transparent operational semantics is problematic here. Maybe a smart code editor could make some of these operational semantics more apparent |
| 00:24:43 | <Peaker> | EvilTerran: still affects operational semantics, though |
| 00:25:14 | <Cale> | Peaker: Imagining that things are as composable in a lazy language as they are in a strict one is also probably one of the big things that leads to inefficient beginner imperative code (I'm willing to bet) |
| 00:25:19 | <EvilTerran> | i mean, any expression would be arbitrarily strict (in every situation it's passed a _|_, ie never, it returns a _|_), *and* arbitrarily non-strict (it never returns a _|_) |
| 00:25:19 | <Peaker> | I guess totality is a little over-rated, because a program that finishes after the universe dies is not that great |
| 00:25:22 | <Cale> | er |
| 00:25:32 | <Cale> | Swap strict and lazy in that sentence :) |
| 00:26:23 | <Peaker> | Cale: Yeah, my first thoughts when introduced to laziness idioms in Haskell were: "I sometimes did that in imperative languages when I didn't care about performance, now it performs well too, cool!" :) |
| 00:26:24 | <Cale> | Quite often, to get good performance out of strict code, you more or less have to tear library functions open and write them by hand. |
| 00:26:56 | <Cale> | Imperative programmers do this so often that they don't even see it anymore. |
| 00:27:17 | <shapr> | Yup |
| 00:27:44 | <Peaker> | Cale: yeah, every piece of code could be said to be parameterized over a variety of things (functionality, programming language, strictness, ...) and thus we have a huge cartesian product body of code, when often there is a lot of code for the same functionality (due to various parameters being changed). laziness eliminates one parameter from the cartesian product |
| 00:28:39 | <Peaker> | I think having explicit file access in addition to a volatile memory store, rather than just one big persistent single-level store adds another parameter to this cartesian product (programs that work well over files, vs ones that are optimized to work "in memory") |
| 00:29:08 | <shapr> | Personally, I think your point is strongly in favor of open source. |
| 00:29:16 | <shapr> | And in favor of small simple naive functions that are easy to understand. |
| 00:29:19 | <Peaker> | shapr: I agree |
| 00:29:40 | <shapr> | Because I believe that source code should be tuned for ease of tearing apart. |
| 00:29:57 | <shapr> | Thus, tuned for ease of understanding. |
| 00:30:06 | <Peaker> | shapr: yeah, naive functions, sophisticated optimizers |
| 00:30:12 | <shapr> | Exactly |
| 00:30:13 | <Cale> | shapr: But it's also something that we should avoid the necessity of doing, as much as possible. |
| 00:30:28 | <shapr> | I'm not convinced of that. |
| 00:30:40 | <Peaker> | even better to be able to use rewrite rules to explain how the naive version becomes the sophisticated one, rather than just write the sophisticated one |
| 00:31:14 | <Peaker> | shapr: if we can compose naive functions together, rather than duplicate them a bit differently, of course we should do that? |
| 00:31:15 | <Philippa> | rewrite rules are far from the best possible way to do that |
| 00:31:21 | <Philippa> | but yeah, they beat no tools at all |
| 00:31:23 | <shapr> | I think that change will always be necessary, so it's best to make changes easy, as long as ability to understanding does not decrease. |
| 00:31:30 | <Peaker> | Philippa: what are better ways to do that? |
| 00:31:44 | <Cale> | Complicated programs are only made possible by abstractions that work. Abstractions are not doing their job if you have to get the source code and copy paste (or worse yet, write over again), then modify things a bit to get decent performance in your individual case. |
| 00:32:03 | <Cale> | Higher order functions are one way to save a lot of trouble here, laziness goes a bit further. |
| 00:32:08 | <shapr> | Yeah |
| 00:32:08 | <Philippa> | Peaker: well, a best possible way would allow me to specify to do certain things in a given position, where they can't just be applied generally |
| 00:32:13 | <Peaker> | shapr: I think the software world should mainly focus on eliminating parameters from this horrible cartesian product. We now have so many in there. |
| 00:32:22 | <shapr> | I can see the point of avoiding the necessity of tearing things apart. |
| 00:32:36 | <Peaker> | Philippa: location-specific rewrite rules? |
| 00:32:43 | <shapr> | But on the other hand, you can't future proof code except by making it easy to understand and modify for future needs. |
| 00:33:01 | <Philippa> | it's also likely to be more capable of introspection than rewrite rules are |
| 00:33:09 | <shapr> | What if memristors or quantum computing completely changes the face of computing? |
| 00:33:26 | <Peaker> | Philippa: Runtime-applied rewrite rules? |
| 00:33:28 | <shapr> | One reason UNIX beat VMS was that UNIX was easy to understand and port. |
| 00:34:02 | <Cale> | A1kmm: what happens if you turn that parameter to parBuffer way way down, like to, say, your number of processors |
| 00:34:08 | <inimino> | I think editor support for rewriting will help |
| 00:34:18 | <A1kmm> | Cale: let me try that. |
| 00:34:41 | <Peaker> | shapr: I don't see how the face of computing can be changed so badly that even extremely declarative programs (e.g FRP ones) would be affected.. they seem to me to be completely implementation-agnostic |
| 00:34:47 | <Peaker> | inimino: yes! |
| 00:34:47 | <inimino> | if you can see the naive code, the rules that optimize it, and the optimized code, along with assurances that they all give the same result, that would be worth a lot |
| 00:35:01 | <shapr> | The extreme case of my point is that a language should not require libraries, you should be able to just make what you need without much trouble. |
| 00:35:02 | <Peaker> | inimino: I think that's another strong point for a smart code editor |
| 00:35:04 | <Cale> | A1kmm: at least then not as many sparks will be created |
| 00:35:15 | <Philippa> | Peaker: no. Look, it's a damn huge research space, stop trying to get me to commit to an answer. Yours aren't the best possible either |
| 00:35:15 | <shapr> | Peaker: Er, tried to build GHC on ARM? |
| 00:35:27 | <Cale> | A1kmm: but the scheduling costs still might be too high, so you might really have to chunk things first. |
| 00:35:47 | <Peaker> | Philippa: I was trying to get you to clarify what you meant by "capable of introspection" -- doesn't it imply they're applied at runtime? |
| 00:35:47 | <inimino> | Peaker: yes, me too. |
| 00:35:55 | <shapr> | g'day Pseudonym |
| 00:35:55 | <Philippa> | Peaker: no, it doesn't |
| 00:36:14 | <Philippa> | it just means that they can examine what they're looking at /including semantic properties determinable at compile-time/ |
| 00:36:15 | <Peaker> | Philippa: ah, so you mean the ability of the rewrite rule to dig deeper into the expressions? |
| 00:36:22 | <shapr> | Peaker: FRP programs may be implementation agnostic, but GHC is not. |
| 00:36:28 | <Philippa> | *argh* |
| 00:37:29 | <Peaker> | shapr: yeah, but if you eliminate all of the possible factors from the cartesian product, you may end up with a body of user-level software that should survive any computing implementation revolution -- the systems-software would have to change, of course |
| 00:37:32 | <vininim> | also, from the profiling info: not a good idea to use read inside a parser. |
| 00:37:48 | <Philippa> | Peaker: there is more to rewriting than syntax, FFS |
| 00:38:09 | <Philippa> | especially to rewriting /to achieve semantic aims/ |
| 00:38:48 | <Peaker> | Philippa: maybe you can work on your anger problem? Note I did just ask questions, not state any fact |
| 00:39:26 | <Cale> | I wonder if it would be reasonable to introduce a standard system for expressing rewrite rules in Haskell programs, that is, one which could have a hope of being compiler-independent. |
| 00:39:34 | <Philippa> | Peaker: not an appropriate response |
| 00:39:46 | <Cale> | I suppose that if you want it to interact with things like inlining, the answer is no. |
| 00:39:49 | <Peaker> | Philippa: Ok |
| 00:40:17 | <Peaker> | shapr: I think if you eliminate the stuff from the product, you end up with a very small body of software that can do everything most desktops are used for.. (e.g: The STEPS project to write a desktop from ground up in 20KLOC) |
| 00:40:52 | <shapr> | Of course, if that were true, perhaps microkernels would rule the world. |
| 00:41:07 | <Peaker> | Philippa: what kind of semantic properties can you get at compile-time? Type information? |
| 00:41:39 | <shapr> | I take the dominance of monolitich kernels (Linux) over microkernels (HURD) as a point in favor of Cale's side of the discussion. |
| 00:41:42 | <Philippa> | Peaker: that's a starting point, yes |
| 00:41:44 | <Peaker> | shapr: kernels are another unnecessary parameter in the cartesian product, IMO :) Code inside kernel very different to user-code, but that isn't necessarily so, if you just use language-level protections instead |
| 00:42:15 | <Philippa> | Peaker: congratulations, you just made the RTS the new kernel |
| 00:42:26 | <Peaker> | Philippa: indeed, and its a much smaller one. Drivers are just libraries |
| 00:42:31 | <Cale> | Yeah, I wonder why microkernels have failed. Has there ever been a microkernel which offered higher-order primitives? |
| 00:42:52 | <Peaker> | Philippa: lack of memory separation may have very desirable properties, decreasing unnecessary copying and cache flushes |
| 00:43:07 | <p_l> | Cale: Microkernels probably failed due to Mach :> |
| 00:43:07 | <shapr> | Peaker: I'd want to see a running example before I'd believe that. |
| 00:43:10 | <Philippa> | Peaker: you still need to write the RTS in something |
| 00:43:32 | <p_l> | Peaker: Bell Labs' Inferno, Microsoft's Singularity |
| 00:43:42 | <p_l> | damn, that was for shapr |
| 00:44:11 | <inimino> | microkernels probably failed because of Linux |
| 00:44:13 | <p_l> | shapr: those two use managed VM in place of normal memory separation |
| 00:44:17 | <Peaker> | Philippa: Some of the RTS may need to use a lower-level language, and some of the libraries that it uses would have to be duplicated for it - so I still have a parameter in the cartesian product, but hopefully it applies to much less code (only the generic libraries the RTS code uses have to be duplicated differently) |
| 00:45:00 | <p_l> | inimino: not really - there exist few successful micro/nanokernel systems, two of them having connection with Mach. Original Mach gave a very bad name to microkernels |
| 00:45:21 | <p_l> | and L4/Linux actually managed to beat linux in terms of performance on Arm |
| 00:45:43 | <inimino> | p_l: partly tongue-in-cheek |
| 00:46:00 | <inimino> | p_l: I think they failed by a historical accident, of which Linux is certainly a part... it's just too hard to turn everything on its head at this point |
| 00:46:09 | <p_l> | inimino: Mach truly sucked :P |
| 00:46:10 | <Peaker> | I think the correct transition to language-level protections, though, may be after we have dependent types |
| 00:46:43 | <inimino> | Peaker: so you're a fan of Oberon? |
| 00:46:50 | <Peaker> | inimino: what's that? |
| 00:46:58 | <p_l> | inimino: there are two (known to me), Mach-based systems that managed to get far enough. Both had decided to run their servers inside kernel mode, afaik |
| 00:47:43 | <inimino> | it's an OS written in Modula-3 IIRC |
| 00:47:51 | <p_l> | one was OSF/1, at least DEC's version. The other one is OS X |
| 00:47:56 | <p_l> | inimino: it's written in Oberon :) |
| 00:48:06 | <inimino> | oh, ok |
| 00:48:08 | <A1kmm> | cale: 7m34.100s with 10 processors, and a look-ahead of 10. |
| 00:48:10 | <sclv_> | I was about to say... |
| 00:48:15 | <Peaker> | inimino: sounds like it could be nice, but there are tons of things that need to be right as well |
| 00:48:15 | <inimino> | it's been a while since I read those papers, sorry ;-) |
| 00:48:24 | <p_l> | inimino: and for some reason doesn't have preemptive scheduler |
| 00:49:12 | <inimino> | well it was written in some ridiculously small number of lines of code |
| 00:50:33 | <sw17ch> | can some one tell me why these view patterns overlap? |
| 00:50:33 | <lambdabot> | sw17ch: You have 1 new message. '/msg lambdabot @messages' to read it. |
| 00:50:34 | <sw17ch> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5478#a5478 |
| 00:52:00 | <sw17ch> | it's my first foray into view patterns and i don't see why they overlap |
| 00:55:29 | <sw17ch> | ah: http://hackage.haskell.org/trac/ghc/ticket/2395 |
| 00:57:19 | <vininim> | um, (atto)parsec might not be the best choice for parsing |
| 00:57:42 | <vininim> | also, nifty parsecing: |
| 00:58:34 | <vininim> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5479#a5479 |
| 00:59:24 | <shapr> | Oberon is really nifty. |
| 01:01:28 | <mmorrow> | sw17ch! |
| 01:01:28 | <lambdabot> | mmorrow: You have 1 new message. '/msg lambdabot @messages' to read it. |
| 01:01:35 | <sw17ch> | mmorrow! |
| 01:01:43 | <mmorrow> | sw17ch: :) |
| 01:33:46 | <keseldude> | > let (+) x y = succ . sum $ [x,y] in 2 + 2 |
| 01:33:51 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 01:33:51 | <lambdabot> | mueval: ExitFailure 1 |
| 01:35:11 | <mmorrow> | > let (+) x y = succ . sum $ [x,y] in 2 + 2 |
| 01:35:14 | <lambdabot> | 5 |
| 01:35:19 | <mmorrow> | weird |
| 01:37:36 | <psygnisfive> | why weird? |
| 01:38:25 | <sm> | evening all |
| 01:38:43 | <mmorrow> | it failed for unknown reasons when keseldude tried |
| 01:38:50 | <mmorrow> | evening |
| 01:39:42 | <psygnisfive> | oh, so it did |
| 01:40:00 | <psygnisfive> | magic! |
| 01:40:54 | <aavogt> | quite the referentially transparent lambdabot |
| 01:43:20 | <jbauman> | > let (+) x y = succ . sum $ [x,y] in 2 + 2 |
| 01:43:23 | <lambdabot> | 5 |
| 01:43:41 | <vininim> | > let (+) x y = succ . sum $ [x,y] in 2 + 2 |
| 01:43:43 | <lambdabot> | 5 |
| 02:03:31 | <gwern> | aavogt: every evaluated expression in lambdabot is in a race condition |
| 02:03:47 | <gwern> | so it's not surprising that the same eval can have different results at different times |
| 02:05:12 | <Twey> | gwern: *wince* |
| 02:05:46 | <gwern> | in an irc channel of infallible angels, that needn't be the case. but alas, we are only men and mortals |
| 02:06:27 | <gwern> | (specifcally, the expressions are racing to be evaluated before either the watchdog thread or process kill mueval) |
| 02:06:56 | <kpreid> | and the watchdog says "no parse"? |
| 02:07:21 | <gwern> | the internals are a bit odd. I could see that being an error message |
| 02:17:15 | <aconbere> | anyone know anything about using edgeflags in hopengl? |
| 02:17:32 | <sclv_> | gwern: or before a netsplit hoses the reply :-) |
| 02:20:54 | <joaopizani> | Good evening everyone. I'd llike some advice on using the Data.Graph module |
| 02:21:23 | <joaopizani> | I've read the official haddock for the module, and haven't found a way to have a label on the graph's edges |
| 02:21:43 | <joaopizani> | Do you know of some way to label the edges of a Data.Graph? |
| 02:24:17 | <joaopizani> | I'm working on a project that involves the manipulation and visualization of finite automata, regular expressions and context-free grammars |
| 02:25:01 | <joaopizani> | My plan is to use the Haskell GraphViz binding for the visualization part, but the toGraphviz function requires a Data.Graph as input |
| 02:25:31 | <joaopizani> | and I want to have the input symbols displayed above the arrows |
| 02:33:02 | <aavogt> | > fix (+1) |
| 02:33:07 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 02:33:07 | <lambdabot> | mueval: ExitFailure 1 |
| 02:33:46 | <aavogt> | gwern: so it seems. I consider that a terrible error message |
| 02:34:06 | <gwern> | ACTION shrugs |
| 02:34:17 | <Gracenotes> | that usually means a stack overflow |
| 02:34:23 | <gwern> | mueval has bigger fish to fry; I'd like to run on windows, for example |
| 02:34:29 | <Gracenotes> | could also be an overflow issue |
| 02:34:40 | <Gracenotes> | like, as in heap |
| 02:35:07 | <gwern> | Gracenotes: as in, the expression has heap big problem? |
| 02:41:29 | <ctran> | how close can haskell get to C for this problem? http://www.codechef.com/problems/FCTRL/ |
| 02:43:29 | <ctran> | any help? |
| 02:43:33 | <dmwit> | ?tell joaopizani I don't know of a way to use Data.Graph for edge-labelled graphs, unfortunately. However, with the GraphViz module you can build the graph description yourself, in which case edge-labellings are Totally Plausible. |
| 02:43:33 | <lambdabot> | Consider it noted. |
| 02:43:48 | <dmwit> | Why would you want to be close to C? |
| 02:44:02 | <ctran> | just learning to write better haskell |
| 02:44:18 | <dmwit> | Good Haskell is not close to C; it's not even close to good C. |
| 02:44:44 | <monochrom> | What is "close"? |
| 02:44:49 | <ctran> | anything I can do to improve http://gist.github.com/121948 |
| 02:45:45 | <inimino> | why wouldn't you want to be close to C? |
| 02:45:48 | <ctran> | close in term of speed/efficiency |
| 02:45:52 | <inimino> | assuming he meant performance |
| 02:46:02 | <dmwit> | Oh, for performance. |
| 02:46:12 | <dmwit> | I thought he meant code that looked like C. |
| 02:46:17 | <ctran> | sorry i should have been more clearer |
| 02:46:58 | <MyCatVerbs> | You can write code that looks roughly like Pascal, without excessive difficulty. |
| 02:47:35 | <MyCatVerbs> | C is harder, because writing a DSL that gives you lvalues is awkward, but I think it's been done. Can't remember who did it, though. |
| 02:48:31 | <dmwit> | > iterate (`div` 5) 625 |
| 02:48:31 | <dibblego> | are ap and (<*>) for ((->) t) the same function with arguments flipped about? |
| 02:48:36 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 02:48:37 | <lambdabot> | mueval: ExitFailure 1 |
| 02:48:38 | <dibblego> | er, ep and (>>=) |
| 02:48:43 | <dibblego> | er, ap and (>>=) |
| 02:48:49 | <dmwit> | no parse? |
| 02:48:57 | <dmwit> | dibblego: ap and (>>=) are not the same |
| 02:48:58 | <Gracenotes> | ap is (=<<) . flip |
| 02:49:08 | <Gracenotes> | (=<<) is ap . flip |
| 02:49:09 | <dibblego> | not the same for the general case |
| 02:49:13 | <Gracenotes> | for (->) |
| 02:49:14 | <dmwit> | :t ap |
| 02:49:20 | <dibblego> | Gracenotes, just checking, thanks |
| 02:49:26 | <lambdabot> | forall (m :: * -> *) a b. (Monad m) => m (a -> b) -> m a -> m b |
| 02:50:10 | <dmwit> | ctran: You might like "iterate (`div` 5)". |
| 02:50:27 | <Gracenotes> | > ((,) =<< length) "hello" |
| 02:50:32 | <Gracenotes> | > ((,) <*> length) "hello" |
| 02:50:33 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 02:50:33 | <lambdabot> | mueval: ExitFailure 1 |
| 02:50:37 | <Gracenotes> | lols. |
| 02:50:38 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 02:50:38 | <lambdabot> | mueval: ExitFailure 1 |
| 02:50:59 | <Gracenotes> | (5,") |
| 02:51:06 | <dmwit> | ctran: print = putStrLn . show |
| 02:51:09 | <BMeph> | MyCatVerbs: Our resident maker-of-interpreters-of-other-lamguages, of course - augustss. :) |
| 02:51:12 | <Gracenotes> | ahem. (5, "hello") and ("hello", 5) |
| 02:51:30 | <MyCatVerbs> | BMeph: ah! I knew it was somebody who frequents here, but couldn't quite remember. Thank you. |
| 02:51:31 | <dmwit> | :t maybe (putStrLn "error") (print . fst) |
| 02:51:40 | <Gracenotes> | >:[ |
| 02:51:43 | <lambdabot> | forall a b. (Show a) => Maybe (a, b) -> IO () |
| 02:52:10 | <dmwit> | :t \fcntrl -> maybe (putStrLn "error") (print . fcntrl . fst) |
| 02:52:17 | <lambdabot> | forall c a b. (Show c) => (a -> c) -> Maybe (a, b) -> IO () |
| 02:52:41 | <dmwit> | ctran: You have way too much code. ;-) |
| 02:53:18 | <dmwit> | :t \f -> interact (unlines . f . lines) |
| 02:53:19 | <ctran> | dmwit: sorry :-) |
| 02:53:25 | <lambdabot> | ([String] -> [String]) -> IO () |
| 02:53:57 | <ctran> | dmwit: it will get shorter in a year, I hope |
| 02:54:02 | <dmwit> | :t \fcntrl -> interact (unlines . map (show . fcntrl . read) . lines) |
| 02:54:03 | <BMeph> | showIntAtBase 5, maybe? :) |
| 02:54:11 | <lambdabot> | forall b c. (Show c, Read b) => (b -> c) -> IO () |
| 02:56:52 | <dmwit> | ctran: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5480#a5480 |
| 02:57:13 | <dmwit> | Oops, didn't notice the "tail" right before C.lines in your paste. |
| 02:57:19 | <dmwit> | whatever |
| 02:57:35 | <ctran> | no problem |
| 02:57:56 | <dmwit> | It shouldn't be hard to adapt to ByteString if you actually find out that the IO is a performance bottleneck. |
| 02:58:23 | <ctran> | wow, your version is the exact reason I want to learn haskell |
| 02:58:57 | <centrinia> | > (\b x -> snd $ until ((==0) . fst) (\(a,b) -> id *** (:b) $ (a `divMod` b)) (x,[])) 10 12341 |
| 02:59:02 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 02:59:02 | <lambdabot> | mueval: ExitFailure 1 |
| 02:59:10 | <gwern> | hm, takeWhile >0 . drop 1 looks suspicious to me |
| 02:59:23 | <dmwit> | centrinia: \bot seems to have acid reflux for now |
| 02:59:32 | <dmwit> | gwern: Nonsense, they operate on two different ends of the list. |
| 02:59:58 | <dmwit> | gwern: The alternative is |
| 03:00:09 | <dmwit> | sum . takeWhile (>0) . iterate (`div` 5) . (`div` 5) |
| 03:00:13 | <dmwit> | which is even more suspicious. |
| 03:03:20 | <ctran> | dmwit: is there a function to turn Int -> ByteString ? |
| 03:03:36 | <dmwit> | oh, uh... dunno |
| 03:03:45 | <dmwit> | I'd be awful surprised if the answer was no. |
| 03:03:50 | <dmwit> | ?hoogle Int -> ByteString |
| 03:03:50 | <lambdabot> | Data.ByteString.Internal unsafeCreate :: Int -> (Ptr Word8 -> IO ()) -> ByteString |
| 03:03:50 | <lambdabot> | Data.ByteString replicate :: Int -> Word8 -> ByteString |
| 03:03:50 | <lambdabot> | Data.ByteString.Char8 replicate :: Int -> Char -> ByteString |
| 03:03:57 | <dmwit> | ?hoogle+ |
| 03:03:58 | <lambdabot> | Data.ByteString drop :: Int -> ByteString -> ByteString |
| 03:03:58 | <lambdabot> | Data.ByteString take :: Int -> ByteString -> ByteString |
| 03:03:58 | <lambdabot> | Data.ByteString.Char8 drop :: Int -> ByteString -> ByteString |
| 03:04:01 | <dmwit> | bleh |
| 03:04:45 | <dmwit> | I sure don't see one. |
| 03:05:07 | <dmwit> | pack . show ;-) |
| 03:07:57 | <mgsloan> | ?hoogle Integer -> ByteString |
| 03:07:58 | <lambdabot> | Data.ByteString unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString |
| 03:07:58 | <lambdabot> | Data.ByteString.Lazy unfoldr :: (a -> Maybe (Word8, a)) -> a -> ByteString |
| 03:07:58 | <lambdabot> | Data.ByteString.Char8 unfoldr :: (a -> Maybe (Char, a)) -> a -> ByteString |
| 03:08:10 | <mgsloan> | hrmm |
| 03:08:57 | <ctran> | thanks everyone, i have enough ideas to play with for now |
| 03:51:01 | <Reiv> | Hrm |
| 03:51:19 | <Reiv> | http://pastebin.com/dfd19651 - I've got brackets working. Now I need to get identifiers (variables) readable. |
| 03:51:27 | <Reiv> | My problem here is that they're fairly arbitary. :/ |
| 03:59:20 | <Reiv> | So I'm just a little unsure how to implement it... |
| 04:01:20 | <jaredj> | do { openTag "CHECKNUM"; TagText checkNumber <- anyToken; return checkNumber } |
| 04:01:27 | <jaredj> | is there a way to do that with >>=? |
| 04:01:39 | <jaredj> | (particularly: the pattern match) |
| 04:02:06 | <jaredj> | without a lambda? |
| 04:02:09 | <BMeph> | jaredj: "You're soaking in it." ;p |
| 04:03:27 | <Twey> | jaredj: If you create a deconstructing function, sure |
| 04:03:52 | <jaredj> | like \TagText x -> x |
| 04:04:03 | <Twey> | That's a lambda |
| 04:04:10 | <jaredj> | yes |
| 04:04:20 | <Twey> | openTag "CHECKNUM" >> anyToken >>= return . deTagText |
| 04:04:30 | <Twey> | where deTagText (TagText x) = x |
| 04:06:36 | <jaredj> | yes - i wasn't sure if you could get around making one of those |
| 04:06:57 | <jaredj> | i should have asked if there was a simpler way to do that do-construct |
| 04:07:25 | <jaredj> | BMeph: i had to everything2 your quote ;P |
| 04:15:37 | <MyCatVerbs> | comonad.com is edwardk, right? |
| 04:16:17 | <MyCatVerbs> | Oh right yes, he prints his name on the blog posts. Hah, I probably should not have missed that. :) |
| 04:17:31 | <Reiv> | Huh. |
| 04:17:41 | <Reiv> | Hi, MCV! |
| 04:18:07 | <MyCatVerbs> | Greetings, Reiver. Nice to see a few nightstar denizens around. |
| 04:18:20 | <Reiv> | Oh, aye. |
| 04:18:33 | <Reiv> | #Code is a wonderful resource, but sometimes you just can't beat the source. ;) |
| 04:18:51 | <MyCatVerbs> | I'm vaguely surprised that McMartin doesn't idle in here too. |
| 04:18:55 | <p_l> | ACTION looks outside, sees light |
| 04:19:18 | <copumpkin> | ACTION looks outside, sees darkness |
| 04:19:26 | <copumpkin> | can darkness be seen? |
| 04:19:35 | <p_l> | nope |
| 04:19:52 | <p_l> | well, not physically, I guess. Languages don't care |
| 04:20:41 | <monochrom> | can non-termination be observed? :) |
| 04:21:35 | <MyCatVerbs> | Reiv: I guess not. On the flip side, you get a lot more newbie questions in here, and answering those is pretty decent karma. :) |
| 04:21:37 | <psygnisfive> | monochrom: by a hyperturing machine, sure! |
| 04:21:50 | <monochrom> | hehe |
| 04:21:58 | <MyCatVerbs> | Can that machine's failure to terminate be observed? |
| 04:22:16 | <monochrom> | I wonder if darkness is analogous to non-termination. |
| 04:22:19 | <psygnisfive> | i dont know if hyperturing machines have those same constraints |
| 04:22:21 | <mmorrow_> | what's the definition of "observe" (in the CS sense)? |
| 04:22:27 | <psygnisfive> | monochrom: what? no. what? |
| 04:22:33 | <MyCatVerbs> | Actually, non-termination is easy. You know that scene with Arnold and the minigun, where he shoots up an entire parking lot and deliberately kills no-one? Yeah, that. |
| 04:22:46 | <monochrom> | hahahahaha |
| 04:22:57 | <psygnisfive> | how would darkness be analogous to non-termination? |
| 04:22:58 | <mmorrow_> | MyCatVerbs: but only TERMINATors can do that |
| 04:23:21 | <monochrom> | That's what "I wonder if" means. I don't know. |
| 04:23:30 | <MyCatVerbs> | mmorrow_: Oh, it's a bugger to pull off, sure. But watching it isn't challenging. |
| 04:23:36 | <psygnisfive> | .. no. its not analogous at all. |
| 04:23:40 | <hackagebot> | urlencoded 0.2.0.0 |
| 04:23:40 | <psygnisfive> | darkness is analogous to an empty list. |
| 04:23:47 | <mmorrow_> | ACTION googles the CS definition of "observe" |
| 04:23:48 | <psygnisfive> | or the emptiness of the list. |
| 04:23:55 | <monochrom> | Hey I can take advantage of people failing to read and succeeding in getting fully surprised! |
| 04:24:02 | <monochrom> | I wonder if P=NP. |
| 04:24:08 | <monochrom> | I wonder if P/=NP |
| 04:24:26 | <MyCatVerbs> | monochrom: I hope not, and I hope not, respectively. |
| 04:24:27 | <psygnisfive> | i suspect P=NP. |
| 04:24:43 | <monochrom> | I wonder if Haskell is untyped. |
| 04:24:52 | <psygnisfive> | well, actually, maybe not |
| 04:24:57 | <psygnisfive> | travelling salesman is i think NP |
| 04:25:11 | <psygnisfive> | and i dont think theres any conceivable deterministic way to computer travelling salesman |
| 04:25:12 | <MyCatVerbs> | On the one hand, P=NP breaks pretty much all reasonable crypto you could come up with. On the other hand, P/=NP means that lots of useful problems can't be completely solved. :/ |
| 04:25:15 | <psygnisfive> | but i could be wrong! |
| 04:25:18 | <mmorrow_> | so is (the general case of) graph coloring |
| 04:25:33 | <psygnisfive> | can someone explain the state monad to be? |
| 04:25:45 | <mmorrow_> | traveling salesman is one of the NP poster-boys |
| 04:25:47 | <dmwit> | Yes! |
| 04:25:48 | <psygnisfive> | i mean, i dont understand monads in general but thats ok |
| 04:25:54 | <dmwit> | ?go you could have invented monads |
| 04:25:56 | <lambdabot> | http://blog.sigfpe.com/2006/08/you-could-have-invented-monads-and.html |
| 04:25:56 | <lambdabot> | Title: A Neighborhood of Infinity: You Could Have Invented Monads! (And Maybe You Alrea ... |
| 04:26:03 | <dmwit> | also |
| 04:26:25 | <dmwit> | ?where all about monads |
| 04:26:26 | <lambdabot> | I know nothing about all. |
| 04:26:28 | <psygnisfive> | see, i figure that like |
| 04:26:30 | <dmwit> | http://www.haskell.org/all_about_monads/html/index.html |
| 04:26:41 | <psygnisfive> | you can sythesize state |
| 04:26:53 | <MyCatVerbs> | Isn't even 3-colouring NP-complete? |
| 04:27:00 | <monochrom> | Anyway, I use "observe" in the physics sense. I don't think there is a widely adopted CS sense. |
| 04:27:09 | <psygnisfive> | by passing around a hash of varname-varvalue pairs that gets mapped in each iteration |
| 04:27:12 | <psygnisfive> | you know what i mean? |
| 04:27:39 | <dmwit> | psygnisfive: Yep. The idea of the State monad is to pass those things for you. |
| 04:27:47 | <dmwit> | psygnisfive: Also, typically, instead of a hash, we use a record. |
| 04:27:52 | <mmorrow_> | hmm, it look like "observe" isn't formally defined (wrt CS), it's just in various "you know, like looking" ways (?) |
| 04:27:53 | <dmwit> | So no hashing, just access the data you want. |
| 04:27:55 | <psygnisfive> | well see dmwit, problem i see with that is that |
| 04:28:04 | <mmorrow_> | *it's just used in ... |
| 04:28:06 | <psygnisfive> | thats effectively precisely what reassignable variables are. |
| 04:28:14 | <dmwit> | mmorrow_: Well, there's barbs as in the pi-calculus. |
| 04:28:23 | <dmwit> | mmorrow_: And there's contextual equivalence for functional calculi. |
| 04:28:25 | <mmorrow_> | dmwit: what is that? |
| 04:28:35 | <psygnisfive> | actually, reassignable variables are also i guess like nested lets |
| 04:28:40 | <mmorrow_> | i'm looking for the definition of "observe" |
| 04:28:43 | <dmwit> | mmorrow_: A barb is a process offering to send on a named channel, where the name is free. |
| 04:28:46 | <psygnisfive> | or lambdas |
| 04:29:03 | <dmwit> | mmorrow_: So "observation" involves what channels with free names are offering to send. |
| 04:29:04 | <psygnisfive> | let x = 5 in (let x = x*x in x) |
| 04:29:13 | <mmorrow_> | i don't see how terms can be used without definitions, so i feel like it has to be defined somewhere |
| 04:29:16 | <psygnisfive> | i dont know if that precisely will work in haskell, but you can convert it down to lambdas and get the same |
| 04:29:32 | <dmwit> | mmorrow_: Similarly, for typed calculi, observation involves putting the thing you're observing into arbitrary contexts. |
| 04:29:44 | <dmwit> | mmorrow: Terms that converge or diverge together in all contexts are observationally equivalent. |
| 04:29:55 | <copumpkin> | psygnisfive: that's how people often implement tight loops |
| 04:30:01 | <psygnisfive> | tight loops? |
| 04:38:24 | <mmorrow> | dmwit: hmm |
| 04:38:24 | <mmorrow> | dmwit: so "observe" := ? |
| 04:38:24 | <mmorrow> | @wn observe |
| 04:38:24 | <mmorrow> | @wd observe |
| 04:38:24 | <mmorrow> | @w observe |
| 04:38:37 | <MyCatVerbs> | ray: n+k patterns are evil. :) |
| 04:38:37 | <timmaxw> | Why did "let 2+2=5" work? |
| 04:38:37 | <MyCatVerbs> | ray: and/or unclean. |
| 04:38:37 | <ray> | where's the n+k pattern |
| 04:38:37 | <copumpkin> | it redefined (+) |
| 04:38:37 | <ray> | STOP SPLITTING FREENODE |
| 04:38:38 | <copumpkin> | ugh |
| 04:38:38 | <monochrom> | It is non-exhaustive pattern, not n+k pattern. |
| 04:38:38 | <MyCatVerbs> | > do { a <- "aaa"; a <- ord a : []; return (a+1); } |
| 04:38:38 | <dmwit> | timmaxw: let (+) = \a b -> case (a, b) of (2, 2) -> 5 in 3 + 3 |
| 04:38:38 | <lambdabot> | [98,98,98] |
| 04:38:38 | <timmaxw> | yes, clever |
| 04:38:38 | <ray> | non-exhaustive doesn't seem like quite the right way to put it since it's in a let |
| 04:38:38 | <MyCatVerbs> | Hee. The old and new bindings don't even have to have the same type. |
| 04:38:38 | <psygnisfive> | ray: its not just freenode splitting, interestingly |
| 04:38:38 | <psygnisfive> | my chat clients are dying too |
| 04:38:40 | <dmwit> | ray: What does let have to do with it? |
| 04:38:49 | <dmwit> | > let 2+2 = 5; 3+3 = 7 in 3+3 |
| 04:38:53 | <timmaxw> | why are functional dependencies necessary in multiparameter type classes? |
| 04:38:55 | <lambdabot> | 7 |
| 04:39:01 | <ray> | that's what |
| 04:39:05 | <monochrom> | "let" doesn't change anything. |
| 04:39:07 | <dmwit> | timmaxw: They're not. |
| 04:39:27 | <dmwit> | timmaxw: They're useful because they help pin down instances for inference, but they're definitely not necessary. |
| 04:39:34 | <timmaxw> | so the "Mult" example with matrices and vectors that I see in every tutorial on them, doesn't actually need them? |
| 04:39:57 | <monochrom> | I mean, it's "let" and it's still non-exhaustive pattern. You could have defined your + with exhaustive patterns, under "let". |
| 04:40:00 | <dmwit> | No; with type-annotations sprinkled around, those same examples would work without the functional dependencies. |
| 04:40:01 | <mmorrow> | whoa, everyone just split, returned, and then 20 lines of conversation all appeared in one big scroll |
| 04:40:07 | <ray> | > let (+) = const in 2+2 |
| 04:40:10 | <psygnisfive> | ok i need to be off to do some coding. :P |
| 04:40:12 | <MyCatVerbs> | timmaxw: All that happens if you don't have them is that you wind up needing more type declarations in funny places. |
| 04:40:13 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 04:40:13 | <lambdabot> | mueval: ExitFailure 1 |
| 04:40:16 | <psygnisfive> | afk. |
| 04:40:17 | <mmorrow> | ACTION was starting to think he was disconnected |
| 04:40:47 | <timmaxw> | suppose that we define class Mult a b c where (*) :: a -> b -> c |
| 04:41:03 | <timmaxw> | and define an instance where (*) :: Matrix -> Matrix -> Matrix |
| 04:41:09 | <lament> | mmorrow: it's not you, it's the rest of the universe. |
| 04:41:17 | <mmorrow> | lament: i knew it! |
| 04:41:22 | <timmaxw> | shouldn't the compiler be able to tell that if m1,m2::Matrix, then (m1*m2)::Matrix? |
| 04:41:29 | <dmwit> | timmaxw: nope |
| 04:41:33 | <timmaxw> | why not? |
| 04:41:41 | <dmwit> | timmaxw: Nothing is stopping you from declaring an instance later for Mult Matrix Matrix Vector. |
| 04:41:53 | <timmaxw> | why can't the compiler look for that? |
| 04:41:56 | <dmwit> | timmaxw: Nothing, that is, except functional dependencies. =) |
| 04:42:04 | <dmwit> | timmaxw: separate compilation |
| 04:42:11 | <dmwit> | timmaxw: The instance might be in another file. |
| 04:42:51 | <timmaxw> | doesn't the compiler detect duplicate instances even if they are in separate files? or no? |
| 04:43:09 | <monochrom> | > let { 0+n=n; (m+1)+n = succ(m+n) } in 2+2 {- this one will cause a flame war -} |
| 04:43:15 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 04:43:15 | <lambdabot> | mueval: ExitFailure 1 |
| 04:43:21 | <ray> | what if it's linked in at runtime |
| 04:43:22 | <monochrom> | Hrm! |
| 04:44:27 | <dmwit> | timmaxw: It does detect multiple instances, yes. |
| 04:44:46 | <timmaxw> | dmwit: but the instance might be in another file... |
| 04:44:52 | <dmwit> | Yes, I know. |
| 04:44:59 | <dmwit> | I'm not totally sure what's going on here. |
| 04:45:04 | <monochrom> | It works in GHC. |
| 04:45:06 | <dmwit> | (I knew at one point...) |
| 04:45:06 | <ray> | your head a splode |
| 04:46:32 | <mmorrow> | squirting brain goo all over the room like a loose fire hose |
| 04:48:08 | <dmwit> | timmaxw: Aha, I got it. |
| 04:48:16 | <dmwit> | ...I lied. |
| 04:48:54 | <dmwit> | No, I do have it. |
| 04:49:02 | <dmwit> | timmaxw: Constraints can only mention type variables. |
| 04:49:13 | <dmwit> | timmaxw: So (Mult Matrix Matrix c) is not a valid constraint. |
| 04:49:56 | <timmaxw> | dmwit: ah... but i'm not sure how functional dependencies solves that... let me think on it a bit |
| 04:49:56 | <dmwit> | bah, FlexibleContexts is for exactly that |
| 04:50:31 | <dmwit> | Well, functional dependencies let us say, "when we know a and b, then we know c", so we don't need a constraint that looks like that. |
| 04:50:44 | <dmwit> | We know a and b, so conceptually we should know c. |
| 04:50:49 | <timmaxw> | dmwit: suppose we define Mult with a functional dependency |
| 04:51:01 | <timmaxw> | dmwit: then what would the constraint look like on (m1*m2) where m1,m2::Matrix? |
| 04:51:50 | <dmwit> | It would likely either complain (if there were no instance for Matrix Matrix c), or simply choose the type c (if there is an instance Matrix Matrix c). |
| 04:52:12 | <dmwit> | But I am so unsure of this. |
| 04:52:28 | <dmwit> | I am a type-system newbie myself. =P |
| 04:52:35 | <timmaxw> | dmwit: But if there's an instance (Mult Matrix Matrix Matrix) and Mult is defined with a functional dependency, then it chooses the type Matrix. I think. |
| 04:52:45 | <dmwit> | right |
| 04:53:01 | <dmwit> | If you substitute "Matrix" for "c" in the sentence above, that's exactly what I predict. |
| 04:53:29 | <dmwit> | But more importantly, if you then try to add an instance Matrix Matrix Int, it will complain loudly. |
| 04:53:33 | <timmaxw> | dmwit: It chooses Matrix by searching through the known instances of Mult and looking for one of the form (Mult Matrix Matrix <something>) |
| 04:53:41 | <dmwit> | I... think so. |
| 04:53:52 | <timmaxw> | dmwit: why does it need the functional dependency to make that decision? |
| 04:54:02 | <bogner> | is there magic involved in turning [a] into tring, when inferring types? |
| 04:54:14 | <bogner> | s/tring/String/ |
| 04:54:14 | <dmwit> | timmaxw: That is the bit I don't know. |
| 04:54:26 | <dmwit> | bogner: type String = [Char] |
| 04:54:30 | <rick_2047> | ls |
| 04:55:20 | <dmwit> | bogner: Other than the usual unification, no magic, I think. |
| 04:55:30 | <bogner> | dmwit: I realize that, but if I create data Foo = Foo String, I end up getting issues with couldn't match expected type [b] against inferred type Foo |
| 04:55:39 | <bogner> | when trying to use concatMap |
| 04:55:52 | <dibblego> | bogner, data and type do different things |
| 04:55:53 | <dmwit> | bogner: But Foo doesn't unify with [b]. |
| 04:56:11 | <bogner> | how can I make it unify with [b]? |
| 04:56:18 | <timmaxw> | bogner: if you want Foo and String to be the same thing, you need "type Foo = String" |
| 04:56:31 | <dibblego> | data Foo = Foo { foo :: String } -- the use Foo and foo to wrap/unwrap |
| 04:56:55 | <bogner> | timmaxw, dibblego: then it doesn't have a distinct identity, so I can't make useful instances of classes |
| 04:57:00 | <monochrom> | (There is no Matrix.) |
| 04:57:10 | <bogner> | dibblego: that might do it |
| 04:57:14 | <dibblego> | bogner, sure you can, instance Monoid Foo where ... |
| 04:57:31 | <bogner> | dibblego: I meant in the type Foo = String case |
| 04:57:36 | <dmwit> | dibblego: I think he was complaining about your earlier "type" suggestion, not your later "data" suggestion. =) |
| 04:57:47 | <bogner> | dmwit: thanks for clearing that up |
| 04:57:52 | <dibblego> | I didn't suggest type |
| 04:57:59 | <dmwit> | bogner: Also, if you're using this *only* to trick the type-system into thinking there's two types when really there's only String, then may I suggest newtype? |
| 04:58:33 | <bogner> | dmwit: using newtype didn't seem to fix the unifying thing, perhaps I'm misunderstanding how to use it? |
| 04:58:34 | <dmwit> | bogner: You use it exactly the same way, but save one indirection on each use. |
| 04:58:43 | <dmwit> | bogner: (i.e. exactly the same way as data) |
| 04:58:44 | <dibblego> | bogner, replace data with newtype |
| 04:59:12 | <monochrom> | newtype Foo = FooConstructor String |
| 04:59:20 | <dmwit> | bogner: Yes, you still have to manually wrap and unwrap it. |
| 04:59:41 | <dmwit> | bogner: The only difference is that wrapping and unwrapping get optimized away for newtypes, but not for data types. |
| 04:59:42 | <bogner> | dmwit: how do I unwrap it, then? |
| 04:59:49 | <bogner> | for a newtype |
| 04:59:57 | <monochrom> | pattern-matching |
| 05:00:00 | <dmwit> | newtype Foo = Foo { unFoo :: String } -- exact same way |
| 05:00:01 | <dibblego> | newtype Foo = Fo o { foo :: String } |
| 05:00:04 | <dmwit> | Pattern-matching works, too. |
| 05:00:07 | <monochrom> | f (FooConstructor s) = s |
| 05:00:25 | <bogner> | oh, cool, I didn't realize that record syntax would work there |
| 05:00:28 | <bogner> | awesome |
| 05:00:33 | <bogner> | thanks guys |
| 05:00:34 | <dibblego> | foo :: Foo -> String |
| 05:00:41 | <dibblego> | Foo :: String -> Foo |
| 05:01:10 | <timmaxw> | regarding the difference between newtype and data: it looks to me like the only difference between newtype and data-with-one-constructor is in the way they are implemented at runtime |
| 05:01:13 | <timmaxw> | right? |
| 05:01:17 | <dmwit> | newtype X = X X -- try it at home, kids! |
| 05:01:30 | <dibblego> | timmaxw, bottoms matter |
| 05:02:08 | <timmaxw> | dibblego: good point. |
| 05:02:40 | <dmwit> | (Constructor undefined) -- actually undefined for newtype, a wrapped-up undefined for data |
| 05:03:09 | <leimy_> | I need to convert Word16 to Int or Int64 |
| 05:03:10 | <cads> | eexcellent, I can (defmacro λ ....) |
| 05:03:18 | <leimy_> | what's the easy way to do that? |
| 05:03:18 | <dmwit> | :t fromIntegral |
| 05:03:27 | <lambdabot> | forall a b. (Integral a, Num b) => a -> b |
| 05:03:39 | <leimy_> | clever |
| 05:03:42 | <leimy_> | :-) |
| 05:03:44 | <dmwit> | =) |
| 05:03:50 | <leimy_> | I don't know why I always forget that :-) |
| 05:03:54 | <cads> | ,(λ [x] (* x x)) |
| 05:03:58 | <lunabot> | luna: Not in scope: `Û§ |
| 05:04:19 | <timmaxw> | dibblego, dmwit: is that behavior particularly useful? |
| 05:04:27 | <dmwit> | timmaxw: Nope, just something to watch out for. |
| 05:05:09 | <timmaxw> | dmwit: then why does newtype exist at all? why not just say that the compiler "should" optimize instances of data with a single declaration? |
| 05:05:31 | <dmwit> | Because they behave differently. |
| 05:05:37 | <leimy_> | Data.Binary is telling me: too few bytes. Failed reading at byte position 20 |
| 05:05:46 | <leimy_> | but I'm telling it to read 19 bytes :-) |
| 05:05:47 | <dmwit> | You can't optimize them just because you *think* people are going to use them in a way that doesn't break the optimization. |
| 05:05:48 | <leimy_> | so I'm confused :-) |
| 05:06:07 | <timmaxw> | dmwit: are there any differences other than the behavior around _/_ and the runtime implementation? |
| 05:06:19 | <dmwit> | Nope. |
| 05:06:24 | <dmwit> | But _ is a useful value at runtime. |
| 05:06:26 | <dmwit> | We use it all the time. |
| 05:06:41 | <timmaxw> | and the behavior around _/_ is "something to watch out for"? |
| 05:06:49 | <dmwit> | You bet! |
| 05:06:58 | <dmwit> | It won't be a problem until you forget to watch for it. ;-) |
| 05:07:42 | <dmwit> | Try "newtype X = X X deriving Show" and then type "undefined :: X" in a ghci terminal. |
| 05:07:51 | <dmwit> | Predict what it will do and see if you're right. =) |
| 05:08:24 | <timmaxw> | why was newtype originally put into the Haskell 98 report then? why not just include a suggestion that compilers optimize data? i don't see how adding a new behavior that acts a tiny bit differently is worth the added language complexity (and confusion to newbies) |
| 05:08:57 | <MyCatVerbs> | @where lyah |
| 05:08:58 | <lambdabot> | www.learnyouahaskell.com |
| 05:09:25 | <dmwit> | timmaxw: ... |
| 05:09:30 | <timmaxw> | dmwit: i wouldn't expect it to accept "newtype X = X X" at all |
| 05:09:35 | <timmaxw> | dmwit: that's what i would *predict* |
| 05:09:38 | <dmwit> | timmaxw: You *can't* optimize data in general. |
| 05:10:04 | <thoughtpolice> | timmaxw: because then you have to treat that optimization as a standard |
| 05:10:28 | <thoughtpolice> | because then code may depend on such functionality as specified by the report |
| 05:10:46 | <thoughtpolice> | it's the same reason they didn't totally kill the monomorphism restriction |
| 05:10:55 | <dmwit> | Detecting when somebody is using data as newtype (i.e. finding "undefined"s in the code) is undecidable. |
| 05:10:57 | <thoughtpolice> | they didn't want the potential performance problems to be held at the mercy of every implementation |
| 05:11:05 | <timmaxw> | dmwit: oh, i think i see it. if "newtype X = X Foo", then there's one possible variation at runtime: "X". If "data X = X Foo", then there are two possible variations: "X" and "_/_". This means that more space has to be used for the "data" declaration. Am I right? |
| 05:11:22 | <dmwit> | timmaxw: Exactly. |
| 05:11:29 | <timmaxw> | also, ghci won't let me run "newtype X = X X" |
| 05:11:40 | <dmwit> | timmaxw: Yeah, you've got to put newtype declarations in a file. |
| 05:11:42 | <timmaxw> | or any "newtype" declarations at the interactive prompt |
| 05:11:59 | <dmwit> | That's why I said to try newtype X = X X deriving Show, *then* go to ghci. ;-) |
| 05:12:44 | <timmaxw> | thoughtpolice: why? it's trivial to implement and it doesn't make a huge performance impact either way. compilers can easily include it or not include it. isn't that like saying that common subexpression elimination has to either be part of the standard or not available at all? |
| 05:13:01 | <timmaxw> | thoughtpolice: (that is, if it weren't for the _/_ thing) |
| 05:13:28 | <dmwit> | It's not trivial to implement, it can make a huge performance difference, and it's not at all like saying something must be available or not available. |
| 05:14:21 | <dmwit> | Strictness analysis is a field with lots of papers and a load of very difficult work. |
| 05:14:27 | <timmaxw> | dmwit: i see. |
| 05:14:30 | <dmwit> | So that's the trivial to implement thing. |
| 05:14:46 | <dmwit> | Wrapping and unwrapping a single constructor can really matter, especially for arithmetic or so. |
| 05:14:49 | <dmwit> | So that's the performance thing. |
| 05:15:14 | <dmwit> | (Imagine following a pointer, doing arithmetic, and then allocating a new pointer every time you wanted to add. yuck) |
| 05:15:31 | <dmwit> | As for the standard, it doesn't come out either way. |
| 05:15:35 | <amckinley> | hey, i need some help writing a line-oriented parsec parser. im trying to parse dns zone files (see http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5483) |
| 05:15:54 | <dmwit> | That lowers the bar for standards-compliant compilers (a good thing), and lets serious compilers do the optimization if it can (also a good thing). |
| 05:16:20 | <amckinley> | i dont want to use lexeme parsers because whitespace is meaningful in a couple complicated ways, and im having trouble doing things without them |
| 05:16:55 | <timmaxw> | dmwit: it adds a little complexity to the language and makes it easier for non-optimizing compilers not to have horrible performance |
| 05:17:15 | <dmwit> | Right. |
| 05:17:24 | <dmwit> | A relatively benign trade-off, really. |
| 05:18:02 | <dmwit> | It also gives the programmer a little control for times when the optimizer fails. |
| 05:18:10 | <dmwit> | For people who care about optimization, this matters, too. |
| 05:18:13 | <amckinley> | what i feel like i *should* do is produce a bunch of substrings that correspond to the record boundaries, then pass those strings off to more specific parsers for each record type |
| 05:18:20 | <amckinley> | which isnt very parsec-y |
| 05:18:42 | <rick_2047> | cant i have an or ( || ) condition in a predicate?? |
| 05:18:50 | <dmwit> | rick_2047: Sure you can. |
| 05:19:01 | <dmwit> | amckinley: That's perfectly parsecy. |
| 05:19:13 | <timmaxw> | dmwit: we could talk about this for a while but unfortunately i have to sign off. goodnight, and this has been an interesting discussion. |
| 05:19:30 | <dmwit> | amckinley: In fact, it's very much like having a lexer stage (where lexemes are records). |
| 05:20:02 | <amckinley> | dmwit: how could i do something like that? my understanding is that once ive consumed a character, i cant consume it again without invoking parse a second time |
| 05:20:18 | <dmwit> | amckinley: Right... but then you *have* the character. ;-) |
| 05:21:08 | <sclv> | amckinley: also you can simply not use lexeme parsers and parse whitespace explicitly. |
| 05:21:09 | <dmwit> | amckinley: One simple way is to have your first-stage parser return a [String], where each element is a record. |
| 05:21:23 | <amckinley> | dmwit: so is that the way to do it? make a pass over the file to break it up, then make another pass with another set of parsers? |
| 05:21:32 | <amckinley> | er, thats a yes^^ :) |
| 05:21:48 | <dmwit> | amckinley: It's certainly not the only way. But if that way seems natural to you, it's also certainly not a bad way. |
| 05:23:08 | <amckinley> | dmwit: it definitely feels natural, but im using this project (partly) as an excuse to learn haskell and parsec, so if theres a preferred way of doing it, id rather jump through the hoops of learning it :) |
| 05:23:57 | <dmwit> | I see nothing wrong with this way. |
| 05:24:04 | <sclv> | also lookAhead is perfectly fine in moderation |
| 05:24:16 | <sclv> | (i.e. for determining if the next character is a paren) |
| 05:24:22 | <amckinley> | sclv: that was my next question :) |
| 05:24:22 | <dmwit> | sclv means try, not lookAhead. ;-) |
| 05:24:34 | <sclv> | dmwit: no. I mean lookAhead too. |
| 05:25:07 | <sclv> | you can write parsers without it, but sometimes I find it more elegant looking if ever so slightly less efficient to use it. |
| 05:36:07 | <amckinley> | sclv: dmwit: so here's a first crack at the lexer stage; i havent tested it yet, but could you (and anyone else) critique my style? http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5484 |
| 05:37:26 | <sclv> | amckinley: return an Either instead? |
| 05:38:23 | <sclv> | or better yet do (parens nlSepList <|> plainList) where those are the two styles.. |
| 05:38:36 | <sclv> | and thus skip the lexer stage. |
| 05:39:18 | <sclv> | if parsec hits the first paren it knows its in the first style, and can parse the rest, then throw away the end, and if it hits anything else, then it'll try in the second style. |
| 05:40:06 | <amckinley> | sclv: its actually hard to say whether or not you could legitimately put content on the same line as the closing paren |
| 05:40:32 | <sclv> | amckinley: its easy to write the parser either way tho... |
| 05:40:39 | <amckinley> | the RFC describes the parens as an "ignore newlines between these delimiters" thing |
| 05:40:48 | <sclv> | there's sepBy and sepEndBy... |
| 05:41:13 | <sclv> | ah! i see what you mean... |
| 05:41:17 | <amckinley> | sclv: ive been totally brainlocking on how to use either one of those combinators :P |
| 05:41:53 | <sclv> | so you really want a restOfLine function that will read the rest of the line, or read downward, tossing out parens as it goes. |
| 05:42:01 | <sclv> | but you also need to know how to ignore comments. |
| 05:42:24 | <amckinley> | sclv: exactly |
| 05:43:25 | <sclv> | restOfLine =parens textWithoutComments < |
| 05:43:33 | <sclv> | <|> manyTill (char '\n') |
| 05:44:33 | <amckinley> | textWithoutComments seems like a hard thing to write |
| 05:45:07 | <notsmack> | any decent mp3 decoding bindings? |
| 05:45:08 | <sclv> | where textWithoutComments = fmap (intercalate " ") $ many lineWithoutComments |
| 05:45:52 | <amckinley> | touche :) |
| 05:46:02 | <sclv> | where lineWithoutComments = manyTill anyChar (char '\n' <|> (char ';' >> manyTill anyChar (char '\n'))) |
| 05:47:17 | <sclv> | I always end up refactoring my parsec parsers quite a bit as I go along, but even more so when I was learning -- its easy to knock something out that works then clean it up later and try to feel out the logic hidden in the grammar. |
| 05:47:53 | <dmwit> | notsmack: Well, there's that "Let's write an mp3 decoder" paper somebody wrote for their master's. |
| 05:48:16 | <dmwit> | http://blog.bjrn.se/2008/10/lets-build-mp3-decoder.html |
| 05:48:28 | <notsmack> | dmwit, hadn't seen, i'll take a look |
| 05:48:48 | <dmwit> | notsmack: I should maybe ask why you want that, though. |
| 05:48:51 | <amckinley> | sclv: im going to try some of this out, back in a minute |
| 05:49:15 | <dmwit> | notsmack: Oh, never mind, you did ask for bindings. =P |
| 05:49:18 | <notsmack> | dmwit, just want to knock a quick music player together |
| 05:49:22 | <dmwit> | notsmack: Have you checked the audio libraries on Hackage? |
| 05:49:40 | <notsmack> | yeah, looked through them a bit |
| 05:49:54 | <dmwit> | ACTION wonders briefly if there is a binding to the mpd stuffs |
| 05:50:21 | <dmwit> | Of course there is! |
| 05:50:41 | <walter_> | Which Lib quite handful to creat HTML file? |
| 05:51:20 | <notsmack> | dmwit, mpd doesn't really suit my needs; i was about to look at rhythmbox or totem via dbus bindings next |
| 05:51:35 | <dmwit> | notsmack: What are your needs? |
| 05:52:03 | <Cale> | walter_: The one called 'html' is probably reasonable, though I haven't really used Haskell to generate much html myself. |
| 05:52:25 | <dmwit> | walter_: WASH has a beautiful DSL for HTML construction. |
| 05:52:26 | <notsmack> | dmwit, well, i want to be able to play a file, not mess with IDs from mpd's music database |
| 05:52:56 | <dmwit> | walter_: There's also html, xhtml, and xml packages on Hackage (by those names, even). |
| 05:53:08 | <Cale> | Hey, is WASH not on Hackage? |
| 05:53:19 | <dmwit> | I wonder if WASH even builds with recent GHCs. |
| 05:53:25 | <Cale> | ACTION doesn't see it there |
| 05:53:33 | <walter_> | yeah, so many lib on html xhtml |
| 05:54:23 | <dmwit> | WASH actually generates correct strict XHTML (guaranteed by the type system!), with a small patch to change the declaration from transitional to strict. |
| 05:54:25 | <walter_> | dev-haskell/wash is in the Gentoo portage overlay |
| 05:54:46 | <walter_> | I will try wash |
| 05:56:34 | <walter_> | Wash is not in Hoogle |
| 05:56:39 | <dmwit> | nope =/ |
| 05:56:45 | <dmwit> | But the docs are good. |
| 05:57:00 | <walter_> | dmwit, that's great |
| 05:57:24 | <dmwit> | http://www.informatik.uni-freiburg.de/~thiemann/WASH/#washhtml |
| 05:57:33 | <MyCatVerbs> | dmwit: off the cuff, is there any library you'd specifically recommend for HTML 4.01? |
| 05:57:41 | <MyCatVerbs> | Er, 4.01 Strict, even. |
| 05:58:05 | <dmwit> | I've only ever used the one. =P |
| 05:59:25 | <Jedai> | MyCatVerbs: I would probably use xhtml (it only produce XHTML 1.0 Transitional, Strict or Frameset though) |
| 05:59:49 | <walter_> | dmwit, thanks! |
| 06:01:11 | <MyCatVerbs> | Jedai: I personally prefer 4.01 to xhtml for a couple of bad ideological reasons. |
| 06:01:46 | <inimino> | there aren't many reasons to prefer XHTML at this point |
| 06:02:40 | <Jedai> | MyCatVerbs: Wash seems to have a good generator for HTML4.01, they use types to guarantee a valid output |
| 06:02:51 | <dmwit> | Oh, is it 4.01? |
| 06:02:57 | <dmwit> | I thought it was XHTML. |
| 06:03:12 | <dmwit> | In any case, I remember validating it as "Strict" for whatever it was. =P |
| 06:03:36 | <Jedai> | MyCatVerbs: I never used it though, and the webpage explain that it was thoroughly tested on the 2001 release of Hugs... |
| 06:03:49 | <dmwit> | Yeah, it's a bit old. |
| 06:03:58 | <Jedai> | dmwit: the link you sent say it's 4.01 anyway |
| 06:04:14 | <dmwit> | I trust its docs much more than my memory. |
| 06:05:25 | <MyCatVerbs> | Jedai: oh! I thought dmwit meant it did xhtml only. |
| 06:05:36 | <dmwit> | That's what I meant, but I was wrong. |
| 06:05:37 | <MyCatVerbs> | Sorry, my bad. Checking the website for WASH, yes it does 4.01 as well. |
| 06:08:33 | <walter_> | I got an error while install WASH, it said "Current maximum heap size is 299999232 bytes (286 MB); |
| 06:08:33 | <walter_> | use `+RTS -M<size>' to increase it. |
| 06:08:33 | <walter_> | " |
| 06:08:57 | <dmwit> | Wow. |
| 06:09:17 | <dmwit> | Could you paste the whole output? |
| 06:09:18 | <dmwit> | ?hpaste |
| 06:09:18 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 06:09:44 | <walter_> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5487#a5487 |
| 06:11:40 | <dmwit> | walter_: Is it easy to have a look at the file that failed compilation? |
| 06:11:48 | <dmwit> | I'd be interested in seeing what makes GHC die. |
| 06:12:50 | <walter_> | dmwit, a moment, let me try |
| 06:13:32 | <Jedai> | dmwit: I think it's a problem with the build system somehow... the heap size isn't supposed to be limited by default |
| 06:14:41 | <Axman6> | anyone got any suggestons for interesting some papers to read, possibly about haskell and/or concurrency/parallelism, or techniques for making it faster... or just papers you think are fascinating |
| 06:15:10 | <MyCatVerbs> | Axman6: if you look up the implementation docs for GHC, there's the spineless-tagless-G-machine paper. |
| 06:15:22 | <MyCatVerbs> | Somewhere or other on haskell.org. |
| 06:15:25 | <Axman6> | heh, that sounds fun |
| 06:15:39 | <MyCatVerbs> | If you're looking for more entertainment than theory, look up the cocaine auction protocol. |
| 06:15:46 | <Axman6> | http://portal.acm.org/citation.cfm?id=289439 ? |
| 06:15:50 | <MyCatVerbs> | Possibly the most exciting infosec paper I've read yet. |
| 06:16:19 | <dmwit> | How about that "bidirectionality for free" paper? |
| 06:16:21 | <MyCatVerbs> | Sounds like the right title. Guess I got the author wrong. |
| 06:17:11 | <mauke> | "naturally" |
| 06:29:07 | <notsmack> | anybody used the DBus bindings? |
| 06:29:31 | <notsmack> | ACTION is trying to figure out how to listen for a signal |
| 06:31:31 | <dmwit> | notsmack: Not sure, but maybe addFilter? |
| 06:32:31 | <walter_> | dmwit, http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5489#a5489 the only log I got while install wash |
| 06:33:18 | <dmwit> | walter_: Dunno. Try upping the heap size, I guess? |
| 06:33:18 | <amckinley> | sclv: still around? |
| 06:34:36 | <walter_> | yep |
| 06:34:38 | <cads> | hehehe |
| 06:34:40 | <cads> | hahaha |
| 06:34:43 | <cads> | HAAAAHAHAHAHA!!!! |
| 06:35:34 | <cads> | we can define tuples as sets! |
| 06:35:34 | <cads> | as in the following example : {{a} {a b} {a b c} {a b c d} {a b c d e}} |
| 06:35:46 | <cads> | which is equivalent to (a b c d e) |
| 06:36:04 | <dmwit> | I'm with you so far. |
| 06:36:32 | <cads> | then we can write functions parameterized on tuple types of varying rank |
| 06:36:40 | <MyCatVerbs> | cads: but tuples are more like bags than sets? Sets enforce singularity. |
| 06:36:57 | <dmwit> | cads: But we can already do that, with lists. |
| 06:37:07 | <dmwit> | cads: (Remember, all the elements of the set have to have the same type.) |
| 06:37:11 | <MyCatVerbs> | Er, wrong term, but anyways. Sets enforce that each element is in there at most once. |
| 06:37:12 | <cads> | no! |
| 06:37:24 | <cads> | that's not the definition of sets! |
| 06:37:36 | <dmwit> | cads: Are we talking about Haskell, or not? |
| 06:38:04 | <cads> | aw that crushes me... I though they'd be mathematical sets |
| 06:38:10 | <cads> | not... unordered lists |
| 06:38:28 | <dmwit> | MyCatVerbs: The standard trick is to wrap things in more and more set brackets until they're unique. |
| 06:38:32 | <cads> | ah well |
| 06:39:19 | <cads> | dmwit: it's my long running pie in the sky dream to be able to write a function that can take a tuple of arbitrary size and type |
| 06:39:45 | <dmwit> | cads: But how would you represent the sets you're using to encode tuples above? |
| 06:40:09 | <dmwit> | cads: If you use Data.Set, then each of the elements has the same type, and so you might as well just use an (ordered) list of elements. |
| 06:40:24 | <dmwit> | cads: Also, have you seen HList? |
| 06:40:51 | <cads> | ah |
| 06:40:53 | <cads> | nice |
| 06:40:55 | <cads> | okay |
| 06:41:06 | <dmwit> | (a, b, c, d) is encoded as (a, (b, (c, (d, ())))), with some major type-hackery to make it convenient |
| 06:41:19 | <dmwit> | cads: (Hence my comment above about using lists. ;-) |
| 06:42:25 | <dmwit> | ACTION realizes that there are really two threads of conversation happening here, and they are mildly confusing. |
| 06:42:52 | <cads> | ok yeah, we got to do something like foldl1 . [curry, curry, curry] |
| 06:42:53 | <dmwit> | (a, b, c, d) is encoded that way in HList. There, I hope I've disambiguated. |
| 06:43:05 | <dmwit> | cads: doesn't type-check |
| 06:43:26 | <dmwit> | cads: Curry is being used at different types there, you'll get an occurs-check errror. |
| 06:43:37 | <dmwit> | > foldl1 (.) [curry, curry, curry] |
| 06:43:38 | <cads> | oh right |
| 06:43:43 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 06:43:43 | <lambdabot> | mueval: ExitFailure 1 |
| 06:44:16 | <dmwit> | :t foldl1 (.) |
| 06:44:23 | <lambdabot> | forall b. [b -> b] -> b -> b |
| 06:44:25 | <dmwit> | :t foldr (.) id |
| 06:44:27 | <cads> | well, I think the HList is exactly what I'd need for anything I'd use 'dynamic tuple functions' for |
| 06:44:32 | <lambdabot> | forall a. [a -> a] -> a -> a |
| 06:44:58 | <cads> | but then there's the problem of how you actually write a function that uses values inside an hlist, but i'd like to see what kind of interface it gives for that |
| 06:45:08 | <dmwit> | http://okmij.org/ftp/Haskell/types.html |
| 06:46:36 | <walter_> | since I can not install WASH, will try HStringTemplate instead |
| 06:46:50 | <rob__> | Hi all, I have a quick question: is it possible to instantiate a type constructor in a type class? |
| 06:47:03 | <dmwit> | walter_: Smart move. =P |
| 06:47:14 | <dmwit> | rob__: Only if the kinds match. |
| 06:47:20 | <walter_> | dmwit, :) |
| 06:47:52 | <walter_> | Someome's advice: http://blog.uncommons.org/2008/12/03/generating-html-with-haskell/ |
| 06:48:16 | <rob__> | dmwit: how can i find out if they match? |
| 06:49:12 | <dmwit> | rob__: You can use :k in ghci to find the kind of a type constructor (even if partially applied). |
| 06:49:31 | <dmwit> | rob__: As for what kind it has to be for the instance... that you can usually do by inspection of the instance. |
| 06:49:41 | <rob__> | dmwit: thanks I'll try that |
| 06:49:47 | <dmwit> | rob__: (You can mostly find the kind of a type constructor by inspection, too. =) |
| 06:49:54 | <dmwit> | rob__: Can I ask what this is about? |
| 06:50:00 | <ray> | haskell kinds are pretty simplistic |
| 06:50:02 | <dmwit> | rob__: If you give us more details, we can help you more. |
| 06:50:31 | <vininim_> | :t liftM2 |
| 06:50:38 | <lambdabot> | forall a1 a2 r (m :: * -> *). (Monad m) => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r |
| 06:50:47 | <ray> | :k ReaderT |
| 06:50:53 | <vininim_> | :t liftM2 (,,) |
| 06:50:55 | <lambdabot> | * -> (* -> *) -> * -> * |
| 06:51:02 | <lambdabot> | forall a1 a2 c (m :: * -> *). (Monad m) => m a1 -> m a2 -> m (c -> (a1, a2, c)) |
| 06:52:04 | <rob__> | dmwit: sure I'm trying to write yet another ray tracer as an exercise and I defined some objects as type constructors in a datatype and I made a type class to define common functions for them |
| 06:52:40 | <dmwit> | Are you sure what you're talking about are actually type constructors and not value constructors? |
| 06:53:02 | <dmwit> | (This is a common mistake, sorry if this is totally obvious to you.) |
| 06:54:00 | <dmwit> | :k Monad m => m a |
| 06:54:07 | <lambdabot> | * |
| 06:54:10 | <dmwit> | lambdabot++ |
| 06:54:34 | <ray> | :k Monad m => m |
| 06:54:40 | <lambdabot> | `m' is not applied to enough type arguments |
| 06:54:40 | <lambdabot> | Expected kind `*', but `m' has kind `* -> *' |
| 06:54:48 | <ray> | it told me, sorta |
| 06:57:20 | <rob__> | dmwit: oh good catch, I got those confused |
| 06:58:18 | <ray> | if so, then you probably want a function, not a class |
| 07:00:32 | <rob__> | is there no way to do class Object Plane where ... for data Objects = Plane ...? |
| 07:03:17 | <dmwit> | rob__: You may be a little confused about what class means. |
| 07:03:25 | <dmwit> | It doesn't mean the same thing in Haskell that it does in other languages. |
| 07:03:49 | <dmwit> | In Haskell, a "class" is a collection of types, and some operations that work on those types. Nothing more, nothing less. |
| 07:04:07 | <dmwit> | If you have a data declaration, that creates one single type; not much sense creating a class just for that one type. |
| 07:04:17 | <bos> | @let m n = if n > 200000 then n - 20000 else m (m (n + 20001)) |
| 07:04:20 | <lambdabot> | <local>:7:40: |
| 07:04:20 | <lambdabot> | Ambiguous occurrence `m' |
| 07:04:20 | <lambdabot> | It could refer to either `L... |
| 07:04:27 | <rob__> | so would I have to define a new data type for every object then? |
| 07:04:42 | <bos> | @let eff n = if n > 200000 then n - 20000 else eff (eff (n + 20001)) |
| 07:04:58 | <lambdabot> | Defined. |
| 07:05:05 | <bos> | > eff 2 |
| 07:05:11 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 07:05:11 | <lambdabot> | mueval: ExitFailure 1 |
| 07:05:18 | <dmwit> | rob__: I'm not even sure I understand your question. |
| 07:05:21 | <dmwit> | rob__: What is an object? |
| 07:05:25 | <bos> | huh. |
| 07:05:35 | <bos> | > eff (222::Int) |
| 07:05:42 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 07:05:42 | <lambdabot> | mueval: ExitFailure 1 |
| 07:05:50 | <rob__> | oh by object I just meant a sphere, plane, torus etc... |
| 07:05:53 | <bos> | lambdabot-- |
| 07:06:14 | <ray> | @thump |
| 07:06:14 | <lambdabot> | Unknown command, try @list |
| 07:06:45 | <dmwit> | rob__: I expect you'd have a single data type for shapes, and spheres, planes, toruses, etc. would simply be values of that type. |
| 07:07:02 | <dmwit> | rob__: But I can't say for sure, as I don't know the problem space very well. |
| 07:09:24 | <rob__> | dmwit: that's what I was doing, but I wanted to implement an intersect function for each one of them, so I tried using a type class and make each object an instance of it |
| 07:16:26 | <edwardk> | ACTION waves hello. |
| 07:16:58 | <dmwit> | Hiya, edwardk! |
| 07:17:11 | <dmwit> | Are you coming to Hac Phi? |
| 07:17:21 | <edwardk> | Looks highly probable |
| 07:17:32 | <dmwit> | awesome! |
| 07:18:03 | <dmwit> | I look forward to days of type hackery. =D |
| 07:18:09 | <edwardk> | I may drag a statistician friend of mine who is doing some work on the hbc BUGS model compiler, and see if we/he can interest folks in helping out on that project |
| 07:18:45 | <dmwit> | hbc? |
| 07:19:00 | <edwardk> | http://www.cs.utah.edu/~hal/HBC/hbc.pdf |
| 07:19:00 | <dmwit> | Whoa, this? |
| 07:19:04 | <dmwit> | http://www.cs.chalmers.se/~augustss/hbc/hbc.html |
| 07:19:15 | <edwardk> | the other one |
| 07:19:27 | <dmwit> | Okay, your link looks a lot more recent than mine. =) |
| 07:19:28 | <edwardk> | I've been teasing Aleks that he should try to get Hal to change its name =) |
| 07:20:10 | <dmwit> | Ah, this looks pretty cool. |
| 07:21:38 | <FERRET_SWAMI> | haskell whats up folks |
| 07:21:45 | <FERRET_SWAMI> | seems like a rpetty exciting lang you all have here |
| 07:22:01 | <edwardk> | Personally, I'm interested in updating the interpreter that has fallen into disuse to include the current feature set of the compiler and in looking into what can be done to distribute the model over the network, etc. |
| 07:22:44 | <edwardk> | That, and seeing if some/all of the surface language could be rewritten into just an EDSL for haskell rather than a traditional compiler model. |
| 07:23:02 | <edwardk> | that would allow for the use of haskell to provide higher order tools for model specification. |
| 07:23:13 | <edwardk> | FERRET_SWAMI: we're fond of it =) |
| 07:23:53 | <FERRET_SWAMI> | paul graham site said he was disappointed with staatic typing |
| 07:23:55 | <FERRET_SWAMI> | languages |
| 07:24:09 | <Twey> | Paul Graham says a lot of things |
| 07:24:09 | <FERRET_SWAMI> | can haskell let em write programs bit by bit |
| 07:24:14 | <FERRET_SWAMI> | me- |
| 07:24:16 | <Twey> | Yes |
| 07:24:28 | <FERRET_SWAMI> | for example a program to monitor a website I build |
| 07:24:31 | <edwardk> | paul graham also has a nice little law in which he points out that 'no one sees the point in any language more powerful than his own' it seems he is somewhat hoist on his own petard in that regard ;) |
| 07:24:34 | <FERRET_SWAMI> | using snmp |
| 07:24:39 | <Twey> | edwardk: Heheheh |
| 07:24:43 | <p_l> | FERRET_SWAMI: Yes, it can, though I miss Lisp-style development |
| 07:24:55 | <FERRET_SWAMI> | I have 2 or 3 haskell book |
| 07:25:01 | <FERRET_SWAMI> | but when I see --> |
| 07:25:04 | <p_l> | edwardk: that would be the matter with Arc, I guess. It became a laughing matter in Lisp circles as well :P |
| 07:25:15 | <FERRET_SWAMI> | and stuff I feel like I missed some prereq class.. |
| 07:25:22 | <FERRET_SWAMI> | can I learn programmign from scratch with ahskell? |
| 07:25:35 | <sjanssen> | edwardk: yes, I always found his talk about "blub" ironic |
| 07:25:35 | <edwardk> | i like the idea of arc, i've even stolen some ideas from it in my toy compilers, but yeah |
| 07:25:50 | <p_l> | FERRET_SWAMI: I guess you can, though the way of programming would be slightly different than let's say C |
| 07:25:59 | <FERRET_SWAMI> | haskell one thing I like is that it can utilize many cpu |
| 07:26:01 | <FERRET_SWAMI> | right? |
| 07:26:11 | <FERRET_SWAMI> | I never learned c |
| 07:26:13 | <FERRET_SWAMI> | .. |
| 07:26:18 | <FERRET_SWAMI> | I have the k+r book |
| 07:26:35 | <FERRET_SWAMI> | plan9 people even told me that c can be quite high level with file abstractions |
| 07:27:09 | <edwardk> | FERRET_SWAMI: haskell can work nicely on multiple cpus because it carefully controls the side effects of code, so you can know how multiple threads will interact in ways you can't with a more traditional language |
| 07:27:10 | <Twey> | That's not making C high-level |
| 07:27:19 | <p_l> | FERRET_SWAMI: They are right, but C is different - it's more like portable assembler, frankly speaking. But steer away from C++ :D |
| 07:27:31 | <Twey> | That's using existing C interfaces to interact with a high-level system |
| 07:27:37 | <edwardk> | FERRET_SWAMI: plan9 just makes everything into a file. if you only have a hammer... |
| 07:27:44 | <FERRET_SWAMI> | llol |
| 07:27:56 | <FERRET_SWAMI> | happstack looks liek cool website tool |
| 07:28:17 | <edwardk> | don't get me wrong, its an incredibly general interface, but not everything can be cleanly mapped onto the file abstraction, nor necessarily should it |
| 07:28:19 | <FERRET_SWAMI> | I have booko by hutton an antoher bybhudak |
| 07:28:33 | <FERRET_SWAMI> | haskell is super 'high level' |
| 07:28:36 | <FERRET_SWAMI> | I hear |
| 07:28:38 | <edwardk> | FERRET_SWAMI: i'd recommend two sources. Learn You a Haskell for Great Good, and Real World Haskell. |
| 07:28:50 | <FERRET_SWAMI> | does this really make it way more fun than popular langs liek ruby |
| 07:28:53 | <Twey> | FERRET_SWAMI: Well |
| 07:28:53 | <FERRET_SWAMI> | ok |
| 07:28:58 | <edwardk> | Real World Haskell will dispel the 'super high level' myth to some extend, and Learn You a Haskell is very accessible. |
| 07:29:02 | <Twey> | It's kind of high-level, and kind of low-level. |
| 07:29:02 | <edwardk> | er extent |
| 07:29:17 | <Twey> | It's quite far away from the hardware (by default) |
| 07:29:33 | <Twey> | But in terms of language and mathematics, I'd say it's closer to its foundations than C |
| 07:29:38 | <edwardk> | to me what i like about haskell is that it is the best language i've found to 'think in'. |
| 07:29:52 | <FERRET_SWAMI> | think in |
| 07:30:11 | <FERRET_SWAMI> | functional you try to jsut think about howto compute the asnwer you want |
| 07:30:15 | <FERRET_SWAMI> | like my bank balance |
| 07:30:18 | <edwardk> | Its my own personal Blub. I don't see the point of those weird dependently typed languages in which you can never seem to get anything done, and I don't like less powerful languages because they are missing so many features I'm used to. |
| 07:30:23 | <FERRET_SWAMI> | or order for 4 new cool t shirt |
| 07:30:35 | <FERRET_SWAMI> | hmm |
| 07:30:38 | <FERRET_SWAMI> | hmmmmmmmmmm |
| 07:30:47 | <jeffwheeler> | That makes me think we need Haskell shirts that don't suck. |
| 07:31:11 | <FERRET_SWAMI> | now what about the schuette problem: 95% of servers at load avg 0.3 while 5% of servers at load avg 17 |
| 07:31:17 | <dmwit> | edwardk: heh, I like that |
| 07:31:34 | <dmwit> | Managers rise to their level of incompetence, programmers rise to their level of Blub. =) |
| 07:31:43 | <edwardk> | dmwit: heh |
| 07:31:50 | <FERRET_SWAMI> | "once you go hask, you never go back!: haskell.org" |
| 07:32:10 | <Twey> | ACTION twitches. |
| 07:32:16 | <edwardk> | well, I generally just look at what I can get done in a weekend in Haskell, and then I compare it to what a good Coq developer can get done, he won't have finished trying to figure out what he's trying to say yet ;) |
| 07:32:22 | <FERRET_SWAMI> | the dream of business people is apps on commodity hardware that are immune to failure |
| 07:32:44 | <p_l> | FERRET_SWAMI: No, the dream of business people is clients who have money and no brains |
| 07:32:57 | <dmwit> | Immune to failure? |
| 07:33:01 | <dmwit> | That sounds tricky. |
| 07:33:07 | <FERRET_SWAMI> | uh oh, looks like I thought wrong, again |
| 07:33:07 | <dmwit> | ACTION pulls the plug and shoots the UPS |
| 07:33:16 | <FERRET_SWAMI> | well somehow you have 40 servers |
| 07:33:18 | <edwardk> | p_l: i'm fond of clients with both money and brains, its easier to reason with them, and you can make them more profitable more easily so they keep coming back to you for more. |
| 07:33:24 | <FERRET_SWAMI> | and the app adjsuts if 3 die |
| 07:33:29 | <FERRET_SWAMI> | and notifies you |
| 07:33:38 | <edwardk> | FERRET_SWAMI: then you probably want Erlang ;) |
| 07:33:44 | <FERRET_SWAMI> | mogileFS I think by danga interactive is a huge step |
| 07:33:47 | <p_l> | edwardk: that's rare, the big players want idiots :_ |
| 07:33:50 | <p_l> | *:P |
| 07:33:54 | <edwardk> | they've been doing that sort of thing for years =) |
| 07:34:04 | <FERRET_SWAMI> | Im amazed how much idiots pay for 'managed' hosts |
| 07:34:06 | <FERRET_SWAMI> | hosting |
| 07:34:13 | <FERRET_SWAMI> | 'managed hosting' |
| 07:34:30 | <FERRET_SWAMI> | erlang, hmm, erlang....I heard its nice |
| 07:34:36 | <FERRET_SWAMI> | even has a webserver yaws |
| 07:34:38 | <Twey> | It's not nice |
| 07:34:43 | <Twey> | It's a horrible language |
| 07:34:47 | <edwardk> | FERRET_SWAMI: its not all that idiotic to focus on your core competencies and farm out the rest, specialization is one path to suceess. |
| 07:34:51 | <Twey> | But it is built on some nice concepts |
| 07:35:34 | <Twey> | I agree with edwardk |
| 07:35:43 | <Twey> | People with brains are much nicer to work for than people with no brains |
| 07:36:23 | <p_l> | Twey: to work for. Hearing some of "big industry" (not necessarily computer industry) heads talk, I think they want cattle |
| 07:36:29 | <jeffwheeler> | ACTION likes Cabal's new warning about the package index being more than 15 days old or so |
| 07:36:40 | <dmwit> | The nicest part is when they succesfully identify the clever solution to a hard problem. =D |
| 07:36:48 | <edwardk> | I like the idea of erlang, but perhaps I'm a language bigot. I want some types and I miss laziness and its slightly better asymptotics too much. And I much prefer constructors with variable arities and Haskell's partial applicative style to the prolog full application style |
| 07:36:59 | <Twey> | ACTION nods. |
| 07:37:24 | <dmwit> | jeffwheeler: Boy howdy! |
| 07:37:33 | <p_l> | edwardk: well, my policy is to learn a few good tools and then use "choose best tool for the job" way :) |
| 07:37:41 | <jeffwheeler> | dmwit: your work? :) |
| 07:37:56 | <dmwit> | jeffwheeler: Nope, I just totally agree with you! |
| 07:37:58 | <dmwit> | Cabal rocks! |
| 07:38:04 | <jeffwheeler> | Ah, yep. |
| 07:38:23 | <edwardk> | p_l: yeah. i'm glad i added haskell to my toolbox, though i seriously took a left turn somewhere and it became more of the focus of my research than the means ;) |
| 07:38:36 | <jeffwheeler> | The whole system kicks the pants off of those for other languages . . . Python's mess of installation tools comes to mind. |
| 07:40:14 | <dmwit> | It helps that our main implementation started out with a pretty sane packaging system. |
| 07:40:27 | <hackagebot> | minesweeper 0.4 |
| 07:40:34 | <dmwit> | Minesweeper?? |
| 07:40:42 | <dmwit> | ?hackage minesweeper |
| 07:40:42 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/minesweeper |
| 07:40:46 | <jeffwheeler> | ACTION installs. |
| 07:41:00 | <edwardk> | my biggest fear for hackage/cabal is the 'layering problem', which is more of a language design/library feature interaction issue. its hard to layer in new abstractions, because if you have a suitably large non-trivial library that introduces new instances for a lot of existing code, you can't split it in a way that makes it palatable to push all of the instances down into the source libraries without making orphan |
| 07:41:04 | <p_l> | dmwit: that's true. On Lisp, the last sensible package manager I had seen was for Genera, I think :D |
| 07:41:06 | <FERRET_SWAMI> | I heard darcs got beat up for performance problems |
| 07:41:11 | <edwardk> | so there is a 'new abstraction tax' inherent in the language that bugs me |
| 07:41:20 | <FERRET_SWAMI> | and mercurial and git are these really good code lockup tools |
| 07:41:49 | <FERRET_SWAMI> | is darcs no longer considered a competitor? |
| 07:41:55 | <FERRET_SWAMI> | in the source safe wars |
| 07:42:12 | <MyCatVerbs> | FERRET_SWAMI: depends on how large your repositories are, mostly. |
| 07:42:15 | <edwardk> | FERRET_SWAMI: i prefer darcs over git for my personal projects, because its so much nicer to be able to pick and choose bits and pieces of patches in darcs, but git does seem to work in the large well. |
| 07:42:23 | <Beelsebob1> | darcs is an excellent compettitor still, as long as you only have small to medium sized repos |
| 07:42:34 | <Beelsebob1> | Mercurial I've found horibly unreliable |
| 07:42:50 | <edwardk> | what i like about darcs is that when i'm working on a 1-3 developer project, darcs just slots right into the work flow and gets out of the way. |
| 07:42:52 | <MyCatVerbs> | I still use darcs myself, but friends of mine have switched over to Mercurial, and the GHC project switched to Git because of darcs' performance issues. |
| 07:43:01 | <edwardk> | and i'm never messing around dealing with messy merges, etc. |
| 07:43:13 | <dmwit> | No other system beats darcs' UI yet. |
| 07:43:26 | <edwardk> | ghc also has to deal with ~10 years of history or something crazy like that |
| 07:43:28 | <cads> | git's cola is not a bad ui |
| 07:43:43 | <MyCatVerbs> | Mmmmmost of darcs' problems don't come up until you get to a fairly large quantity of code. |
| 07:43:52 | <cads> | rather, cola for git |
| 07:44:31 | <FERRET_SWAMI> | good night all |
| 07:44:36 | <jeffwheeler> | That minesweeper game is great. |
| 07:44:43 | <edwardk> | the main thing i like about darcs is that i just sort of initialize the repository and i don't think about it until its saving my ass |
| 07:44:57 | <maxote> | darcs' performance issues can be improved if the GHC's performance issues are solved |
| 07:45:00 | <jeffwheeler> | I love the probabilities features. |
| 07:45:14 | <edwardk> | jeffwheeler: the oz thing? |
| 07:45:34 | <jeffwheeler> | edwardk: C-p in the minesweeper package on Hackage that was just updated |
| 07:45:59 | <jeffwheeler> | edwardk: it shows the probabilities that each square might contain a mine, given the revealed locations. |
| 07:45:59 | <edwardk> | ah |
| 07:46:09 | <edwardk> | ok, so the same idea |
| 07:46:27 | <dmwit> | uh-oh |
| 07:46:35 | <dmwit> | I accidentally ln -s something . |
| 07:48:09 | <sjanssen> | maxote: darcs issues at this point don't really have anything to do with the compiler |
| 07:51:55 | <dmwit> | Hey, this minesweeper game is really cool! |
| 07:52:37 | <dmwit> | jeffwheeler: Try focusing another window while you're playing. |
| 07:53:48 | <jeffwheeler> | dmwit: you mean that it pauses? |
| 07:54:13 | <dmwit> | yep |
| 07:54:18 | <jeffwheeler> | The default GNOME Minesweeper does that, but I'm impressed with the 'lucky' stuff at the top. |
| 07:54:22 | <dmwit> | But just in general the idea is totally rad. |
| 07:54:31 | <dmwit> | Guaranteed no guessing. |
| 07:54:40 | <dmwit> | If you die, it's because you didn't reason well enough. =) |
| 07:54:43 | <jeffwheeler> | I'm not that good, though. ;) |
| 07:54:49 | <dmwit> | ACTION is |
| 07:55:00 | <dmwit> | More importantly |
| 07:55:04 | <jeffwheeler> | I'm trying to learn, based on its probabilities. |
| 07:55:06 | <MyCatVerbs> | dmwit: IIRC there's a paranoid version of Minesweeper too. |
| 07:55:07 | <dmwit> | ACTION 's mother is |
| 07:55:30 | <MyCatVerbs> | Where the game plants a mine under the cursor whenever it's possible for a mine to be there. |
| 07:55:33 | <dmwit> | MyCatVerbs: What, it always kills you if it can? |
| 07:55:37 | <dmwit> | ACTION nods |
| 07:55:39 | <dmwit> | jerks |
| 07:55:46 | <MyCatVerbs> | Aye. |
| 07:56:19 | <jeffwheeler> | It must be very difficult to start that game. ;) |
| 07:56:47 | <jeffwheeler> | (Alternatively, that could make it very easy to program.) |
| 08:02:46 | <dmwit> | yipe! |
| 08:03:00 | <dmwit> | It gets a little slow if you guess randomly a lot at the beginning. =P |
| 08:05:39 | <MyCatVerbs> | Heh. |
| 08:06:01 | <cads> | http://projectfortress.sun.com/Projects/Community/wiki/FortressQuestions#InwhatwaysdoesFortresssyntaxresemblemathematicalnotation |
| 08:06:07 | <cads> | oh my god |
| 08:06:16 | <cads> | I want to code in that. |
| 08:06:58 | <cads> | except... those semantics look imperative ... |
| 08:08:29 | <flux> | cads, but here clearly is a difference between bindings and assignments |
| 08:08:45 | <cads> | ah, very very true! |
| 08:08:59 | <cads> | I missed right over that |
| 08:09:55 | <flux> | haven't heard of Fortress much since it was announced |
| 08:10:09 | <cads> | nope |
| 08:10:22 | <cads> | people are commiting code to it though |
| 08:10:45 | <cads> | I think they lost their funding and now it's just an open project |
| 08:11:05 | <cads> | I'm trying to find a mailing list or something |
| 08:11:20 | <cads> | the whole rendering to tex thing is fucking supreme. |
| 08:12:01 | <cads> | something that's been really souped up like that could be pretty nice for haskell |
| 08:12:29 | <cads> | the day I see an integral symbol in computer code will be a happy day |
| 08:12:42 | <rick_2047> | well in there general forums there is only one topic and that too 2 years old |
| 08:12:49 | <MyCatVerbs> | There's TeX style literate Haskell notation, though that doesn't do much for you. |
| 08:12:51 | <dmwit> | Well, Agda uses Unicode. |
| 08:13:03 | <dmwit> | So you can get the integral symbol if you really want it. |
| 08:13:25 | <rick_2047> | cads, http://research.sun.com/projects/plrg/faq/index.html#twelve <-- here is your mailing list |
| 08:13:50 | <ray> | it's true, haskell should look like that |
| 08:14:31 | <MyCatVerbs> | ray: excuse me if I take a sliiiightly derisory view of combinators whose names are difficult to type on any keyboard that I own. |
| 08:15:14 | <cads> | rick_2047: thanks bud :) |
| 08:15:49 | <rick_2047> | cads, your most welcome |
| 08:16:13 | <ray> | monospaced code listings are so 1970s |
| 08:16:37 | <cads> | MyCatVerbs: you'd type \special_shit_{underscript}^{overscript}_subscript^superscript (function args) 3 beers a cigarette some pizza |
| 08:17:09 | <cads> | you you have to touch tex, that is |
| 08:17:15 | <ray> | i was thinking more "a fancy editor" than "write it in latex" myself |
| 08:17:32 | <ray> | if it doesn't look pretty while you're entering it what good is it |
| 08:17:37 | <cads> | I think this has special rules for turning it pretty |
| 08:17:42 | <MyCatVerbs> | cads: aye, but that's TeX notation (which I'm happy with), rather than putting Unicode characters right in (which is a pain in the unmentionables, for the moment). |
| 08:18:12 | <MyCatVerbs> | cads: ray suggested the latter, so I went "bletch!". |
| 08:19:13 | <cads> | a generic way of mapping tex to various programming semantics would be neat |
| 08:19:28 | <cads> | I wouldn't mind writing code in renderable tex |
| 08:19:39 | <cads> | as long as well written programs would typeset well :) |
| 08:20:08 | <QtPlaty[HireMe]> | Well TeX is turing compleate. |
| 08:20:15 | <cads> | I'd be killing two birds with one stone, coding and documentation |
| 08:20:26 | <ray> | you just need a fancy editor |
| 08:20:30 | <ray> | emacs could probably do it |
| 08:20:32 | <MyCatVerbs> | SCIM has a mode that lets you put unicode maths characters in by giving their TeX names, but it was a pain in the arse last time I tried to set it up, and it's kind of incomplete. |
| 08:20:40 | <cads> | QtPlaty[HireMe]: sure, but the symbols don't have any semantics of their own |
| 08:21:02 | <MyCatVerbs> | Plus, it wouldn't work anywhere near Windows, which is a bit of a problem too. (And that's me saying that as a diehard Unix goon.) |
| 08:21:35 | <MyCatVerbs> | QtPlaty[HireMe]: not only that, but TeX is deliberately Turing-complete several times over. :) |
| 08:21:47 | <cads> | when you say \sum_{a in E} a^2 in tex you're not telling it to "sum the square of every element in E", you're telling it to gorgeous-print the summation symbol |
| 08:21:55 | <MyCatVerbs> | QtPlaty[HireMe]: IIRC, at least two different phases of TeX are both Turing complete, and it's deliberate too. |
| 08:22:45 | <cads> | MyCatVerbs: really? where could I read about this? |
| 08:23:25 | <cads> | does tex have the stuff it would take to emit executable code in another language as a side effect of printing its symbols? |
| 08:23:55 | <cads> | heh, would we want to code that system in tex, in other words |
| 08:24:03 | <ray> | ouch |
| 08:24:16 | <dmwit> | cads: Oh, that's easy, the answer to that one is no. |
| 08:24:41 | <ray> | tex has what it takes to emit tex, i think |
| 08:25:25 | <cads> | that's what I thought too |
| 08:25:47 | <ray> | i doubt it can really emit, say, ELF |
| 08:25:48 | <cads> | ACTION remembers getting lost in the directory trees of tex macros for writing papers |
| 08:26:54 | <ray> | anyway, haskell source should look like the output of tex, not the (hideous) input |
| 08:27:30 | <cads> | working with that kind of format is pretty hideous in itself |
| 08:27:46 | <cads> | have you ever tried to seriously edit a typeset equation in mathematica? |
| 08:28:13 | <ray> | i don't claim that a sufficiently smart editor exists |
| 08:28:16 | <ray> | just that it's not impossible |
| 08:28:33 | <ray> | maybe it's impossible with current input devices :) |
| 08:29:49 | <cads> | well in mathematica you have a palette of symbols that you can click on, and once you've inserted say an integral sign, then putting your mouse directly over or beneath it highlights a box that you can click on to put in symbols on top or below the integral |
| 08:29:57 | <rick_2047> | where can i have a look into the base libs of haskell?? |
| 08:30:06 | <dmwit> | ?where hhl |
| 08:30:07 | <lambdabot> | I know nothing about hhl. |
| 08:30:08 | <ziman> | rick_2047, http://www.haskell.org/ghc/docs/latest/html/libraries/ |
| 08:30:12 | <dmwit> | ?where hierarchical |
| 08:30:12 | <lambdabot> | I know nothing about hierarchical. |
| 08:30:15 | <dmwit> | damn |
| 08:30:49 | <cads> | ray, that's pretty simple, but there's no way to enter code quickly that way, it's purely for final typesetting |
| 08:31:03 | <rick_2047> | ziman, i meant there source |
| 08:31:13 | <rick_2047> | ziman, i am presuming that they are written in haskell itself |
| 08:31:27 | <cads> | well I take that back, sometimes I build up integrals and stuff using pretty equations |
| 08:31:53 | <ray> | yeah, i was thinking more emacs |
| 08:32:39 | <cads> | but mathematica code is written like Integral[x^2, {x,-1,1}], and then that can both be evaluated to yield zero in this case, or a typeset integral equation |
| 08:33:11 | <ziman> | rick_2047, choose a lib, click it, scroll down the page and there you'll have a "Source" link on the right, at every function |
| 08:33:31 | <rick_2047> | ziman, isnt it included in /usr/lib/ghc?? |
| 08:33:44 | <rick_2047> | ziman, are they all executables of some type?/ |
| 08:33:47 | <cads> | emacs would be good as it would get you away from the temptation to make people write things using their mouse :) |
| 08:34:20 | <ziman> | rick_2047, yes i've got a copy in file://localhost/usr/share/doc/ghc-6.10.1/libraries/index.html |
| 08:35:45 | <ray> | pretty-entry shouldn't have to mean mouse |
| 08:35:52 | <cads> | hmm, perhaps the trick is to write haskell code that emits tex as a side effect |
| 08:36:02 | <rick_2047> | ziman, arent there any plain text files just of the source and some comments, dont want this web page crap |
| 08:36:29 | <cads> | and then lets you edit the tex rendered equations |
| 08:36:33 | <ziman> | rick_2047, i've already described how you get to the source |
| 08:37:04 | <ray> | if you do some just-in-time conversion of your expressions to tex, you can render them |
| 08:37:07 | <ray> | or something |
| 08:37:07 | <sjanssen> | rick_2047: http://darcs.haskell.org/packages |
| 08:37:10 | <cads> | wait, the haskell code wouldn't emit the tex, whatever you were using for this exercise would do it |
| 08:37:13 | <Athas> | How do I force the complete evaluation of a term? |
| 08:37:27 | <cads> | ray, yeah |
| 08:38:02 | <cads> | and I think we could bind positions in the rendered tex to positions in the code, and allow bidirectional editing |
| 08:38:09 | <sjanssen> | Athas: evaluation to WHNF is via seq, NF can be achieved with Control.Parallel.Strategies.rnf |
| 08:38:21 | <ray> | if your computer is fast enough, and people tend to lug around these multi-core gigglehertz behemoths these days, you can basically type in rendered tex |
| 08:38:38 | <Athas> | sjanssen: thanks. |
| 08:39:21 | <cads> | god what I would give for read access to the mathematica code tree |
| 08:39:56 | <ray> | tell wolfram you'll give him some fancy cellular automata in exchange |
| 08:40:10 | <cads> | would that be wolfram speak for a blowjob? |
| 08:40:22 | <cads> | because I don't think I want the code that much |
| 08:40:59 | <cads> | wolfram is nuts :) |
| 08:43:07 | <cads> | thinks the universe is cellular automata and stuff |
| 08:43:07 | <ray> | i have his doorstopper |
| 08:43:07 | <ray> | and by doorstopper, i mean garage door stopper |
| 08:43:07 | <rick_2047> | cads, well even though he is selfrighteous and cocky but he knows how to do things |
| 08:43:07 | <cads> | oh I got some respect |
| 08:43:07 | <rick_2047> | cads, u should me too not a big fan but the things he makes force me to respect him |
| 08:43:07 | <cads> | gonna start a company with my last name and all that some day |
| 08:43:30 | <rick_2047> | whats ur age?? |
| 08:43:50 | <cads> | well, I mean, he was a professor, starting a company, used code his students wrote with him |
| 08:44:07 | <cads> | academia type, politically savvy |
| 08:44:22 | <rick_2047> | i sometimes like the path he took |
| 08:44:23 | <cads> | just something I don't like about those kinds of people |
| 08:44:35 | <cads> | the path of industry you mean? |
| 08:44:40 | <mgsloan> | I agree, I have utmost respect for his products, but the man is a douche |
| 08:45:03 | <rick_2047> | cads, the path of industry through academia |
| 08:45:07 | <mgsloan> | reading a good portion of NKS convinced me of that |
| 08:45:15 | <rick_2047> | it shows people the value of academia |
| 08:45:18 | <cads> | and they're not even _his_ products, they're the work of countless developers most likely, and they just bear his name |
| 08:45:40 | <rick_2047> | cads, he has done his work in the field |
| 08:45:49 | <cads> | sure |
| 08:46:20 | <cads> | there were others too, and I don't know their name or their work |
| 08:46:34 | <cads> | I don't know him because of his work, but from his company |
| 08:46:45 | <rick_2047> | cads, that also sticks in my craw |
| 08:46:58 | <rick_2047> | he never gives creadit u know |
| 08:47:25 | <cads> | why should he, he's wolfram |
| 08:48:16 | <cads> | as far as i'm concerned computer algebra systems should be farther along than they are now |
| 08:48:25 | <sohum> | is there a screenplay for a thriller where the climax happens when a frantic haskell programmer is asked by his tormentor to calculate the fibonacci sequence and ends up launching nuclear missiles? |
| 08:48:29 | <sohum> | "Damn yoooooooou, unsafePerformIO! I thought this code was puuuuuuuure!" |
| 08:48:30 | <rick_2047> | u know if u google a quote (i dont remember exactly) but it invovles "wolfram created mathematica" google will correct u " did u mean wolfram created mathematics?" |
| 08:49:23 | <mgsloan> | I think mathematics should follow some functional stuff, and use more things like streams |
| 08:49:35 | <mgsloan> | indices as used in summation etc, are soo ugly |
| 08:50:37 | <Berengal> | mgsloan: Wouldn't that mean we need to teach high-schoolers induction? |
| 08:50:52 | <quicksilver> | ACTION learnt induction at high school. |
| 08:51:03 | <rick_2047> | Berengal, we are taught basic theory of induction in high school |
| 08:51:05 | <cads> | rick_2047: rofl |
| 08:51:06 | <ski> | indices is just another notation for function arguments |
| 08:51:10 | <mgsloan> | so did I :) but yes, it would be good |
| 08:51:14 | <cads> | @wolfram joke |
| 08:51:14 | <rick_2047> | Berengal, very basic though |
| 08:51:15 | <lambdabot> | Unknown command, try @list |
| 08:51:28 | <rick_2047> | cads, its true |
| 08:51:36 | <rick_2047> | cads, wait i find out the quote |
| 08:51:56 | <Berengal> | rick_2047: Well, I did too, in its basic form, but I was doing indexing long before that |
| 08:52:22 | <ray> | @quote wolfram |
| 08:52:22 | <lambdabot> | No quotes match. :( |
| 08:55:23 | <cads> | what's the haskell off topic chan |
| 08:55:23 | <rick_2047> | and they are back |
| 08:55:23 | <ray> | -blah |
| 08:55:23 | <cads> | h-chan if you will |
| 08:55:23 | <rick_2047> | ray, nice name |
| 08:55:23 | <ejt> | qualified bashing: I wish the 'qualified' keyword came after the module name, so I could sort my lines |
| 08:55:23 | <juhp> | hmm pandoc s5 doesn't seem to display well in chromium |
| 08:55:23 | <Berengal> | I want two types of export lists for modules: One that gets imported when no import list is given, and one of functions that can only be imported when explicitly told to |
| 08:56:26 | <dibblego> | cads, #haskell-blah |
| 08:56:29 | <quicksilver> | Berengal: the supported way to do that is do make another dummy module |
| 08:56:37 | <quicksilver> | Berengal: for the 'default' set. |
| 08:56:42 | <quicksilver> | which just imports + re-exports. |
| 08:56:58 | <quicksilver> | However there are some ways in which re-exporting is not very satisfactory. |
| 08:56:58 | <Berengal> | quicksilver: But that's ugly, no? |
| 08:58:43 | <Berengal> | Hmmm, "module Foo (foo, bar, baz) hiding (quux, fuxsputzle) where" |
| 08:58:46 | <ray> | not exactly pretty |
| 08:58:52 | <ray> | better |
| 09:01:03 | <quicksilver> | Berengal: I don't think it's particularly ugly. |
| 09:01:12 | <quicksilver> | Berengal: it's a broadly similar amount of typing. |
| 09:01:14 | <Berengal> | It'd also be nice to be able to enter a package in ghci, analogous to entering a module |
| 09:01:39 | <quicksilver> | it's mildly annoying to have a separate file but that's all |
| 09:01:46 | <quicksilver> | Berengal: packages don't have source |
| 09:01:55 | <walter_> | I am trying HStringTemplate code from http://blog.uncommons.org/2008/12/03/generating-html-with-haskell/, but I got a parse error. http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5492#a5492 |
| 09:02:06 | <Berengal> | quicksilver: No, but they have modules, which can be hidden |
| 09:03:14 | <doserj> | walter_: let template = ... instead of template = ... |
| 09:03:41 | <quicksilver> | Berengal: oh, I see what you mean. Yes. |
| 09:04:00 | <dibblego> | how would you pronounce (***) :: (Arrow a) => a b c -> a b' c' -> a (b, b') (c, c') ? |
| 09:04:55 | <Berengal> | dibblego: "foo, of type, a is an arrow in a b c gives a b c gives a b b c c" |
| 09:05:02 | <codolio> | (***) is the action of the product bifunctor on morphisms. |
| 09:05:03 | <dibblego> | I mean the function name |
| 09:05:17 | <Berengal> | foo |
| 09:05:20 | <dibblego> | heh |
| 09:06:03 | <walter_> | doserj, after add let , got another error : test.hs:6:62: Not in scope: `template' http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5492#a5493 |
| 09:07:50 | <doserj> | walter_: yes. template is not in scope in the 'where'. try making that a let to |
| 09:08:07 | <quicksilver> | I pronounce it star-star-star |
| 09:08:16 | <quicksilver> | I'm not sure if there should be a cleverer way. |
| 09:08:25 | <dibblego> | ok cheers |
| 09:08:26 | <ski> | star-thrice |
| 09:08:51 | <walter_> | doserj, thanks |
| 09:10:23 | <Peaker> | quicksilver: vertical arrow composition? |
| 09:11:37 | <ray> | i convert punctuation operators like that to grunts in my internal vocalizer |
| 09:11:44 | <ray> | they're all the same grunt because i guess it only does lexing |
| 09:12:00 | <quicksilver> | not unreasonable but I'd have to spend a few seconds each time remembering which way vertical was ;) |
| 09:12:00 | <ray> | so, it's pronounced *grunt* |
| 09:12:54 | <Peaker> | quicksilver: the arrows are always drawn horizontal :) |
| 09:22:46 | <walter_> | help please! Ambiguous type variable error: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5492#a5494 |
| 09:23:59 | <walter_> | how to fix it by add type signature |
| 09:24:30 | <doserj> | walter_: let template = (newSTMP templateText :: whatever_your_type) |
| 09:24:55 | <ski> | or |
| 09:24:57 | <ski> | let template :: Stringable a => StringTemplate a; template = newSTMP templateText |
| 09:25:27 | <walter_> | got, thank you both. |
| 09:29:20 | <poucet> | Am I the only one that finds it appalling that jonharrop owns "haskell-news.blogspot.com" where he mostly reports on negative things and then has a bunch of links to f# and ocaml books of his? |
| 09:30:04 | <quicksilver> | there are many things about jdh which sometimes appal |
| 09:30:17 | <poucet> | Disgusting |
| 09:34:48 | <walter_> | doserj, ski, still doesnt work. http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5492#a5496 |
| 09:35:44 | <doserj> | let template = (newSTMP templateText::Stringable a) doesn't work because it simply doesn't have this type. |
| 09:36:13 | <doserj> | try let template = (newSTMP templateText::StringTemplate String) or sth similar. |
| 09:36:31 | <ski> | `Stringable a' isn't a type |
| 09:36:42 | <walter_> | I see |
| 09:36:49 | <doserj> | let template :: Stringable a => StringTemplate a doesn't work, because you also need to give a definition for template. |
| 09:36:59 | <doserj> | try let template :: Stringable a => StringTemplate a; template = ... |
| 09:37:08 | <walter_> | This work: let template = (newSTMP templateText::StringTemplate String) |
| 09:37:21 | <walter_> | thanks, doserj |
| 09:37:24 | <ski> | (doserj : which was what i suggested above :) |
| 09:37:58 | <doserj> | (ski: I know :) |
| 09:38:26 | <ski> | walter_ : btw, why are you entering this into GHCi, instead of into a file, as you seemed to try before ? |
| 09:39:16 | <walter_> | ski, because I the demo code doesn't work, and I want to find why. |
| 09:39:50 | <walter_> | this is the demo code from http://blog.uncommons.org/2008/12/03/generating-html-with-haskell/, |
| 09:40:42 | <walter_> | let template :: StringTemplate String |
| 09:41:21 | <ski> | (walter_ : i would try binary search, instead of trying to enter the code in GHCi) |
| 09:42:16 | <walter_> | Infact, I am very green on Haskell. Just want do that step by step to understand. :) thank you. |
| 09:42:50 | <ski> | (i.e. binary search debugging) |
| 09:43:45 | <walter_> | ski, I still have no idea on debugging, btw how to do binary search |
| 09:45:33 | <ski> | comment out about half the code (making sure not to comment out code which the non-commented-out code depends on, optionally instead making stubs); if still error, repeat on non-commented-out code; otherwise; flip what is commented-out and repeat |
| 09:46:55 | <ski> | (btw, generally, if you get actual static error messages, that provides you with hopefully-not-too-far-off file positions from which to look for an error) |
| 09:50:05 | <walter_> | ski, thank you very much. |
| 09:50:51 | <cads> | hey, ski, I always wonder, what's the ski combinator do? |
| 09:51:18 | <cads> | i've looked it up multiple times I'm sure, but either couldn't get it or it was so basic I subsequently forgot it |
| 09:51:39 | <dolio> | @type ap const id |
| 09:51:45 | <lambdabot> | forall b. b -> b |
| 09:51:57 | <hackagebot> | explicit-sharing 0.5.0 |
| 09:52:00 | <cads> | oh it's the whole combinator calculus |
| 09:52:47 | <dolio> | s and k are all you need, technically. You can define i in terms of them. |
| 09:53:08 | <cads> | aaaah skiskiskiski |
| 09:53:18 | <cads> | wonder what I just programmed |
| 09:53:37 | <dolio> | skxy = ky(xy) = y, so skx = i for all x. |
| 09:53:47 | <ski> | i |
| 09:54:16 | <dolio> | Provided the types work out, if you worry about that. |
| 09:55:16 | <ski> | @type let s = ap; k = return; i = id in s k i s k i s k i s k i |
| 09:55:23 | <lambdabot> | forall a. a -> a |
| 10:13:44 | <Tarrant> | So I'm loving this lazy thing. It is kinda freaking me out. So: take 10 (reverse [1..100]) really only generates 100-91? |
| 10:13:59 | <ejt> | nope |
| 10:14:30 | <Berengal> | It generates [1..100] and [100..91] |
| 10:15:12 | <BONUS> | the thing about reverse is that it needs all the elements |
| 10:15:33 | <Tarrant> | That makes sense |
| 10:15:40 | <idnar> | BONUS: surely reverse only forces the spine? |
| 10:15:44 | <BONUS> | haskell is smart but not smart enough to figure out that it could only use 100..91 |
| 10:16:07 | <Tarrant> | If you have a pre-generated list can it take the shortcut? |
| 10:16:15 | <idnar> | hmm |
| 10:16:24 | <idnar> | > take 10 (reverse [1..100000]) |
| 10:16:30 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 10:16:30 | <lambdabot> | mueval: ExitFailure 1 |
| 10:16:44 | <BONUS> | for instance, suppose you have a list iterate (*2) 1 |
| 10:17:04 | <hackagebot> | minesweeper 0.4.1 |
| 10:17:27 | <Berengal> | > iterate (*2) 1 |
| 10:17:32 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 10:17:32 | <lambdabot> | mueval: ExitFailure 1 |
| 10:17:40 | <Berengal> | > 2 + 2 |
| 10:17:46 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 10:17:46 | <lambdabot> | mueval: ExitFailure 1 |
| 10:18:01 | <Berengal> | Lambdabot's in a funk :/ |
| 10:18:02 | <BONUS> | > take 3 . reverse . take 10 $ iterate (*2) 1 |
| 10:18:06 | <idnar> | @src reverse |
| 10:18:07 | <lambdabot> | reverse = foldl (flip (:)) [] |
| 10:18:07 | <lambdabot> | [512,256,128] |
| 10:18:35 | <BONUS> | haskell has to calculate all the elements up to the tenth one |
| 10:19:12 | <BONUS> | it can't figure out that it could just do [2^9, 2^8, 2^7] on its own |
| 10:19:19 | <Tarrant> | Makes sense. |
| 10:19:20 | <idnar> | > take 3 . reverse . take 1000000 $ iterate (*1) 1 |
| 10:19:26 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 10:19:26 | <lambdabot> | mueval: ExitFailure 1 |
| 10:19:35 | <idnar> | bleh, it takes too long, but I think that should stack overflow |
| 10:19:38 | <BONUS> | this is much like take 10 ( reverse [1..100]), only a bit more obvious |
| 10:19:50 | <mgsloan> | wouldn't it not actually perform the calculations, and thunk them all? |
| 10:20:48 | <BONUS> | fing is, with iterate (*2) 1, to get the nth element, it has to know the n-1th element |
| 10:21:08 | <BONUS> | so they will all have to be evaluated eventually, but most of them will be dropped |
| 10:21:44 | <opqdonut> | yeah, instead of keeping the list in memory, that keeps the huge 2*2*2*2*2*2*...1 thunk in memory |
| 10:24:24 | <Tarrant> | So lets say I have: xs = [1..100]. Using the function: "take 10 (reverse xs)" It reverses 100-91 before realizing that it has the 10 it needs and stops reversing the list, correct? |
| 10:24:48 | <opqdonut> | it has to iterate to the end of the list first |
| 10:24:57 | <opqdonut> | and build the reversed list at the same time |
| 10:24:58 | <opqdonut> | so no |
| 10:25:09 | <Tarrant> | Yes, sorry I'm using [1..100] as shorthand instead of writing [1,2... |
| 10:25:15 | <opqdonut> | but "take 10 [1..1000000]" will only generate ten numbers |
| 10:25:48 | <opqdonut> | Tarrant: getting to the end of a haskell list is O(n) |
| 10:25:55 | <opqdonut> | so no magical help here |
| 10:26:11 | <Tarrant> | opqdonut: Ok I think I have it now. |
| 10:26:16 | <Beelsebob1> | I think the key phraze here is that reverse is strict in the spine of the list |
| 10:26:26 | <Beelsebob1> | so the whole list spine will get evaluated |
| 10:26:31 | <opqdonut> | yeah |
| 10:26:31 | <Beelsebob1> | but not all the numbers will |
| 10:26:35 | <BONUS> | yeah |
| 10:26:40 | <BONUS> | the : : : : [] things |
| 10:26:54 | <ejt> | It's more obvious if you put an expensive comuptation in the list |
| 10:26:56 | <ejt> | take 10 . reverse . map fib $ [1000,999..1] |
| 10:27:05 | <opqdonut> | good point |
| 10:27:09 | <Beelsebob1> | yep |
| 10:27:15 | <Beelsebob1> | so that will only do 10 expensive computations |
| 10:27:38 | <Beelsebob1> | but will still create a 1000 element list of thunks |
| 10:29:46 | <Tarrant> | Thanks. That's really awesome. |
| 10:31:31 | <BONUS> | this is a pretty good read if you want to understand laziness in depth http://en.wikibooks.org/wiki/Haskell/Laziness |
| 10:35:08 | <koala_man> | where does the word "thunk" come from? |
| 10:35:56 | <quicksilver> | old english future tense of 'think' |
| 10:36:07 | <quicksilver> | it means 'something which I may or may not think in the future' |
| 10:37:52 | <dibblego> | @check \a b -> a + b == b + a |
| 10:37:56 | <lambdabot> | mueval-core: Time limit exceeded |
| 10:38:08 | <ejt> | koala_man: http://www.ccil.org/jargon/jargon_35.html |
| 10:38:45 | <ejt> | 'the sound made by data hitting the stack' lol |
| 10:41:52 | <mornfall> | Hackage does not love me? : - ( ERROR: dist/hashed-storage-0.3.1.tar.gz: 400 Error in upload |
| 10:51:30 | <TThijs> | can somebody tell me what the $ does in a haskell functions |
| 10:51:55 | <wjt> | TThijs: f <$> x = f x |
| 10:52:01 | <wjt> | erm. f $ x = f x |
| 10:52:32 | <ejt> | TThijs: it applies a function to an argument |
| 10:52:34 | <wjt> | it's used to let you omit parentheses around the argument when they would otherwise be necessary |
| 10:52:39 | <wjt> | > show (5 + 3) |
| 10:52:45 | <lambdabot> | mueval-core: Prelude.read: no parse |
| 10:52:45 | <lambdabot> | mueval: ExitFailure 1 |
| 10:52:50 | <wjt> | lambdabot: uh... |
| 10:52:54 | <wjt> | > show (5 + 3 :: Int) |
| 10:52:55 | <BONUS> | f $ x is just f x, thing is it has rly low precedence |
| 10:52:56 | <lambdabot> | "8" |
| 10:53:01 | <wjt> | > show $ 5 + 3 |
| 10:53:02 | <lambdabot> | "8" |
| 10:53:07 | <wjt> | > show 5 + 3 |
| 10:53:08 | <lambdabot> | No instance for (GHC.Num.Num GHC.Base.String) |
| 10:53:08 | <lambdabot> | arising from the literal `... |
| 10:53:26 | <BONUS> | so instead of writing reverse (take 10 [1..]), you can write reverse $ take 10 [1..] |
| 10:54:00 | <mgsloan> | and usage of $ leads to a very direct path to compositional style |
| 10:54:52 | <Gracenotes> | anything has lower precedence than function application |
| 10:55:29 | <TThijs> | thanks wjt |
| 10:55:43 | <ejt> | try not to chain more than one $ together, use (.) instead. eg, "take 10 $ map fib $ [1..]" is better written "take 10 . map fib $ [1..]" |
| 10:56:51 | <koala_man> | why is it better written like that? |
| 10:57:34 | <ejt> | because it's getting you thinking in a more compositional (point free) way |
| 10:58:22 | <BONUS> | take 10 . reverse . tail $ xs is cool because you can do z = take 10 . reverse and then say z . tail $ xs |
| 10:58:33 | <BONUS> | but you can't say z = take 10 $ reverse |
| 10:58:41 | <BONUS> | cause that tried to apply take 10 to reverse |
| 10:58:42 | <Gracenotes> | not to mention, "a $ b $ c" relies on the infixity of ($) being right. |
| 10:59:04 | <Gracenotes> | so a $ b $ c $ d means (a $ (b $ (c $ d))) |
| 10:59:47 | <Gracenotes> | if the infixity is left -- not a terribly mind-boggling change to make -- then a $ b $ c $ d's won't be valid a . b . c $ d will be, though |
| 11:00:22 | <Gracenotes> | just a note. Since I have heard arguments for changing the infixity before |
| 11:00:47 | <canvon> | so the underlying difference is that (.) is associative, ($) isn't? interesting... |
| 11:00:48 | <ejt> | Gracenotes: wow, that would break _so_ much |
| 11:01:01 | <ski> | Gracenotes : .. except `@',`~',`!',record construction/update) |
| 11:01:41 | <Gracenotes> | then "a $ b $ c $ d" will be equivalent to "a b c d", not "a (b (c d))". It would break a lot, but not if (.) is used where appropriate :) |
| 11:01:50 | <ski> | > (:[]) Node {rootLabel = 1,subForest = []} {rootLabel = 42} |
| 11:01:53 | <lambdabot> | [Node {rootLabel = 42, subForest = []}] |
| 11:02:08 | <canvon> | (okay, ($) can't be associative, as the type signature tells ($) uses two arguments that /have/ to be of different type...) |
| 11:02:36 | <canvon> | Gracenotes: what's the point of using $, then? :) |
| 11:02:54 | <ski> | Gracenotes : additionally, it seems more useful for `$!' to be `infixl' (or renamed) |
| 11:03:07 | <Gracenotes> | canvon: The main difference is how they're used in practice to eliminate parens :) |
| 11:03:27 | <ejt> | canvon: just read some haskell code, it's used a lot |
| 11:03:30 | <Gracenotes> | (.) composes functions. ($) applies functions |
| 11:03:35 | <canvon> | Gracenotes: no, I meant: when it would be changed to being left associative |
| 11:03:39 | <ejt> | plus people pass it around too as ($) |
| 11:03:53 | <canvon> | Gracenotes: in response to what you said |
| 11:03:55 | <BONUS> | it's cool to write stuff like |
| 11:04:19 | <BONUS> | filter (>3) $ take 10 xs |
| 11:04:23 | <BONUS> | you could write that as |
| 11:04:28 | <BONUS> | filter (>3) . take 10 $ xs |
| 11:04:40 | <BONUS> | but i think the first option is better |
| 11:04:58 | <Gracenotes> | canvon: for function application. "map show . filter even $ [1..10]" could still be used. The function is "map show . filter even", and the value is "[1..10]". However, you couldn't chain function application, merely apply more arguments |
| 11:05:40 | <Gracenotes> | so if it was left-associative, you could write "filter $ const True $ [1..10]", although I'm not sure how useful this would be :) |
| 11:06:53 | <ski> | (BONUS : the first option work work with left-associative `$' as well ..) |
| 11:07:05 | <BONUS> | yeah |
| 11:07:08 | <ski> | consider |
| 11:07:10 | <Gracenotes> | plus, ($) and (.) are frequently used together, and mixing left-associative operators and right-associative operators tends to be a nightmare if not done carefully. in languages like C/C++/Java, too |
| 11:07:13 | <ski> | foldl' f z [ ] = z |
| 11:07:14 | <ski> | foldl' f z (a:as) = (foldl' f $! f z a) as |
| 11:07:41 | <ski> | if `$' (and `$!') were left-associative, we could write the last equation as |
| 11:07:48 | <ski> | foldl' f z (a:as) = foldl' f $! f z a $ as |
| 11:08:05 | <BONUS> | yeah, $ should have been made left associative |
| 11:08:24 | <PeakerWork> | ski: that's one big empty list! |
| 11:08:43 | <quicksilver> | there is an argument not to make it associative |
| 11:08:48 | <ski> | ACTION likes the empty lists lining up with the cons pattern :) |
| 11:09:00 | <quicksilver> | withWidgets $ withFudgets $ do ..... |
| 11:09:00 | <BONUS> | i never thought of matching up the [ and ] and the cons pattern |
| 11:09:04 | <BONUS> | it actually looks really nice |
| 11:09:25 | <quicksilver> | sorry "not to make it associate to the left", I mean |
| 11:09:58 | <ski> | you could use `.' there .. but one might consider that unnatural, i suppose |
| 11:10:01 | <Gracenotes> | BONUS: hm. I like the idea of matching "(x:xs)" with "[] " (with spaces), mahself |
| 11:10:22 | <ski> | (i don't recall which i've used) |
| 11:10:41 | <quicksilver> | ski: that's not quite the point |
| 11:10:51 | <quicksilver> | ski: it was a warmup |
| 11:10:54 | <quicksilver> | ski: now suppose you have |
| 11:11:14 | <quicksilver> | withThisWidget $ \widg -> withThisFudget $ \fudg -> do .... |
| 11:11:22 | <quicksilver> | ski: now you *really* have to use $. |
| 11:11:49 | <quicksilver> | ski: so the full argument is - it would be annoying swapping between $ and . based on whether the with construct has a binding or not |
| 11:12:11 | <Saizan> | nah, you simply rewrite that in the ContT monad ;) |
| 11:12:11 | <ski> | Gracenotes : how about lining up ` Nothing ' with `(Just foo)' ? :) |
| 11:12:31 | <ski> | (Gracenotes : or `(Left e)' with `(Right a)' ?) |
| 11:12:58 | <Gracenotes> | I'd probably go with "(Left e) " and "(Right a)" :) But it depends |
| 11:12:59 | <ski> | quicksilver : i see your point |
| 11:13:10 | <quicksilver> | I line up the = signs in defintions. I don't bother to line up the () in the constructors. |
| 11:13:22 | <quicksilver> | if there are multi-arg constructors I line the args up though |
| 11:13:34 | <quicksilver> | (or multiple args to the function) |
| 11:13:52 | <Gracenotes> | it depends.. |
| 11:13:52 | <quicksilver> | ski: it was someone else's point, I dont' remember whose, but it struck me as a good one :) |
| 11:13:56 | <Gracenotes> | hm |
| 11:15:18 | <Gracenotes> | on the other hand, changing the infixity of (.) from right wouldn't exactly break anything |
| 11:15:46 | <Gracenotes> | but.. given the way we think of composition.. possibly not bright |
| 11:15:54 | <ski> | it might be nice if editing modes lined up things like the `='/`->' (& `|') .. |
| 11:16:19 | <Twey> | ski: I always line up my arguments |
| 11:16:33 | <philipp_> | i've got a function with a memory leak because of lazyness, printing the variable seems to fix this but how can i get the same effect without printing? already tried several possibilities with `seq` but it seems that i need hnf data, here's the function: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5497#a5497 where " lift $ print (f2i 0) |
| 11:16:38 | <philipp_> | is the fix |
| 11:16:50 | <Twey> | You end up with a sort of ‘table’ of functions, instead of a bunch of discordant lines |
| 11:16:56 | <ski> | Twey : maybe you should create a poll for this ? :) |
| 11:17:08 | <ski> | s/you/we/ |
| 11:17:19 | <Twey> | It's possibly the only good thing about different patterns require the same number of arguments :-P |
| 11:17:23 | <Twey> | A poll? What sort of a poll? |
| 11:17:29 | <ski> | @list poll |
| 11:17:30 | <lambdabot> | poll provides: poll-list poll-show poll-add choice-add vote poll-result poll-close poll-remove |
| 11:17:35 | <Twey> | Oho |
| 11:17:36 | <Twey> | Good idea |
| 11:17:42 | <Twey> | How does this work? |
| 11:17:53 | <ski> | @help poll-add |
| 11:17:54 | <lambdabot> | poll-add <name> Adds a new poll, with no candidates |
| 11:18:02 | <ski> | @help choice-add |
| 11:18:03 | <lambdabot> | choice-add <poll> <choice> Adds a new choice to the given poll |
| 11:18:03 | <Twey> | @help choice-add |
| 11:18:04 | <lambdabot> | choice-add <poll> <choice> Adds a new choice to the given poll |
| 11:18:05 | <Twey> | Heh |
| 11:18:11 | <Twey> | Noted |
| 11:18:28 | <quicksilver> | ski: I make frequent use of M-x align-regexp |
| 11:18:31 | <Twey> | @poll-list |
| 11:18:32 | <lambdabot> | ["logoVotingMethod"] |
| 11:18:41 | <Twey> | @poll-show logoVotingMethod |
| 11:18:41 | <lambdabot> | ["Schulze"] |
| 11:18:46 | <Twey> | o.@ |
| 11:19:20 | <Saizan> | philipp_: can you paste the definition of Model too? |
| 11:19:21 | <Twey> | @poll-add functionFormatting |
| 11:19:22 | <lambdabot> | Added new poll: "functionFormatting" |
| 11:19:31 | <ski> | ACTION hasn't seen that emacs command before .. |
| 11:19:40 | <philipp_> | Saizan: sure, one second |
| 11:19:54 | <Twey> | @choice-add functionFormatting Line up = and all arguments |
| 11:19:54 | <lambdabot> | usage: @choice-add <poll> <choice> |
| 11:20:09 | <Twey> | ACTION scratches his head. |
| 11:20:33 | <philipp_> | Saizan: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5499#a5499 |
| 11:22:05 | <quicksilver> | ski: it's great for not just making code pretty. It also lets you line up text data into columns, so you can edit them with rectangle mode |
| 11:22:08 | <Saizan> | philipp_: i'd probably make all the fields strict |
| 11:22:19 | <Twey> | quicksilver: Cool |
| 11:22:38 | <Saizan> | philipp_: also, i don't see where the getF2I field is populated |
| 11:22:46 | <philipp_> | Saizan: how? bang patterns? |
| 11:23:16 | <Saizan> | philipp_: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5499#a5500 |
| 11:23:24 | <mornfall> | Oh. |
| 11:23:29 | <ski> | (quicksilver : ty) |
| 11:23:36 | <mornfall> | Btw, what's the cabal version that comes with ghc 6.8? |
| 11:23:41 | <philipp_> | Saizan: thanks, I'll try that |
| 11:23:49 | <dcoutts> | mornfall: 1.2.x |
| 11:25:19 | <hackagebot> | hashed-storage 0.3.1 |
| 11:25:22 | <mornfall> | Hm, "cabal upload" should probably give full error text from hackage, not just "ERROR". :) |
| 11:25:26 | <philipp_> | Saizan: now i get a strange error while running the binary |
| 11:25:33 | <ski> | philipp_ : style comment : i'd define arnold' in a `let' in the `do'-block, to avoid passing in `fina',`finb',`f2i' .. or even use `flip parMapM [(a,b) | ...] $ \(a,b) -> do ...' |
| 11:25:55 | <Saizan> | philipp_: which error? |
| 11:26:05 | <philipp_> | Saizan: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5499#a5501 |
| 11:26:11 | <philipp_> | ski: thanks |
| 11:27:09 | <dcoutts> | mornfall: http://hackage.haskell.org/trac/hackage/ticket/549 |
| 11:27:14 | <Saizan> | philipp_: uhm, that's weird, try with -fforce-recomp |
| 11:27:30 | <ski> | i.e. |
| 11:27:34 | <ski> | flip parMapM (liftM2 (,) omegaA omegaB) $ \(a,b) -> do |
| 11:27:36 | <ski> | ... |
| 11:27:38 | <mornfall> | dcoutts: : - ) |
| 11:27:58 | <dcoutts> | mornfall: patches gratefully accepted :-) |
| 11:28:01 | <philipp_> | Saizan: didn't work |
| 11:28:05 | <mornfall> | I imagine. :) |
| 11:28:24 | <mornfall> | But if I get cabal hacking time, I'll first and foremost fix the double compile that darcs suffers. |
| 11:28:28 | <Saizan> | philipp_: i meant recompiling with that flag |
| 11:28:42 | <Saizan> | philipp_: if it still doesn't work it looks like a ghc bug |
| 11:28:49 | <philipp_> | I did |
| 11:28:54 | <dcoutts> | mornfall: great then you can work on this ticket, because the double compile is fixed :-) |
| 11:28:55 | <mornfall> | Which ought to have happened long time ago, but I somehow managed to not have that time. |
| 11:29:04 | <mornfall> | dcoutts: \o/ |
| 11:29:05 | <mornfall> | : - ) |
| 11:29:20 | <mornfall> | Maybe I should upgrade my cabal, then. :) |
| 11:29:41 | <dcoutts> | mornfall: it's not released yet, it went in the day before yesterday |
| 11:29:57 | <mornfall> | Well, I can sustain some breakage from unreleased cabal versions. |
| 11:29:59 | <philipp_> | Saizan: it's probably also not a good idea to use bang patters since constructing the Model takes a lot of time and the program should only construct those Models which are actually used in a function |
| 11:30:01 | <mornfall> | I guess. |
| 11:30:10 | <mornfall> | : - ) |
| 11:30:21 | <dcoutts> | mornfall: then you need Cabal head and cabal-install head |
| 11:30:30 | <mornfall> | Aye, working on it. Let's see. |
| 11:30:54 | <Saizan> | philipp_: the strict fields will only ensure that if you use a Model it won't hide unevaluated thunks in it |
| 11:31:07 | <Saizan> | philipp_: they won't force the creation of the whole model by themselves |
| 11:31:26 | <philipp_> | Saizan: ah ok |
| 11:31:32 | <philipp_> | that should be fine |
| 11:31:50 | <Saizan> | philipp_: however since most fields are functions they can "hide" unevaluated thunks inside them, depending on how they are constructed |
| 11:33:36 | <Saizan> | or keep something alive that should be GC'ed |
| 11:33:55 | <Saizan> | you could use heap profiling to get a better idea of what's going on |
| 11:34:03 | <Saizan> | ?google ghc heap profiling |
| 11:34:05 | <lambdabot> | http://www.haskell.org/ghc/docs/latest/html/users_guide/prof-heap.html |
| 11:34:05 | <lambdabot> | Title: 5.4.�Profiling memory usage |
| 11:34:18 | <philipp_> | Saizan: thanks! |
| 11:35:35 | <philipp_> | Saizan: now it works, but it doesn't have the same effect as printing |
| 11:37:03 | <Saizan> | philipp_: you mean it uses less memory but not so much less? |
| 11:37:28 | <Saizan> | maybe with "!f2i <- gets .." |
| 11:37:53 | <Saizan> | the code is a bit dense and partial so i'm kind of shooting in the dark :) |
| 11:38:24 | <philipp_> | also doesn't work, memory goes up all the time |
| 11:39:42 | <philipp_> | Saizan: added some revisions |
| 11:39:55 | <Saizan> | a bruteforce option is to write !() <- rnf (f2i 0) `seq` return () |
| 11:40:11 | <Saizan> | instead of the lift (print (f2i 0)) |
| 11:41:40 | <philipp_> | yes, that works |
| 11:41:56 | <LeCamarade> | @tell conal Well, it was only tangentially about threads. I had asked about what prompted different behaviour between native and runhaskell, and you asked if my program was threaded. |
| 11:41:57 | <lambdabot> | Consider it noted. |
| 11:43:00 | <LeCamarade> | @tell conal Well, it is threaded, and learning the vagaries of threads under both native and runhaskell GHC programs (from you, I hoped) would likely be helpful. |
| 11:43:00 | <lambdabot> | Consider it noted. |
| 11:44:35 | <philipp_> | (f2i 0) `seq` parMapM ... also seems to work |
| 11:44:59 | <Saizan> | LeCamarade: native without -threaded doesn't use the threaded runtime which is instead used by ghci and runghc |
| 11:45:08 | <MarcWeber> | Any chance implementing something like SQLAlchemy (python lib) in haskell ? |
| 11:45:30 | <Saizan> | LeCamarade: the threaded runtime can run haskell threads in multiple OS threads |
| 11:45:31 | <Baughn> | MarcWeber: What's it do? |
| 11:46:03 | <Baughn> | LeCamarade: The threaded runtime can also spawn OS threads to handle blocking system/library calls, which may otherwise block a program with multiple haskell threads |
| 11:46:12 | <LeCamarade> | Ha! |
| 11:46:18 | <MarcWeber> | Baughn I'ts a SQL framework for python including an ORM (object relational mapper). So you can get "users" and lazy load associated adresses. |
| 11:46:32 | <quicksilver> | I started to explain this to LeCamarade yesterday |
| 11:46:37 | <LeCamarade> | So ... I'm probably being bitten by that. |
| 11:46:40 | <quicksilver> | evidently my explanation didn't entirely satisfy :) |
| 11:46:41 | <Baughn> | MarcWeber: Well, an object-relational mapper doesn't really make sense in haskell? |
| 11:46:53 | <LeCamarade> | quicksilver, You were much help, but I want a PhD in Haskell threads, it seems. :o) |
| 11:47:02 | <Baughn> | MarcWeber: Lazily reading results, of course, is easy. |
| 11:47:04 | <quicksilver> | MarcWeber: lazy loading of columns is the biggest make an ORM ever made :) |
| 11:47:06 | <MarcWeber> | Baughn It depends on how you do define "object" if you consider AGDTs beeing objects (estimatino) then yes! |
| 11:47:08 | <LeCamarade> | GHC threads, to be precise. |
| 11:47:24 | <quicksilver> | LeCamarade: did you try compiling with -threaded? |
| 11:47:43 | <MarcWeber> | quicksilver The point is : It's short to write. I don't even know if you can get such a nice syntax in haskell. |
| 11:48:10 | <LeCamarade> | quicksilver, Yes, and I'm closer to a solution because of that. |
| 11:48:11 | <quicksilver> | I was making a specific point about lazy column loading. |
| 11:48:17 | <LeCamarade> | Now, it blocks immediately. |
| 11:48:19 | <quicksilver> | not a general point about conveneitn database mappers. |
| 11:48:28 | <MarcWeber> | And if it works (I haven't tried) its really nice to use. While writing you applications you don't want to bother with IO, you don't want to think about monads, you don't want to think about relations. This lib seems ome close to this. |
| 11:48:28 | <LeCamarade> | It deadlocks immediately, rather. |
| 11:49:01 | <Baughn> | MarcWeber: You can do quite interesting things with SYB/TH and relatives |
| 11:49:02 | <quicksilver> | I think some of the haskell database libraries try to be convenient in this way |
| 11:49:08 | <quicksilver> | I haven't used any opf them. |
| 11:49:25 | <MarcWeber> | Baughn You can't do users[0].adresses[0].user.name |
| 11:49:30 | <Baughn> | MarcWeber: Also, in my experience, you /do/ want to think about monads. They help a lot, when appliable. |
| 11:49:47 | <Baughn> | MarcWeber: Sure you can. You might have to write the code first, but you can do that. |
| 11:50:24 | <MarcWeber> | Baughn How does it look then? |
| 11:50:35 | <p_l> | MarcWeber: I think I had seen it work quite nicely, easily, in something that might be quite nicely modified into functional world... |
| 11:50:52 | <quicksilver> | users ! 0 # Address ! 0 # User # Name |
| 11:51:02 | <quicksilver> | assuming appropriate definitions (and fixities!) for ! and # |
| 11:51:17 | <MarcWeber> | users >>= \l -> l!!0 >>= adresses >>= x \-> x!!1 >>= user ? @ Baughn |
| 11:51:28 | <Baughn> | MarcWeber: Ugh. That's awful. |
| 11:51:35 | <quicksilver> | where Address, User, Name would be constructors from appropriate field datatypes. |
| 11:52:43 | <MarcWeber> | Baughn By the way my example showed how back references can be used. |
| 11:53:11 | <Baughn> | MarcWeber: Unfortunately it was also unreadable. I prefer mercury's version. |
| 11:53:20 | <MarcWeber> | users[0].adresses[0].user.name thus the user at the end is the same object as users[0]. Of course you can start messing around with fix types and such.. but you don't want to. |
| 11:54:01 | <MarcWeber> | So how I can I represent this 1 user has many addresses relation easily? Using data User = User [Adress] ? |
| 11:54:20 | <Baughn> | That's one way |
| 11:54:36 | <Baughn> | Of course, instead of Address being the literal address value, it'd probably be some kind of reference to SQL-reading code |
| 11:54:39 | <MarcWeber> | Then when passing an address I don't have a reference to users. (I know this is nice if you want to start using multithreading..) |
| 11:55:44 | <MarcWeber> | Baughn: users[0].adresses[0].user.name so how many selects do you want to run here? |
| 11:56:05 | <Baughn> | MarcWeber: One, of course |
| 11:56:52 | <Baughn> | Though it'd be a pretty complex one, I suppose |
| 11:57:10 | <Baughn> | Still. There's only one deRefSQL call in there. |
| 11:57:31 | <ketil> | Is there a way to get my own URL using (Fast)CGI? |
| 11:57:31 | <lambdabot> | ketil: You have 3 new messages. '/msg lambdabot @messages' to read them. |
| 11:57:49 | <MarcWeber> | Baughn: The alchemy lib can do more. You can just do users[3].name="newname" and do a session.commit() afterwards. Only the "users" which have changed will be written back to the database. |
| 11:58:15 | <Baughn> | MarcWeber: A simple matter of programming. What's your point? |
| 11:58:53 | <MarcWeber> | Baughn That I'd like haskell to take off. But all the sql libs made me having headache for different reasons. |
| 11:59:22 | <quicksilver> | well it's certainly not a limitation of haskell as a language |
| 11:59:23 | <MarcWeber> | And reading that documentation made me think: Yes, that's what I want to use, no matter wether it has been written in haskell or python. |
| 11:59:32 | <quicksilver> | it may be a limitation of the libraries, or their docs |
| 12:12:42 | <saynte> | WTB: someone who has used the LLVM hackage-package ;) |
| 12:13:52 | <ejt> | I played with LLVM last week |
| 12:14:06 | <ejt> | working through Lennarts posts |
| 12:15:25 | <portartus> | Hallo |
| 12:15:57 | <portartus> | ihr seid doch alle schwul! |
| 12:16:29 | <portartus> | hello |
| 12:16:33 | <portartus> | any1 here? |
| 12:17:35 | <Beelsebob> | people are here |
| 12:17:41 | <Beelsebob> | but you may want to try #haskell.de |
| 12:17:48 | <ejt> | he's gone |
| 12:17:52 | <MarcWeber> | he's gone and he's lacking brain. |
| 12:17:52 | <Beelsebob> | oh, so he has >.< |
| 12:18:26 | <MarcWeber> | Beelsebob: he said "you're all gay" |
| 12:18:42 | <quicksilver> | statistically it's likely that some of us are |
| 12:18:48 | <quicksilver> | but overwhelmingly unlikely that we all are |
| 12:18:58 | <quicksilver> | poor chap just doesn't understand demographics very well |
| 12:19:24 | <saynte> | ejt: have you tried to create anything like a compiler yet? |
| 12:19:40 | <saynte> | ejt: in the sense of going from AST -> bytecode using the bindings? |
| 12:19:51 | <ejt> | saynte: no, I was tempted to code up the 'kaleidescope' example from the llvm docs |
| 12:20:36 | <ejt> | I basically worked through Lennarts posting, then decided that I need to understand LLVM more so worked through writing assembly directly for a bit |
| 12:21:15 | <ejt> | I'm looking at it to compile a little fractal rendering DSL |
| 12:21:19 | <saynte> | ejt: hmm. yeah. i was curious, because it seems like the strong typing that they have used to represent functions is rather too restrictive. |
| 12:21:39 | <ejt> | I had terrible trouble with the for loop construct |
| 12:22:02 | <ejt> | and it's return type |
| 12:22:18 | <saynte> | In their "examples" directory, or from the LLVM tutorial? |
| 12:22:22 | <tux-foo> | twanvl, ping |
| 12:22:36 | <tux-foo> | twanvl, tux-foo=foo-nix |
| 12:22:41 | <ejt> | from Lennarts posting |
| 12:22:42 | <jacobian> | yarg, for some reason my program isn't lazy enough |
| 12:23:03 | <ejt> | there is an examples dir of haskell code ? |
| 12:25:14 | <saynte> | yeah, in the repository/package. |
| 12:25:20 | <saynte> | did you get it from cabal? |
| 12:26:33 | <ejt> | y, but I just installed it |
| 12:26:43 | <ejt> | ok, I should look through those |
| 12:27:15 | <ejt> | I was very impressed with the code that LLVM produces |
| 12:27:46 | <saynte> | yeah, it has this reputation :) |
| 12:27:51 | <ejt> | very similar performance to gcc on the little examples I tried |
| 12:28:13 | <ejt> | what are you using it for ? |
| 12:28:42 | <saynte> | and the binding the have on hackage is pretty good i think except for this one area that I can't for the LIFE of me figure out how to write functions from an AST in it. |
| 12:28:54 | <saynte> | just trying to write a small language as an experiment. |
| 12:29:02 | <saynte> | so far (as you can tell) I am hung up on functions. |
| 12:31:00 | <ejt> | ok, let me dig a bit ... |
| 12:31:55 | <saynte> | yeah. the trick is this: it's easy to do if you write your functions in Haskell, because you'll define them like a Haskell function, and it will use it's type-class trickery to make it all ok. |
| 12:32:30 | <saynte> | however, if you have a representation of a function from a file at runtime, then you're in more trouble. |
| 12:32:40 | <ejt> | hmm, I don't think that's much different |
| 12:32:43 | <ejt> | let me try |
| 12:33:13 | <blackh> | Hi all. Is there a 'touch' function that allows you to prevent a data structure (with a finalizer attached) getting GC'ed, like touchForeignPtr but for general data structures? |
| 12:33:34 | <ejt> | blackh: just hold onto a reference ? |
| 12:33:52 | <Lemmih> | blackh: The short answer is no. |
| 12:34:20 | <blackh> | ejt: I've pulled a Chan out of my data structure and I'm waiting on that, and I want to keep it alive until something is received... I could add the finalizer to the Chan but that doesn't solve the problem..... |
| 12:34:36 | <blackh> | because Chan in turn has its own internal structure. |
| 12:34:45 | <saynte> | ejt: a good example may be to try to create an "incr" function, fairly simple but should show you the problem. |
| 12:34:48 | <blackh> | Lemmih: Thanks. I'll see if I can't dream something up. |
| 12:34:52 | <ejt> | saynte: y |
| 12:35:13 | <ejt> | blackh: just have another thread wait on the channel ? |
| 12:36:16 | <blackh> | ejt: Well, waiting on the Chan doesn't actually necessarily keep the top-level 'Chan' data structure alive. That assumes things about how it's implemented. |
| 12:36:32 | <saynte> | ejt: because it's very hard to do. so essentially go from a function data-type to an LLVM function. |
| 12:37:25 | <blackh> | In case anyone's wondering what I'm trying to do, it's a client for a communications channel (socket based). I want the socket to get cleaned up when the client is no longer used. |
| 12:37:52 | <blackh> | I just want to ensure it gets kept alive for the during the 'request' function. |
| 12:38:46 | <blackh> | Not very functional code. :) |
| 12:42:26 | <blackh> | touch x = newIORef x >> return () <-- this seems to work |
| 12:44:12 | <Lemmih> | blackh: That's unlikely to work with compilers such as LHC. |
| 12:47:30 | <blackh> | Lemmih: Thanks. Well, either I could use something from FFI (since C must makes concrete assumptions), or I maybe I re-think the whole thing. |
| 12:48:02 | <byorgey> | /win 3 |
| 12:48:09 | <byorgey> | sigh |
| 12:48:55 | <Lemmih> | /fail (: |
| 12:49:00 | <ejt> | saynte: have you looked at the BASIC example ? |
| 12:49:48 | <ejt> | (and I see your problem :( ) |
| 12:52:56 | <saynte> | ejt: just took a look, that's kinda ninja, hehe. |
| 12:53:45 | <saynte> | ejt: yeah, it's sort of fundamental i think. i've considered using existential types, TH and Data.Dynamic, i don't think any of those give a solution. |
| 12:54:55 | <saynte> | I think it just needs a less-typed version of the function to do it. In a compiler you're probably doing your own type-checking anyway, so I think this is ok. Although I'd be curious to see if there is a way to do it with the available bindings. |
| 12:55:36 | <ejt> | augustss: ? |
| 13:00:21 | <RayNbow> | Functor has fmap :: (a->b) -> f a -> f b, ContraFunctor has contramap :: (b->a) -> f a -> f b... is there a class that contains a function of type (a->b) -> (b->a) -> f a -> f b? |
| 13:01:11 | <Saizan> | ExpFunctor in category-extras |
| 13:02:43 | <RayNbow> | Saizan: ah nice... and there's also a link to the Comonad Reader :) |
| 13:02:46 | <RayNbow> | thx :) |
| 13:03:08 | <RayNbow> | (not that I'm all too familiar with CT, but I was wondering about it earlier today when I was waiting for a train to depart) |
| 13:11:32 | <RayNbow> | Saizan: data Socket a = Socket (Source a) (Sink a) -- this would be a nice candidate for ExpFunctor, right? :) |
| 13:12:35 | <ejt> | saynte: maybe the point is the type of your entry point should always be the same |
| 13:12:42 | <Saizan> | probably, iirc the definition of Source and Sink |
| 13:14:14 | <kig> | how do i make a ptr out of a bytestring? (drudging through using cairo imagesurfaces as gl textures) |
| 13:14:48 | <Saizan> | look at Data.ByteString.Internal |
| 13:15:16 | <saynte> | ejt: could be, but this is rather restrictive. I feel that it's just a design flaw. |
| 13:15:35 | <RayNbow> | Saizan: well, I don't know whether Source/Sink already exists in some package... but they seem like a functor/contrafunctor resp. to me |
| 13:16:35 | <MyCatVerbs> | blackh: er, if you want Haskell values to stay in-place and existent for specific lengths of time, use Foreign.StablePtr |
| 13:17:07 | <blackh> | MyCatVerbs: Thanks - that looks promising. |
| 13:17:38 | <Saizan> | RayNbow: ah, i thought you were referring to reactive |
| 13:20:06 | <kig> | Saizan: thanks, let (fptr,_,_) = toForeignPtr bstr in let ptr = unsafeForeignPtrToPtr fptr seems to work |
| 13:20:47 | <kig> | now to bang head against getWidth and getHeight being inside Render monad |
| 13:21:30 | <quicksilver> | kig: you don't need to nest the lets like that |
| 13:21:53 | <quicksilver> | let (fptr,_,_) = toForeignPtr bstr; ptr = unsafeForeignPtrToPtr fptr in ... |
| 13:22:52 | <quicksilver> | and 'withForeignPtr' is the preferred way, not unsafeForeignPtrToPtr |
| 13:23:29 | <kig> | oh, there's withForeignPtr. nice, thanks |
| 13:23:40 | <quicksilver> | and finally... |
| 13:23:52 | <quicksilver> | ignoring the two other fields of toForeignPtr is not a good idea. |
| 13:23:57 | <quicksilver> | they are there for a reason :P |
| 13:28:31 | <blackh> | Lemmih, ejt, MyCatVerbs: The whole finalizer thing doesn't work. GHC seems to be optimizing out the containing object. I need to abandon the idea and close it explicitly with a 'withClient' sort of function. Thanks again. |
| 13:37:46 | <quicksilver> | blackh: if you need reliable finalizers, attach them to an MVar or an IORef |
| 13:37:46 | <lambdabot> | quicksilver: You have 1 new message. '/msg lambdabot @messages' to read it. |
| 13:38:02 | <quicksilver> | lambdabot: why tell me that now? I only said something 14 minutes ago? |
| 13:38:05 | <quicksilver> | @messages |
| 13:38:05 | <lambdabot> | ivanm said 3d 41m 19s ago: after playing with kuribas' indentation mode, I recall using it once and discarding it because I keep expecting tab to indent no matter where in the line I am (and |
| 13:38:05 | <lambdabot> | backspace doesn't unindent the same amount as tab indents either) :s |
| 13:38:07 | <ksf> | @seen conal |
| 13:38:07 | <lambdabot> | I saw conal leaving #haskell and #ghc 4m 14d 8h 23m 51s ago, and . |
| 13:38:11 | <quicksilver> | Oh, that's an old one. |
| 13:38:21 | <blackh> | quicksilver: much appreciated |
| 13:38:37 | <ksf> | someone raise lambdabot's wage, she can't even afford her meds. |
| 13:39:16 | <ejt> | has conal really been missing for 4 months ! |
| 13:40:28 | <Gracenotes> | is there a particular reason Real requires Ord? |
| 13:40:41 | <byorgey> | ejt: no =) |
| 13:40:58 | <byorgey> | looks like lambdabot crashed and lost some state. |
| 13:41:22 | <Gracenotes> | seen has been somewhat suspect.. |
| 13:41:27 | <Gracenotes> | preflex: seen conal |
| 13:41:27 | <preflex> | conal was last seen on #haskell 16 hours, 32 minutes and 34 seconds ago, saying: mempty :: Sum a |
| 13:50:06 | <quicksilver> | blackh: using addMVarFinalizer, not using the standard addFinalizer |
| 13:50:14 | <quicksilver> | the standard addFinalizer is soggy and hard to light. |
| 13:53:56 | <kig> | if i hit a mysterious problem like image w*h*4 != dataLength, i should throw an exception, right? or wrap the retval inside Maybe ? |
| 13:54:36 | <ksf> | loadFile :: Either LoadError Image |
| 14:00:55 | <mux> | someone unbreak reddit please! |
| 14:21:00 | <hackagebot> | bindings-common 0.1.2 |
| 14:26:01 | <hackagebot> | bindings-libusb 0.0.2 |
| 14:28:29 | <PeakerWork> | given an incoming XML on top of streaming data -- what XML library lets me read it incrementally and tell me when its done? |
| 14:29:50 | <quicksilver> | none of them, probably. |
| 14:30:36 | <PeakerWork> | so I have no way to read a "whole XML" from a pipe? |
| 14:31:30 | <quicksilver> | dunno for sure |
| 14:31:33 | <mux> | HaXml can do that with lazy parsing |
| 14:31:33 | <quicksilver> | I only said 'probably' |
| 14:31:54 | <mux> | it's actually the only XML library for haskell that I've used that allowed me to parse a _big_ XML file incrementally |
| 14:31:55 | <quicksilver> | mux: HaXml knows when it is done and gives you back the rest of the stream then? |
| 14:32:07 | <mux> | no, but the lazy parser of HaXml lets you parse only part of the document |
| 14:32:15 | <mux> | you'll have to write some boilerplate code around that |
| 14:34:02 | <bd_> | mux: clear your reddit cookies and you should be able to get in, apparently |
| 14:34:27 | <bd_> | though commenting seems broken still |
| 14:34:59 | <mux> | bd_: mmm, just tried that and I still get a "service unavailable" error |
| 14:35:16 | <quicksilver> | mux: well, you can't get a stream back out of a String which has interleaved IO in it |
| 14:35:25 | <quicksilver> | that's one of the many many reasons that interleaved IO is broken. |
| 14:36:17 | <mux> | quicksilver: yeah, I was thinking about a usage scheme when you read incrementally, ie with hGetLine |
| 14:37:10 | <quicksilver> | haxml supports that? |
| 14:37:14 | <quicksilver> | you can feed it lines one by one? |
| 14:37:36 | <mux> | yes |
| 14:37:45 | <mux> | this is how I achieved parsing a ~50MB XML file |
| 14:37:51 | <mux> | any other way would result in a space leak |
| 14:38:13 | <quicksilver> | mux: Nice. |
| 14:38:14 | <quicksilver> | haxml++ |
| 14:38:25 | <quicksilver> | PeakerWork: The correct answer is: Yes, HaXML |
| 14:38:34 | <quicksilver> | although you need to development version for the incremental parsing. |
| 14:38:37 | <quicksilver> | IIRC> |
| 14:38:42 | <mux> | but in my case I didn't have to hGetLine stuff; I just used readFile |
| 14:39:12 | <mux> | but it worked, otherwise my program would have quickly crashed after having consumed all of my RAM |
| 14:39:51 | <blackh> | Hexpat does lazy parsing too |
| 14:40:15 | <mux> | but it's impure :-) |
| 14:40:27 | <blackh> | No it isn't - I wrote it, so I should know |
| 14:40:50 | <mux> | I was assuming Hexpat would be a bidnings module to expat |
| 14:40:59 | <blackh> | It is, but I did it all properly |
| 14:41:33 | <quicksilver> | mux: readFile is the impure thing, if anything is impure :P |
| 14:41:38 | <mux> | blackh: however you did it, it's still in IO, right? |
| 14:41:43 | <mux> | quicksilver: hah. touché. |
| 14:42:05 | <blackh> | mux: There's a low-level interface that's in IO and a high-level interface that's pure |
| 14:43:09 | <mux> | cool |
| 14:46:37 | <mux> | blackh: mmm, except that it doesn't look like hexpact can actually do incremental XML parsing (not lazy XML parsing), at least not without using the SAX interface$ |
| 14:47:12 | <blackh> | mux: It can definitely do lazy parsing with the tree interface. |
| 14:47:26 | <blackh> | I've written a lot of code that relies on that. |
| 14:47:43 | <mux> | blackh: I repeat that I'm talking about incremental parsing, not lazy parsing |
| 14:48:04 | <blackh> | mux: Oh. What's incremental parsing? |
| 14:48:10 | <mux> | ie, a way to explicitely parse an incomplete XML document |
| 14:48:12 | <rick_2047> | can haskell have function overloading??? |
| 14:48:39 | <mux> | (like you get when you parse XML streams such as the Jabber protocol - it seems this was the motivating example for this technique in HaXml) |
| 14:49:33 | <blackh> | mux: I use hexpat to implement communications protocols using lazy parsing. |
| 14:49:51 | <quicksilver> | rick_2047: yes. That's what typeclasses are for. |
| 14:50:12 | <rick_2047> | quicksilver, typeclasses ok |
| 14:50:26 | <blackh> | mux: But you're right - you can't do it explicitly, i.e non-lazily, without using the lower level interface. |
| 14:50:53 | <uccus> | hi guys, anyone here uses Cygwin? I am trying to build hmatrix and running into trouble, experienced help needed |
| 14:51:11 | <mux> | blackh: this is way cool then; what I liked about the HaXml way was that I was __sure__ that it didn't try to read more of the file than it should :-) |
| 14:51:34 | <mux> | ACTION notes most reddits are back up except proggit |
| 14:51:56 | <quicksilver> | ACTION dislikes this use of the term "lazy" |
| 14:52:05 | <gnuvince> | mux: nothing works here :( |
| 14:52:16 | <quicksilver> | I think it inhibits discussion. |
| 14:52:38 | <mux> | gnuvince: it's a bit weird though: I can access haskell reddit for instance, but only the main page. clicking on "new" gives me a service unavailable error |
| 14:52:47 | <borisl> | > map (+1) [1..10] |
| 14:52:50 | <lambdabot> | [2,3,4,5,6,7,8,9,10,11] |
| 14:53:34 | <gnuvince> | That'll teach those guys not to have XXL hoodies! |
| 14:54:40 | <blackh> | mux: It could well be that it is technically incorrect to rely on Haskell being maximally lazy. I will add incremental parsing next time I work on hexpat. |
| 14:55:07 | <mux> | blackh: it's true that the "level" of laziness (cannot think of a better term) isn't guaranteed by the standard, AFAIK |
| 14:55:14 | <blackh> | mux: Thanks for the assistance you inadvertently gave me. |
| 14:55:26 | <mux> | blackh: I'm glad :-) |
| 14:56:01 | <blackh> | mux: I've had a few people say they wanted features that I hadn't thought of, so it's great to talk to people about it. |
| 14:57:23 | <PeakerWork> | ByteString.Char8 returns its own bytestring type -- how can I use existing functions that work with either Strict or Lazy bytestring with it? e.g: Data.Binary.Get.runGet? |
| 14:59:03 | <alexsuraci> | Is HaskellDB the preferred way to work with databases? |
| 14:59:08 | <quicksilver> | alexsuraci: no. |
| 14:59:22 | <alexsuraci> | It hasn't been updated in a while and the documentation on it seems pretty sparse |
| 14:59:27 | <quicksilver> | alexsuraci: AFAIK there is no preferred way. |
| 14:59:38 | <quicksilver> | there are just a bunch of libraries, each one used by a small number of people. |
| 14:59:46 | <quicksilver> | takusen, HDBC, haskelldb |
| 14:59:57 | <alexsuraci> | Haven't heard of takusen, I'll check that out |
| 15:00:00 | <Saizan> | PeakerWork: it returns either a strict or a lazy BS, depending which .Char8 it is |
| 15:00:10 | <Saizan> | PeakerWork: there are only two ByteString types |
| 15:00:17 | <PeakerWork> | Saizan: ah, thanks |
| 15:01:02 | <alexsuraci> | Huh, no MySQL support on that one, strange |
| 15:01:06 | <blackh> | BerkeleyDBXML |
| 15:01:22 | <alexsuraci> | well, "full" support anyway |
| 15:07:18 | <quicksilver> | alexsuraci: that's because mysql is so full of fail no self-respecting haskell programmer would use it? ;) |
| 15:08:11 | <alexsuraci> | I understand that, but it's the most popular with whoever will be using this software. |
| 15:08:37 | <Saizan> | hsql has mysql support, iirc |
| 15:09:03 | <alexsuraci> | Saizan: yea, it does |
| 15:17:15 | <gwern> | it always distresses me to see how shite my computer performs when a little load is put on the hard drive |
| 15:17:39 | <gwern> | I knew when I was building it that hard drive performance was more important these days than ram or gigahertz, but apparently I didn't compensate enough |
| 15:18:15 | <walter_> | Did anyone know something about HStringTemplate? I want to put serveral into <p>$paragraph$</p>, but I dont know exactly how many paragraph, it depends on the data I get. |
| 15:22:33 | <doserj> | walter_: I think there is sth like $foreach x in list$ sth $end$? |
| 15:23:25 | <walter_> | doserj, yeah, that is what I need. |
| 15:26:08 | <walter_> | doserj, thanks. $foreach works well. |
| 15:31:53 | <skorpan> | i'm looking for a function which given a function f and an integer n returns the composition of "n" fs |
| 15:32:09 | <skorpan> | i.e. g f 3 = f . f . f |
| 15:32:13 | <skorpan> | is this possible? |
| 15:32:19 | <Beelsebob> | @hoogle (a -> a) -> Int -> a -> a |
| 15:32:20 | <lambdabot> | Data.Sequence adjust :: (a -> a) -> Int -> Seq a -> Seq a |
| 15:32:20 | <lambdabot> | Data.IntMap adjust :: (a -> a) -> Key -> IntMap a -> IntMap a |
| 15:32:20 | <lambdabot> | Data.Generics.Basics gmapQi :: Data a => Int -> (a -> u) -> a -> u |
| 15:32:28 | <Beelsebob> | nope, none of them... |
| 15:32:29 | <skorpan> | already hoogled :) |
| 15:32:55 | <mux> | skorpan: I don't know how to write it point-free but you can write it point-wise with iterate and (!!) |
| 15:32:57 | <Beelsebob> | > let nTimes f 0 = id; nTimes f n = f . nTimes f (n-1) in nTimes (+1) 6 $ 1 |
| 15:32:59 | <lambdabot> | 7 |
| 15:33:19 | <trez> | är la bara att skriva själv |
| 15:33:19 | <mux> | > let double = (*2) in iterate double 1 !! 10 |
| 15:33:20 | <lambdabot> | 1024 |
| 15:33:26 | <skorpan> | trez: redan gjort, men vill ha en snyggare |
| 15:33:31 | <mux> | > let double = (*2) in iterate double 1 !! 11 |
| 15:33:32 | <lambdabot> | 2048 |
| 15:33:37 | <Beelsebob> | > let nTimes f = foldr (f .) id . enumFromTo 1 in nTimes (+1) 6 $ 1 |
| 15:33:39 | <lambdabot> | No instance for (GHC.Num.Num (a -> a)) |
| 15:33:39 | <lambdabot> | arising from the literal `1' at <... |
| 15:33:45 | <skorpan> | :t iterate (*2) |
| 15:33:46 | <lambdabot> | forall a. (Num a) => a -> [a] |
| 15:33:49 | <Beelsebob> | oops, not quite right |
| 15:37:29 | <Philonous> | @type replicate |
| 15:37:31 | <lambdabot> | forall a. Int -> a -> [a] |
| 15:38:17 | <skorpan> | > (replicate 3 (*2)) 1 |
| 15:38:18 | <lambdabot> | Couldn't match expected type `t1 -> t' |
| 15:38:30 | <skorpan> | :t replicate 3 (*2) |
| 15:38:31 | <lambdabot> | forall a. (Num a) => [a -> a] |
| 15:39:04 | <ski> | it might be nice with a `Num Church' where `newtype Church = MkChurch {unChurch :: forall a. (a -> a) -> (a -> a)} |
| 15:39:05 | <skorpan> | > foldr1 (replicate (*2)) 1 |
| 15:39:06 | <lambdabot> | The section `GHC.Num.* 2' takes one argument, |
| 15:39:06 | <lambdabot> | but its type `GHC.Types.Int'... |
| 15:39:18 | <Beelsebob> | > let nTimes f n = foldr (.) id $ replicate n f in nTimes (+1) 6 $ 1 |
| 15:39:19 | <lambdabot> | 7 |
| 15:40:36 | <PeakerWork> | Why doesn't Get have a typeclass MonadGet/etc like State/et-al? |
| 15:41:05 | <PeakerWork> | I would like getWord8 to be in MaybeT Get Word8 rather than in Get Word8 so it can fail reasonably |
| 15:43:03 | <quicksilver> | PeakerWork: i suspect the answer is because the authors were terribly concerned with extremely good performance |
| 15:43:11 | <quicksilver> | (to both of your questions, basically) |
| 15:43:28 | <PeakerWork> | but type-classes can be inlined in compile-time when possible :-( |
| 15:43:29 | <quicksilver> | I think it's axiomatic that Get Word8 can't fail; failure should be handled at a higher level. |
| 15:43:46 | <Beelsebob> | can't it? |
| 15:43:53 | <PeakerWork> | quicksilver: Well, getByteString can fail, and it fails with pure exceptions, rather than the polymorphic method "fail" |
| 15:43:55 | <Beelsebob> | what if it's past the end of the input? |
| 15:44:09 | <PeakerWork> | quicksilver: (it does use "fail" but its hard-coded to be in the Get monad, rather than some monad that had MonadGet) |
| 15:44:24 | <quicksilver> | by 'axiomatic' I mean 'an assumption of the design' |
| 15:44:48 | <quicksilver> | you call runGet on ByteStrings - you're only supposed to call it on ByteStrings which hold enough input |
| 15:44:52 | <PeakerWork> | quicksilver: I need to manually call "remaining" and verify its big enough, which forces the rest of the string :( |
| 15:44:57 | <quicksilver> | to do otherwise is a programming error, in terms of the API. |
| 15:45:06 | <PeakerWork> | quicksilver: what if I want binary parsers that can fail? |
| 15:45:10 | <PeakerWork> | Get is no good? |
| 15:45:37 | <quicksilver> | get isn't really a parser in the normal sense |
| 15:45:43 | <quicksilver> | it's a high performance bytestring reader |
| 15:45:55 | <quicksilver> | it's pretty limited as a parser |
| 15:45:57 | <PeakerWork> | its not a terribly powerful parser, but it is a kind of parser combinator |
| 15:46:04 | <quicksilver> | but you can layer a parser above it. |
| 15:46:24 | <PeakerWork> | are you supposed to really verify that the data you're giving to Get wasn't corrupted/truncated along the way? |
| 15:46:46 | <quicksilver> | look I'm not saying it's perfect, or it can do everything. |
| 15:46:52 | <quicksilver> | I'm explaining its intended use. |
| 15:47:04 | <quicksilver> | I"m not saying it wouldn't be better if it was different, or you can't imagine something better, or... |
| 15:47:34 | <quicksilver> | of course, no reliable system should even consider using Get on a Lazy Bytestring which comes from IO |
| 15:48:10 | <quicksilver> | reliability and interleaved IO are at worst completely incompatible, and at best a research topic. |
| 15:49:03 | <Saizan> | and in teh middle you can use attoparsec |
| 15:49:32 | <quicksilver> | attoparsec is described as 'text-oriented' |
| 15:54:39 | <fracture> | how do you wait for input from multiple Handles in haskell? (i.e. something like unix select) |
| 15:55:11 | <mux> | fracture: you typically don't do that but use threads instead |
| 15:55:18 | <Beelsebob> | fracture: there may be a more basic way of doing it, but fire off threads to monitor each |
| 15:55:24 | <Beelsebob> | and get each to feed into a channel when it gets data |
| 15:55:41 | <quicksilver> | fracture: indeed, threads use unix select behind the scenes. |
| 15:55:55 | <mux> | also, haskell threads are very, very, veeeery cheap. |
| 15:55:57 | <fracture> | what do they use on windows? |
| 15:55:57 | <quicksilver> | so threads are the "simplest" way to get select-like behaviour |
| 15:56:07 | <quicksilver> | some windows API whose name escapes me |
| 15:56:13 | <fracture> | WaitForMultipleObjects? |
| 15:56:16 | <mux> | WaitForMultipleEvents or something |
| 15:56:19 | <quicksilver> | WaitForNextThingyWotsitBuriedDeepInSomeUglyAPI |
| 15:56:20 | <mux> | heh, yeah |
| 15:56:43 | <fracture> | so... if I were writing say a telnet client |
| 15:56:48 | <fracture> | I'd want a thread for interaction with the user |
| 15:56:53 | <fracture> | and a thread for interaction with the remote host |
| 15:56:53 | <fracture> | ? |
| 15:56:56 | <mux> | yup |
| 15:56:58 | <fracture> | ok |
| 15:57:00 | <quicksilver> | probably four |
| 15:57:03 | <fracture> | I'll learn about threads now :) |
| 15:57:06 | <mux> | each blocking on its file descriptor |
| 15:57:08 | <fracture> | four? |
| 15:57:10 | <quicksilver> | hmm |
| 15:57:17 | <mux> | and you'll probably have a third one to manage the rest |
| 15:57:21 | <quicksilver> | maybe just three. |
| 15:57:25 | <fracture> | ahh I see |
| 15:57:26 | <fracture> | ok |
| 15:57:27 | <quicksilver> | at least two threads for the socket. |
| 15:57:27 | <mux> | that will be blocking on MVar's or Chan's |
| 15:57:48 | <quicksilver> | (so reading and writing don't accidentally block each other) |
| 15:58:06 | <fracture> | ok |
| 15:58:23 | <mux> | in the case of a telnet client, I think you can actually get away with only two threads |
| 15:58:25 | <fracture> | and... I'm hoping the referential transparency stuff probably simplifies MT correctness a lot in haskell, eh? |
| 15:58:39 | <quicksilver> | yes, hugely |
| 15:58:48 | <fracture> | (the idea of using threads for something like this in other languages would be pretty scary, from a reliability perspective) |
| 15:58:50 | <quicksilver> | everything is immutable and can be safely shared between threads |
| 15:58:54 | <fracture> | cool, sounds good |
| 15:59:00 | <mux> | the one blocking on the socket will just putStrLn stuff when it has some, and the thread blocking on the keyboard input will write to the socket when it has lines to send |
| 15:59:12 | <Beelsebob> | fracture: note though – while executing an IO action you don't have referential transparency |
| 15:59:13 | <fracture> | makes sense |
| 15:59:20 | <Beelsebob> | so, be careful still ;) |
| 15:59:25 | <quicksilver> | Beelsebob: eh? |
| 15:59:27 | <quicksilver> | Beelsebob: what? |
| 15:59:28 | <fracture> | I might actually try a telnet client first to make sure I grok all this (should be pretty quick to whip up) |
| 15:59:38 | <Beelsebob> | quicksilver: creating IO actions is pure, running them is not |
| 15:59:51 | <quicksilver> | Beelsebob: what's that got to do with referential transparency. |
| 16:00:00 | <quicksilver> | haskell is referentially transparent, inside IO and out. |
| 16:00:08 | <fracture> | quicksilver: well, you could communicate with side-effects by putting data on the filesystem |
| 16:00:15 | <Beelsebob> | yes, but the haskell runtime evaluating an IO action does not |
| 16:00:16 | <fracture> | (that's what you mean, right beel?) |
| 16:00:21 | <Beelsebob> | you don't get the same result from getChar every time |
| 16:00:24 | <fracture> | you could get deadlocks that way if you tried |
| 16:00:27 | <quicksilver> | Beelsebob: referential transparency is a static property. |
| 16:00:31 | <quicksilver> | it applies to code |
| 16:00:32 | <quicksilver> | terms |
| 16:00:33 | <quicksilver> | expressions |
| 16:00:35 | <quicksilver> | not running code. |
| 16:00:41 | <quicksilver> | All of haskell is referentially transparent |
| 16:00:43 | <quicksilver> | including IO |
| 16:00:49 | <quicksilver> | "getChar" always denotes the same thing |
| 16:00:50 | <Beelsebob> | quicksilver: yes, it's a static property of Haskell, but not of the programs that IO based code generates |
| 16:00:52 | <quicksilver> | (an IO action) |
| 16:01:01 | <fracture> | quicksilver: that is definitely not how I understand that terms "referentially transparent" |
| 16:01:03 | <Beelsebob> | the IO action you get back, is not referentially transparent |
| 16:01:12 | <quicksilver> | ACTION counts to 10, slowly. |
| 16:01:33 | <quicksilver> | Beelsebob: it is absolutely meaningless to say "...not of the programs that IO based code generates". |
| 16:01:47 | <quicksilver> | referential transparency is a property of terms - or source code. |
| 16:02:11 | <Beelsebob> | it's a property of a program - and when we use IO we talk about two programs |
| 16:02:15 | <Beelsebob> | the one we write in haskell |
| 16:02:16 | <quicksilver> | it is not meaningful to discuss if a compiled program is referentially transparent. |
| 16:02:24 | <Beelsebob> | and the one it generates and causes the runtime to execute |
| 16:02:45 | <quicksilver> | I am very sorry. I do not have time to have this argument with you now. |
| 16:02:51 | <quicksilver> | Some time later when I have more time, perhaps. |
| 16:03:14 | <kynky> | haskell communcating with world full of side effects |
| 16:03:25 | <quicksilver> | However, lest anyone else in the channel get confused, haskell *is* referentially transparent, and Beelsebob, much as I respect him, and value his friendship, is quite wrong here. |
| 16:03:35 | <tromp> | evaluating getChar just gives you getChar, it's already evaluated. executing it is something quite different |
| 16:03:45 | <Beelsebob> | quicksilver: note – I'm not claiming haskell isn't RT |
| 16:03:53 | <Beelsebob> | I'm claiming that the programs it generates are not |
| 16:04:07 | <tromp> | so in terms of evaluation yeielding substitutable values, it is perfectly RT |
| 16:04:13 | <Beelsebob> | IO actions are not RT |
| 16:04:15 | <Beelsebob> | Haskell is |
| 16:04:17 | <Ferdirand> | what does it mean for a program not to be RT ? |
| 16:04:29 | <Ferdirand> | it cannot be substituted with its output ? |
| 16:04:35 | <Beelsebob> | Ferdirand: indeed |
| 16:04:41 | <tromp> | it's not evaluation that gives its output |
| 16:04:44 | <kynky> | IO is just a special case of Monad ? |
| 16:04:55 | <Beelsebob> | kynky: it's a secret special case that has hooks into the runtime |
| 16:05:12 | <ski> | "referentially transparent" is about being able to replace variables with the expressions they're defined as |
| 16:05:28 | <fracture> | I don't see how IO could be considered RT if it can change filesystem state |
| 16:06:03 | <opqdonut> | there's a trick to it |
| 16:06:04 | <tromp> | the real IO takes place outside of haskell's evaluation |
| 16:06:05 | <Philonous> | I wonder whether unsafePerformIO is referentially transparent or not haskell. |
| 16:06:09 | <fracture> | what's the difference between evaluating and running IO actions? |
| 16:06:15 | <Beelsebob> | fracture: IO code in Haskell generates an action |
| 16:06:18 | <ski> | one may replace variables of type `IO Whatever' with their defining expressions in exactly the same way as variables of other types |
| 16:06:19 | <Beelsebob> | and that action is always the same action |
| 16:06:20 | <opqdonut> | fracture: openFile "asdf" is always the same action |
| 16:06:29 | <Beelsebob> | the action however, is itself not RT |
| 16:06:44 | <ski> | the action is a value |
| 16:06:47 | <kynky> | the consequence of the action |
| 16:06:49 | <opqdonut> | fracture: you could interpret a haskell program as producing a tree of IO operations and reactions to them |
| 16:06:58 | <Beelsebob> | ski: programs are values too |
| 16:06:59 | <opqdonut> | fracture: the production of the tree is pure |
| 16:06:59 | <Ferdirand> | why not ? the effects of an action are not its values, right ? |
| 16:06:59 | <Beelsebob> | ;) |
| 16:07:14 | <ski> | Beelsebob : you mean the `main' action ? |
| 16:07:35 | <Beelsebob> | Ferdirand: take for example the unsafeLaunchMissiles function – when run, it has side effects - it itself is not RT |
| 16:07:38 | <Beelsebob> | *however* |
| 16:07:47 | <Beelsebob> | the unsafeLaunchMissiles function is always the same value |
| 16:07:55 | <Beelsebob> | so a program that refers to it and passes it around *is* RT |
| 16:08:12 | <fracture> | is "actions" a concept applicable to other monads? (I thought I understood monads by now... guess not) |
| 16:08:18 | <Beelsebob> | fracture: no |
| 16:08:20 | <fracture> | meaning, a distinction between evaluating and running them |
| 16:08:22 | <kynky> | the program, and the system the program runs on ? |
| 16:08:26 | <fracture> | ok |
| 16:08:28 | <Beelsebob> | an "action" is a secret runtime thing that's magical |
| 16:08:35 | <fracture> | I see |
| 16:08:40 | <Beelsebob> | it's applicable only with the IO monad |
| 16:08:51 | <SamB> | Beelsebob: well ... not quite! |
| 16:09:10 | <ski> | fracture : yes :) `action' is applicable to every monad |
| 16:09:11 | <SamB> | STM, for instance ... |
| 16:09:33 | <ski> | e.g. here's an action in the list monad |
| 16:09:37 | <SamB> | maybe ST |
| 16:09:49 | <SamB> | have similar magical runtime secret things |
| 16:09:50 | <ski> | > [(+),(*)] `ap` [2,3] `ap` [4,5] |
| 16:09:51 | <lambdabot> | [6,7,7,8,8,10,12,15] |
| 16:10:24 | <fracture> | (where's ap defined?) |
| 16:10:29 | <ski> | @index ap |
| 16:10:30 | <lambdabot> | Control.Monad, Control.Monad.Reader, Control.Monad.Writer, Control.Monad.State, Control.Monad.RWS, Control.Monad.Identity, Control.Monad.Cont, Control.Monad.Error, Control.Monad.List, Data.Graph. |
| 16:10:30 | <lambdabot> | Inductive.Query.ArtPoint, Data.Graph.Inductive.Query, Data.Graph.Inductive |
| 16:10:30 | <opqdonut> | fracture: you can think of things in the State monad as actions too |
| 16:10:39 | <opqdonut> | fracture: you run them with execState |
| 16:10:39 | <ski> | `Control.Monad', really |
| 16:10:44 | <ski> | @src ap |
| 16:10:44 | <lambdabot> | ap = liftM2 id |
| 16:10:51 | <opqdonut> | of course, running the other monads is doable with a pure function |
| 16:10:58 | <gwern> | ಥ_ಥ beautiful |
| 16:11:16 | <opqdonut> | there are many metaphors for monads. which ones are most applicable depends on the situation |
| 16:11:27 | <fracture> | ski: what makes that an action? |
| 16:12:12 | <ski> | fracture : it having a type of form `M Foo' for a type constructor `M' (here `[]') being an instance of `Monad' |
| 16:12:40 | <EvilTerran> | ACTION talks about actions in monads other than IO |
| 16:13:21 | <fracture> | ok so, "action" is either a metaphor for understanding what monads do, or a part of the implementation details of the IO monad.... (or both)? |
| 16:13:40 | <Saizan> | the former |
| 16:13:43 | <fracture> | when I write a user defined monad though, there doesn't seem to be a separate evaluation step vs. "run the actions" step |
| 16:14:19 | <fracture> | ok... so how can IO be referentially transparent at evaluation time then? |
| 16:14:24 | <ski> | (imo whether a monad is defined (wrt some implementation) in haskell or not isn't that important (here). the important part is that it obeys the same reasoning laws as all the rest of haskell) |
| 16:14:31 | <Beelsebob> | fracture: because those two steps are seperate |
| 16:14:33 | <Beelsebob> | first you evaluate |
| 16:14:36 | <Beelsebob> | and you get an action |
| 16:14:41 | <Beelsebob> | that action is always the same action |
| 16:14:45 | <Beelsebob> | then you run the action in the runtime |
| 16:14:48 | <roconnor> | @wiki IO_Semantics |
| 16:14:48 | <lambdabot> | http://www.haskell.org/haskellwiki/IO_Semantics |
| 16:14:50 | <Beelsebob> | the action itself is not RT though |
| 16:15:02 | <ski> | ACTION disagrees with Beelsebob |
| 16:15:04 | <fracture> | can I manipulate IO actions in code? |
| 16:15:07 | <Saizan> | Beelsebob: that's confusing |
| 16:15:26 | <Saizan> | you can pass IO actions around as the other values, yes |
| 16:15:27 | <fracture> | (if they are purely an implementation detail of the compiler, I think that makes no sense, and we should call IO non-referentially transparent) |
| 16:15:54 | <roconnor> | ACTION kinda agrees with Beelsebob |
| 16:16:07 | <fracture> | can you give an example saizan? (sorry if I'm being dense; just trying to grok) |
| 16:16:12 | <Ferdirand> | but you cannot run an action from haskell code |
| 16:16:19 | <Beelsebob> | no, sure |
| 16:16:23 | <Beelsebob> | that's why Haskell is RT |
| 16:16:23 | <Saizan> | Ferdirand: for example replicateM |
| 16:16:28 | <Saizan> | ?type replicateM |
| 16:16:29 | <lambdabot> | forall (m :: * -> *) a. (Monad m) => Int -> m a -> m [a] |
| 16:16:41 | <Beelsebob> | we use main to create an IO action and the runtime happens to run it for us as well |
| 16:16:55 | <Saizan> | fracture: that takes a number and an action and performs it that number of times |
| 16:17:32 | <dmwit> | A value of type "IO a" is a description of how to generate a value of type "a", perhaps doing some IO in the process. |
| 16:17:35 | <Ferdirand> | no, that builds a new action that when performed, will perform the other a number of times |
| 16:17:41 | <dmwit> | It can be referentially transparent because it is always the same description. |
| 16:17:45 | <ski> | executing `IO'-actions may cause "effects" to happen. in most languages, these would be "side-effects", while in haskell they're not, because the effects are accounted for in the types - you can't use an `State Foo Int' in place of an `Int' or vice versa (similarly for any other monad than `State Foo') |
| 16:17:53 | <dmwit> | But following its instructions can produce different values. |
| 16:17:56 | <Saizan> | Ferdirand: yeah, right |
| 16:18:00 | <Beelsebob> | dmwit: no no - that would be the program *generating* the IO action that's referentially transparent |
| 16:18:07 | <Beelsebob> | the description itself is not RT |
| 16:18:24 | <Beelsebob> | otherwise all C programs would be RT - after all, it's always the same program you're running |
| 16:18:24 | <dmwit> | Sure, I'm fine with that distinction. |
| 16:19:06 | <dmwit> | That's not how the term RT is usually used, I think, but it's a fine way to use it if you're consistent. |
| 16:19:08 | <ski> | in the same way as `IO'-effects, we can talk about `State Foo'-effects, `Cont Answer'-effects, and even `[]'-effects and `Parser Token'-effects |
| 16:19:14 | <Saizan> | Beelsebob: i think you're mixing layers |
| 16:19:35 | <dmwit> | (i.e. usually we would say the "IO a" value is RT because we can refer to it many times, and it is still the same value, i.e. the same description.) |
| 16:19:37 | <Beelsebob> | ski: yes, but those ones actually always will give the same value when run |
| 16:19:40 | <Beelsebob> | unlike IO actions |
| 16:19:53 | <Saizan> | Beelsebob: i can subsitute the description for the expression that evaluates to it anywhere |
| 16:19:57 | <ski> | Beelsebob : "run" isn't well-defined here, i'd claim |
| 16:20:13 | <Beelsebob> | Saizan: sure - that makes the program generating the description RT |
| 16:20:21 | <Beelsebob> | what you can't do, is substitute the value that the description computes for the description |
| 16:20:24 | <fracture> | Saian: ok that seems to make sense (w/ the replicate) |
| 16:20:27 | <Beelsebob> | so the description is *not* RT |
| 16:20:39 | <fracture> | is there a function that just runs an IO action? |
| 16:20:56 | <dmwit> | But the value the description computes doesn't even have the same type! |
| 16:21:00 | <Saizan> | fracture: no |
| 16:21:06 | <dmwit> | Of *course* you can't substitute it for the description itself. |
| 16:21:13 | <fracture> | @src replicateM |
| 16:21:13 | <lambdabot> | replicateM n x = sequence (replicate n x) |
| 16:21:26 | <dmwit> | fracture: Yes, but we don't use it. ;-) |
| 16:21:29 | <ski> | (Beelsebob : in Clean, one can easily imagine `IO a' being implemented as `*World -> (a,*World)', would you claim such an `IO'-action to not be RT, as well ?) |
| 16:21:47 | <SamB> | doesn't the description compute the program ? |
| 16:22:03 | <Beelsebob> | ski: sure - but that's not in any way useful - if you want nice strong guarentees about how the program behaves, you don't want to have to think about how the world behaves too |
| 16:22:11 | <SamB> | I wish you'd stop saying RT, I keep thinking of Real Time |
| 16:22:19 | <Beelsebob> | and as we were talking about whether RT helps with threading using forkIO, that's pretty useless |
| 16:22:34 | <Beelsebob> | RT helps with threading, as long as the threading happens in the RT bit, not in the description |
| 16:22:49 | <fracture> | ok so.... something like putStrLn is referentially transparent, because it always returns the same action. But sequence or replicateM or main (anything that runs actions) is not RT. |
| 16:22:51 | <fracture> | correct? |
| 16:22:58 | <ski> | Beelsebob : the point of defining such an `IO' would be to not "have to think about how the world behaves" .. just as with haskell's `IO' |
| 16:23:03 | <SamB> | referential transparency helps a lot with threading |
| 16:23:13 | <quicksilver> | RT helps enormously with threading. |
| 16:23:17 | <quicksilver> | and there is no RT bit. |
| 16:23:19 | <Saizan> | fracture: sequence is still RT |
| 16:23:21 | <quicksilver> | all of haskell is RT |
| 16:23:21 | <Beelsebob> | sure it helps with threading |
| 16:23:21 | <dmwit> | fracture: replicateM is RT |
| 16:23:25 | <quicksilver> | there is no "bit" which is not. |
| 16:23:26 | <Beelsebob> | what it doesn't help with is forkIO |
| 16:23:30 | <quicksilver> | (sorry, I know I said I didn't have time) |
| 16:23:30 | <quicksilver> | ;) |
| 16:23:32 | <Beelsebob> | because forkIO is not threaded |
| 16:23:35 | <SamB> | if most of your computations are done in referentially transparent code, you have a heck of a lot less mutation to worry about the interactions between ... |
| 16:23:37 | <fracture> | how can it be RT if it runs actions that have side effects? |
| 16:23:42 | <Beelsebob> | it's an action that happens to generate threads |
| 16:23:45 | <Saizan> | fracture: they just build bigger actions out of smaller ones |
| 16:23:53 | <dmwit> | fracture: It doesn't run actions that have side effects, that's the thing. |
| 16:24:00 | <ski> | (Beelsebob : my point there was that haskell's `IO' could have been defined in haskell, provided lower primitives in terms of `*World' was given, and provided haskell had uniqueness types) |
| 16:24:09 | <jacobian> | hmmm, if I use the error monad it serialises in such a way that the computation doesn't terminate. Is there some way to do errors that wont have this problem? |
| 16:24:10 | <SamB> | fracture: only if the side effects end up cancelling out ... |
| 16:24:15 | <SamB> | or something like that |
| 16:24:26 | <Beelsebob> | ski: sure – but then you have to think about "World" when dealing with your values - and you're back at square one with threading being hard |
| 16:24:32 | <fracture> | ok... so only main is not RT? |
| 16:24:32 | <dmwit> | fracture: replicateM takes a description of how to build an "a" value and returns a description of how to return several "a" values in a list. |
| 16:24:33 | <Beelsebob> | if all threading does is manipulate the "world" |
| 16:24:36 | <Saizan> | fracture: only the action corresponding to main gets run |
| 16:24:47 | <SamB> | for instance, RT code is allowed to use dynamically allocated memory |
| 16:24:47 | <Saizan> | fracture: but that doesn't mean main is not RT |
| 16:24:53 | <ski> | (Beelsebob : these lower-level primitives might be defined in C or some assembler .. but the same may be true of `cos' .. what matters is what modes of *reasoning* is allowed) |
| 16:25:13 | <Beelsebob> | ski: but they're not allowed - they're no easier when talking about IO code than when talking about C code |
| 16:25:23 | <ski> | Beelsebob : no, the point of defining an abstract data type `IO' is exactly *not* to have to think about `World' |
| 16:25:30 | <Beelsebob> | they're easier when talking about magically parallelising things because we're not affecting the world |
| 16:25:35 | <Beelsebob> | but they're not easier in IO at all |
| 16:25:47 | <roconnor> | Nothing in Haskell runs any actions. The only thing that runs actions in the "run-time system" which runs the action called main (which is probably has been built up from lots of little actions), and the "run-time system" isn't accessible inside Haskell |
| 16:25:51 | <Philonous> | Beelsebob: If haskell ist RT, what about unsafePerformIO? Clearly let a = unsafePerformIO ( randomIO ) can not be replaced with a value, because haskell is not lazy after all |
| 16:25:54 | <SamB> | Beelsebob: um, IO code is a lot easier than C code |
| 16:26:06 | <Beelsebob> | SamB: what extra guarentee do you get? |
| 16:26:10 | <Beelsebob> | when it comes to threading? |
| 16:26:24 | <roconnor> | unsafePerformIO isn't part of Haskell. It is part of GHC, and other perhaps implementations. |
| 16:26:25 | <dmwit> | Philonous: SSSHHHH! You're not helping. |
| 16:26:31 | <SamB> | Beelsebob: well, a lot of the function calls in your IO code can be plainly seen to not involve IO |
| 16:26:37 | <SamB> | that helps |
| 16:26:46 | <SamB> | so you only have to look at the ones that do |
| 16:26:51 | <Beelsebob> | SamB: that's not what I asked – that's a case of non-IO code is nice to reason about |
| 16:26:55 | <SamB> | in C, any of them code! |
| 16:26:59 | <Beelsebob> | that's not a guarentee that you get in IO code, but not in C |
| 16:27:01 | <SamB> | er. could |
| 16:27:10 | <dmwit> | Philonous: We've even consciously avoided that when he asked whether there was a function that just runs an IO action. ;-) |
| 16:27:11 | <SamB> | Beelsebob: sure it is! |
| 16:27:12 | <Beelsebob> | that's a guarentee you get by *not* using IO |
| 16:27:32 | <SamB> | what I'm saying is that IO isn't all-or-nothing, which is really nice |
| 16:27:42 | <Beelsebob> | sure - but that doesn't make it easy to reason about IO |
| 16:27:44 | <SamB> | in C, it's all C ... |
| 16:27:47 | <Saizan> | it's a guarantee you get by the existence of IO, that let you make a distinction |
| 16:27:48 | <Beelsebob> | it makes it easy to reason about things that aren't IO |
| 16:27:55 | <Beelsebob> | IO is no easier to reason about than C code |
| 16:27:59 | <SamB> | Beelsebob: well, it cuts down the stuff you need to be careful about |
| 16:28:07 | <fracture> | it's seeming harder so far |
| 16:28:09 | <SamB> | it's a reason to use IO instead of C ... |
| 16:28:14 | <Beelsebob> | SamB: again -- that's not something that IO gives you |
| 16:28:18 | <Beelsebob> | it's something that *not* using IO gives you |
| 16:28:29 | <fracture> | so, I need to change my mental model here is what it sounds like |
| 16:28:39 | <SamB> | well, it's something Haskell gives you ... |
| 16:28:44 | <Beelsebob> | sure |
| 16:28:57 | <Beelsebob> | but that doesn't make reasoning about threading code in IO any easier than reasanoing about threading code in C |
| 16:28:59 | <Beelsebob> | ... |
| 16:29:06 | <Beelsebob> | it makes reasoning about *pure* code easy |
| 16:30:24 | <SamB> | yeah, well, IO has that advantage over C |
| 16:30:29 | <Beelsebob> | no |
| 16:30:31 | <fracture> | so in practice, does the program really build this action tree before executing? |
| 16:30:33 | <Beelsebob> | pure code has that advantage over C |
| 16:30:34 | <SamB> | you don't have to use it everywhere! |
| 16:30:41 | <Beelsebob> | I don't have to use C everywhere |
| 16:30:45 | <Beelsebob> | I can make FFI calls into Haskell |
| 16:30:47 | <dmwit> | fracture: Yes, but lazily. |
| 16:30:52 | <fracture> | I see |
| 16:30:57 | <SamB> | it can invoke pure code, and you can tell AT A GLANCE when it does |
| 16:30:57 | <Beelsebob> | in fact, if we consider IO in Haskell to be referentially transparent, then IO actions like forkIO are not multi threaded by nature – we can use a single thread to evaluate the IO action that contains the instruction to fork a new thread |
| 16:31:04 | <TomMD> | dcoutts: Did you ever get the hackage patches I sent? I sent them again just now just in case. |
| 16:31:17 | <fracture> | and the value of main is an action, composed of other actions... this sorta makes sense |
| 16:31:19 | <Beelsebob> | so it's totally useless to talk about threading being easy to reason about in haskell if we consider haskell to be RT |
| 16:31:23 | <SamB> | you CAN write pure code in C; you can even annotate it as such. |
| 16:31:28 | <Saizan> | fracture: if by "in practice" you mean "how GHC implements this" then no, but you shouldn't care |
| 16:31:31 | <ski> | in some sense, the point of using monads for traditional effects (state, i/o, exceptions, environment/reader, output/writer, continuations, angelic nondeterminism, demonic nondeterminism, ...) is to know when you're *not* using a certain kind of effect |
| 16:31:35 | <Beelsebob> | SamB: or... I can make an FFI call into some pure Haskell code |
| 16:31:36 | <SamB> | but what you can't do is tell at a glance from the call site that it's pure! |
| 16:31:43 | <quicksilver> | Beelsebob: reasoning about threaded code in haskell is about a million times easier than reasoning in C |
| 16:31:53 | <Beelsebob> | quicksilver: exactly how |
| 16:31:54 | <quicksilver> | Beelsebob: the main reason being that data is immutable and safely shared. |
| 16:32:04 | <quicksilver> | it's still not easy, but it's at least a million times easier. |
| 16:32:07 | <Beelsebob> | no it's not |
| 16:32:13 | <Beelsebob> | ACTION points at the iORef |
| 16:32:18 | <SamB> | Beelsebob: you can't mutate a cons cell |
| 16:32:21 | <SamB> | that helps! |
| 16:32:27 | <Beelsebob> | SamB: yes - *pure* code again |
| 16:32:27 | <quicksilver> | in C someone can modify one byte of a word when you're halfway through reading it. |
| 16:32:28 | <Beelsebob> | not IO code |
| 16:32:33 | <Beelsebob> | IO code however car do mutation |
| 16:32:38 | <lilac> | Beelsebob: when you said earlier that haskell's not referentially transparent when running IO actions, presumably you meant that you can say "do forkIO $ evilUnsafePointerFiddling; let { x = pureThing; y = pureThing }; return (x, y)" |
| 16:32:38 | <mreh> | can I implement the exponential operator in pure code? |
| 16:32:38 | <Beelsebob> | ACTION points at the IORef again |
| 16:32:39 | <Saizan> | Beelsebob: you don't use IORef everywhere in IO code either |
| 16:32:42 | <SamB> | Beelsebob: IO code can't mutate a cons cell either, though |
| 16:32:47 | <quicksilver> | you don't even use IORef mostly. |
| 16:32:49 | <Beelsebob> | lilac: I never said that |
| 16:32:51 | <quicksilver> | you use it very sparingly. |
| 16:32:54 | <Beelsebob> | I said that the IO action is not RT |
| 16:32:56 | <lilac> | ... and have it be different from " ... let { x = pureThing; y = x }; ..." |
| 16:32:57 | <Philonous> | quicksilver: If you say haskell is referentially transparent, does that include unsafePerformIO or is that function not haskell (but a compiler extension) |
| 16:32:57 | <quicksilver> | and never with threads. |
| 16:33:04 | <quicksilver> | Philonous: it's not even a function. |
| 16:33:12 | <SamB> | so, you can tell WHAT code could mutate stuff, and WHAT things could possibly be mutated |
| 16:33:17 | <quicksilver> | Philonous: it's a compiler primitive which breaks everything about the language which is good. |
| 16:33:23 | <lilac> | Beelsebob: pity, because i was going to agree with you :) |
| 16:33:47 | <lilac> | inside the IO monad, you can tell how a pure function was written |
| 16:33:48 | <Beelsebob> | lilac: well, evilUnsafePointerFiddling isn't part of Haskell |
| 16:33:49 | <SamB> | it reduces the places you have to pay attention to by about 99% ... |
| 16:33:55 | <Philonous> | quicksilver: Right it's not a function. But it's there and I wonder if this is haskell or not |
| 16:33:57 | <lilac> | Beelsebob: is the FFI part of haskell? |
| 16:34:12 | <lilac> | what do you call 'Haskell' here? |
| 16:34:12 | <Beelsebob> | lilac: yes, but everything's wrapped up in an IO type |
| 16:34:20 | <Beelsebob> | so that's all safe |
| 16:34:21 | <lilac> | Beelsebob: yes, my do-block was in IO |
| 16:34:23 | <lament> | gets() is not part of C! |
| 16:34:23 | <SamB> | lilac: yeah, mutating cons cells by using unsafe pointer manipulations is NOT done in any serious code ... |
| 16:34:32 | <Beelsebob> | lilac: well then your two programs don't have the same type |
| 16:34:34 | <TomMD> | Beelsebob: IORef is a poor example for your argument - I use it in threaded code all the time. Once I read the IORef I know the data structure won't change - sure the IORef might get updated with a newer piece of information but the copy I have is _new enough_ that my opertions can continue... and the copy I have won't change, a promise I wouldn't have in C. |
| 16:34:36 | <lilac> | SamB: no, absolutely not. |
| 16:34:37 | <Beelsebob> | quicksilver: okay, so... Haskell is easy to do multithreading – if you avoid all the nasty parts of it |
| 16:34:39 | <lilac> | Beelsebob: yes they do... |
| 16:34:40 | <SamB> | lilac: Linus would never allow such things in his tree ;-P |
| 16:34:44 | <Beelsebob> | which is roughly what I was trying to say |
| 16:34:51 | <Beelsebob> | it's not inhearantly easier in Haskell |
| 16:34:57 | <Beelsebob> | it's just easier to dodgy the nasty things |
| 16:35:00 | <Beelsebob> | dodge* |
| 16:35:06 | <lilac> | Beelsebob: they're both :: IO (x, y) for some x and y |
| 16:35:10 | <Guest39336> | anyone know if those libs for updating record fields kill any performance optimizations or rewrite rules? |
| 16:35:20 | <Beelsebob> | lilac: then they both return the same IO action every time |
| 16:35:22 | <Beelsebob> | and are RT |
| 16:35:31 | <lilac> | Beelsebob: it's not the IO action i'm looking at |
| 16:35:36 | <Beelsebob> | the IO actions that are run by the runtime when you evaluate the Haskell program is not RT though |
| 16:35:57 | <quicksilver> | Beelsebob: it *is* inherently easier. |
| 16:35:58 | <lilac> | Beelsebob: the IO action invokes some pure code, and that pure code can produce different results for the same input depending on what evils the IO code surrounding it does |
| 16:36:08 | <quicksilver> | it's inherently easier because data is immutable |
| 16:36:08 | <Beelsebob> | quicksilver: sure – but it needs some qualification |
| 16:36:13 | <lilac> | Beelsebob: given all Haskell code is surrounded by IO code I consider this to be an issue |
| 16:36:16 | <Botje> | Guest39336: why, are you running into problems? |
| 16:36:16 | <quicksilver> | I don't understand what's so controversial about that. |
| 16:36:19 | <TomMD> | Guest39336: Its just sugar so it shouldn't harm anything compared with rebuilding the structure by hand. |
| 16:36:19 | <Beelsebob> | threading is not easier in Haskell |
| 16:36:24 | <quicksilver> | yes it is. |
| 16:36:24 | <SamB> | the dangerous things in Haskell mostly have yellow-and-black stripes on them, and there is much less need to use them than in C -- C doesn't have any other option in most cases. |
| 16:36:29 | <Beelsebob> | threading is easier in a subset of haskell that's inherantly safe |
| 16:36:35 | <quicksilver> | I have programmed using threads in quite a few languages |
| 16:36:44 | <quicksilver> | and it honestly is much easier in haskell |
| 16:36:47 | <ski> | in Mercury, there's a `promise_pure' construct that can be used on code the implements a pure inferface (regardless of implementation details). if one lies to the compiler, all bets are off. it would be nice if (e.g.) GHC would give similar guarrantees about `unsafePerformIO' (or similar) |
| 16:36:52 | <quicksilver> | (than C, C++, Java for example) |
| 16:37:01 | <Saizan> | Beelsebob: how the language is normally, and most naturally used does have an importance in such discussions |
| 16:37:09 | <jkramer> | Hello |
| 16:37:16 | <fracture> | thanks for all the help grokking that all (gotta go play scrabble now... haha) |
| 16:37:18 | <opqdonut> | ski: indeed, something like how unsafePerformIO is used in unamb |
| 16:37:21 | <Beelsebob> | Saizan: true – and I'd 100% agree if we consider the naturally part |
| 16:37:29 | <Beelsebob> | but completelly disagree if we consider the normally part |
| 16:37:29 | <Guest39336> | TomMD: are you talking about the haskell98 accessors? |
| 16:37:33 | <opqdonut> | er, insert "for" into previous sentence |
| 16:37:37 | <jkramer> | How can I kill a thread in Haskell? |
| 16:37:44 | <opqdonut> | :t killThread |
| 16:37:44 | <Beelsebob> | because the normal use of Haskell involves all sorts of crazy calls out to other languages, and weird shit going on |
| 16:37:45 | <lambdabot> | Not in scope: `killThread' |
| 16:37:48 | <opqdonut> | gah |
| 16:37:56 | <Saizan> | Beelsebob: why? we don't write datastructures with mutable variables at every node |
| 16:37:57 | <Guest39336> | Botje: nah no problems yet just curious before i change code to use it |
| 16:38:13 | <jkramer> | Are you sure? The description if killThread sounds like it doesn't really kill it |
| 16:38:19 | <Saizan> | Beelsebob: and that's exactly what makes threading much easier |
| 16:38:20 | <TomMD> | Guest39336: I was talking about the record field updating, which I believe is just sugar. i.e. let newFoo = Foo { fieldOne = x } |
| 16:38:31 | <TomMD> | jkramer: It kills it. |
| 16:38:32 | <Beelsebob> | Saizan: certainly if we're writing naturally – however, I suspect the majority of packages on Hackage involve a large amount of crazyCallToCBecauseI'mBindingStuff |
| 16:38:35 | <opqdonut> | jkramer: anyway, killThread :: ThreadId -> IO () |
| 16:38:46 | <opqdonut> | ah, you were talking about it already |
| 16:38:53 | <jkramer> | And how do I get the ThreadId? |
| 16:38:59 | <TomMD> | @type forkIO |
| 16:38:59 | <Beelsebob> | so naturally - yes |
| 16:39:01 | <lambdabot> | Not in scope: `forkIO' |
| 16:39:01 | <Beelsebob> | normally - no |
| 16:39:03 | <TomMD> | grrr |
| 16:39:05 | <ski> | opqdonut : yes, and in variouse byte-string implementations too, iirc .. it would be nice if the implementations could rely on more than the optimizer in GHC not currently botching it up (cf. `NO_INLINE' nonsense) |
| 16:39:06 | <dmwit> | jkramer: from forkIO |
| 16:39:08 | <opqdonut> | jkramer: you got it from forkIO |
| 16:39:14 | <opqdonut> | :t Control.Concurrent.forkIO |
| 16:39:15 | <lambdabot> | IO () -> IO GHC.Conc.ThreadId |
| 16:39:19 | <Saizan> | Beelsebob: bindings are quite a different thing, and most provide an RT interface |
| 16:39:20 | <opqdonut> | qualified works |
| 16:39:22 | <jkramer> | And inside the thread? |
| 16:39:28 | <Beelsebob> | Saizan: most? |
| 16:39:29 | <Beelsebob> | o.O |
| 16:39:33 | <lament> | Beelsebob: probably because the majority of useful packages on hackage are library wrappers, but surely that's not the way to judge a language |
| 16:39:33 | <Beelsebob> | dunno which you've looked at |
| 16:39:41 | <opqdonut> | ski: yeah |
| 16:39:41 | <Beelsebob> | I think I've only met 1 binding that provided an RT interface |
| 16:39:47 | <Saizan> | Beelsebob: which have you looked at? |
| 16:39:52 | <Beelsebob> | OpenGL is a good start |
| 16:39:55 | <dmwit> | jkramer: Inside the thread, you can just die, you don't need to commit suicide. |
| 16:39:59 | <Beelsebob> | wanna try using that + threading? |
| 16:40:05 | <Beelsebob> | or GLUT |
| 16:40:14 | <lament> | Beelsebob: if you judge haskell by what's in library bindings, that's like saying you can't write a useful program in the language itself :) |
| 16:40:15 | <dmwit> | jkramer: However, all the usual methods of inter-thread communication work here, in case you really want to kill your own self. |
| 16:40:16 | <Beelsebob> | or any of the graphics/UI packages for that matter |
| 16:40:21 | <Saizan> | ah, ok, i've never worked with graphics |
| 16:40:30 | <Saizan> | but that's a peculiar subset, i'd think |
| 16:40:32 | <jkramer> | dmwit: I just want the thread to disappear :) |
| 16:40:45 | <dmwit> | jkramer: It disappears when it stops running. |
| 16:40:49 | <jkramer> | exitSuccess seems to work, but I'm not sure if it's intended to be used in threads |
| 16:41:05 | <Beelsebob> | Saizan: maybe for natural code – but I don't think so for "normal" people – I know very few coders who don't at some point have to write a UI |
| 16:41:25 | <TomMD> | Outside of graphics you don't run into such issues as GLUT or OpenGL... take the OpenSSL, Network, XML, and Xen bindings as examples. |
| 16:41:26 | <dmwit> | jkramer: forkIO (return ()) -- does not strand any threads or anything, that thread just "disappears" |
| 16:41:28 | <Saizan> | graphic toolkits tend to impose you a mainloop, even, right? |
| 16:41:37 | <Beelsebob> | Saizan: some of them, yeh |
| 16:41:40 | <Beelsebob> | (most?) |
| 16:41:52 | <Guest39336> | glfw doesnt |
| 16:42:06 | <Beelsebob> | Saizan: I don't know of one single one that's thread safe though |
| 16:42:10 | <Beelsebob> | nor one that's RT |
| 16:42:21 | <Saizan> | well, there's lot of networking where concurrency is important that's quite far from GUIs |
| 16:43:01 | <TomMD> | Indeed, graphics are unique in their terrible use of TLS. |
| 16:43:18 | <Philonous> | @type myThreadId -- jkramer |
| 16:43:19 | <lambdabot> | Not in scope: `myThreadId' |
| 16:43:25 | <Beelsebob> | which is a shame... because graphics is one of the main areas where RT is *most* beneficial |
| 16:43:29 | <TomMD> | @type Control.Concurrent.myThreadId |
| 16:43:31 | <lambdabot> | IO GHC.Conc.ThreadId |
| 16:43:42 | <Beelsebob> | because we have lovely hardware that can run 1600 threads at once |
| 16:43:58 | <jkramer> | Philonous: Great, thanks :) |
| 16:44:11 | <lament> | my computer can only run two threads at once :( |
| 16:44:22 | <ski> | a binding not providing an RT interface would be similar to calling `unsafePerformIO' on specific impur `IO'-actions .. if the bindings bind side-effecting actions into haskell `IO', and (roughly) don't mutate values which can be "inspected" in haskell without using `IO', then it should be RT |
| 16:44:41 | <TomMD> | I think Beelsebob is talking about GPUs, which is somewhat conflating the issue if that's the case. |
| 16:45:14 | <ski> | of course, an `IO'-intersive binding would be an *imperative* (/ effectful) interface .. but still RT |
| 16:45:28 | <mightybyte> | Is there an easy way to have cabal-install rebuild all dependencies with profiling enabled? |
| 16:45:49 | <alexsuraci> | oi, neither hsql nor hdbc seem to work with the latest ghc |
| 16:45:54 | <Saizan> | mightybyte: nothing automatic |
| 16:46:03 | <ski> | this is similar to how an `State Foo'-based solution for a problem is imperative/effectful |
| 16:46:13 | <alexsuraci> | hsql gives me a segfault, hdbc errors with "schedule: re-entered unsafely" |
| 16:47:22 | <TomMD> | alexsuraci: If you're using the hsql package, I think haskelldb (and thus haskelldb-hsql) are the recommended DB libraries these days. |
| 16:48:08 | <alexsuraci> | TomMD: I'd go further with HaskellDB if I could find some decent documentation on it. Plus if it uses hsql and hsql is "broken" it's doubtful I'd have much luck there. :/ |
| 16:48:48 | <TomMD> | alexsuraci: It could potentially use it safely, but admitadly I haven't used the DB libraries in a while. |
| 16:55:54 | <mightybyte> | Saizan: Hmm, that seems like a pretty significant omission. |
| 16:59:12 | <Athas> | Where do I get the profiling libraries for binary-0.4.4? |
| 17:00:19 | <mux> | Athas: you have them by building the package with profiling libraries enabled |
| 17:00:33 | <mux> | Athas: you can do that by passing the -p flag to the configure command (of cabal) |
| 17:00:38 | <mux> | ie runhaskell Setup.hs configure -p |
| 17:01:29 | <Athas> | mux: I think I used 'cabal install binary' to get them (at least they seem to be installed locally). Can I do that with cabal install? |
| 17:01:55 | <mux> | there's most likely a similar flag to use, but I don't know it |
| 17:03:35 | <Athas> | Where can I find a manual for cabal-install? It didn't install any manpages. |
| 17:04:22 | <mux> | -p --enable-library-profiling Enable Library profiling |
| 17:04:26 | <mux> | from cabal help install |
| 17:04:32 | <Athas> | Thanks. |
| 17:04:34 | <mux> | so you can pass the very same flag |
| 17:08:06 | <tibbe> | @seen bos |
| 17:08:06 | <lambdabot> | bos is in #haskell-in-depth, #ghc and #haskell. I don't know when bos last spoke. |
| 17:08:54 | <philipp_> | i'm using parMap to parallelise a job which works fine for half an hour (cpu is constantly at 180%) but after that it drops to ~100% for the remaining 2 hours, any ideas? |
| 17:09:41 | <tibbe> | philipp_: does profiling output give anything? i.e. is lots of time spent in GC? |
| 17:10:10 | <philipp_> | tibbe: have to check that... |
| 17:10:20 | <philipp_> | what if so? |
| 17:10:30 | <tibbe> | philipp_: don't remember the exact flag |
| 17:10:41 | <tibbe> | philipp_: if there's excessive GC you need to figure out why ;) |
| 17:10:45 | <tibbe> | i.e. profile |
| 17:12:41 | <lilac> | philipp_: does your list have two entries, one of which takes 5x longer to process than the other, by any chance? :) |
| 17:14:14 | <jkramer> | Is there a way to work around circular module imports? |
| 17:15:05 | <jkramer> | I have two modules and both use functions from the other module |
| 17:15:30 | <roconnor> | jkramer: usually you can pull apart modules further to break the cycle. |
| 17:15:48 | <roconnor> | jkramer: for example putting one of those functions into it's own module |
| 17:16:00 | <lilac> | philipp_: http://www.nabble.com/Control.Parallel.Strategies.parMap-CPU-usage-td22497395.html |
| 17:16:15 | <roconnor> | jkramer: then just re-export it from the module you originally wanted it in. |
| 17:16:24 | <saynte> | jkramer: you can define a the necessary function in interface files, hs-boot i think. but you have to do this manually. |
| 17:17:03 | <dons> | ACTION ponders why the 'probability monad' post is at the top of programming reddit. |
| 17:18:05 | <mux> | reddit is being weird today |
| 17:19:29 | <philipp_> | lilac: thanks, so I'll try the head revision |
| 17:22:45 | <voker57_> | how to convert numbers between bases? |
| 17:22:58 | <JamesSanders> | I keep get this error in one of my programs "Not in scope: type constructor or class `True'" |
| 17:23:11 | <kpreid> | JamesSanders: True is not a type; it is a value. |
| 17:23:36 | <Twey> | voker57_: That is not a valid question |
| 17:23:51 | <Twey> | Numbers are simply numbers; they have no associated base until they're formatted for human reading |
| 17:24:30 | <Twey> | (which can be done with Numeric.showIntAtBase, as well as several small helper functions for common cases like Numeric.showHex) |
| 17:25:07 | <Botje> | #haskell: we fix your question _AND_ answer it! |
| 17:25:16 | <mightybyte> | How do you do a ghc build with profiling when it tells you "You need to build the program twice...using -osuf"? |
| 17:25:33 | <JamesSanders> | so when something calls for Bool then I should be able to use True right? |
| 17:25:41 | <JamesSanders> | @type True |
| 17:25:41 | <lambdabot> | Bool |
| 17:27:45 | <kpreid> | JamesSanders: Yes, but you can't give it a *type* True |
| 17:28:10 | <kpreid> | JamesSanders: The difference between True and other Bools (i.e. False) does not show up at the type level. |
| 17:28:18 | <kpreid> | If that's still confusing, show us your code |
| 17:31:19 | <Beelsebob> | kpreid: sure it does... look... data True; data False |
| 17:31:38 | <Twey> | ACTION twitches. |
| 17:31:44 | <Beelsebob> | >.> |
| 17:31:45 | <Beelsebob> | <.< |
| 17:32:15 | <JamesSanders> | so there is a Conf constructor and it looks a bit like this Conf = Conf { |
| 17:32:15 | <JamesSanders> | priority :: !Bool |
| 17:32:15 | <JamesSanders> | groupMembership :: !Bool |
| 17:32:53 | <JamesSanders> | and my code is like so : conf = Conf True True |
| 17:33:08 | <JamesSanders> | what am I doing wrong? |
| 17:33:09 | <kpreid> | That's fine. |
| 17:33:19 | <Beelsebob> | looks good to me :) |
| 17:33:24 | <kpreid> | There's something else wrong. |
| 17:33:25 | <JamesSanders> | yeah but it throws those errors in ghci |
| 17:33:37 | <Saizan> | it must be something else |
| 17:33:42 | <ski> | @paste |
| 17:33:43 | <lambdabot> | Haskell pastebin: http://hpaste.org/new |
| 17:33:47 | <kpreid> | You're not trying to define the data type at the ghci command line, are you? |
| 17:33:54 | <kpreid> | ghci only takes expressions. |
| 17:33:57 | <JamesSanders> | no |
| 17:34:02 | <kpreid> | If that's not the problem, pastebin ^ your code |
| 17:34:15 | <JamesSanders> | when I load the module into ghci I get the error |
| 17:34:23 | <ski> | (also paste the error you get) |
| 17:34:58 | <JamesSanders> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5507#a5507 |
| 17:35:25 | <Beelsebob> | that's not all the source |
| 17:35:30 | <Beelsebob> | nor the error |
| 17:35:45 | <Saizan> | well it's enough source |
| 17:35:51 | <JamesSanders> | http://hpaste.org/fastcgi/hpaste.fcgi/view?id=5508#a5508 |
| 17:35:54 | <JamesSanders> | that is the error |
| 17:36:04 | <Saizan> | JamesSanders: you've to put parentheses around ("htest")::PrivateName |
| 17:36:12 | <mauke> | ("htest" :: PrivateName) |
| 17:36:20 | <Saizan> | otherwise it parses what comes after as part of the type |
| 17:36:24 | <ski> | (JamesSanders : next time, annotate the same paste with related pastes :) |
| 17:36:25 | <mauke> | ("test") is the same as "test" |
| 17:36:25 | <Beelsebob> | oh, heh, well spotted Saizan |
| 17:36:39 | <JamesSanders> | sorry |
| 17:37:55 | <kpreid> | JamesSanders: Similar problem in 'main' -- you're saying that join "test" is of type Group a |
| 17:38:12 | <kpreid> | well, I suppose it is if Group is a type alias for IO |
| 17:38:21 | <kpreid> | but I suspect you meant ("test" :: Group a) |
| 17:38:32 | <kpreid> | use spacing. :: is least-precedence, not highest |
| 17:39:30 | <JamesSanders> | so I went ahead and removed main |
| 17:39:40 | <Saizan> | you actually have to use mkGroup to get a Group |
| 17:39:58 | <Saizan> | (that part of the api is a bit annoying maybe) |
| 17:40:33 | <JamesSanders> | ah seems like I might need to read up a little more on hspread |
| 17:41:02 | <Saizan> | i'm the author, so you can blame me for the lack of documentation :) |
| 17:41:56 | <karld> | I'm a newbie. Is there a way to apply something like ( take 2 ) to a list until there are no elements remaining and return a list of lists? |
| 17:42:27 | <mauke> | > iterate (take 2) "foo bar" |
| 17:42:28 | <lambdabot> | ["foo bar","fo","fo","fo","fo","fo","fo","fo","fo","fo","fo","fo","fo","fo"... |
| 17:42:33 | <mauke> | no! |
| 17:42:38 | <karld> | iterate! |
| 17:42:41 | <karld> | thanks |
| 17:42:45 | <mauke> | > iterate (drop 2) "foo bar" |
| 17:42:46 | <lambdabot> | ["foo bar","o bar","bar","r","","","","","","","","","","","","","","","","... |
| 17:42:56 | <Saizan> | > map (take 2) . iterate (drop 2) $ [1..10] |
| 17:42:57 | <lambdabot> | [[1,2],[3,4],[5,6],[7,8],[9,10],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[... |
| 17:43:01 | <JamesSanders> | Saizan: small world |
| 17:43:03 | <mauke> | > takeWhile (not . null) . iterate (drop 2) $ "foo bar" |
| 17:43:04 | <lambdabot> | ["foo bar","o bar","bar","r"] |
| 17:43:34 | <karld> | Cool, thanks for all the answers |
| 17:43:38 | <ski> | > unfoldr (\as -> guard (not (null as)) >> return (splitAt 3 as)) "foo bar baz" |
| 17:43:39 | <lambdabot> | ["foo"," ba","r b","az"] |
| 17:44:01 | <ski> | > unfoldr (\as -> if null as then Nothing else Just (splitAt 3 as)) "foo bar baz" -- if you prefer |
| 17:44:02 | <lambdabot> | ["foo"," ba","r b","az"] |
| 17:45:16 | <rfmge> | > replicateM 3 "HT" |
| 17:45:17 | <lambdabot> | ["HHH","HHT","HTH","HTT","THH","THT","TTH","TTT"] |
| 17:45:22 | <rfmge> | can someone explain how 'replicateM n list' generates all permutations of length n of the given list? |
| 17:45:30 | <lilac> | @src replicateM |
| 17:45:30 | <lambdabot> | replicateM n x = sequence (replicate n x) |
| 17:45:50 | <lilac> | rfmge: replicate 3 "HT" returns ["HT", "HT", "HT"] |
| 17:46:00 | <ski> | > unfoldr (\as -> const (splitAt 3 as) `liftM` guard (not (null as))) "foo bar baz" -- hm, longer :) |
| 17:46:01 | <lambdabot> | ["foo"," ba","r b","az"] |
| 17:46:01 | <lilac> | rfmge: sequence for the list monad is nondeterministic choice |
| 17:46:31 | <rfmge> | lilac: okay, that helps |
| 17:46:40 | <ski> | > return (,,) `ap` [0,1] `ap` [2,3] `ap` [4,5] |
| 17:46:41 | <lambdabot> | [(0,2,4),(0,2,5),(0,3,4),(0,3,5),(1,2,4),(1,2,5),(1,3,4),(1,3,5)] |
| 17:47:02 | <ski> | > do x <- [0,1]; y <- [2,3]; z <- [4,5]; return (x,y,z) |
| 17:47:04 | <lambdabot> | [(0,2,4),(0,2,5),(0,3,4),(0,3,5),(1,2,4),(1,2,5),(1,3,4),(1,3,5)] |
| 17:47:16 | <ski> | > [(x,y,z) | x <- [0,1] , y <- [2,3] , z <- [4,5]] |
| 17:47:18 | <lambdabot> | [(0,2,4),(0,2,5),(0,3,4),(0,3,5),(1,2,4),(1,2,5),(1,3,4),(1,3,5)] |
| 17:47:19 | <lilac> | rfmge: sequence is nondeterministic choice because it's the repeated application of >>=, and >>= on lists applies the rhs to every element of the lhs |
| 17:47:49 | <ski> | > liftM3 (,,) [0,1] [2,3] [4,5] -- for completeness, i suppose |
| 17:47:50 | <lambdabot> | [(0,2,4),(0,2,5),(0,3,4),(0,3,5),(1,2,4),(1,2,5),(1,3,4),(1,3,5)] |
| 17:47:53 | <ski> | @src liftM3 |
| 17:47:54 | <lambdabot> | liftM3 f m1 m2 m3 = do { x1 <- m1; x2 <- m2; x3 <- m3; return (f x1 x2 x3) } |
| 17:48:03 | <rfmge> | > "H" >>= "HT" |
| 17:48:04 | <lambdabot> | Couldn't match expected type `GHC.Types.Char -> [b]' |
| 17:48:09 | <lilac> | rfmge: put another way, if you think of [] as the nondeterminism monad, you're asking "give me 3 things taken nondeterministically from ['H', 'T']" |
| 17:48:30 | <ski> | > "ab" >>= \x -> x : "cd" |
| 17:48:31 | <lambdabot> | "acdbcd" |
| 17:48:45 | <Cale> | > replicateM 3 "HT" |
| 17:48:46 | <lambdabot> | ["HHH","HHT","HTH","HTT","THH","THT","TTH","TTT"] |
| 17:48:50 | <ski> | > "ab" >>= \x -> "cd" >>= \y -> [x,y,'*'] |
| 17:48:51 | <lambdabot> | "ac*ad*bc*bd*" |
| 17:49:30 | <lilac> | > do x <- "ab"; y <- cd; x:y:"*" |
| 17:49:31 | <lambdabot> | Not in scope: `cd' |
| 17:49:37 | <lilac> | > do x <- "ab"; y <- "cd"; x:y:"*" |
| 17:49:38 | <trofi> | > eval "1+2" |
| 17:49:39 | <lambdabot> | "ac*ad*bc*bd*" |
| 17:49:40 | <lambdabot> | Not in scope: `eval' |
| 17:49:45 | <wjt> | @pl \f x -> fromMaybe x (f x) |
| 17:49:45 | <lambdabot> | ap fromMaybe |
| 17:49:59 | <ski> | @redo "ab" >>= \x -> "cd" >>= \y -> [x,y,'*'] |
| 17:49:59 | <lambdabot> | do { x <- "ab"; y <- "cd"; [x, y, '*']} |
| 17:50:01 | <wjt> | is there a better name for that other than ap? |
| 17:50:27 | <Saizan> | the only other name is <*> |
| 17:50:35 | <Cale> | wjt: Oh, what a curious application of ap :) |
| 17:50:35 | <lesshaste> | hi all |
| 17:50:46 | <ski> | @type \f x -> fromMaybe x (f x) |
| 17:50:47 | <Cale> | hello |
| 17:50:47 | <lambdabot> | forall a. (a -> Maybe a) -> a -> a |
| 17:50:52 | <lilac> | rfmge: another way of looking at it is, replicateM n x = do v1 <- x; ...; vn <- x; return [v1,v2,...,vn] |
| 17:50:56 | <trofi> | :t fromMaybe |
| 17:50:57 | <lambdabot> | forall a. a -> Maybe a -> a |
| 17:51:06 | <wjt> | Cale: yeah, it made me smile |
| 17:51:20 | <wjt> | in this case, i want to strip a prefix from a path if it has it, but otherwise leave it intact |
| 17:51:25 | <rfmge> | lilac: okay, it makes more sense now, thanks |
| 17:51:31 | <ski> | \f -> fromMaybe `ap` f |
| 17:51:37 | <ski> | (fromMaybe `ap`) |
| 17:51:38 | <wjt> | so i'm using \p -> fromMaybe p (stripPrefix "foo/bar" p) |
| 17:51:48 | <^Someone^> | lilac: I use Konversation, and it has colored nicks. Interestingly, your nick color is very close to lilac xD |
| 17:51:58 | <ski> | fromMaybe `ap` stripPrefix "foo/bar" |
| 17:52:01 | <lilac> | ^Someone^: woo yay :) |
| 17:53:13 | <^Someone^> | lilac: http://imagebin.org/51219 |
| 17:53:20 | <wjt> | using the ((->) r) monad makes me a bit sad |
| 17:53:36 | <wjt> | I guess I'm surprised that S isn't sitting around somewhere less obtuse :) |
| 17:53:38 | <Cale> | wjt: I suppose you could use fromMaybe <*> stripPrefix "foo/bar" |
| 17:54:02 | <Cale> | wjt: <*> is in Control.Applicative |
| 17:54:46 | <Cale> | wjt: Though, that's using the ((->) e) Applicative functor instance instead :) |
| 17:54:50 | <wjt> | Cale: well exactly :P |
| 17:55:06 | <Cale> | wjt: The lovely thing about that is that the Applicative methods for ((->) e) are *exactly* K and S. |
| 17:55:12 | <wjt> | i guess i'm golfing here anyway |
| 17:55:28 | <wjt> | Cale: oh, sure |
| 17:55:29 | <Cale> | and the Functor instance has fmap = (.) |
| 17:55:32 | <lilac> | wjt: in that case, use stripPrefix "foo/bar" p <:> p |
| 17:55:52 | <lilac> | ACTION still pimping out <?> and <:> |
| 17:55:56 | <Cale> | <:> |
| 17:55:57 | <Cale> | ? |
| 17:56:00 | <wjt> | @src (<:>) |
| 17:56:00 | <lambdabot> | Source not found. Maybe you made a typo? |
| 17:56:03 | <wjt> | @ty (<:>) |
| 17:56:04 | <lambdabot> | Not in scope: `<:>' |
| 17:56:11 | <Cale> | ACTION does not know of it |
| 17:56:14 | <ski> | @index <:> |
| 17:56:15 | <lambdabot> | bzzt |
| 17:56:19 | <lilac> | <?> :: Bool -> a -> Maybe a; <:> :: Maybe a -> a -> a |
| 17:56:33 | <Cale> | ah |
| 17:56:35 | <mauke> | :t fromMaybe |
| 17:56:36 | <Cale> | cute |
| 17:56:36 | <lambdabot> | forall a. a -> Maybe a -> a |
| 17:56:42 | <wjt> | nice |
| 17:56:43 | <lilac> | ACTION will get around to uploading to hackage Real Soon Now |
| 17:57:36 | <Cale> | I actually rather like how (fromMaybe <*> stripPrefix "foo/bar") reads. |
| 17:57:44 | <lilac> | @let False <?> a = mzero; True <?> a = return a; (<:>) = flip fromMaybe |
| 17:57:46 | <lambdabot> | Defined. |
| 17:57:47 | <Saizan> | why <:> ? |
| 17:57:59 | <Cale> | Saizan: It agrees with C syntax in a funny way |
| 17:58:00 | <wjt> | Saizan: by analogy to ?: in C |
| 17:58:06 | <hackagebot> | bindings-libusb 0.0.3 |
| 17:58:10 | <Saizan> | ah, i see |
| 17:58:23 | <lilac> | > map (\a -> (a > 3) <?> a - 3 <:> 0) [1..10] |
| 17:58:24 | <lambdabot> | No instance for (GHC.Num.Num (m a)) |
| 17:58:24 | <lambdabot> | arising from the literal `0' at <int... |
| 17:58:35 | <monochrom> | ACTION is eager for Haskell Weekly News |
| 17:58:44 | <lilac> | :( |
| 17:58:50 | <Cale> | ACTION is lazy for Haskell Weekly News |
| 17:59:27 | <kig> | is there an optimized lib for fiddling with 4x4 opengl transformation matrices? |
| 17:59:34 | <monochrom> | ACTION is strict for Haskell Weekly News |
| 17:59:43 | <ski> | > map (\a -> (a > 3) <?> (a - 3) <:> 0) [1..10] |
| 17:59:45 | <lambdabot> | [0,0,0,1,2,3,4,5,6,7] |
| 18:00:07 | <lament> | Haskell Weekly World News? |
| 18:02:17 | <lilac> | > (<:> '?') <$> safeHead <$> ["foo", "bar", "", "baz"] |
| 18:02:19 | <lambdabot> | "fb?b" |
| 18:11:11 | <hackagebot> | bindings-common 0.1.3 |
| 18:25:49 | <olsner> | hmm, ghci seem to get the column numbers wrong (one off, presumably from the '>') for literal haskell |
| 18:35:03 | <JamesSanders> | Saizan: join expects a Group but mkGroup gives Maybe(Group), how do I get around that |
| 18:35:24 | <JamesSanders> | sorry talking about hspread btw |
| 18:35:54 | <Saizan> | JamesSanders: you've to pattern match on the returned Maybe |
| 18:36:07 | <Saizan> | JamesSanders: the point is that not all strings are valid group names |
| 18:36:14 | <JamesSanders> | ah |
| 18:36:17 | <JamesSanders> | makes sense |
| 18:36:48 | <gwern> | System.Directory is in directory, which works on windows, right |
| 18:37:09 | <EvilTerran> | gwern, in my experience, yes |
| 18:37:18 | <gwern> | experience? no guarantees? |
| 18:37:36 | <EvilTerran> | i've used it, it worked for me. YMMV. |
| 18:37:56 | <Saizan> | System.Directory is supposed to abstract over the platform, yeah |
| 18:38:17 | <EvilTerran> | i don't know the official status; i've not felt the need to look it up, seeing as it WFM. |
| 18:48:57 | <voker57_> | @hoogle (a, a) -> [a,a] |
| 18:48:57 | <lambdabot> | Parse error: |
| 18:48:57 | <lambdabot> | --count=20 "(a, a) -> [a,a]" |
| 18:48:57 | <lambdabot> | ^ |
| 18:50:06 | <ClaudiusMaximus> | is call-by-need an optimal evaluation strategy for untyped lambda calculus? my naive evaluator is very slow (in (\x . f x x) y it ends up evaluating y twice...) |
| 18:51:23 | <mauke> | then it's obviously not optimal |
| 18:51:41 | <byorgey> | ClaudiusMaximus: call-by-need is only efficient if you do some sort of sharing / graph reduction. |
| 18:51:55 | <ClaudiusMaximus> | my naive evaluator isn't call-by-need |
| 18:52:00 | <Cale> | ClaudiusMaximus: You seem to be doing plain outermost-first evaluation |
| 18:52:07 | <ClaudiusMaximus> | Cale: yes indeed |
| 18:52:18 | <Cale> | (I don't understand these call-by-X evaluation strategy names) |
| 18:52:53 | <ibid> | ClaudiusMaximus: call by need is not optimal, if measured by number of beta reductions. see the work of levy et al on optimal beta reduction |
| 18:52:55 | <Cale> | In order to do lazy evaluation, you need to ensure that whenever a function parameter occurs more than once in the body of a function, then any results of evaluating it are shared between the copies. |
| 18:52:59 | <byorgey> | call-by-need = outermost-first |
| 18:53:08 | <byorgey> | call-by-name = that, but with sharing |
| 18:53:19 | <ibid> | byorgey: you have that backward |
| 18:53:25 | <Cale> | byorgey: Yeah, but those names are very unintuitive to me. |
| 18:53:26 | <byorgey> | oh, do I? |
| 18:53:30 | <byorgey> | Cale: me too. |
| 18:53:40 | <byorgey> | well, and apparently I had them backwards. =) |
| 18:53:42 | <mornfall> | call-by-{need,name} is stupid :) |
| 18:53:46 | <ibid> | yes, call-by-name is weak normal order reduction |
| 18:53:55 | <Cale> | I don't see why people don't just say what they mean :) |
| 18:53:57 | <ibid> | call by need is that + sharing |
| 18:54:01 | <mornfall> | call-by-value and call-by-reference make some limited sense I guess :) |
| 18:54:15 | <ibid> | call by name goes back to Algol 60 |
| 18:54:31 | <mornfall> | Yes, and it was really by name then, IIRC. |
| 18:54:38 | <ibid> | and call by need is iirc almost as old as wadsworth's thesis |
| 18:55:51 | <ibid> | (the name, i mean) |
| 18:55:59 | <Cale> | Even for call-by-value, it makes more sense to me just to say 'innermost-first' |
| 18:56:14 | <ibid> | ah, but call by value is *not* innermost first |
| 18:56:21 | <mornfall> | Lol. :) |
| 18:56:21 | <ibid> | call by value is the weak version of that |
| 18:56:33 | <ibid> | (ie. never reduce under a lambda) |
| 18:56:59 | <mornfall> | call by value = strict, call by *cough* name = normal, call by need = lazy? : - ) |
| 18:57:23 | <ibid> | mornfall: call by name is weak normal, otherwise correct |
| 18:57:43 | <Cale> | Ah, well then, it's still clearer to say weak innermost-first or innermost-first without evaluating under lambdas. |
| 18:58:03 | <mornfall> | So what's the weakness about, then? |
| 18:58:20 | <Cale> | mornfall: Whether the evaluator will evaluate inside of an unapplied lambda |
| 18:59:03 | <ibid> | and basically no evaluator that is intended for programming does that |
| 18:59:26 | <mornfall> | http://en.wikipedia.org/wiki/Evaluation_strategy has all of it :) |
| 18:59:31 | <Cale> | Yeah, when I say 'innermost first' I usually mean 'without evaluating under lambda' |
| 18:59:31 | <ibid> | (evaluators that are inside theorem provers or partial-evaluation optimizers do) |
| 18:59:44 | <marcot> | Why aren't more licenses add to the list in Distribution.License? |
| 18:59:44 | <lambdabot> | marcot: You have 1 new message. '/msg lambdabot @messages' to read it. |
| 19:00:11 | <marcot> | http://www.opensource.org/licenses/category |
| 19:00:14 | <ibid> | lambdabot: why do you insist on that broken message interface, when Freenode provides a better one? |
| 19:00:16 | <Cale> | I think it's probably more sensible to adopt a convention of calling the versions which do evaluate underneath lambdas 'strong' |
| 19:00:17 | <marcot> | .:: Licenses that are popular and widely used or with strong communities ::. |
| 19:00:35 | <ibid> | Cale: people do that, when it is important, yes :) |
| 19:04:46 | <ClaudiusMaximus> | so for sharing i guess i need something like data Term = Variable Name | Lambda Name Term | Apply Term Term | Reference Integer along with type Graph = Map Integer Term |
| 19:06:42 | <marcot> | I'm trying to use UnkownLicense in the license field of a cabal file, but I'm getting: Setup: questionary.cabal:5: Parse of field 'license' failed. |
| 19:08:33 | <MyCatVerbs> | marcot: spelling error? It's UnknownLicense. |
| 19:09:38 | <marcot> | MyCatVerbs: no, this was only to type here on IRC. |
| 19:09:45 | <marcot> | I tried here: |
| 19:09:55 | <marcot> | > read "UnknownLicense \"FreeBSD\"" :: License |
| 19:09:56 | <lambdabot> | Not in scope: type constructor or class `License' |
| 19:10:01 | <mmorrow> | what is the reverse postorder of the graph [(0,[1,2]),(1,[0,2]),(2,[])] ? |
| 19:10:04 | <marcot> | And it worked in ghci. |
| 19:10:13 | <mmorrow> | [0,1,2], right? |
| 19:10:45 | <MyCatVerbs> | marcot: er... why specify the license as unknown "FreeBSD"? |
| 19:10:49 | <mmorrow> | suprisingly there are no examples to verify on google... |
| 19:11:02 | <marcot> | MyCatVerbs: can you configure a cabal package with this field there? I'm using ghc 6.10.3, and cabal 1.6.0.3 |
| 19:11:18 | <MyCatVerbs> | There are BSD-2, BSD-3 and BSD-4 entries for the license, and people will be much happier if you write one of those in. |
| 19:11:40 | <marcot> | MyCatVerbs: There's not BSD-2. |
| 19:11:55 | <marcot> | MyCatVerbs: If there was, I think it would mean the same license as FreeBSD. |
| 19:12:12 | <MyCatVerbs> | Eh, just make it BSD-3. BSD-2 and BSD-3 aren't, AIUI, interestingly different. |
| 19:12:53 | <marcot> | http://www.gnu.org/licenses/license-list.html#FreeBSD |
| 19:14:20 | <marcot> | 3. The name of the author may not be used to endorse or promote products derived from this software without specific prior written permission. |
| 19:14:23 | <marcot> | This is the difference. |
| 19:14:38 | <marcot> | And I don't want to have this clause in my license. So, it's not BSD3. |
| 19:14:57 | <roconnor> | ACTION uses MIT |
| 19:15:11 | <marcot> | MIT is also cool. |
| 19:15:21 | <marcot> | roconnor: do you use BSD3 in .cabal? |
| 19:15:41 | <fracture> | I am trying to import Control.Monad.Reader, and get |
| 19:15:42 | <fracture> | Failed to load interface for `Control.Monad.Reader': |
| 19:15:42 | <fracture> | it was found in multiple packages: monads-fd-0.0.0.1 mtl-1.1.0.2 |
| 19:15:44 | <roconnor> | no |
| 19:15:47 | <fracture> | (in ghc) |
| 19:15:55 | <fracture> | anyone know what I need to do? |
| 19:15:56 | <roconnor> | I use unknown licence |
| 19:16:11 | <MyCatVerbs> | fracture: ghc-pkg hide monads-fd # at the command prompt, should solve this. |
| 19:16:18 | <marcot> | roconnor: UnknownLicense or OtherLicense? I can't make UnknownLicense work here.. |
| 19:16:40 | <MyCatVerbs> | What the Hell is monads-fd anyway? People really should not be writing packages that conflict with mtl! |
| 19:16:44 | <roconnor> | sorry OtherLicense |
| 19:16:45 | <seliopou> | fracture, or you can use ghc's -hide-package flag |
| 19:16:50 | <fracture> | dunno |
| 19:16:53 | <fracture> | ok thanks |
| 19:16:55 | <marcot> | Has anyone ever used UnknownLicense? |
| 19:16:56 | <fracture> | I dunno what monads-fd is |
| 19:17:04 | <seliopou> | it's mtl with functional dependencies |
| 19:17:11 | <seliopou> | instead of type classes |
| 19:17:15 | <fracture> | I think the only package I've installed that is not default was a Data.Numbers thing |
| 19:17:21 | <fracture> | (prime number functions) |
| 19:17:28 | <roconnor> | marcot: conal was trying a few days ago, and failing IIRC |
| 19:17:41 | <marcot> | roconnor: hum, good to know I'm not the only one. |
| 19:18:12 | <MyCatVerbs> | fracture: cabal install chases dependencies. So if Data.Numbers requires monads-fd then it'll install both. |
| 19:18:20 | <fracture> | *nod* |
| 19:23:31 | <marcot> | roconnor: They've added MIT in darcs version of cabal. |
| 19:24:45 | <roconnor> | marcot: yes |
| 19:25:59 | <thoughtpolice> | well, the idea is that cabal is smart enough to do the hard stuff providing you write your dependencies correctly |
| 19:26:05 | <thoughtpolice> | but shadowing names is never a good idea, no |
| 19:26:36 | <thoughtpolice> | it makes it particularly problematic for GHC just on the command line (since you have to -hide-package) unless you use the PackageImports extension, which helps |
| 19:27:02 | <thoughtpolice> | but it's still not very fun to deal with |
| 19:27:15 | <thoughtpolice> | mtl may be on the way out anyway |
| 19:27:24 | <thoughtpolice> | providing we can get some sort of consensus to switch |
| 19:28:16 | <thoughtpolice> | I do *not* like how monads-fd and monads-tf etc. shadow the mtl names, however. |
| 19:28:37 | <thoughtpolice> | i should probably just use monadLib or something |
| 19:29:19 | <roconnor> | > sqrt (1-0.568) |
| 19:29:21 | <lambdabot> | 0.6572670690061994 |
| 19:29:43 | <roconnor> | thoughtpolice: they are supposed to be drop in replacements for the mtl |
| 19:30:18 | <roconnor> | > 1-sqrt (1-0.568) |
| 19:30:18 | <lambdabot> | 0.34273293099380064 |
| 19:31:18 | <thoughtpolice> | roconnor: can packages which work with mtl work without problem using e.g.transformers+monads-fd as a drop-in? |
| 19:31:50 | <sjanssen> | thoughtpolice: I believe you have to add extra imports to get the classes |
| 19:32:41 | <thoughtpolice> | the problem is that I have packages which I use, some of which use mtl, some of which use transformers+something, and it makes it annoying to test things with ghci sometimes |
| 19:33:36 | <thoughtpolice> | if we see a shift hopefully it will be soon, so I can cabal uninstall mtl and not have that problem anymore |
| 19:33:55 | <roconnor> | thoughtpolice: *shrugs* that's what you get for using a global environment for ghc packages. |
| 19:34:10 | <Berengal> | thoughtpolice: If you're only troubled in ghci, you can use :set -hide-package to hide one of them |
| 19:34:38 | <thoughtpolice> | Berengal: I can totally get around it (PackageImports works good,) I just don't like it. :) |
| 19:36:39 | <thoughtpolice> | sjanssen: really? awesome. that makes switching simple, worthy of automating, even if that's all it takes. |
| 19:38:35 | <roconnor> | thoughtpolice: switch to monadLib instead |
| 19:39:26 | <thoughtpolice> | roconnor: I like monadLib a lot (and use it,) I just want a solution for *that* problem. :) |
| 19:39:48 | <thoughtpolice> | although last I remember I had to do something to get it to work with 6.10 |
| 19:39:52 | <thoughtpolice> | that was a while ago |
| 20:01:11 | <MrChutney> | I'm trying my hand at a lexical analyzer for this small project of mine. I have a language designed, and I have this datatype which describes a set of instructions. |
| 20:01:45 | <MrChutney> | And I want to make some function, f, which converts from the language to the instructions. |
| 20:01:58 | <MrChutney> | I've considered a certain approach, but I'm not terribly certain of myself: |
| 20:02:32 | <MrChutney> | I'm wanting to create an intermediate language, which is a subset of valid code under the entire language: |
| 20:02:45 | <MrChutney> | And under this subset, all code is unsynonymous |
| 20:03:18 | <MrChutney> | And thus any line of code corresponds uniquely to an instruction in my datatype, so that there is an isomorphism between the two. |
| 20:04:06 | <MrChutney> | The drawback is that this involves a lot of rearranging of code, and since I am trying to make an interpreter with concerns about efficiency, I'm not utterly convinced of my method :/ |
| 20:04:51 | <Saizan> | the representation of the syntax tree and the code interpreted by your runtime can be different |
| 20:04:52 | <MrChutney> | Can anyone offer any advice on the subject? |
| 20:05:06 | <Saizan> | i.e. you might have more than one layer |
| 20:05:34 | <Saizan> | that's what's usually done nowadays, afaik |
| 20:06:35 | <Baughn> | MrChutney: Modern "interpreters" typically compile to bytecode, which is then interpreted |
| 20:06:49 | <Baughn> | FWIW, a primitive compiler can be really very simple indeed |
| 20:07:07 | <MrChutney> | I've honestly never heard of syntax trees until now, and this gives me something to work with. Thanks a bunch! |
| 20:08:13 | <lunarisbluemoon> | Hi #haskell; I'm writing up a benchmark in Haskell which is essentially a port of a C program. Any tips for speed? |
| 20:08:28 | <Saizan> | ah, the "abstract syntax tree" is how the result of parsing is generally called |
| 20:09:18 | <mgee> | hi, i am using the HERA package, which provides the datatype CReal. Now ghc tells me that I have to add "(RealFloat CReal) =>" to every function using CReal... how can i prevent this? I just want to use the datatype without any instance declarations... |
| 20:09:23 | <MrChutney> | Oh, I see. |
| 20:09:35 | <lunarisbluemoon> | I've read several articles on the matter, but really I'm not a Haskell guru and am wondering if it's standard practice to use a state monad to mimic an imperative program. |
| 20:09:50 | <lunarisbluemoon> | mgee: what is the exact error message? |
| 20:10:17 | <Beelsebob> | lunarisbluemoon: people seem to do it a lot |
| 20:10:23 | <Beelsebob> | but I would hardly call it natural |
| 20:10:33 | <Saizan> | lunarisbluemoon: direct recursion or the use of combinators like foldl' / foldr are often more natural |
| 20:10:36 | <Beelsebob> | better to find a truely functional description of the problem |
| 20:10:43 | <mgee> | lunarisbluemoon: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2537#a2537 |
| 20:10:47 | <Saizan> | it mostly depends on the problem |
| 20:11:32 | <Saizan> | a State monad is most useful to organize a larger program than a little benchmark |
| 20:11:33 | <lunarisbluemoon> | mgee: That's not asking you to add "(RealFloat CReal) => " to every function, is it? |
| 20:11:44 | <lunarisbluemoon> | Saizan: this benchmark isn't that little. |
| 20:11:46 | <lunarisbluemoon> | :) |
| 20:11:50 | <mgee> | lunarisbluemoon: instead? |
| 20:12:15 | <lunarisbluemoon> | mgee: You need something like "instance RealFloat CReal where ..." somewhere don't you? |
| 20:12:30 | <lunarisbluemoon> | I've never used the package, sorry. |
| 20:12:39 | <lunarisbluemoon> | Does it provide both RealFloat and CReal? |
| 20:12:53 | <Saizan> | ?src RealFloat |
| 20:12:53 | <lambdabot> | Source not found. The more you drive -- the dumber you get. |
| 20:13:00 | <mgee> | lunarisbluemoon: mhh. it provides fractional. but not realfloat :-/ |
| 20:13:54 | <lunarisbluemoon> | Which function do you want? |
| 20:13:55 | <roconnor> | CReal isn't an instance of RealFloat |
| 20:13:56 | <lunarisbluemoon> | floatDigits? |
| 20:14:10 | <lunarisbluemoon> | Isn't CReal for "exact real arithmetic?" |
| 20:14:17 | <roconnor> | oh |
| 20:14:23 | <roconnor> | or is this some other CReal? |
| 20:14:46 | <lunarisbluemoon> | I'm not sure :) |
| 20:14:52 | <mgee> | lunarisbluemoon: yes it is. I want to use /=. This should be covered by Eq. mhh ok I investigate a little bit. thanks |
| 20:15:05 | <mgee> | roconnor: It is exact real arithmetic |
| 20:15:15 | <lunarisbluemoon> | mgee: As you say, shouldn't CReal have an Eq instance? |
| 20:15:15 | <J11> | Is there a monadic operator that works almost like >>= but is m a -> (a -> m b) -> m a ? |
| 20:15:41 | <mgee> | lunarisbluemoon: it has. i am wondering why haskell tells me to add an instance of realfloat just because i am using /= |
| 20:15:50 | <Baughn> | @type (/=) |
| 20:15:52 | <lambdabot> | forall a. (Eq a) => a -> a -> Bool |
| 20:16:04 | <Baughn> | Well, I don't think /= is what is doing it. |
| 20:16:10 | <lunarisbluemoon> | mgee: That may not be it - what are f and g's types in your pasting? |
| 20:16:27 | <lunarisbluemoon> | mgee: Alternatively, do the bodies of f and g reference any of the functions in the RealFloat typeclass? |
| 20:17:16 | <mgee> | lunarisbluemoon: I am not quite sure. Actually I am modifying someone else's work. I think f and g are "((Bool,Bool) -> Complex CReal)" |
| 20:17:17 | <lunarisbluemoon> | J11: Hoogle doesn't think so. |
| 20:17:17 | <roconnor> | mgee: using (/=) doesn't require a RealFloat instance |
| 20:17:34 | <lunarisbluemoon> | J11: At the risk of sounding stupid, what's the second argument's purpose? |
| 20:17:46 | <lunarisbluemoon> | (Since b seems unused?) |
| 20:18:15 | <lunarisbluemoon> | mgee: It's certainly not Eq that's causing this. |
| 20:18:26 | <roconnor> | what a strange error. |
| 20:18:44 | <lunarisbluemoon> | HeHe says :) |
| 20:19:17 | <roconnor> | oh |
| 20:19:23 | <Zao> | J11: const would satisfy your signature, but that's probably not what you intended. |
| 20:19:23 | <lunarisbluemoon> | Sorry, irssi went a bit haywire. |
| 20:19:28 | <roconnor> | Complex is broken |
| 20:19:32 | <roconnor> | and doesn't work with CReal |
| 20:19:55 | <mgee> | roconnor: whaat? oh no |
| 20:19:56 | <roconnor> | some idiot wrote: |
| 20:19:57 | <roconnor> | data (RealFloat a) => |
| 20:19:59 | <roconnor> | Complex a = !a :+ !a |
| 20:19:59 | <J11> | I don't needs it's output, the function will change a state |
| 20:20:00 | <roconnor> | deriving (Eq,Read,Show) |
| 20:20:03 | <roconnor> | into the standard |
| 20:20:10 | <roconnor> | ACTION glares at Simon |
| 20:20:15 | <mgee> | roconnor: so? |
| 20:20:37 | <roconnor> | the :+ constructor requires that the parameters be RealFloat for no good reason. |
| 20:20:47 | <roconnor> | @type (:+) |
| 20:20:48 | <lambdabot> | forall a. (RealFloat a) => a -> a -> Complex a |
| 20:20:51 | <mgee> | roconnor: oh no |
| 20:20:56 | <lunarisbluemoon> | God bless '98 xD |
| 20:21:16 | <Saizan> | roconnor: it's required for something in the instance of Num, iirc |
| 20:21:25 | <roconnor> | oh? |
| 20:22:10 | <roconnor> | I see |
| 20:22:16 | <roconnor> | That's still stupid |
| 20:22:27 | <Zao> | @type \a f -> a >>= \x -> f x >> pure x |
| 20:22:29 | <lambdabot> | forall (m :: * -> *) a a1. (Applicative m, Monad m) => m a -> (a -> m a1) -> m a |
| 20:22:30 | <Zao> | J11: Like that? |
| 20:22:52 | <roconnor> | mgee: the solution is to write your own Complex module/type |
| 20:22:58 | <roconnor> | mgee: and use that instead |
| 20:23:29 | <Zao> | @type \a f -> do { x <- a ; f x ; pure x } |
| 20:23:31 | <lambdabot> | forall (m :: * -> *) b a. (Monad m, Applicative m) => m b -> (b -> m a) -> m b |
| 20:23:35 | <Zao> | Or if you want to use fancy sugar :) |
| 20:23:55 | <J11> | yes looks like it |
| 20:23:55 | <mgee> | roconnor: I just discovered another CReal: http://darcs.augustsson.net/Darcs/CReal/ (this has an instance Num) |
| 20:24:24 | <roconnor> | mgee: you can probably just copy the Complex module from the report and fix it. |
| 20:24:31 | <roconnor> | mgee: that is the CReal I was thinking of. |
| 20:24:56 | <mgee> | roconnor: first I try to use that other CReal... this way I also get rid of the mpfr dependency |
| 20:25:19 | <roconnor> | oh |
| 20:25:38 | <roconnor> | mgee: right, I think that Augustsson's CReal might have a stupid RealFrac instance. |
| 20:26:17 | <roconnor> | I guess that is another solution, write a RealFrac instance for your CReal. I don't like that idea much myself. |
| 20:26:36 | <mgee> | ^^ |
| 20:27:24 | <Geheimdienst> | hey guys, i got a newbie question |
| 20:27:34 | <roconnor> | instance RealFloat CReal where |
| 20:27:36 | <roconnor> | floatRadix _ = error "CCeal.floatRadix" |
| 20:27:38 | <roconnor> | ... |
| 20:27:40 | <Geheimdienst> | i'm seeing a linker error when compiling |
| 20:28:25 | <Geheimdienst> | about 20 errors like this: t.o: In function `rWb_info': |
| 20:28:26 | <Geheimdienst> | (.text+0xaa): undefined reference to `mtlzm1zi1zi0zi0_ControlziMonadziError_zdf13_closure' |
| 20:28:35 | <Saizan> | Geheimdienst: use --make |
| 20:28:43 | <Zao> | Or -package whatever |
| 20:29:02 | <Geheimdienst> | you mean ghc --make ? |
| 20:29:11 | <Zao> | Or cabal, which concocts a nice command line from the packages listed in the .cabal file. |
| 20:29:11 | <roconnor> | CReal really ought not to be an instance of RealFloat. |
| 20:29:14 | <Zao> | Geheimdienst: YEs. |
| 20:29:25 | <roconnor> | > magnitude (1:+1) :: CReal |
| 20:29:26 | <lambdabot> | 1.4142135623730950488016887242096980785697 |
| 20:29:42 | <Geheimdienst> | ok great, that fixed it :-) |
| 20:29:42 | <roconnor> | but it seems to work |
| 20:29:47 | <Geheimdienst> | thanks a ton |
| 20:30:08 | <lunarisbluemoon> | So guys, excuse me asking again - will a state monad cost me a lot of speed? |
| 20:32:50 | <dons> | Haskell Platform testing time: http://projects.haskell.org/pipermail/haskell-platform/2009-June/000411.html |
| 20:32:53 | <Saizan> | lunarisbluemoon: it can cost some speed, yes, a way to make it faster is using the monad-ran package, however it depends on the use-case |
| 20:33:03 | <dons> | If you're on windows: check this installs, and let me no YES/NO: http://code.haskell.org/~refold/HaskellPlatform-2009.2.0.1-rc2-setup.exe |
| 20:33:10 | <dons> | Unix, same story, http://haskell.org/~duncan/haskell-platform-2009.2.0.1.tar.gz |
| 20:33:34 | <dons> | note: the windows installer will install GHC on your system |
| 20:34:10 | <lunarisbluemoon> | Saizan: Thanks; also should I be worried about using mutable arrays (IOArray for example)? |
| 20:35:25 | <roconnor> | lunarisbluemoon: the state monad does exactly the same thing as manually threading the state through your code. It simply provides combinators that make doing so easier. |
| 20:36:00 | <lunarisbluemoon> | roconnor: That makes sense, I'm just worried I'm making stupid errors. |
| 20:36:05 | <roconnor> | lunarisbluemoon: to answer if this is slow, I need to know what this is opposed to doing. |
| 20:36:06 | <lunarisbluemoon> | Since I'm way off getting the C speed. |
| 20:36:32 | <lunarisbluemoon> | roconnor: At the top level it's replacing having globals in C. |
| 20:36:42 | <lunarisbluemoon> | (I never said it was a nice benchmark :) |
| 20:37:00 | <Saizan> | lunarisbluemoon: large mutable arrays have poor GC performance currently |
| 20:37:06 | <mm_freak> | is there any way to easily parse any reasonable date/time string? |
| 20:37:15 | <mm_freak> | no specific format, that is |
| 20:37:18 | <lunarisbluemoon> | Saizan: I see; thanks for your help. |
| 20:37:48 | <lunarisbluemoon> | mm_freak: I only know of the parsedate package; not sure if it does what you want. |
| 20:38:17 | <lunarisbluemoon> | Afaik I think you need to give it a format string though. |
| 20:38:22 | <lunarisbluemoon> | :/ |
| 20:38:28 | <mm_freak> | Date.Time.Format has the parseTime function, but it asks for a specific format "with some variations allowed" |
| 20:39:25 | <paper_cc> | mm_freak: well, you won't be able to tell MM/DD/YYYY from DD/MM/YYYY in some cases anyway =) |
| 20:39:48 | <mm_freak> | hmm, then i |
| 20:39:58 | <mm_freak> | hmm, then i'll accept specific formats only =) |
| 20:41:55 | <roconnor> | ISO 8601 FTW! |
| 20:41:58 | <paper_cc> | ACTION lives in Russia and has great trouble understanding US dates formatted as MM/DD |
| 20:42:37 | <Zao> | Big-endian padded dates are nice. |
| 20:42:40 | <Zao> | Sorts well too. |
| 20:43:31 | <riddochc> | Right, so... now that I'm in front of my computer, I can see from ghci what (,) does. It wasn't obvious from when it's first used in the monads chapter of real world haskell. |
| 20:44:21 | <riddochc> | I'm running into a surprisingly large number of things in the real world haskell book, showing up in the code but never get explained. |
| 20:46:28 | <riddochc> | In the logger example, for the regexes, I can't find any definition for the execLogger aka runLogger function. |
| 20:46:28 | <paper_cc> | @where LYAH |
| 20:46:28 | <lambdabot> | www.learnyouahaskell.com |
| 20:46:45 | <paper_cc> | @ty runWriter |
| 20:46:46 | <lambdabot> | forall w a. Writer w a -> (a, w) |
| 20:47:04 | <paper_cc> | riddochc: Logger is a Writerish thing? |
| 20:48:58 | <riddochc> | paper_cc: It says it's a "specialized version of the standard Writer monad" but it doesn't elaborate on that for another 50 pages, and I haven't gotten that far yet. |
| 20:49:18 | <paper_cc> | @where RWH |
| 20:49:18 | <lambdabot> | is http://www.realworldhaskell.org/blog/ |
| 20:50:39 | <riddochc> | paper_cc: Yeah, I haven't looked at what's on the site very carefully, I'm working through the dead-tree version from the library. |
| 20:52:57 | <mgee> | Ok now I got it nearly working! Just one thing missing. CReal is missing the Random instance. So I wanted to add one and let is just wrap around the Double Random instance. I use this code: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2538#a2538 |
| 20:53:00 | <paper_cc> | the @where was for me =) |
| 20:53:01 | <paper_cc> | riddochc: the logger example starts with "We'll intentionally keep the internals of the Logger module abstract." and section title "Information hiding" |
| 20:53:04 | <mgee> | the error is also in the paste |
| 20:53:32 | <mgee> | I know that the right side will evaluate to a double value. but if i use read $ random ... I get errors tooo... :( so,ebopdy know why? |
| 20:54:09 | <paper_cc> | @ty randomR |
| 20:54:10 | <lambdabot> | forall a g. (Random a, RandomGen g) => (a, a) -> g -> (a, g) |
| 20:54:29 | <mgee> | Here is the paste with the read $ and the new errors: http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2539#a2539 |
| 20:54:42 | <riddochc> | Hmm. Seems several other people had the same confusion I have - see comments on first paragraph of "Using a new monad: show your work!" |
| 20:54:52 | <paper_cc> | @instances RandomGen |
| 20:54:53 | <lambdabot> | Couldn't find class `RandomGen'. Try @instances-importing |
| 20:55:15 | <Saizan> | ?type random |
| 20:55:16 | <lambdabot> | forall g a. (Random a, RandomGen g) => g -> (a, g) |
| 20:55:34 | <Saizan> | mgee: ^^^ the argument is the generator |
| 20:55:47 | <mgee> | ah oh |
| 20:55:52 | <paper_cc> | mgee: well, Double is not an instance of RandomGen |
| 20:55:57 | <Saizan> | mgee: not of the type of value you want to generate |
| 20:56:03 | <paper_cc> | @instances-importing System.Random RandomGen |
| 20:56:04 | <lambdabot> | StdGen |
| 20:56:30 | <mgee> | paper_cc: mhh... so how would i wrap my instance around the random instance of double? |
| 20:56:37 | <Saizan> | so you need something like random g = let (d,g') = random g in (read $ show d,g') |
| 20:56:55 | <sjanssen> | Saizan: or just fromRational? |
| 20:56:56 | <mgee> | Saizan: ah ok. I will try |
| 20:57:05 | <paper_cc> | sjanssen: or realToFrac? |
| 20:57:12 | <Saizan> | sjanssen: yeah, i was going to suggesting some other conversion |
| 20:57:19 | <sjanssen> | paper_cc: yeah, that's the one I meant |
| 20:57:24 | <Saizan> | but i'm not sure what works for Double -> CReadl |
| 20:57:50 | <Saizan> | *CReal |
| 20:58:12 | <refold> | /quit |
| 20:58:12 | <sjanssen> | > realToFrac (1 :: Double) :: CReal |
| 20:58:13 | <lambdabot> | 1.0 |
| 20:59:53 | <riddochc> | Hey, cool! My 2:00 AM idea has actually already been looked into - I had the idea that doing things with monads is like working with variations on progn in lisp. |
| 20:59:54 | <fynn> | Hey. |
| 20:59:55 | <fynn> | What's the equivalent of optparse for Haskell? |
| 21:00:33 | <fynn> | (A library like Python's optparse, for parsing command-line arguments) |
| 21:01:38 | <trofi> | @hoogle getOpt |
| 21:01:39 | <lambdabot> | System.Console.GetOpt getOpt :: ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String]) |
| 21:01:39 | <lambdabot> | module System.Console.GetOpt |
| 21:01:39 | <lambdabot> | System.Console.GetOpt getOpt' :: ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String], [String]) |
| 21:01:41 | <kynky> | ts a string, just parse it ? |
| 21:02:11 | <paper_cc> | @hackage parseargs |
| 21:02:11 | <lambdabot> | http://hackage.haskell.org/cgi-bin/hackage-scripts/package/parseargs |
| 21:02:14 | <JamesSanders> | Saizan: any good (src code) examples of hspread in use |
| 21:03:56 | <fynn> | trofi: so, System.Console.GetOpt should actually be in any 98-compliant Haskell implementation? |
| 21:04:32 | <trofi> | ACTION googles getopt page to read portability section |
| 21:04:40 | <paper_cc> | s/98-compliant/H'98-with-hierachical-modules-compliant/ at lease |
| 21:04:43 | <paper_cc> | *at least |
| 21:05:09 | <trofi> | Portability portable |
| 21:05:09 | <trofi> | Stability experimental |
| 21:05:29 | <trofi> | http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-Console-GetOpt.html |
| 21:06:00 | <hackagebot> | BoundedChan 1.0.0.2 |
| 21:06:13 | <paper_cc> | cabal-install and darcs use their own custom parsers anyway |
| 21:06:26 | <mgee> | Saizan: that works nearly... http://moonpatio.com/fastcgi/hpaste.fcgi/view?id=2539#a2540 sorry it seems like I am a bit slow today. I tried adding ::Double and ::CReal in some places but it didn't help |
| 21:06:49 | <trofi> | GetOpt.hs does not have any special exts |
| 21:07:51 | <gwern> | trofi: I suspect the stability is experimental because getopt is fairly hard to figure out |
| 21:08:08 | <mgee> | Saizan: i solved it :) |
| 21:08:14 | <gwern> | I had a dickens of a time working getopt out when I was trying to add real options to mueval |
| 21:08:26 | <idnar> | getopt is bad enough in C, why would you inflict it on yourself in Haskell? |
| 21:08:40 | <Igloo> | idnar: What would you recommend instead? |
| 21:08:48 | <tibbe> | is it possible import macros using hsc2hs? |
| 21:08:51 | <gwern> | Igloo: ad hoc parsing using drop and take! |
| 21:08:58 | <BONUS> | what's that library that draws data structures |
| 21:09:01 | <BONUS> | how they point to each other etc |
| 21:09:08 | <gwern> | BONUS: graphvzi |
| 21:09:09 | <fynn> | trofi: thanks. |
| 21:09:11 | <gwern> | *viz |
| 21:09:16 | <fynn> | paper_cc: you too. |
| 21:09:18 | <idnar> | Igloo: I'm not exactly an expert on Haskell command line parsing libraries :/ |
| 21:09:21 | <trofi> | gwern: heh, true. i used C' getopt, then ruby's and then haskell's. it was not so intuitive w/o reading docs :] |
| 21:09:23 | <BONUS> | i mean like the one where you pass it [1,2,3] |
| 21:09:30 | <kau> | hello all! how to display a counter that increment itself every seconds (using the State monad)? |
| 21:09:31 | <BONUS> | and it draws the cons' and stuff |
| 21:09:34 | <Igloo> | BONUS: vacuum |
| 21:09:39 | <BONUS> | ah vacuum, yeah |
| 21:09:49 | <gwern> | oh, you meant live haskell datastructures |
| 21:10:02 | <paper_cc> | BONUS: it's actually vacuum-graphviz || vacuum-ubigraph |
| 21:10:03 | <fynn> | gwern, Igloo, idnar: so the general consensus is, it's getOpt or nothing? |
| 21:10:03 | <gwern> | (graphviz can draw data structures. graphs, specifically) |
| 21:10:08 | <fynn> | ACTION misses Python :( |
| 21:10:15 | <gwern> | fynn: well, there are a few obscure other approachs |
| 21:10:19 | <BONUS> | ah :) |
| 21:10:22 | <gwern> | fynn: but who knows what other packages lurk on hackage! |
| 21:10:23 | <kau> | i can't figure it out with State |
| 21:10:31 | <paper_cc> | fynn: there's something called parseargs on hackage |
| 21:10:43 | <fynn> | gwern: there's this other one (yeah, parseargs) but it's self-designated Alpha |
| 21:10:50 | <Igloo> | fynn: getOpt is the best solution I know of |
| 21:11:12 | <fynn> | Igloo: cool. who knows, maybe we'll write an optparse port ourselves |
| 21:11:35 | <fynn> | we're going to be possibly the first commercial entity to release open source Haskell libraries... exciting |
| 21:11:49 | <gwern> | fynn: may not mean much. secretly, haskellers believe a package is only out of alpha/beta when the code is written in coq and compiled to haskell, and has been firetested by the nsa |
| 21:12:00 | <gwern> | fynn: sorry, but galois at least beat you to the punch by years |
| 21:12:18 | <fynn> | gwern: well, 2nd place is pretty good too ;) |
| 21:12:31 | <gwern> | ACTION stares at shoes. no, not there either |
| 21:12:40 | <kau> | nobody has got an idea for my problem? |
| 21:13:06 | <paper_cc> | kau: you can't do that |
| 21:13:21 | <gwern> | kau: where would the state monad get 'seconds' from? |
| 21:13:21 | <kau> | yes we can! |
| 21:13:31 | <fynn> | gwern: we're getting this guy to work in Haskell sort of full time. I'm a bit concerned that there's no large, open-source Haskell codebases out there that commercial entities depend on |
| 21:13:54 | <fynn> | I hope we won't discover down the road that it's because there are huge problems we can't foresee right now. |
| 21:14:02 | <gwern> | fynn: I'd say that just about every commercial entity depending on haskell also depends on that large open-source codebase we call ghc |
| 21:14:22 | <fracture> | is wxHaskell supposed to be good enough for real use? (it's randomly crashing and sometimes giving error dialog boxes about loading comctrl32.dll for me) |
| 21:14:24 | <fynn> | well, the thing is there's no visibility to those applications. |
| 21:14:52 | <kau> | gwern: there is threadDelay? |
| 21:15:00 | <gwern> | kau: but that's up in the IO monad |
| 21:15:00 | <fynn> | gwern: like, in Python, everything depends on CPython, so I can go "yeah, Google Groups and YouTube and a million Django websites are fire-testing CPython daily" |
| 21:15:14 | <Hunner> | If I have a (String -> IO ()) and I want to apply it to a [String], what am I looking for? |
| 21:15:14 | <riddochc> | Is there a good list of larger apps written in Haskell? |
| 21:15:41 | <gwern> | fynn: galois does high-performance, high security programs & libraries for government etc. and dons who works there tells me they're happy with ghc |
| 21:15:45 | <fynn> | with Haskell it's "there are rumored to be some super-secret Haskell stuff done by Galois for the nsa or something, but you need top-secret clearance to even know about it" |
| 21:15:45 | <Zao> | @src mapM_ |
| 21:15:47 | <lambdabot> | mapM_ f as = sequence_ (map f as) |
| 21:15:51 | <Zao> | @type mapM_ |
| 21:15:53 | <lambdabot> | forall a (m :: * -> *) b. (Monad m) => (a -> m b) -> [a] -> m () |
| 21:15:55 | <gwern> | Hunner: mapM |
| 21:15:59 | <Hunner> | thanks |
| 21:16:07 | <kau> | i would like my program to just output the number of seconds since it started, never ending... |
| 21:16:17 | <Zao> | As your function yields IO (), you probably don't care about the result, so mapM_ |
| 21:16:21 | <roconnor> | Hunner: mapM_ |
| 21:16:22 | <Zao> | mapM is when you want a list of the results. |
| 21:16:23 | <travisbrady> | fynn: did you see "Commercial Uses: Going functional on exotic |
| 21:16:23 | <travisbrady> | trades |
| 21:16:27 | <gwern> | fynn: nah, they're released stuff like cryptol which are pretty darn big |
| 21:16:29 | <travisbrady> | woops |
| 21:16:32 | <Hunner> | Yeah, saw that difference. Thanks guys |
| 21:16:42 | <fynn> | travisbrady: nope |
| 21:16:47 | <paper_cc> | kau: when you have time, it's either IO or FRP. State is pure so you can't use it |
| 21:16:47 | <gwern> | fynn: and travisbrady is linking you to a paper whose compiler/dsl was about 30k lines iirc |
| 21:16:59 | <kau> | gwern: oh |
| 21:17:01 | <travisbrady> | fynn: http://www.google.com/url?sa=t&source=web&ct=res&cd=3&url=http%3A%2F%2Fwww.lexifi.com%2Fdownloads%2Ffrankau.pdf&ei=wpYlSrzWI6eWswOxmozIBg&usg=AFQjCNGTOcU4y7JhznjELS76oxBpn9dweg&sig2=iR9U9TP98Zq7BATc1_ZD3Q |
| 21:17:13 | <Hunner> | ACTION wonders why mapM_ is the name of the function and not mapM' |
| 21:17:24 | <travisbrady> | ugh, woops again: www.lexifi.com/downloads/frankau.pdf |
| 21:17:30 | <Raevel> | @hoogle mapM |
| 21:17:30 | <lambdabot> | Prelude mapM :: Monad m => (a -> m b) -> [a] -> m [b] |
| 21:17:30 | <lambdabot> | Control.Monad mapM :: Monad m => (a -> m b) -> [a] -> m [b] |
| 21:17:30 | <lambdabot> | Data.Traversable mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b) |
| 21:17:33 | <Zao> | Hunner: It owes it to sequence_. Now where that got the underscore from... |
| 21:17:43 | <gwern> | kau: if you just want that, then your program will look something like 'main = main' 0; main' x = print x >> main' (x+1)' |
| 21:17:43 | <paper_cc> | @ty sequence' |
| 21:17:44 | <lambdabot> | Not in scope: `sequence'' |
| 21:17:46 | <Botje> | Hunner: maybe because it resembles _ in pattern matching? |
| 21:17:50 | <Raevel> | oh i can't read |
| 21:17:58 | <Zao> | Hunner: Probably related to how you use _ to skip binding pattern matches. |
| 21:18:21 | <gwern> | kau: and if you want every second, it'd be like 'threadDelay 1000 >> print x >> main' (x+1)', if you follow |
| 21:18:31 | <kau> | gwern: OK super |
| 21:18:43 | <fynn> | travisbrady: cool, thanks |
| 21:18:43 | <Zao> | > let f _ _ = "lol" in f 42 3 |
| 21:18:45 | <lambdabot> | "lol" |
| 21:18:56 | <gwern> | I can never remember, is it threadDelay 100 that is a second, or threadDelay 1000... |
| 21:19:01 | <fynn> | gwern: we're still sort of pioneering here. well, I guess it's also exciting. |
| 21:19:05 | <jmcarthur_work> | 1000000 |
| 21:19:07 | <Berengal> | gwern: 10^6 |
| 21:19:09 | <kau> | gwern: can i use map to remove the recursion? |
| 21:19:51 | <eu-prleu-peupeu> | hello |
| 21:19:58 | <O_4> | kau: why would you want to? |
| 21:20:00 | <gwern> | kau: not really. you're thinking something like 'main = map (\x -> threadDelay 1000 >> print x) [1..]', right? |
| 21:20:18 | <paper_cc> | @ty repeat |
| 21:20:19 | <kau> | gwern: exactly |
| 21:20:19 | <lambdabot> | forall a. a -> [a] |
| 21:20:21 | <gwern> | kau: but there's no guarantee that this will perform the way you think it will |
| 21:20:24 | <Zao> | @type sequence_ $ repeat $ threadDelay 1000 |
| 21:20:26 | <lambdabot> | Not in scope: `threadDelay' |
| 21:20:29 | <Zao> | @type sequence_ $ repeat $ ?threadDelay 1000 |
| 21:20:31 | <lambdabot> | forall (m :: * -> *) a t. (Monad m, ?threadDelay::t -> m a, Num t) => m () |
| 21:20:47 | <gwern> | kau: in theory, ghc could make it so that 1000 of those maps happen simultaneously. that's allowed |
| 21:21:02 | <paper_cc> | gwern: sequence_ $ zipWith (>>) (threadDelay 1000000) (map print [1..]) -- won't this work? |
| 21:21:18 | <kau> | gwern: oh, i guess some sort of strictness is needed here? |
| 21:21:22 | <Zao> | gwern: Which would be harmless as threadDelay is an IO action, and all yours does is generate a list of actions. |
| 21:21:24 | <gwern> | paper_cc: I don't know enough about sequence to say |
| 21:21:31 | <paper_cc> | @src sequence |
| 21:21:32 | <lambdabot> | sequence [] = return [] |
| 21:21:32 | <lambdabot> | sequence (x:xs) = do v <- x; vs <- sequence xs; return (v:vs) |
| 21:21:32 | <lambdabot> | --OR |
| 21:21:32 | <lambdabot> | sequence xs = foldr (liftM2 (:)) (return []) xs |
| 21:21:35 | <roconnor> | paper_cc: I don't think that typechecks |
| 21:21:52 | <paper_cc> | @ty threadDelay 1 |
| 21:21:53 | <lambdabot> | Not in scope: `threadDelay' |
| 21:22:00 | <Zao> | paper_cc: Control.Concurrent |
| 21:22:02 | <Berengal> | @type let threadDelay :: Int -> IO (); threadDelay = undefined in mapM_ (\x -> threadDelay 1000 >> print x) [1..] |
| 21:22:04 | <lambdabot> | IO () |
| 21:22:39 | <paper_cc> | @type let threadDelay :: Int -> IO (); threadDelay = undefined in zipWith (>>) (threadDelay 1) (map print [1..]) |
| 21:22:40 | <lambdabot> | Couldn't match expected type `[m a]' against inferred type `IO ()' |
| 21:22:40 | <lambdabot> | In the second argument of `zipWith', namely `(threadDelay 1)' |
| 21:22:40 | <lambdabot> | In the expression: |
| 21:22:50 | <gwern> | now, a fold might work |
| 21:22:52 | <paper_cc> | oh |
| 21:22:55 | <Berengal> | @src sequence_ |
| 21:22:56 | <lambdabot> | sequence_ ms = foldr (>>) (return ()) ms |
| 21:23:02 | <gwern> | oh :) |
| 21:23:12 | <jmcarthur_work> | heh |
| 21:23:14 | <Berengal> | @src sequence |
| 21:23:14 | <lambdabot> | sequence [] = return [] |
| 21:23:14 | <lambdabot> | sequence (x:xs) = do v <- x; vs <- sequence xs; return (v:vs) |
| 21:23:14 | <lambdabot> | --OR |
| 21:23:14 | <lambdabot> | sequence xs = foldr (liftM2 (:)) (return []) xs |
| 21:23:26 | <mgee> | Is it in Haskell impossible to use a Complex Number with arbitrary precision? I think so because the Complex Type requires the RealFloat instance. And this instance want decodeFloat and encodeFloat, which is not possible for a real with arbitrary precision, right? |
| 21:23:46 | <rubendv> | paper_cc: do a repeat on the threadDelay |
| 21:23:52 | <paper_cc> | roconnor: it should be (repeat $ threadDelay 1000000), sorry |
| 21:23:52 | <Berengal> | mgee: Write your own Complex type |
| 21:23:54 | <gnuvince_> | @index comparing |
| 21:23:55 | <lambdabot> | bzzt |
| 21:23:55 | <rubendv> | zipWith needs two lists |
| 21:23:57 | <roconnor> | mgee: unless you give make a "fake" RealFloat instance, yes |
| 21:24:10 | <ray> | encodeFloat = error "floats suck" |
| 21:24:29 | <roconnor> | mgee: this is what numbers package does. |
| 21:24:32 | <mgee> | yeah then my programm terminates |
| 21:24:37 | <jmcarthur_work> | :t (1 :: CReal) :+ 2 |
| 21:24:39 | <lambdabot> | Complex CReal |
| 21:25:05 | <fynn> | paper_cc: what does "with compliant hierarchal modules" mean? what kind of a standard is that? |
| 21:25:10 | <paper_cc> | @ty let threadDelay = undefined :: Int -> IO (); print = undefined :: (Show a) => a -> IO () in sequence_ $ zipWith (>>) (repeat $ threadDelay 1) (map print [1..]) |
| 21:25:12 | <lambdabot> | IO () |
| 21:25:13 | <mgee> | Mhh so I have to find the function which is causing the encodeFloat to be called, right? |
| 21:25:19 | <roconnor> | decodeFloat _ = error "CReal.decodeFloat" |
| 21:25:21 | <roconnor> | encodeFloat _ _ = error "CReal.encodeFloat" |
| 21:25:27 | <kau> | sequence $ map (\x -> threadDelay 1000000 >> print x) [1..] works fine!! |
| 21:25:32 | <roconnor> | this is how numbers defines those functions for CReal. |
| 21:26:03 | <gwern> | fynn: it means that one could do 'import Data.List' instead of 'import List' |
| 21:26:12 | <Berengal> | kau: 'seuqence . map' is called mapM, and 'sequence_ . map' is called mapM_, just FYI |
| 21:26:22 | <gwern> | fynn: otherwise you basically have a flat module hierarchy - no nesting |
| 21:26:24 | <roconnor> | mgee: Complex uses magnitude which uses scaleFloat and exponent for precision. |
| 21:26:28 | <paper_cc> | fynn: the hierachical modules addendum (IO -> System.IO, Random -> System.Random etc) |
| 21:26:30 | <roconnor> | @src magnitude |
| 21:26:30 | <lambdabot> | Source not found. Maybe if you used more than just two fingers... |
| 21:26:39 | <kau> | Berengal: tks |
| 21:26:42 | <roconnor> | @type magnitude |
| 21:26:44 | <lambdabot> | forall a. (RealFloat a) => Complex a -> a |
| 21:26:44 | <gwern> | fynn: the hierarchical module is an addition to the haskell '98 standard |
| 21:26:44 | <Berengal> | kau: Also note that it will never return, so using 'sequence' over 'sequence_' is a space leak |
| 21:26:47 | <mgee> | roconnor: ah ok. I saw some code piece which used magnitude |
| 21:26:50 | <roconnor> | src is so random |
| 21:27:02 | <mgee> | roconnor: thanks |
| 21:28:08 | <kau> | i first asked this question to me reading the State monad chapter from RWH |
| 21:28:09 | <fynn> | gwern, paper_cc: OK, so the 3 levels of standards are: 1) Core '98, 2) standard additions to the '98 standard (where are those defined?), 3) platform-specific extensions, defined ad-hoc by the extender (I understand GHC has a ton of those) |
| 21:28:18 | <kau> | indeed i understood quite nothing |
| 21:28:48 | <kau> | is this example re-writable with State? |
| 21:28:55 | <paper_cc> | fynn: really I'm not much into this, but at least there are 1) the FFI addendum and 2) the hierachical modules addendum |
| 21:29:02 | <paper_cc> | kau: no |
| 21:29:03 | <gwern> | fynn: I'd add the common subset of platform-specific extensions between ghc/hugs/yhc as 3.5 |
| 21:29:11 | <gwern> | CPP, for example. I think everyone has CPP |
| 21:29:25 | <paper_cc> | kau: time is an impure thing |
| 21:29:39 | <kau> | but State is monadic! |
| 21:29:50 | <paper_cc> | kau: Maybe is monadic too |
| 21:29:54 | <kau> | i figured out that monads where for impure things ;) |
| 21:30:02 | <paper_cc> | kau: nope |
| 21:30:11 | <gwern> | kau: monads are mu! |
| 21:30:19 | <kau> | a state is impure? |
| 21:30:29 | <paper_cc> | kau: State, Writer, Reader, Maybe are perferctly pure |
| 21:30:31 | <Cale> | kau: That's only part of what they're good for. |
| 21:30:36 | <gwern> | do not ask what monads are; let monads ask what you are |
| 21:30:37 | <kau> | yes |
| 21:30:42 | <Cale> | heh |
| 21:30:44 | <gnuvince_> | Is it normal that with a very large list (235,000 words) the following code overflows the stack: maximumBy (comparing length) myWords |
| 21:30:53 | <gnuvince_> | (unless I compile with -O2) |
| 21:30:58 | <Cale> | gnuvince_: yeah |
| 21:30:58 | <ray> | do not use monads, use haskell |
| 21:31:08 | <gwern> | realize the truth: there is no monad. |
| 21:31:16 | <paper_cc> | kau: a state emulates a mutable state, but there's no mutability inside it |
| 21:31:19 | <ray> | there is only Monad |
| 21:31:20 | <Heffalump> | @src maximumBy |
| 21:31:21 | <lambdabot> | Source not found. That's something I cannot allow to happen. |
| 21:31:27 | <Heffalump> | @src Data.List.maximumBy |
| 21:31:27 | <lambdabot> | Source not found. Have you considered trying to match wits with a rutabaga? |
| 21:31:34 | <mux> | monads hide side effects under the carpet. |
| 21:31:37 | <paper_cc> | kau: s/a state/the State/ |
| 21:31:40 | <gnuvince_> | Cale: to much thunking? |
| 21:31:43 | <gnuvince_> | *too |
| 21:32:03 | <Heffalump> | it's a foldl, is the problem |
| 21:32:04 | <Cale> | gnuvince_: The problem is that without optimisations, strictness analysis isn't done, and a large expression is constructed consisting of all the elements of the list combined with a max-type function. |
| 21:32:07 | <Heffalump> | so not designed for lazy things like that |
| 21:32:30 | <paper_cc> | kau: State s a is just a fancy way to write a function s -> (s, a) which is perfectly pure |
| 21:32:36 | <Cale> | gnuvince_: Finding a reducible subexpression in that is what causes the stack to overflow. |
| 21:32:46 | <kau> | imaging you receive input from time to time from the user, and you have to compare each inputs to others, would you use State? |
| 21:32:48 | <Heffalump> | why is sum a foldl? |
| 21:33:02 | <Cale> | There really ought to be a sum' |
| 21:33:11 | <Cale> | and a maximumBy' and all those. |
| 21:33:38 | <conal> | time needn't be modeled impurely. |
| 21:33:38 | <Cale> | Though, strictness analysis is good enough now that it usually finds this sort of thing. |
| 21:33:41 | <Zao> | let maximumBy' = tickify maximumBy |
| 21:33:59 | <Zao> | The implementation of tickify is left as an exercise for the reader. |
| 21:34:10 | <ray> | compiler magic |
| 21:35:59 | <paper_cc> | conal: well, is there a way to access time other than doing some IO? |
| 21:36:09 | <kau> | the State monad is a mystery for me ;) |
| 21:37:17 | <gwern> | ACTION has a sudden vision of 50 years from now. people will be writing webpages like 'The Road to FRP', and creating motivational posters of conal which read 'programming: ur doing it rong', and the mainstreamers will be looking up from their GADT design patterns and deriding those FRPers |
| 21:37:33 | <roconnor> | @src State |
| 21:37:34 | <lambdabot> | Source not found. Just try something else. |
| 21:37:35 | <Berengal> | kau: The State monad is just regular code, except it carries one extra value around for you behind the scenes. You can read this value as you wish, and exchange it for a new value in the remaining computation |
| 21:38:18 | <gwern> | @quote state |
| 21:38:18 | <lambdabot> | state says: ?. ++ . read . show . state ?. ++ . read . show . state |
| 21:38:24 | <kau> | Berengal: i see |
| 21:38:29 | <gwern> | @quote state |
| 21:38:29 | <lambdabot> | state says: ?. ++ . read . show . state ?. ++ . read . show . state |
| 21:38:33 | <conal> | gwern: :) |
| 21:38:45 | <gwern> | I'm tempted to delete that quote because it makes no sense whatsoever |
| 21:38:54 | <gwern> | @hoogle (?.) |
| 21:38:54 | <lambdabot> | No results found |
| 21:39:20 | <roconnor> | kau: the state monad just offers a better way of writing f s x = y where {(s1,y1) = foo s x; (s2,y2) = bar s1 y1; (s3,y3) = baz s2 y2; (s4,y) = quux s3 y3} |
| 21:39:41 | <conal> | paper_cc: yeah. check out frp. |
| 21:40:16 | <paper_cc> | conal: well, the interface is pure, but there's still IO under the hood |
| 21:40:34 | <Heffalump> | paper_cc: that's true of any Haskell code |
| 21:40:40 | <conal> | paper_cc: there's IO under the hood of 2+3 |
| 21:40:45 | <Heffalump> | it's just hidden by the compiler rather than by unsafePerformIO |
| 21:40:49 | <kau> | ok, then there is no possibility to hold a state through time (during a certain amout of time)? |
| 21:41:16 | <roconnor> | kau: time is not really relvent to state. |
| 21:41:24 | <Berengal> | kau: Not with State |
| 21:41:30 | <roconnor> | kau: depending on what you mean by time. |
| 21:41:33 | <conal> | all of functional programming is implemented via unsafePerformIO (by some name). |
| 21:41:49 | <Twey> | Ergo, unsafePerformIO is a compiler hook, not a part of Haskell. |
| 21:41:55 | <kau> | Berengal with what instead? |
| 21:42:08 | <conal> | Twey: indeed! |
| 21:42:24 | <gwern> | IO? in *my* 2+3? |
| 21:42:51 | <augustss> | gwern: not in your 2+3, because you never see the result :) |
| 21:43:04 | <Berengal> | kau: There are IORefs, which are mutable references living in the IO monad |
| 21:43:04 | <Twey> | Hehe |
| 21:43:09 | <paper_cc> | > let 2+3 = "IO" in 2+3 |
| 21:43:10 | <lambdabot> | "IO" |
| 21:43:12 | <gwern> | augustss: dang it, you were supposed to say 'it's more likely than you think!' |
| 21:43:17 | <conal> | i mean things like side-effecting registers. |
| 21:43:18 | <kau> | roconnor: say user inputs |
| 21:43:25 | <kau> | Berengal: oh |
| 21:43:36 | <Twey> | > let 2+3 = print "hi" in 2+3 |
| 21:43:37 | <lambdabot> | <IO ()> |
| 21:43:50 | <SubStack> | what |
| 21:43:55 | <jkramer> | Hello, I have another newbie question |
| 21:44:08 | <augustss> | > let 2+3 = "Hello" in 2+3 |
| 21:44:09 | <lambdabot> | "Hello" |
| 21:44:14 | <kau> | Berengal: thats the way to do it? i missed that! ;) |
| 21:44:15 | <gwern> | SubStack: it's lambdabot's l33t security measures |
| 21:44:16 | <jkramer> | When I have a rather complex data type and I want to change a single element |
| 21:44:44 | <jkramer> | Is there a nice way to do it or should I make a constructor that copies all the other values and only sets the one I change? |
| 21:44:46 | <SubStack> | I am more boggled by the ability to define 2+3 like that |
| 21:44:51 | <Berengal> | > let 2+2 = 5; a+b = a - (-b); fibs = 1:1:zipWith (+) fibs in sum (take 10 fibs) |
| 21:44:52 | <lambdabot> | Couldn't match expected type `[t]' |
| 21:44:56 | <Berengal> | :/ |
| 21:45:08 | <Berengal> | kau: That's one way to do it |
| 21:45:08 | <jmcarthur_work> | jkramer, look into records? |
| 21:45:12 | <byorgey> | jkramer: there is a nice way to do it if you have given the elements of the structure names using record syntax. |
| 21:45:13 | <sjanssen> | jkramer: you can use record syntax |
| 21:45:14 | <BONUS> | or zippers |
| 21:45:24 | <byorgey> | i.e. data Foo = { x :: Int, y :: Double, z :: Char } |
| 21:45:41 | <kau> | jkramer: there is someting like let a = rec { foo = "toto"} |
| 21:45:42 | <byorgey> | jkramer: then if f :: Foo, you can change just the x field of f by f { x = 6 } |
| 21:45:57 | <roconnor> | jkramer: also see the Data.Accessor package. |
| 21:46:31 | <jkramer> | If record syntax is the :: Type-stuff then I'm already using it :) |
| 21:47:11 | <gwern> | no, records are more like {} |
| 21:47:28 | <jkramer> | Like: data Foo = Foo { something :: String } deriving ... |
| 21:47:37 | <paper_cc> | jkramer: that's it |
| 21:47:39 | <byorgey> | yup, that's record syntax |
| 21:47:42 | <jkramer> | \o/ |
| 21:47:49 | <byorgey> | jkramer: as opposed to just data Foo = Foo String |
| 21:48:14 | <Axman6> | jkramer: nice thing about it is you can still pattern match on those datatypes too |
| 21:48:39 | <paper_cc> | jkramer: you can then write things like \(foo :: Foo) -> foo { something = "changedValue" } |
| 21:49:16 | <jkramer> | I'll try it, wait a second :) |
| 21:49:18 | <Axman6> | so you can have data Vec = V {x,y,z :: Double}, and you can still have a function f :: Vec -> Double; f (V a b c) = a + b + c |
| 21:49:25 | <Jedai> | Axman6: and contruct them the same way you always did... In fact record syntax is more or less just syntax sugar over algebraic data types |
| 21:49:34 | <Axman6> | yup |
| 21:50:07 | <BONUS> | do {handle <- ContT $ withFile "foo.txt" ReadMode; lift $ putStrLn "blah"; ... |
| 21:50:12 | <BONUS> | learned this trick today here |
| 21:50:14 | <BONUS> | pretty cool :] |
| 21:50:21 | <Axman6> | so you can also say V 1.0 2.5 3.7, which is the same as V { x = 1.0, y = 2.5, z = 3.7} |
| 21:50:21 | <Jedai> | but you can also do "f (V {y = yv}) = yv + 3 |
| 21:50:39 | <BONUS> | never thought of withFile as returning a CPS transformed value |
| 21:50:40 | <Axman6> | :o |
| 21:50:55 | <paper_cc> | @ty ContT |
| 21:50:56 | <lambdabot> | forall a (m :: * -> *) r. ((a -> m r) -> m r) -> ContT r m a |
| 21:51:08 | <paper_cc> | wow |
| 21:51:13 | <kau> | are "IOref" academic? i didn't came across it since i began with haskell that's why i'm asking lol |
| 21:51:29 | <paper_cc> | @google Monadic state transformers |
| 21:51:29 | <Jedai> | What's funny is that with GHC at least, you can use the special pattern "Contructor {}" even with datatypes that don't use record syntax |
| 21:51:30 | <lambdabot> | http://en.wikibooks.org/wiki/Haskell/Monad_transformers |
| 21:51:32 | <Axman6> | kau: i don't understand what you mean |
| 21:51:53 | <kau> | are IOref safe? |
| 21:51:55 | <jkramer> | Hmm, I don't completely get it. I have: updateSessionInput session newInput = UserSession { userInput = newInput } |
| 21:51:56 | <Axman6> | they're pretty widely used, the OpenGL bindings use them a lot |
| 21:52:10 | <jkramer> | Now I get a lot of warnings that everything but userInput is uninitialized |
| 21:52:14 | <jkramer> | Did I mis something |
| 21:52:14 | <jkramer> | ? |
| 21:52:15 | <Jedai> | kau: IORef, academic ? IORef are pretty much like normal variables in imperative languages |
| 21:52:24 | <kau> | and good programming style ;) |
| 21:52:25 | <Axman6> | Jedai: replace the UserSession with session |
| 21:52:32 | <Jedai> | kau: they're as "safe" as those always are |
| 21:52:43 | <O_4> | s/Jedai/jkramer/ |
| 21:52:46 | <jkramer> | Yay, works!3! \o/ |
| 21:52:51 | <jkramer> | Thanks a lot :) |
| 21:52:56 | <Axman6> | uh yeah, sorry. meant jkramer |
| 21:53:02 | <jkramer> | I have no Idea where the 3! came from |
| 21:53:39 | <kau> | Jedai, Axman6: ok i see |
| 21:53:51 | <Axman6> | kau: MVars are far more interesting imo |
| 21:54:10 | <kau> | Axman6: i'll have a look;) |
| 21:54:25 | <paper_cc> | IORef -> MVar -> TVar -> ? |
| 21:54:33 | <Axman6> | MVars let you do pretty safe and fast concurrency |
| 21:54:44 | <Axman6> | TMvar ;) |
| 21:56:40 | <kau> | i have to go, thanks a lot for your answers!!! |
| 21:56:44 | <conal> | paper_cc: -> NoVar |
| 21:56:46 | <Axman6> | kau: also, if you feel you need to use mtuable variables, check out the ST monad. it's basically the IO monad without all the dangerous stuff |
| 21:57:50 | <paper_cc> | conal: -> Behavior ? |
| 21:58:09 | <conal> | paper_cc: yeah! |
| 22:02:28 | <FunctorSalad> | any ideas what this could be? "error: macro "hsc_const" passed 2 arguments, but takes just 1" |
| 22:02:40 | <FunctorSalad> | (when running hsc2hs on something generated by hsffig) |
| 22:03:20 | <FunctorSalad> | I know it's referring to a CPP macro, but why would it mismatch? :( |
| 22:04:44 | <Axman6> | what's the macro? |
| 22:05:08 | <FunctorSalad> | "hsc_const" - no idea what its purpose is |
| 22:05:36 | <FunctorSalad> | some version mismatch of hsffig and hsc2hs? |
| 22:05:52 | <jkramer> | Is there a nice way to check if there's input on a handle or EOF reached? hIsEOF seems to block until there's actually input or EOF, and if I do hWaitForInput first, it crashes when EOF is reached |
| 22:07:07 | <FunctorSalad> | I don't know of a *nice* way, but you could run either isEOF in a seperate thread, or run hWaitForInput and catch the exception |
| 22:07:44 | <paper_cc> | jkramer: maybe hReady? |
| 22:08:15 | <jkramer> | paper_cc: I think hReady would crash on EOF too |
| 22:08:23 | <paper_cc> | ACTION opens ghci |
| 22:08:26 | <jkramer> | FunctorSalad: How can I catch the exception? |
| 22:08:34 | <jkramer> | paper_cc: At least it says so in the docs |
| 22:08:35 | <paper_cc> | @hoogle catch |
| 22:08:35 | <lambdabot> | package catch |
| 22:08:36 | <lambdabot> | Prelude catch :: IO a -> (IOError -> IO a) -> IO a |
| 22:08:36 | <lambdabot> | Control.Exception catch :: IO a -> Exception -> IO a -> IO a |
| 22:09:59 | <troutwine> | Anybody have resources for stateful parsing with Parsec? (I'm parsing chess notation out of PGN files and would like the resulting AST to have absolute positioning.) |
| 22:15:45 | <troutwine> | Ah, seems Parsec has an embedded user state. Nevermind, then. |
| 22:15:50 | <paper_cc> | @ty \h -> (hReady h >> (return . Just)) `catch` (\e -> if isEOFError e then return Nothing else ioError e) -- the not-so-pretty way to solve jkramer's problem |
| 22:15:51 | <lambdabot> | Not in scope: `hReady' |
| 22:15:51 | <lambdabot> | Not in scope: `isEOFError' |
| 22:17:49 | <dons> | The Haskell Platform 2009.2.0.1 release is live: be a little bit more awesome today: http://hackage.haskell.org/platform/ |
| 22:19:00 | <sm> | woot! |
| 22:19:39 | <FunctorSalad> | if anyone cares, the offending expression generated by hsffig (on which hsc2hs chokes) was "#const( 2 ), #const( 2 )" |
| 22:19:47 | <dons> | tell your friends. install haskell on their machines :) |
| 22:19:53 | <FunctorSalad> | apparently the preprocessor misinterprets the comma? |
| 22:20:10 | <Badger> | dons: or House? :P |
| 22:21:28 | <troutwine> | dons: Is the Haskell Platform not installing on Arch a known issue (wants happy 1.18.2, system has 1.18.4)? |
| 22:21:47 | <sm> | dons: are there release notes ? any word on the mac installer ? |
| 22:22:17 | <dons> | troutwine: Arch isn't updated yet (look at the version) |
| 22:22:22 | <dons> | working on it NOW, troutwine |
| 22:22:36 | <dons> | sm, mac installer close. i'll put up some release notes. |
| 22:22:49 | <dons> | http://trac.haskell.org/haskell-platform/wiki/2009.2#CandidatesforUpgradein2009.2.0.1 |
| 22:22:52 | <sm> | fantastic, thanks a lot for working on this |
| 22:22:53 | <dons> | release notes ^^ |
| 22:23:05 | <sm> | this = HP |
| 22:23:12 | <troutwine> | dons: Woops, quite true. My apologies. |
| 22:26:36 |